From 9064e32f29027e20ed8437fd7e4f2134e3290b91 Mon Sep 17 00:00:00 2001 From: Panos Koutsovasilis Date: Tue, 17 Jun 2025 08:46:57 +0300 Subject: [PATCH 1/9] feat: vendor all necessary test artifacts for kubernetes integration to minimise flakiness due to transient errors --- Makefile | 1 + NOTICE-fips.txt | 60 +- NOTICE.txt | 60 +- .../charts/kube-state-metrics-5.30.1.tgz | Bin 0 -> 14581 bytes go.mod | 4 +- magefile.go | 30 + pkg/testing/kubernetes/kustomize.go | 47 + testing/integration/k8s/common.go | 25 - testing/integration/k8s/journald_test.go | 2 - testing/integration/k8s/k8s.go | 20 + .../k8s/kubernetes_agent_service_test.go | 2 +- .../k8s/kubernetes_agent_standalone_test.go | 66 +- testing/integration/k8s/otel_helm_test.go | 20 +- .../k8s/testdata/elastic-agent-kustomize.yaml | 1231 +++++++++++++++++ .../opentelemetry-kube-stack-0.3.9.tgz | Bin 0 -> 196265 bytes 15 files changed, 1420 insertions(+), 148 deletions(-) create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics-5.30.1.tgz create mode 100644 pkg/testing/kubernetes/kustomize.go create mode 100644 testing/integration/k8s/k8s.go create mode 100644 testing/integration/k8s/testdata/elastic-agent-kustomize.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack-0.3.9.tgz diff --git a/Makefile b/Makefile index d3415691eaf..6e3854c1467 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,7 @@ check-ci: @mage -v helm:lint @mage -v helm:updateAgentVersion @mage -v helm:renderExamples + @mage -v integration:buildKubernetesTestData @$(MAKE) check-no-changes ## check: run all the checks including linting using golangci-lint. diff --git a/NOTICE-fips.txt b/NOTICE-fips.txt index 25e9ee01688..8d285471ec7 100644 --- a/NOTICE-fips.txt +++ b/NOTICE-fips.txt @@ -109,6 +109,36 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-------------------------------------------------------------------------------- +Dependency : github.com/cenkalti/backoff/v5 +Version: v5.0.2 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/cenkalti/backoff/v5@v5.0.2/LICENSE: + +The MIT License (MIT) + +Copyright (c) 2014 Cenk Altı + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + -------------------------------------------------------------------------------- Dependency : github.com/cespare/xxhash/v2 Version: v2.3.0 @@ -36741,36 +36771,6 @@ SOFTWARE. --------------------------------------------------------------------------------- -Dependency : github.com/cenkalti/backoff/v5 -Version: v5.0.2 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/cenkalti/backoff/v5@v5.0.2/LICENSE: - -The MIT License (MIT) - -Copyright (c) 2014 Cenk Altı - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------------- Dependency : github.com/cespare/xxhash Version: v1.1.0 diff --git a/NOTICE.txt b/NOTICE.txt index 3132856e2c0..35800802151 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -109,6 +109,36 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-------------------------------------------------------------------------------- +Dependency : github.com/cenkalti/backoff/v5 +Version: v5.0.2 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/cenkalti/backoff/v5@v5.0.2/LICENSE: + +The MIT License (MIT) + +Copyright (c) 2014 Cenk Altı + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + -------------------------------------------------------------------------------- Dependency : github.com/cespare/xxhash/v2 Version: v2.3.0 @@ -38378,36 +38408,6 @@ SOFTWARE. --------------------------------------------------------------------------------- -Dependency : github.com/cenkalti/backoff/v5 -Version: v5.0.2 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/cenkalti/backoff/v5@v5.0.2/LICENSE: - -The MIT License (MIT) - -Copyright (c) 2014 Cenk Altı - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------------- Dependency : github.com/cespare/xxhash Version: v1.1.0 diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics-5.30.1.tgz b/deploy/helm/elastic-agent/charts/kube-state-metrics-5.30.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..05bd6fd564702bc7052277f56af5d55dc0b220a6 GIT binary patch literal 14581 zcmVDc zVQyr3R8em|NM&qo0PMYcbK5r7Fus5DQ{a`dZ|puHB|FY#HBX*dH%Z&fCaK3xyT4~T znFb;u2{lQu0BA=|^ZV@Y;NU{=B8ie6C(W9jX)F>rH~5- zmX$e`%h7_QSr{uIBESXxnQ%c_K0z0U0WJ#n^DsJi5RHR`h?vtt!n+r_kT^|Io3xQ+ zXijp%u_OrR2_o+cCJ2htQb@wXlw6P$nZm(>sg86YtN`?MYmzd^+LuHa-nof|!ocGU9+FOeXOf zAo{y5+aAS00Oi0iY(E2XS&#|BMUm1NXgj#D1oI%eKaLK9&%Nxvn5Sd-E^t~Bag73C zJ^w#CIvgK0`2T~0qer*=|0bRxdPZirOeNCOj%JK^tj8#*c-C3Wv07h}mn5JWo)aZG zIGIx+`Eug^iq0R4h%)$AFrnDrvTLn(Ea3p5A$l=GWiE(Br6A}6{TGTrsEDW%00BZ0 z&nIXw2oMqrZ2l_BG(BM{jh7SjV)mNJ6HWxlWuVbLDbw_f#GFVmLBG5WhE8e?;Cra* zhXP6rf?%GqDNZMV(;J2sBrQ;e=I^Fmnqr5hgiLikV?D=w3jhX6owhg z5y(+pK{x652BFq?nD=%-Dg+KzemR6MjBf?L3veA|=Tspy^aifLoaEAuxnzi45YA~r z91Wrc6H*~;0iHTC9Snj1h)j`~WI)dMkX%rKE@_&ggcK=Tc4-k)Uq3-qK6GeTD7WZ z7)vr=qRR!zkq=T~m{0*QqhN?QnNBqdmod+2Vh z{#_K~9Hj&&KyQ}}@iNb$Z%Sp&W5a$i5(~zqYKpQ%Ep16NqIgP5(A`tD92_+Lx2lpU zop+84L~|fSg;5FZo|*nlkgcmG;B}cz30KfrnxF+0ia#sFI8i#N`U}G3rJ|#x%oMTQLt&V*c{rmfxrd01)nKUcQRG%I zA?P$!|I5KT)ZZ$Q*D^~Q7_>qP`&PgR-H9ORE=h{}6ab83tg zztCz`Dadov@F`P_X~{|+T3kX^E3h3lv!mC4h)&BKMp_N#)3lU?<0PXwDmc9mC?`Z| z4I%pR^~?V?!%kxr9vtuc8O)YfX~3-Ps@}z4*#?+#T3b_W%Pa-p?@o$Z#bo; ze1TZrDysUY9YUaYXm?eDet7fd1d%)`7|kWxb9$+oHIfqbd#Q-TG_fBU&4!cTOCqEI zMNW}BQG9{3a=y^ZU(+=#16Url3LvRe(`Qkj@KlTRL}A&X?HO%b%Y@1_{Jq3WZ4%av z!YRjj{Ku%#dng9>-NiUMcpM$Vi^|MfXXvR3+dWPC$U|ov>uzHJ|{J_fms9-Jpj{EY3mo*25eYED0S|k1R-dMcylAoXAiv zNZ9-m&KM7IRaFTE`}bKLF-vtgQ3}B+WAZzi60sDLWQK#O0-z|IaC$*gGAGYPj8m*V z$d&FA<3igyN_#PW?1Zzz{vD#@moI~$#ymixD?0eMVrwNBf1D_Loa71088ClgCe0cf zuD)KyOqmH6M00JhH)EEIn6gqB;PHZ~RjQ`gYLAgNj)$I*st{O3}Wm$3$hLv&xUAIfFro@3a zZ9%k3Vsyv`Sgp`SR&7!%M;LF5(H5yN+9P(Vjosf#JWtB3OjE5QlB`IT{c8pXK%XjO zgXA%&K1v8Pj=+VcJ%Au4tcC(^2_<#FYF8po`zkkiBi3_4@HZOQBc~Ti|F<%8w8j(G z952r-(S!DrASlMLfA{Y*^!#6E=*96X&|tM}u%h0myd7Op$Vd26L^#8LupC4bITs@} zh(eAO*O`|zAtS>9LIW~1AVKks7BWja%qBChSGR)^>SGDlY_#VU|3ep;Q&__R$uAsc z*3tR>kFSpZzmwA+pPpGQ5T_;ijAx~u2Oi5Ik22M?KZ_bRt=vc^aY-+4EQ&eI;C(=SRr3#k3>3Xk}573Ul#iL}I zV(Us(4Z*S`y30!5%CjNn#lKP-}cu8_N8*O&gSIP2;LX zMN92gb^rRbDl71Qt0!waXHEYu=+?Ify@|B5;sU1>?4A=x56J9Q3UnA9K8nV`?{acU zcnv*hsTX!B$>(z6VW(N)4WalNXXGVdup6@4zj#yFf=|AIE|6fSr^WQ6V~fBVXHY~j zQ>!r2ToQhPs|AM)X}+NuVWsrmgSh^Q`$dOCWjlfpmdr2;Fv$*mer~vlsiRB%AZ2mr zvlN6DEN9%VX#a!m#3_LhQHF$D@QRyty%q6-WTcL$(z&%e87tKQb3po>fN`T>tX)6n7^94ev$s)akvD+9Q4tzhAM#VnWB1{3%f!Md9+ zRjCT1M|nRMN*8fc;q^}U#qn&dkZFOV@eIwbmHl>3mJ_7@?|+b~&~AnrJqnV}UKw0# zglMSqmKJYm@srb{=a`@~gwY90khRm1_Svk6H9(oN2`ghF=;38>yL|;f9x46Wc@WII zU^om4mRKZ=->A!X)unEE{V7=D7qOqO1IHmQ3d}PzOVT5fKwuS z!Q;x@$Vde+@RjbLwRvy6y}r9Q*P9)vSV!c6DYb?Qhp1L2nx*)HaTJE=JN=ijnj7u; zR`XNvIcjU<8!yrjkTUgXJ~xp%ql<&lYrjcTFQzFiGg#!Rp8g5t4@XboN3)hjb>hc1 zYIjF9O5oMefEyiv!NLUv2Q_!97a*f+SYM4Qd0fylDCle(%l%M@BzvCAn)6Oan$(-n z-eNN6L?Xe;9#1JU+jI*Kq36JF-W0(LVd z=;4D0_mAwmp9JC6t6686*DOC}Ogdm@of(qX!=v|iPc_|}?co|H-|S+(RtNLvbT6-S zE^lxxZ+0xV-O80y*|?O4L-d*@#F{~BoI&mgLFeGM=rcN{AUxC#nw%x7*NSQ>%SVCw zUAY77CiZMb^Va;f+tqx%swtWuk+4&f*10N~K!9nCHyB ze*T`sB}`>t-8-S4p^6{a52(o%{0|6y_z)tR$7z`mH0TJpv}{k;9-s*QiD;gXT%v<9 z`uNcUCt1N#HeddWEPa-%2F``QsR4e&QlbZKS9)481!|$l5a&rKT@$0A`n!^nZw#tP z6re80EEkfi>Q_doit{R%{$FSZCe*EkUTX?H{qYRGJ*__34cy~O#WR{YP7=+o>QQSW zVPXLVkwH5)WD}r*B>@m+tKv%+NV1}i=lO%>3nQnLZB7~RtP~6J+5|^Hcp-)GgJ6h? zW)T|^*^lG$G7r4~d!GX*(~-jM85O()R{w38%#D2k`{G%KLqQ6x-Sny1rS;BeOo`p< zj%<7)lu{CdQ$d6(Pu}BLnp)aUQi5j0IO1eZ-lGCbNq8>o<~ML<0HfqlLh_~l!3oMr zskiCK`#3EHy&zGb0Uz5+)vo?}?9KL`>Ot;e6+dSWo|$5sI^YRtFS<`h3Z0W>!>4J( zHFQ*wc5vSn!O)5;-FAe&t#&w7QPWo=TLofyy43DS@X0x2S3`k*Gsh)yGs5Z~Dmc5K z>XYk+MaGP$Mv-zZ3(k_j1WfbP2mzDLp4u5Tw~>&Cs3=FhO^pIE2NM zU(O$k5a5Id_o~11dr=gt{g2y#IvNF8FJKZBsmaAAIOmjA}4`bUCE#&SVS(MrS6zpXD<|5`9k|4{Uv7A%2C z`531)&O#%)z-h39FC1$lUcAfBEidI=e*GnyLz0Vi@& zLrauJ!MN03qFN{@L~Y*F$hsp78sIB9vYtu58<^2|LBAs)Yy~%GA-S=8Kty{JPpY@I|1mGi7q2gK1Dk_}mI=JJ=q`CNvkr z-7V|)wB5gt7)MK-rA~Hw2-NiB>*#j%#TqfI)DRCwTT_Q1Bd?L#u!S{!+m7G8U|8uI zwtI?fL3F$a{Q`)k3y`n!_?@U!cIb?E0HASN%2f%5!>WF@N3E(i0~0@CSmLJ)O8m4T ziJv4O(GN##1S7UX5$l17^)SR%5Tf4LGs@}tV;A87dI>NnFYw;DRqESbHu4{0^1=J| zogeG0233dGn1i+zO&vrBN6|kN!L2Ez7olN!f~1vwToau2AhbNO0d2_aUI(40ldBN- zIxwTx8ozTwa?K7EUBCedTkW+uN^}oC!Dgd7Kw*%HxC^C8#yHhpF{k0x#B7H!wAD^na_lN~oygR|kA?$iBcNcp z-bhxkO(>=2%BEN~Z)z2=>2D;KQ59`pMS_y7kV~}Z!ul$XQZ)z+&?V&1QqgZ`-<&MA znv3?Bq)Uj>^Z-R>0l62VVYyC>91p!Rp=Ywx&kIyc4_LXvYt>Z15lpRoMwV9fxq_ku ziq;F)1gnFJnw)y)Oy0IaY-zlxtT99NUVN>CGC`+?VL;pyuyp1jnNhMFh4D*C|j zq+Kwu=K&Sx0CO6@M`oYa8x1?_1xo^?${gz=PO<>cIplQLNq`1jyX4*w*k}@6($B@tp(#n(WzY(KAEJ)PcP$L`wuo8t@FvvNE9^EP z)<9_uMjkTGlyTcU289eZ77YsPaC@#y2bAHQ&fvtALjv?HljcF6BYtHId0eiRBgv*z zIH!3sF?;T>aACKqiNpz(*zQxOja_S#-=RA335}Z1enoQ}DTH@u0Hidq!4T$@gI?qU z(fl`~;QObsT(PLyZ|&gSJPBz|rJqz{g3jqBopYLuASDJ(NR0VJ$E5=fii~^WL2E^$ zp#HlPAJgD=D4qGcs<5of;vQ0bCMQA|6%!{EeifWeiMaY6c=g^k6uL%2gG8tsgAge| zRKM0ZfRNLh_Fy#B_BMur0db;=cB)1*Ow*E+Hw#Y0f~Cm>-4Aq7?Dxc+)lxrxAlQ@K zRUDuC79f}-iqmH##mh4ivpf+xI9F#$aIX&3J5fSNoY$mU5>kgXx}p!DuP^QJLuXZw z>^QkDeZn3*xP~5_)@ep{!Oierp%0%s2hxA?(~-@>9+DEH*FU~_eiq61@@j2t$p3hF zaR0E8|Lft=_`z-dubX%}!f&ZS7zqmMjy2A~5K6&o?~-bGTYASQFOUh>Q$oy|bi$ea zcnaGl3!>faHgr+jk0J`*EZmlV+r_Jra9Md;(lXj5_L>oeuW zMI4!pgD7P&PA4BeAe&&y`ZU02@bTlw@9@%31z=;i1S(QYA=*vZl?7*#P0N|mM~Tjb zVfuUw2XW8>WJXlMOJL{ASyC~}MVVC%OqYIKI+frcV(=cD69`;W92G7HO-i&!(8beZ zA4r^1l1n!`Q4m0U)yxe-Enz`qbd--DgP@sl!A-F0whoqqC1KT?Aauzm+@2^gSAc6)?qg)ZZG_r*@0kwxM{~68&D{l+Gwg5H1SnL=^m+Xy{O0 zsy0-I1e%foZjrw#5q)??*wkHLHQR zU?mtqlfa-62nBm=3VDNVpHZ&(wH+K!4%&}yaBZ2D1$vD>WU?|p?m$l_Px?==ho>79 z4JA6&Bc>}mTx)N)MzG*Cmoqf@y9oa-1`TMs-EBy2)!#KzY_6JylsBh#dd+V=NyqC| zGhHthnWzg@P=}wp>DgNshVBXf{Z*i$U(JDTG%_%M40-`sIhs1}Yj^yFRyM2cKk%|; zWh!Y{74l-Lbh@!@3h^8!)qGzrW|VK;(Z;~HHsZbU2sf7M7{ms_>yCJ(H_@KQUlaqk zo5k4VfinzCmjY*SKRyE$1}j&Uzv%Vf#zBq#gk2ZaiNSvj(BRj>4jle_yK6Ybg2px> zVjr|qbD-km$6!IyEE00a8Idj%GV(Keh>lbMs5OrD?~w+ecc!c54_0vG zrGin-*D}K>tUEB(6}@aO>O(EL%i4-no)z`p&$_a?S|j&~1JKHevKdq}F^PlK&RDVn zSe<`<$9RU73~c75M=$cC1kcMJ9OWBmiga?@n4#pLhe zpMS3?pu1wd#VWZc+H-oQ1$yD>2bILwZ-9_^-hAct!%o0PWGz0Q2~BVMJ&bpph0iht zJqG-SM|-6-YKicbi_E!#yVqCcDPFy_I?CPXLhEY(N+a9_utwb*dfa!Ae|ks#a?PqOV+yOrhlMpE*)^Ex1s9^kQxbz zu9$MuuRHRYJ>PU}8Kof(|a$Bz!<=Cp1BrJD7J$n&LI38y!%+Zm!-*`ZuT zOE6wiCi=>)xbdg9Mp&4Xl*qPW%RAapia zm9L#dL4P`@&ExUogZ}7L;`LU#{>7j5^1pRTd8b=JH{Jhyc=)g>{~sJ3+{*u(csjT^ zoMblJg|&C}yMVwZ_T@a3!KH-61R!~sabS)VJ5E|_3$?|(Q(X|16b#=yfk$&z~@t^ao z=l@)UE?>#+7ea5~|KmrG?l<`V_-K5~|8L~!+>os$((r<18;8uA$IEF*CknQ&@8p%sJjnqZ-V}G_;+rQ*Qd>-CTTR%^oXrp|K7pOtK0^^e*ND+ z8Xt_C>wkPWzFq$}@%T#`7llx|T9eGZTbO-=)94V@J=isUMSp!(oul>BBY7ZqnYW)@+JjuboZ53nG;iH*yX?Aen66>n zF3>$|tFhNw?(5y?Qy=Vpnqr#0vHa8=s;u?ILY>$PI^4oQs7|Om66<5%ol^ysnC`nA zvdvOn1M{e4UBRlQ+6Bg5ZSQ?m zxNRF<$)4(T|JCx5w_SkEO!5GLsRghC1R59^5QwR#qR*H&r@WPP*j4OEHtY@L%8H#t zR-@ngN&Tu|;{<=OmareL?4ftZXbs36GiBgKojgI3@Er3c`p5VmW3;!z*X#LO$E!9q zD_z@btnRd}H+SGS*U!(}x9zZ}Y|fhm>nNiKm(>r+FDfQy+dcX5*{`pUUp;pp8dvXC z&&<1auk~K12(g?ss$FH%Z0hXf_~|ETPv>ZB42~Tel3%Q1zFvvGY*@SJy)BN-E!GDA z8k%pt!hGJ4VKr>*mBy$Erd?t^dor+9>uY-7N%VgC5QU-Q?N1I4A3+kYgLR!#rPTs| z^5H|BEi}>ct?Vj6Z4;C;exG;@(kuTb`i;>X4ekxL?RRH}=VtS|kk05VLYHvdN2VLj zYP>q=qlHyh8sHVEc?!fj{5m0C5y=gMwho(X8Yi0>as>u9vt%0qS8=QM?|4})Cr?nb z)y|k1`9m9Jk2Pm%nj(UG0QKVFMq37fBM474zU;pKvEK+FW&i?i+s_DCLrcm7) znT=ui&LZuDEuGb%H)h{U60Vp~Z9KD5$e(ih`_6>dPD{GF`5FPjL5?+0DunjYo$YYi zq)up_oIJU+X9fFy^IL_rR|>@c{uYQ-d6ZY7QI&WyVuc)?KNcgXHgb;5Z5rDsxSZm* zN`%!5ImuO57@M=PUZ3bxJbz$qN@*asDMq0QV)GEKR)JSy(sKm1raEL;Zp*e6okxw_ zcCGS8KmGL{x}$R$DLu8bTL$sS1J`WHbDJ1w?rb}%J>XoZmD6{fHwv!kP@%cWg5Xpx z{#ZAV8}$Zc7D?Zw(5!271nTTZE!-Q+vDVrui`fVJ;R7m*g7Eb-qD%K0yv`(ss|dNH za2;AB^WiEuwPJM$?L3LAfHX_i;WRTVu7Xl8w}ErCl406sEib6m`ihuAy4KO=1g$A5;T*2m%>@YE_+Z-Af7B}te z6&GyR?2zW&+wJC7g6U|z!zkLkG^!fDQ^HFb8k*eL`dPo()o5bl*4L`?J8gu8DAf0! zlTc@?4RMliBE*xG>0(#fzzSAb2+0Y~o~Qwsj7E+JPukLaRCmC_xVikP+6njg@#DvJ z$5_(^)*N_UVC0pnyTZC1QL87i<+o{jZZ=kFg(%dgu<4?ySL_H*I2gB!ZQ+aQIy1eM zXQq`3AzI^GxgPJz3jaz6@EXZ9Du%{19`sOVI#rO>va9HBT+86LMZPj=zJ1y$@%`Ce z$v!Gh+m|=5s=u07u0`OQSa?sMn;3eN*LFGJHZyalb$m@6eS76?Gk0zws1GhD%KE&VW&oM zn*i!7c-F4}N`nZs9yz6f4lx~;@KRP+f4K15`Sou@#=ne7L^+uhnfLItQ%g67?jnJ|i(uXg>Gy#NB3r-7yPn^Vn8>5+Px!ZfiJ1&q%&R zI89AHS2SH(?|es&*R=^)4S@AS>*Y&bi=`=N?bD5o+w$G5dyc^25b2AyX?FiW4 zsE=9dnai`%$o@o|Sm*{ClN)(|}*6MF(w4 z_#}CATAfyyy;&B-k=~-{ufPMKtaBC$5>VVpJgEaWNW9s#K*TK@S zgDba%Wn-YW%>lU{Lc8%sPRN4O3!0KSNhbQ(bI{nF4$)oho4VTr_avdJU7Y^BZiBH; z#g&LRlIdBT)yo$rPwOvEUOcN_@G?IZKM7(4Aum%hL3dx3LY}HGuUUS|n7j)T^Civ8 z_qB3R<~U!%_p&IIU6V_kLYjBc4f3vji}QK4(?3MtF+QaUQeDpH`W|Y=B$_Kgk&7(N zXg)#JNu&(FpP+{i9^8KrAT$#?x%`bbYBLI`LHdrSL@b3QnH}CQ!VtNAKFhOS{)-~? z?g05j`@aW=kDB|x2jlUBTls$z&u5nZ+ua%R$u0{~gud;CA!VwgZ9{ZNm3{*^O55Ad zCr_O7tv+V|DyPI0ioU0=yziT*i~Dw&DM~-T}4I|M#G||95!*cK`oop1&0T|I~Lz?IH%Qes9zj zTCc8jf_n?QFLkRaOC!4(d=+QlE_kh9Z`Qp2wc~!XUBuCyE5{Yy@%%--yV?{SP44PkUJB|$8GJF} zlFn$XxCNc(5MK9tNrY6LsE%8^+bdd*rWyn@OM|yHHxrmPs~f7kO}`8j^$hNz!6laQ zV(``;PpJY}G}2a~?Tut7Mh?mj7;u*V#-_d7pBiXwBn+VKQAjY!ST0EanW|iZ3OX(d z(S=b3cL$u@Wr5d?R0Vi@tXvM0t5Ayra)tI&rEc{_BB3H?7lbd@EUG%>?J)!X%5sU* zf+cV#LyS|xd*f)U(0ty7-YW3hBWl8a`;T6otXhHUUD&!dwny(;Six>=0IoUd&#W2a z3C(?x+J%Y+x&tyaqf&2vUuCU%V7A90E0xKX&o9Yz!PvRx@}!Tw${iLZ!}4{3W$giZIgI|>HGE^TZ7@YNc3KIUy(H@DJnL$s^N)Q7bT zCXC}b*;3aqwbts4b;#Rec7aoxd=6!IL&H1t1lT>6632_J+y{Mzxdps8emYU?oz3aR z+jjASwa7_!PI68zD7mcRrCqm!w_Tt&D>y)1IoF8OsWwDTg~>5+-6bN$gu zZmh+vo3De7&;->F^4^@5X*2G9Ln*K4{>1-f&PHwA|JgO@%X>EM{~tBa ze;$qxZqNVR%+uKaS+@by+#c%OkZEoLxxJq|?aiP4=6%0gZRAuNGuIUsc1_zZo!clo z#)-L|B|6hPaIKx3`WD>PHj7AYBS>cfSl3?jSdxoITN#VCdn8)t(Dn^&xbv6h(Vy~J z%l~bniz|izY~cU*j~*U0_WvK!^9Roe!iV^NU_qt)Q~bd?#I{S7kb>9}m^3%my8qYt$F?@#CN! z=w?gM;#rB)Gl}E#dUhIGe1|idQljsUT7j%zy{gg1+k9Jg+-tA~)Y8A(ppkopOKwY7@v1TKM(TaNz>@=hdC*R@}=P}_gP7JTAz3X0ft$Kqsmo9WwIs=3E z6!tdT&H7($vMqC)VN8?yrN+I0nL=DjI|J2j>7I_h!VuFw`XAPM_$Q11KWgWHe)!-v{{KdvZl+@_FY5qU zlLEG8->HQU*D2NCzhUPj?~-S>nRWH9Bc5{CJdJBkL|ySb)aoJMHigKV>MPT5wC}HJ zK-uLwo34v&ZsH1?4XE$0$Xs>n1c0Xx|Idu>^lAA2!O^3`*7>hThqwOU8+lgR!co?? zAbc5MJ}VV3W}Gk)#Vi{&C4*7BzYnf&>;i|GBX$`Vw+51;0_{Q+Qb#Jy(scvkp z$HBBM8@BF)-`Eto0OM`Vvq5*l!NEElEuj9r()Oc2fc~3yZesK&lALB6@(}lFxnRkg zR^yGAS83l7UW2!4_tHz6QD3&T5o}1aHO?&8CAS*t$#q+=y&RJ+MMu9uThT(tD7Eg@ zTb(<2L+Z;ucv%pB5|u5`s$C^_?P-Et^nE?gw7X2at)zAIP?e5oE(yQD>AHfhjO&nn zQ&Y@0Hc>fhwrH%|9onO3dR4s97iF%U=~_Y8$J*;&9jycE)!WXtckVJ=srD0JJDIMG zpOhQk^y;Il-m81f#&+(RRwRCqvN+tVZ|GvKf8NVpUG#zU>Saf(J9l)!a?1zSmi3Cc zj(RUAur?$=Ps2+0wnwMeSAADC~G(Pm2=O(aTW3U2)j?RO|w{Z$Qc-jlJH5$6w ze&<-6HLhu0p-Xnp;hIgY#w8$DAv6kR|M_>$wNI)RwpzI{&CqGwH>n(UH+r-Bp~d0T zs)(&tZcIzGE#Hu$*wx%k>Wa4gFGF3l*nBw}<7$jPv(ji0`&@csSNoq$b*vcUr_ml8 z@NYu4?+GmB|h~zC?Yp9gx$1|7ZRFpA;^SNVt14uubtF z<5vFPgZsDlf8WgWp`HJ?GkmLd3}8iANYCRM9h-qQLi_9O44TAP{&_Ztwj2yLoWX`S zb0XVSaRG^?uAVc!-*Hxlh)$p)^dE3^?l!;T*Zge9|93kKxQYKCJZj$me)woSzUBWn z@q7mU-*sH?>ktE1IOBI6LvWi7{`T4SSz(#o2 zID{F^+gQ4HJ78JC+l-}-6*Zbz{VD@xR*%em2E9+MSw-#4Sk7leb_NORQqNqn;V!?U z=3Cn{uAYmjED|h~QIvn9W{Rn@-!r$hgX79`E+JZGF-Pa7Nbzwv{E2aWs>4-Rhc z|GAlGh)%GSgy#ZDhV-nX%LU2Nw4^CqI9%ZP9M6e}f+2ddpaQN?W?Tv+79>s4JY`cI zpH1`mJ=ocl^n#!Q%Z2wI=SeU`IhlhIjP?pnX7oKtG+X;W`w{vvPnU@0P*b6V3c^uJ za}ov7v$J2%B;zC)qNgm&SdM;vdWI6pMG(!Y9KruJ`av}PgOA|<_Qhg8Qvb6*#YH}< z08MdxUKVIZQzC+IB5_#+-$YY<9()tYtO&mO|AQg=8FR`?fnGd&E`q4wOc~liL=%EX zx*TV}{S~=n$NE2ge*Em!^C(NMtBnoo|A8|0>g)gL*8aPpXNcMqfPNrphMq1kmqG9% z7ZRtbfP2S(=_rinB$sdZ7E%^sG8)aPT$EEd3|1Wz8nx@~M?o+gqVI`Br=(zlO2(Jy zMLuJ}fB&B_M3TIhDa~b=P@!}&6o&s3ynFX9X1QP~36zjRoD>YM2M^${jXr916S}Ad#f-U~f@ZI&`TWc2^Ow($&z}GK`uNrJx1D3qG4SY@ zS&HZ4t>3j;0?xO4!`knCG$kp!jDD>Rgh68CSeSAfhC}uGr<|_ucbRwhT=xV-6DJwF zAOfjEieUfcNKiFhu$<&lAS?unDVA3FsFFYc;0H-a3Kig@eFB#mM76FvJT`XTmF&~~ zV$LxL+*RF&0^}N}-3Pn5FS^|3o($0|I_Hqz70o!ykdTVHyKqtv)^dp;_+M6{80W6{ zG!Kgu$7B)&2NC*ZP9&^J!#`*~V{i9{b0Wj)ZK&SvLvh#HVQGh3Fa3SAWF<$$WVf>u z5B3@=g?gpvAt#rHQY!F`*^>-i+>gf5I0*E=)=wn5Snb7OG`@!fA)3F&3!KkM%I4cM z)X_9$(~-eDJdDPpr#~FO{{H#PAHR>XM9*4=e^Ya}&^caM4vpf%<-HCCO%$=eSr9wm ziRo|7E}`^{DLY(s)PR`;!8hm`XGK90s~SRMKwTGyXixufA2E)U!OIaW)Za_WNwOb& zgS-^I=VXa4vHGkAK2d||wy%S4D)(JiLGQW>H6u@b9u@>Z@J}IeEd9eyC#*E|Etx5; z*Kl2$&sVGknoG_`Kn%aax){b4yihKPCZ%u+@Iva~?MLVhgGp9=$uU>O@>!wJ?gAf5 zh{QBiLk=!Jsm8X+1;m0~q6_Ux>bdmwl2;28zQJ9a5U*RUE+c^6wJX1K2NfYv6p2B5 z*DK;(1Kzs`eY-@0Na?<|5+3U?)pz%hRQy`g)+J3-b4e5E|EiLXSFW6pU<^1^_U!uk zzsO~D+K+-a%w3jAkWO8E4|(a7iC*RQ?l81>K{3MUU457A9gr`1kFz2r`+90HdgmoO zeTQ^DXrTCbfv}mWCC<_-+;83C;cibz$O%qt$cYXWsgfw8!2rDt5UStP?~<{15XV3l zcVQsf_d6$2Qw=Pe#x&cZ5uHqG%5fh5F>2HqNlwTp!>X$zTYqGc46(b#)G#WwAoX$( f(O=Q7x_xe++voQA(x3kq00960vM4M00B8XKPW+EP literal 0 HcmV?d00001 diff --git a/go.mod b/go.mod index fea5e3270ea..c6a3fe06003 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 github.com/cavaliergopher/rpm v1.2.0 github.com/cenkalti/backoff/v4 v4.3.0 + github.com/cenkalti/backoff/v5 v5.0.2 github.com/cespare/xxhash/v2 v2.3.0 github.com/docker/docker v28.1.1+incompatible github.com/docker/go-units v0.5.0 @@ -105,6 +106,7 @@ require ( kernel.org/pub/linux/libs/security/libcap/cap v1.2.70 sigs.k8s.io/e2e-framework v0.4.0 sigs.k8s.io/kustomize/api v0.18.0 + sigs.k8s.io/kustomize/kyaml v0.18.1 ) require ( @@ -277,7 +279,6 @@ require ( github.com/bitfield/gotestdox v0.2.2 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect github.com/cilium/ebpf v0.16.0 // indirect @@ -726,7 +727,6 @@ require ( oras.land/oras-go v1.2.5 // indirect sigs.k8s.io/controller-runtime v0.20.4 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect - sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.3 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/magefile.go b/magefile.go index 0e54efae997..af06e56913f 100644 --- a/magefile.go +++ b/magefile.go @@ -59,6 +59,7 @@ import ( pv "github.com/elastic/elastic-agent/pkg/testing/tools/product_versions" "github.com/elastic/elastic-agent/pkg/testing/tools/snapshots" "github.com/elastic/elastic-agent/pkg/version" + "github.com/elastic/elastic-agent/testing/integration/k8s" "github.com/elastic/elastic-agent/testing/upgradetest" bversion "github.com/elastic/elastic-agent/version" @@ -2344,6 +2345,7 @@ func (Integration) TestServerless(ctx context.Context) error { // TestKubernetes runs kubernetes integration tests func (Integration) TestKubernetes(ctx context.Context) error { + mg.Deps(Integration.BuildKubernetesTestData) // invoke integration tests if err := os.Setenv("TEST_GROUPS", "kubernetes"); err != nil { return err @@ -2354,6 +2356,7 @@ func (Integration) TestKubernetes(ctx context.Context) error { // TestKubernetesSingle runs single k8s integration test func (Integration) TestKubernetesSingle(ctx context.Context, testName string) error { + mg.Deps(Integration.BuildKubernetesTestData) // invoke integration tests if err := os.Setenv("TEST_GROUPS", "kubernetes"); err != nil { return err @@ -2364,6 +2367,7 @@ func (Integration) TestKubernetesSingle(ctx context.Context, testName string) er // TestKubernetesMatrix runs a matrix of kubernetes integration tests func (Integration) TestKubernetesMatrix(ctx context.Context) error { + mg.Deps(Integration.BuildKubernetesTestData) // invoke integration tests if err := os.Setenv("TEST_GROUPS", "kubernetes"); err != nil { return err @@ -2372,6 +2376,32 @@ func (Integration) TestKubernetesMatrix(ctx context.Context) error { return integRunner(ctx, "testing/integration/k8s", true, "") } +// BuildKubernetesTestData builds the test data required to run k8s integration tests +func (Integration) BuildKubernetesTestData(ctx context.Context) error { + // build the dependencies for the elastic-agent helm chart + mg.Deps(Helm.BuildDependencies) + + // download opentelemetry-kube-stack helm chart + kubeStackHelmChartPath, err := devtools.DownloadFile(k8s.KubeStackChartURL, filepath.Join("testing", "integration", "k8s", "testdata")) + if err != nil { + return fmt.Errorf("failed to download opentelemetry-kube-stack helm chart: %w", err) + } + if err := os.Rename(kubeStackHelmChartPath, filepath.Join("testing", "integration", "k8s", k8s.KubeStackChartPath)); err != nil { + return fmt.Errorf("failed to move elastic-agent helm chart package to testing dir: %w", err) + } + + // render elastic-agent-standalone kustomize + kustomizeYaml, err := kubernetes.RenderKustomize(ctx, filepath.Join("deploy", "kubernetes", "elastic-agent-kustomize", "default", "elastic-agent-standalone")) + if err != nil { + return fmt.Errorf("failed to render kustomize: %w", err) + } + if err := os.WriteFile(filepath.Join("testing", "integration", "k8s", k8s.AgentKustomizePath), kustomizeYaml, 0o644); err != nil { + return fmt.Errorf("failed to write kustomize.yaml: %w", err) + } + + return nil +} + // UpdateVersions runs an update on the `.agent-versions.yml` fetching // the latest version list from the artifact API. func (Integration) UpdateVersions(ctx context.Context) error { diff --git a/pkg/testing/kubernetes/kustomize.go b/pkg/testing/kubernetes/kustomize.go new file mode 100644 index 00000000000..c43cb171a89 --- /dev/null +++ b/pkg/testing/kubernetes/kustomize.go @@ -0,0 +1,47 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package kubernetes + +import ( + "context" + "fmt" + "time" + + "github.com/cenkalti/backoff/v5" + "sigs.k8s.io/kustomize/api/krusty" + "sigs.k8s.io/kustomize/kyaml/filesys" +) + +// RenderKustomize renders the given kustomize directory to YAML +func RenderKustomize(ctx context.Context, kustomizePath string) ([]byte, error) { + kustomizeYaml, err := backoff.Retry(ctx, func() ([]byte, error) { + // Create a file system pointing to the kustomize directory + fSys := filesys.MakeFsOnDisk() + // Create a kustomizer + k := krusty.MakeKustomizer(krusty.MakeDefaultOptions()) + // Run the kustomizer on the given directory + resMap, err := k.Run(fSys, kustomizePath) + if err != nil { + return nil, fmt.Errorf("error running kustomizer: %w", err) + } + + // Convert the result to YAML + renderedManifest, err := resMap.AsYaml() + if err != nil { + return nil, fmt.Errorf("error rendering kustomize: %w", err) + } + + return renderedManifest, nil + }, + backoff.WithBackOff(backoff.NewConstantBackOff(1*time.Second)), + backoff.WithMaxTries(10), + ) + + if err != nil { + return nil, fmt.Errorf("error rendering kustomize: %w", err) + } + + return kustomizeYaml, nil +} diff --git a/testing/integration/k8s/common.go b/testing/integration/k8s/common.go index 65667ed2aa5..f23830b48d0 100644 --- a/testing/integration/k8s/common.go +++ b/testing/integration/k8s/common.go @@ -35,8 +35,6 @@ import ( "k8s.io/client-go/kubernetes" "sigs.k8s.io/e2e-framework/klient" "sigs.k8s.io/e2e-framework/klient/k8s" - "sigs.k8s.io/kustomize/api/filesys" - "sigs.k8s.io/kustomize/api/krusty" "github.com/elastic/elastic-agent-libs/kibana" "github.com/elastic/elastic-agent-libs/testing/estools" @@ -293,29 +291,6 @@ func k8sKustomizeAdjustObjects(objects []k8s.Object, namespace string, container } } -// k8sRenderKustomize renders the given kustomize directory to YAML -func k8sRenderKustomize(kustomizePath string) ([]byte, error) { - // Create a file system pointing to the kustomize directory - fSys := filesys.MakeFsOnDisk() - - // Create a kustomizer - k := krusty.MakeKustomizer(krusty.MakeDefaultOptions()) - - // Run the kustomizer on the given directory - resMap, err := k.Run(fSys, kustomizePath) - if err != nil { - return nil, err - } - - // Convert the result to YAML - renderedManifest, err := resMap.AsYaml() - if err != nil { - return nil, err - } - - return renderedManifest, nil -} - // k8sDeleteOpts contains options for deleting k8s objects type k8sDeleteOpts struct { // wait for the objects to be deleted diff --git a/testing/integration/k8s/journald_test.go b/testing/integration/k8s/journald_test.go index 60c0c9df506..352cf467c57 100644 --- a/testing/integration/k8s/journald_test.go +++ b/testing/integration/k8s/journald_test.go @@ -51,7 +51,6 @@ func TestKubernetesJournaldInput(t *testing.T) { steps := []k8sTestStep{ k8sStepCreateNamespace(), k8sStepDeployKustomize( - agentK8SKustomize, "elastic-agent-standalone", k8sKustomizeOverrides{ agentContainerExtraEnv: []corev1.EnvVar{ @@ -138,7 +137,6 @@ func TestKubernetesJournaldInputOtel(t *testing.T) { steps := []k8sTestStep{ k8sStepCreateNamespace(), k8sStepDeployKustomize( - agentK8SKustomize, "elastic-agent-standalone", k8sKustomizeOverrides{ agentContainerArgs: []string{"--config", "/etc/elastic-agent/agent.yml"}, diff --git a/testing/integration/k8s/k8s.go b/testing/integration/k8s/k8s.go new file mode 100644 index 00000000000..c620dabf29f --- /dev/null +++ b/testing/integration/k8s/k8s.go @@ -0,0 +1,20 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package k8s + +import "path/filepath" + +const ( + AgentKustomizePath = "./testdata/elastic-agent-kustomize.yaml" + AgentHelmChartPath = "../../../deploy/helm/elastic-agent" + + KubeStackChartVersion = "0.3.9" + KubeStackChartName = "opentelemetry-kube-stack-" + KubeStackChartVersion + ".tgz" + KubeStackChartURL = "https://github.com/open-telemetry/opentelemetry-helm-charts/releases/download/opentelemetry-kube-stack-" + KubeStackChartVersion + "/" + KubeStackChartName +) + +var ( + KubeStackChartPath = filepath.Join("testdata", KubeStackChartName) +) diff --git a/testing/integration/k8s/kubernetes_agent_service_test.go b/testing/integration/k8s/kubernetes_agent_service_test.go index d14f42b8750..d854fa33d59 100644 --- a/testing/integration/k8s/kubernetes_agent_service_test.go +++ b/testing/integration/k8s/kubernetes_agent_service_test.go @@ -44,7 +44,7 @@ func TestKubernetesAgentService(t *testing.T) { testSteps := []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepDeployKustomize(agentK8SKustomize, "elastic-agent-standalone", k8sKustomizeOverrides{}, func(obj k8s.Object) { + k8sStepDeployKustomize("elastic-agent-standalone", k8sKustomizeOverrides{}, func(obj k8s.Object) { // update the configmap to only run the connectors input switch objWithType := obj.(type) { case *corev1.ConfigMap: diff --git a/testing/integration/k8s/kubernetes_agent_standalone_test.go b/testing/integration/k8s/kubernetes_agent_standalone_test.go index 8c37fb834b3..fd8cf463f50 100644 --- a/testing/integration/k8s/kubernetes_agent_standalone_test.go +++ b/testing/integration/k8s/kubernetes_agent_standalone_test.go @@ -19,7 +19,6 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/elastic/elastic-agent-libs/kibana" @@ -37,16 +36,10 @@ import ( "github.com/elastic/elastic-agent/internal/pkg/agent/application/coordinator" "github.com/elastic/elastic-agent/pkg/testing/define" - "github.com/elastic/elastic-agent/pkg/testing/helm" testK8s "github.com/elastic/elastic-agent/pkg/testing/kubernetes" "github.com/elastic/elastic-agent/pkg/testing/tools/fleettools" ) -const ( - agentK8SKustomize = "../../../deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-standalone" - agentK8SHelm = "../../../deploy/helm/elastic-agent" -) - func TestKubernetesAgentStandaloneKustomize(t *testing.T) { info := define.Require(t, define.Requirements{ Stack: &define.Stack{}, @@ -80,7 +73,7 @@ func TestKubernetesAgentStandaloneKustomize(t *testing.T) { name: "default deployment - rootful agent", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepDeployKustomize(agentK8SKustomize, "elastic-agent-standalone", k8sKustomizeOverrides{}, nil), + k8sStepDeployKustomize("elastic-agent-standalone", k8sKustomizeOverrides{}, nil), k8sStepCheckAgentStatus("app=elastic-agent-standalone", schedulableNodeCount, "elastic-agent-standalone", nil), }, }, @@ -88,7 +81,7 @@ func TestKubernetesAgentStandaloneKustomize(t *testing.T) { name: "drop ALL capabilities - rootful agent", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepDeployKustomize(agentK8SKustomize, "elastic-agent-standalone", k8sKustomizeOverrides{ + k8sStepDeployKustomize("elastic-agent-standalone", k8sKustomizeOverrides{ agentContainerRunUser: int64Ptr(0), agentContainerCapabilitiesAdd: []corev1.Capability{}, agentContainerCapabilitiesDrop: []corev1.Capability{"ALL"}, @@ -100,7 +93,7 @@ func TestKubernetesAgentStandaloneKustomize(t *testing.T) { name: "drop ALL add CHOWN, SETPCAP capabilities - rootful agent", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepDeployKustomize(agentK8SKustomize, "elastic-agent-standalone", k8sKustomizeOverrides{ + k8sStepDeployKustomize("elastic-agent-standalone", k8sKustomizeOverrides{ agentContainerRunUser: int64Ptr(0), agentContainerCapabilitiesAdd: []corev1.Capability{"CHOWN", "SETPCAP"}, agentContainerCapabilitiesDrop: []corev1.Capability{"ALL"}, @@ -113,7 +106,7 @@ func TestKubernetesAgentStandaloneKustomize(t *testing.T) { name: "drop ALL add CHOWN, SETPCAP, DAC_READ_SEARCH, SYS_PTRACE capabilities - rootless agent", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepDeployKustomize(agentK8SKustomize, "elastic-agent-standalone", k8sKustomizeOverrides{ + k8sStepDeployKustomize("elastic-agent-standalone", k8sKustomizeOverrides{ agentContainerRunUser: int64Ptr(1000), agentContainerRunGroup: int64Ptr(1000), agentContainerCapabilitiesAdd: []corev1.Capability{"CHOWN", "SETPCAP", "DAC_READ_SEARCH", "SYS_PTRACE"}, @@ -127,7 +120,7 @@ func TestKubernetesAgentStandaloneKustomize(t *testing.T) { name: "drop ALL add CHOWN, SETPCAP, DAC_READ_SEARCH, SYS_PTRACE capabilities - rootless agent random uid:gid", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepDeployKustomize(agentK8SKustomize, "elastic-agent-standalone", k8sKustomizeOverrides{ + k8sStepDeployKustomize("elastic-agent-standalone", k8sKustomizeOverrides{ agentContainerRunUser: int64Ptr(500), agentContainerRunGroup: int64Ptr(500), agentContainerCapabilitiesAdd: []corev1.Capability{"CHOWN", "SETPCAP", "DAC_READ_SEARCH", "SYS_PTRACE"}, @@ -188,7 +181,7 @@ func TestKubernetesAgentOtel(t *testing.T) { name: "run agent in otel mode", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepDeployKustomize(agentK8SKustomize, "elastic-agent-standalone", k8sKustomizeOverrides{ + k8sStepDeployKustomize("elastic-agent-standalone", k8sKustomizeOverrides{ agentContainerExtraEnv: []corev1.EnvVar{}, agentContainerArgs: []string{}, // clear default args }, nil), @@ -230,11 +223,8 @@ func TestKubernetesAgentHelm(t *testing.T) { ctx := context.Background() kCtx := k8sGetContext(t, info) - err := helm.BuildChartDependencies(agentK8SHelm) - require.NoError(t, err, "failed to build helm dependencies") - nodeList := corev1.NodeList{} - err = kCtx.client.Resources().List(ctx, &nodeList) + err := kCtx.client.Resources().List(ctx, &nodeList) require.NoError(t, err) schedulableNodeCount, err := k8sSchedulableNodeCount(ctx, kCtx) @@ -253,7 +243,7 @@ func TestKubernetesAgentHelm(t *testing.T) { name: "helm standalone agent default kubernetes privileged without host network port collision", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "kubernetes": map[string]any{ "enabled": true, }, @@ -292,7 +282,7 @@ func TestKubernetesAgentHelm(t *testing.T) { name: "helm standalone agent default kubernetes unprivileged", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "kubernetes": map[string]any{ "enabled": true, "state": map[string]any{ @@ -330,7 +320,7 @@ func TestKubernetesAgentHelm(t *testing.T) { name: "helm managed agent default kubernetes privileged", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": false, "image": map[string]any{ @@ -354,7 +344,7 @@ func TestKubernetesAgentHelm(t *testing.T) { name: "helm managed agent unenrolled with different enrollment token", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": false, "image": map[string]any{ @@ -391,7 +381,7 @@ func TestKubernetesAgentHelm(t *testing.T) { enrollParams, err := fleettools.NewEnrollParams(ctx, info.KibanaClient) require.NoError(t, err, "failed to create fleet enroll params") require.NotEqual(t, kCtx.enrollParams.EnrollmentToken, enrollParams.EnrollmentToken, "enrollment token did not change") - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": false, "image": map[string]any{ @@ -426,7 +416,7 @@ func TestKubernetesAgentHelm(t *testing.T) { // uninstall and reinstall but this time check that the elastic-agent is not re-enrolling k8sStepHelmUninstall("helm-agent")(t, ctx, kCtx, namespace) - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": false, "image": map[string]any{ @@ -467,7 +457,7 @@ func TestKubernetesAgentHelm(t *testing.T) { name: "helm managed agent unenrolled", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": false, "image": map[string]any{ @@ -501,7 +491,7 @@ func TestKubernetesAgentHelm(t *testing.T) { // under the same release name and same namespace will have the same state // as the previous deployment k8sStepHelmUninstall("helm-agent")(t, ctx, kCtx, namespace) - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": false, "image": map[string]any{ @@ -536,7 +526,7 @@ func TestKubernetesAgentHelm(t *testing.T) { // uninstall and reinstall but this time check that the elastic-agent is not re-enrolling k8sStepHelmUninstall("helm-agent")(t, ctx, kCtx, namespace) - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": false, "image": map[string]any{ @@ -577,7 +567,7 @@ func TestKubernetesAgentHelm(t *testing.T) { name: "helm managed agent upgrade older version", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": false, "image": map[string]any{ @@ -606,7 +596,7 @@ func TestKubernetesAgentHelm(t *testing.T) { return nil })(t, ctx, kCtx, namespace) k8sStepHelmUninstall("helm-agent")(t, ctx, kCtx, namespace) - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": false, "image": map[string]any{ @@ -645,7 +635,7 @@ func TestKubernetesAgentHelm(t *testing.T) { name: "helm managed agent default kubernetes unprivileged", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": true, "image": map[string]any{ @@ -669,7 +659,7 @@ func TestKubernetesAgentHelm(t *testing.T) { name: "helm standalone agent unprivileged kubernetes hints", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": true, "image": map[string]any{ @@ -714,7 +704,7 @@ func TestKubernetesAgentHelm(t *testing.T) { steps: []k8sTestStep{ k8sStepCreateNamespace(), k8sStepHintsRedisCreate(), - k8sStepHelmDeploy(agentK8SHelm, "helm-agent", map[string]any{ + k8sStepHelmDeploy(AgentHelmChartPath, "helm-agent", map[string]any{ "agent": map[string]any{ "unprivileged": true, "image": map[string]any{ @@ -961,16 +951,12 @@ type k8sKustomizeOverrides struct { // adjust the k8s objects created from the rendering to match the needs of the current test with k8sKustomizeOverrides. // However, this is not that as flexible as we would like it to be. As a last resort somebody can use forEachObject callback // to further adjust the k8s objects -func k8sStepDeployKustomize(kustomizePath string, containerName string, overrides k8sKustomizeOverrides, forEachObject func(object k8s.Object)) k8sTestStep { +func k8sStepDeployKustomize(containerName string, overrides k8sKustomizeOverrides, forEachObject func(object k8s.Object)) k8sTestStep { return func(t *testing.T, ctx context.Context, kCtx k8sContext, namespace string) { - var renderedManifest []byte - require.EventuallyWithT(t, func(collect *assert.CollectT) { - var err error - renderedManifest, err = k8sRenderKustomize(kustomizePath) - assert.NoError(collect, err) - }, 5*time.Second, 500*time.Millisecond, "failed to render kustomize") - - objects, err := testK8s.LoadFromYAML(bufio.NewReader(bytes.NewReader(renderedManifest))) + kustomizeYaml, err := os.ReadFile(AgentKustomizePath) + require.NoError(t, err, "failed to read kustomize manifest") + + objects, err := testK8s.LoadFromYAML(bufio.NewReader(bytes.NewReader(kustomizeYaml))) require.NoError(t, err, "failed to parse rendered kustomize") if forEachObject != nil { diff --git a/testing/integration/k8s/otel_helm_test.go b/testing/integration/k8s/otel_helm_test.go index 57dd740e465..be46af207ad 100644 --- a/testing/integration/k8s/otel_helm_test.go +++ b/testing/integration/k8s/otel_helm_test.go @@ -17,7 +17,6 @@ import ( "time" "github.com/stretchr/testify/require" - "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/cli/values" "helm.sh/helm/v3/pkg/getter" @@ -29,11 +28,6 @@ import ( testK8s "github.com/elastic/elastic-agent/pkg/testing/kubernetes" ) -var ( - kubeStackChartVersion = "0.3.9" - kubeStackChartURL = "https://github.com/open-telemetry/opentelemetry-helm-charts/releases/download/opentelemetry-kube-stack-" + kubeStackChartVersion + "/opentelemetry-kube-stack-" + kubeStackChartVersion + ".tgz" -) - func TestOtelKubeStackHelm(t *testing.T) { info := define.Require(t, define.Requirements{ Stack: &define.Stack{}, @@ -52,16 +46,6 @@ func TestOtelKubeStackHelm(t *testing.T) { kCtx := k8sGetContext(t, info) - chartOptions := &action.ChartPathOptions{ - RepoURL: kubeStackChartURL, - Version: kubeStackChartVersion, - } - - chartLocation, err := action.NewPull().LocateChart(chartOptions.RepoURL, cli.New()) - if err != nil { - panic(err) - } - testCases := []struct { name string steps []k8sTestStep @@ -70,7 +54,7 @@ func TestOtelKubeStackHelm(t *testing.T) { name: "managed helm kube-stack operator standalone agent kubernetes privileged", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepHelmDeployWithValueOptions(chartLocation, "kube-stack-otel", + k8sStepHelmDeployWithValueOptions(KubeStackChartPath, "kube-stack-otel", values.Options{ ValueFiles: []string{"../../../deploy/helm/edot-collector/kube-stack/values.yaml"}, Values: []string{ @@ -113,7 +97,7 @@ func TestOtelKubeStackHelm(t *testing.T) { name: "mOTel helm kube-stack operator standalone agent kubernetes privileged", steps: []k8sTestStep{ k8sStepCreateNamespace(), - k8sStepHelmDeployWithValueOptions(chartLocation, "kube-stack-otel", + k8sStepHelmDeployWithValueOptions(KubeStackChartPath, "kube-stack-otel", values.Options{ ValueFiles: []string{"../../../deploy/helm/edot-collector/kube-stack/managed_otlp/values.yaml"}, Values: []string{fmt.Sprintf("defaultCRConfig.image.repository=%s", kCtx.agentImageRepo), fmt.Sprintf("defaultCRConfig.image.tag=%s", kCtx.agentImageTag)}, diff --git a/testing/integration/k8s/testdata/elastic-agent-kustomize.yaml b/testing/integration/k8s/testdata/elastic-agent-kustomize.yaml new file mode 100644 index 00000000000..415f217275c --- /dev/null +++ b/testing/integration/k8s/testdata/elastic-agent-kustomize.yaml @@ -0,0 +1,1231 @@ +apiVersion: v1 +data: + agent.yml: |- + outputs: + default: + type: elasticsearch + hosts: + - >- + ${ES_HOST} + api_key: ${API_KEY} + ssl.ca_trusted_fingerprint: ${CA_TRUSTED} + # Uncomment username/password and remove api_key if you want to use alternative authentication method + # username: ${ES_USERNAME} + # password: ${ES_PASSWORD} + agent: + monitoring: + enabled: true + use_output: default + logs: true + metrics: true + providers.kubernetes: + node: ${NODE_NAME} + scope: node + #Uncomment to enable hints' support - https://www.elastic.co/guide/en/fleet/current/hints-annotations-autodiscovery.html + #hints.enabled: true + #hints.default_container_logs: true + inputs: + - id: kubernetes-cluster-metrics + condition: ${kubernetes_leaderelection.leader} == true + type: kubernetes/metrics + use_output: default + meta: + package: + name: kubernetes + version: 1.52.0 + data_stream: + namespace: default + streams: + - data_stream: + dataset: kubernetes.apiserver + type: metrics + metricsets: + - apiserver + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + hosts: + - 'https://${env.KUBERNETES_SERVICE_HOST}:${env.KUBERNETES_SERVICE_PORT}' + period: 30s + ssl.certificate_authorities: + - /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + - data_stream: + dataset: kubernetes.event + type: metrics + metricsets: + - event + period: 10s + add_metadata: true + - data_stream: + dataset: kubernetes.state_container + type: metrics + metricsets: + - state_container + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_cronjob + type: metrics + metricsets: + - state_cronjob + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_daemonset + type: metrics + metricsets: + - state_daemonset + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_deployment + type: metrics + metricsets: + - state_deployment + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_job + type: metrics + metricsets: + - state_job + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_namespace + type: metrics + metricsets: + - state_namespace + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_node + type: metrics + metricsets: + - state_node + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_persistentvolume + type: metrics + metricsets: + - state_persistentvolume + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_persistentvolumeclaim + type: metrics + metricsets: + - state_persistentvolumeclaim + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_pod + type: metrics + metricsets: + - state_pod + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + processors: + - add_fields: + fields: + onboarding_id: '%ONBOARDING_ID%' + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_replicaset + type: metrics + metricsets: + - state_replicaset + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_resourcequota + type: metrics + metricsets: + - state_resourcequota + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_service + type: metrics + metricsets: + - state_service + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_statefulset + type: metrics + metricsets: + - state_statefulset + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - data_stream: + dataset: kubernetes.state_storageclass + type: metrics + metricsets: + - state_storageclass + add_metadata: true + hosts: + - 'kube-state-metrics:8080' + period: 10s + # Openshift: + # if to access 'kube-state-metrics' are used third party tools, like kube-rbac-proxy or similar, that perform RBAC authorization + # and/or tls termination, then configuration below should be considered: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + - id: system-logs + type: logfile + use_output: default + meta: + package: + name: system + version: 1.20.4 + data_stream: + namespace: default + streams: + - data_stream: + dataset: system.auth + type: logs + paths: + - /var/log/auth.log* + - /var/log/secure* + exclude_files: + - .gz$ + multiline: + pattern: ^\s + match: after + processors: + - add_locale: null + ignore_older: 72h + - data_stream: + dataset: system.syslog + type: logs + paths: + - /var/log/messages* + - /var/log/syslog* + exclude_files: + - .gz$ + multiline: + pattern: ^\s + match: after + processors: + - add_locale: null + ignore_older: 72h + - id: windows-event-log + type: winlog + use_output: default + meta: + package: + name: system + version: 1.20.4 + data_stream: + namespace: default + streams: + - data_stream: + type: logs + dataset: system.application + condition: '${host.platform} == ''windows''' + ignore_older: 72h + - data_stream: + type: logs + dataset: system.security + condition: '${host.platform} == ''windows''' + ignore_older: 72h + - data_stream: + type: logs + dataset: system.system + condition: '${host.platform} == ''windows''' + ignore_older: 72h + # Input ID allowing Elastic Agent to track the state of this input. Must be unique. + - id: container-log-${kubernetes.pod.name}-${kubernetes.container.id} + type: filestream + use_output: default + meta: + package: + name: kubernetes + version: 1.52.0 + data_stream: + namespace: default + streams: + # Stream ID for this data stream allowing Filebeat to track the state of the ingested files. Must be unique. + # Each filestream data stream creates a separate instance of the Filebeat filestream input. + - id: container-log-${kubernetes.pod.name}-${kubernetes.container.id} + data_stream: + dataset: kubernetes.container_logs + type: logs + prospector.scanner.symlinks: true + parsers: + - container: ~ + # - ndjson: + # target: json + # - multiline: + # type: pattern + # pattern: '^\[' + # negate: true + # match: after + paths: + - /var/log/containers/*${kubernetes.container.id}.log + - id: audit-log + type: filestream + use_output: default + meta: + package: + name: kubernetes + version: 1.52.0 + data_stream: + namespace: default + streams: + - data_stream: + dataset: kubernetes.audit_logs + type: logs + exclude_files: + - .gz$ + parsers: + - ndjson: + add_error_key: true + target: kubernetes_audit + paths: + - /var/log/kubernetes/kube-apiserver-audit.log + # The default path of audit logs on Openshift: + # - /var/log/kube-apiserver/audit.log + processors: + - rename: + fields: + - from: kubernetes_audit + to: kubernetes.audit + - script: + id: dedot_annotations + lang: javascript + source: | + function process(event) { + var audit = event.Get("kubernetes.audit"); + for (var annotation in audit["annotations"]) { + var annotation_dedoted = annotation.replace(/\./g,'_') + event.Rename("kubernetes.audit.annotations."+annotation, "kubernetes.audit.annotations."+annotation_dedoted) + } + return event; + } function test() { + var event = process(new Event({ "kubernetes": { "audit": { "annotations": { "authorization.k8s.io/decision": "allow", "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"system:kube-scheduler\" of ClusterRole \"system:kube-scheduler\" to User \"system:kube-scheduler\"" } } } })); + if (event.Get("kubernetes.audit.annotations.authorization_k8s_io/decision") !== "allow") { + throw "expected kubernetes.audit.annotations.authorization_k8s_io/decision === allow"; + } + } + - id: system-metrics + type: system/metrics + use_output: default + meta: + package: + name: system + version: 1.20.4 + data_stream: + namespace: default + streams: + - data_stream: + dataset: system.cpu + type: metrics + period: 10s + cpu.metrics: + - percentages + - normalized_percentages + metricsets: + - cpu + system.hostfs: '/hostfs' + - data_stream: + dataset: system.diskio + type: metrics + period: 10s + diskio.include_devices: null + metricsets: + - diskio + system.hostfs: '/hostfs' + - data_stream: + dataset: system.filesystem + type: metrics + period: 1m + metricsets: + - filesystem + system.hostfs: '/hostfs' + processors: + - drop_event.when.regexp: + system.filesystem.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/) + - data_stream: + dataset: system.fsstat + type: metrics + period: 1m + metricsets: + - fsstat + system.hostfs: '/hostfs' + processors: + - drop_event.when.regexp: + system.fsstat.mount_point: ^/(sys|cgroup|proc|dev|etc|host|lib|snap)($|/) + - data_stream: + dataset: system.load + type: metrics + condition: '${host.platform} != ''windows''' + period: 10s + metricsets: + - load + - data_stream: + dataset: system.memory + type: metrics + period: 10s + metricsets: + - memory + system.hostfs: '/hostfs' + - data_stream: + dataset: system.network + type: metrics + period: 10s + network.interfaces: null + metricsets: + - network + - data_stream: + dataset: system.process + type: metrics + period: 10s + processes: + - .* + process.include_top_n.by_cpu: 5 + process.include_top_n.by_memory: 5 + process.cmdline.cache.enabled: true + process.cgroups.enabled: false + process.include_cpu_ticks: false + metricsets: + - process + system.hostfs: '/hostfs' + - data_stream: + dataset: system.process_summary + type: metrics + period: 10s + metricsets: + - process_summary + system.hostfs: '/hostfs' + - data_stream: + dataset: system.socket_summary + type: metrics + period: 10s + metricsets: + - socket_summary + system.hostfs: '/hostfs' + - data_stream: + type: metrics + dataset: system.uptime + metricsets: + - uptime + period: 10s + - id: kubernetes-node-metrics + type: kubernetes/metrics + use_output: default + meta: + package: + name: kubernetes + version: 1.52.0 + data_stream: + namespace: default + streams: + - data_stream: + dataset: kubernetes.controllermanager + type: metrics + metricsets: + - controllermanager + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + hosts: + - 'https://${kubernetes.pod.ip}:10257' + period: 10s + ssl.verification_mode: none + condition: ${kubernetes.labels.component} == 'kube-controller-manager' + # On Openshift condition should be adjusted: + # condition: ${kubernetes.labels.app} == 'kube-controller-manager' + - data_stream: + dataset: kubernetes.scheduler + type: metrics + metricsets: + - scheduler + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + hosts: + - 'https://${kubernetes.pod.ip}:10259' + period: 10s + ssl.verification_mode: none + condition: ${kubernetes.labels.component} == 'kube-scheduler' + # On Openshift condition should be adjusted: + # condition: ${kubernetes.labels.app} == 'openshift-kube-scheduler' + - data_stream: + dataset: kubernetes.proxy + type: metrics + metricsets: + - proxy + hosts: + - 'localhost:10249' + # On Openshift port should be adjusted: + # - 'localhost:29101' + period: 10s + - data_stream: + dataset: kubernetes.container + type: metrics + metricsets: + - container + add_metadata: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + hosts: + - 'https://${env.NODE_NAME}:10250' + period: 10s + ssl.verification_mode: none + # On Openshift ssl configuration must be replaced: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /path/to/ca-bundle.crt + - data_stream: + dataset: kubernetes.node + type: metrics + metricsets: + - node + add_metadata: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + hosts: + - 'https://${env.NODE_NAME}:10250' + period: 10s + ssl.verification_mode: none + # On Openshift ssl configuration must be replaced: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /path/to/ca-bundle.crt + - data_stream: + dataset: kubernetes.pod + type: metrics + metricsets: + - pod + add_metadata: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + hosts: + - 'https://${env.NODE_NAME}:10250' + period: 10s + ssl.verification_mode: none + # On Openshift ssl configuration must be replaced: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /path/to/ca-bundle.crt + - data_stream: + dataset: kubernetes.system + type: metrics + metricsets: + - system + add_metadata: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + hosts: + - 'https://${env.NODE_NAME}:10250' + period: 10s + ssl.verification_mode: none + # On Openshift ssl configuration must be replaced: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /path/to/ca-bundle.crt + - data_stream: + dataset: kubernetes.volume + type: metrics + metricsets: + - volume + add_metadata: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + hosts: + - 'https://${env.NODE_NAME}:10250' + period: 10s + ssl.verification_mode: none + # On Openshift ssl configuration must be replaced: + # bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + # ssl.certificate_authorities: + # - /path/to/ca-bundle.crt + # Add extra input blocks here, based on conditions + # so as to automatically identify targeted Pods and start monitoring them + # using a predefined integration. For instance: + #- id: redis-metrics + # type: redis/metrics + # use_output: default + # meta: + # package: + # name: redis + # version: 0.3.6 + # data_stream: + # namespace: default + # streams: + # - data_stream: + # dataset: redis.info + # type: metrics + # metricsets: + # - info + # hosts: + # - '${kubernetes.pod.ip}:6379' + # idle_timeout: 20s + # maxconn: 10 + # network: tcp + # period: 10s + # condition: ${kubernetes.labels.app} == 'redis' +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: elastic-agent-standalone + name: agent-node-datastreams + namespace: kube-system +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app: elastic-agent-standalone + app.kubernetes.io/name: elastic-agent-standalone + name: elastic-agent-standalone + namespace: kube-system +spec: + selector: + matchLabels: + app: elastic-agent-standalone + app.kubernetes.io/name: elastic-agent-standalone + template: + metadata: + labels: + app: elastic-agent-standalone + app.kubernetes.io/name: elastic-agent-standalone + spec: + containers: + - args: + - -c + - /etc/elastic-agent/agent.yml + - -e + env: + - name: ES_USERNAME + value: elastic + - name: ES_PASSWORD + value: changeme + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: ELASTIC_NETINFO + value: "false" + - name: API_KEY + valueFrom: + secretKeyRef: + key: api_key + name: elastic-agent-creds-ht4th6hfkd + - name: ES_HOST + valueFrom: + configMapKeyRef: + key: host + name: elastic-agent-configs-k799f79hhb + - name: CA_TRUSTED + valueFrom: + configMapKeyRef: + key: ca_trusted + name: elastic-agent-configs-k799f79hhb + image: docker.elastic.co/elastic-agent/elastic-agent:9.1.0 + name: elastic-agent-standalone + resources: + limits: + memory: 1Gi + requests: + cpu: 100m + memory: 500Mi + securityContext: + runAsUser: 0 + volumeMounts: + - mountPath: /etc/elastic-agent/agent.yml + name: datastreams + readOnly: true + subPath: agent.yml + - mountPath: /hostfs/proc + name: proc + readOnly: true + - mountPath: /hostfs/sys/fs/cgroup + name: cgroup + readOnly: true + - mountPath: /var/lib/docker/containers + name: varlibdockercontainers + readOnly: true + - mountPath: /var/log + name: varlog + readOnly: true + - mountPath: /hostfs/etc + name: etc-full + readOnly: true + - mountPath: /hostfs/var/lib + name: var-lib + readOnly: true + - mountPath: /sys/kernel/debug + name: sys-kernel-debug + - mountPath: /usr/share/elastic-agent/state + name: elastic-agent-state + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + serviceAccountName: elastic-agent-standalone + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + - effect: NoSchedule + key: node-role.kubernetes.io/master + volumes: + - configMap: + defaultMode: 420 + name: agent-node-datastreams + name: datastreams + - hostPath: + path: /proc + name: proc + - hostPath: + path: /sys/fs/cgroup + name: cgroup + - hostPath: + path: /var/lib/docker/containers + name: varlibdockercontainers + - hostPath: + path: /var/log + name: varlog + - hostPath: + path: /etc + name: etc-full + - hostPath: + path: /var/lib + name: var-lib + - hostPath: + path: /sys/kernel/debug + name: sys-kernel-debug + - hostPath: + path: /var/lib/elastic-agent-standalone/kube-system/state + type: DirectoryOrCreate + name: elastic-agent-state +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: elastic-agent-standalone +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: elastic-agent-standalone +subjects: +- kind: ServiceAccount + name: elastic-agent-standalone + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: elastic-agent-standalone + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: elastic-agent-standalone +subjects: +- kind: ServiceAccount + name: elastic-agent-standalone + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: elastic-agent-standalone-kubeadm-config + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: elastic-agent-standalone-kubeadm-config +subjects: +- kind: ServiceAccount + name: elastic-agent-standalone + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: elastic-agent-standalone + name: elastic-agent-standalone +rules: +- apiGroups: + - "" + resources: + - nodes + - namespaces + - events + - pods + - services + - configmaps + - serviceaccounts + - persistentvolumes + - persistentvolumeclaims + verbs: + - get + - list + - watch +- apiGroups: + - extensions + resources: + - replicasets + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - statefulsets + - deployments + - replicasets + - daemonsets + verbs: + - get + - list + - watch +- apiGroups: + - batch + resources: + - jobs + - cronjobs + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - nodes/stats + verbs: + - get +- nonResourceURLs: + - /metrics + verbs: + - get +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - get + - list + - watch +- apiGroups: + - policy + resources: + - podsecuritypolicies + verbs: + - get + - list + - watch +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: elastic-agent-standalone + name: elastic-agent-standalone + namespace: kube-system +rules: +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - create + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: elastic-agent-standalone + name: elastic-agent-standalone-kubeadm-config + namespace: kube-system +rules: +- apiGroups: + - "" + resourceNames: + - kubeadm-config + resources: + - configmaps + verbs: + - get +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: elastic-agent-standalone + name: elastic-agent-standalone + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.15.0 + name: kube-state-metrics +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kube-state-metrics +subjects: +- kind: ServiceAccount + name: kube-state-metrics + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.15.0 + name: kube-state-metrics +rules: +- apiGroups: + - "" + resources: + - configmaps + - secrets + - nodes + - pods + - services + - serviceaccounts + - resourcequotas + - replicationcontrollers + - limitranges + - persistentvolumeclaims + - persistentvolumes + - namespaces + - endpoints + verbs: + - list + - watch +- apiGroups: + - apps + resources: + - statefulsets + - daemonsets + - deployments + - replicasets + verbs: + - list + - watch +- apiGroups: + - batch + resources: + - cronjobs + - jobs + verbs: + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - list + - watch +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - list + - watch +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests + verbs: + - list + - watch +- apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + - volumeattachments + verbs: + - list + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - networkpolicies + - ingressclasses + - ingresses + verbs: + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - list + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - list + - watch +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.15.0 + name: kube-state-metrics + namespace: kube-system +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: kube-state-metrics + template: + metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.15.0 + spec: + automountServiceAccountToken: true + containers: + - image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.15.0 + livenessProbe: + httpGet: + path: /livez + port: http-metrics + initialDelaySeconds: 5 + timeoutSeconds: 5 + name: kube-state-metrics + ports: + - containerPort: 8080 + name: http-metrics + - containerPort: 8081 + name: telemetry + readinessProbe: + httpGet: + path: /readyz + port: telemetry + initialDelaySeconds: 5 + timeoutSeconds: 5 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: kube-state-metrics +--- +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.15.0 + name: kube-state-metrics + namespace: kube-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.15.0 + name: kube-state-metrics + namespace: kube-system +spec: + clusterIP: None + ports: + - name: http-metrics + port: 8080 + targetPort: http-metrics + - name: telemetry + port: 8081 + targetPort: telemetry + selector: + app.kubernetes.io/name: kube-state-metrics +--- +apiVersion: v1 +data: + ca_trusted: '%CA_TRUSTED%' + host: '%ES_HOST%' +kind: ConfigMap +metadata: + name: elastic-agent-configs-k799f79hhb + namespace: kube-system +--- +apiVersion: v1 +data: + api_key: JUFQSV9LRVkl +kind: Secret +metadata: + name: elastic-agent-creds-ht4th6hfkd + namespace: kube-system +type: Opaque diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack-0.3.9.tgz b/testing/integration/k8s/testdata/opentelemetry-kube-stack-0.3.9.tgz new file mode 100644 index 0000000000000000000000000000000000000000..66c8f0f82b014669b9845d93e43b4a95a8a6aefc GIT binary patch literal 196265 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ğ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�GzoO60XI>fhV-CZy&~MSDvTb~I(zxUk9(MOy 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

3+6HohgNCqzYL{3_O$arUYs* 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 Date: Wed, 18 Jun 2025 03:27:13 +0300 Subject: [PATCH 2/9] fix: correct decode api key --- testing/integration/k8s/common.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testing/integration/k8s/common.go b/testing/integration/k8s/common.go index f23830b48d0..f00a7eb98d2 100644 --- a/testing/integration/k8s/common.go +++ b/testing/integration/k8s/common.go @@ -119,6 +119,9 @@ func k8sGetContext(t *testing.T, info *define.Info) k8sContext { require.NoError(t, err, "failed to generate ES API key") require.NotEmpty(t, esAPIKey, "failed to generate ES API key") + beatsStyleAPIKey, err := base64.StdEncoding.DecodeString(esAPIKey.Encoded) + require.NoError(t, err, "failed to decode ES API key") + enrollParams, err := fleettools.NewEnrollParams(context.Background(), info.KibanaClient) require.NoError(t, err, "failed to create fleet enroll params") @@ -130,7 +133,7 @@ func k8sGetContext(t *testing.T, info *define.Info) k8sContext { agentImageTag: agentImageTag, logsBasePath: testLogsBasePath, esHost: esHost, - esAPIKey: esAPIKey.APIKey, + esAPIKey: string(beatsStyleAPIKey), esEncodedAPIKey: esAPIKey.Encoded, enrollParams: enrollParams, createdAt: time.Now(), From 0e92811f98143b8b7345530db8be3cd6817c0b2e Mon Sep 17 00:00:00 2001 From: Panos Koutsovasilis Date: Wed, 18 Jun 2025 03:27:50 +0300 Subject: [PATCH 3/9] fix: clear CA_TRUSTED env var for kustomize --- testing/integration/k8s/kubernetes_agent_standalone_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/testing/integration/k8s/kubernetes_agent_standalone_test.go b/testing/integration/k8s/kubernetes_agent_standalone_test.go index fd8cf463f50..86bcd588291 100644 --- a/testing/integration/k8s/kubernetes_agent_standalone_test.go +++ b/testing/integration/k8s/kubernetes_agent_standalone_test.go @@ -1005,6 +1005,11 @@ func k8sStepDeployKustomize(containerName string, overrides k8sKustomizeOverride container.Env[idx].Value = kCtx.esAPIKey container.Env[idx].ValueFrom = nil } + if env.Name == "CA_TRUSTED" { + // empty this otherwise it defaults to %CA_TRUSTED% and causes issues + container.Env[idx].Value = "" + container.Env[idx].ValueFrom = nil + } } if len(overrides.agentContainerExtraEnv) > 0 { From b2d39c8877222bab10cc7a278b3c4561f10cccc9 Mon Sep 17 00:00:00 2001 From: Panos Koutsovasilis Date: Wed, 18 Jun 2025 06:06:43 +0300 Subject: [PATCH 4/9] fix: bump memory limits for kustomize --- .../base/elastic-agent-managed-daemonset.yaml | 2 +- .../base/elastic-agent-standalone-daemonset.yaml | 2 +- .../base/elastic-agent-managed-daemonset.yaml | 2 +- .../extra/elastic-agent-managed-statefulset.yaml | 2 +- .../base/elastic-agent-standalone-daemonset.yaml | 2 +- .../extra/elastic-agent-standalone-statefulset.yaml | 2 +- deploy/kubernetes/elastic-agent-managed-kubernetes.yaml | 2 +- .../elastic-agent-managed/elastic-agent-managed-daemonset.yaml | 2 +- deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml | 2 +- .../elastic-agent-standalone-daemonset.yaml | 2 +- testing/integration/k8s/testdata/elastic-agent-kustomize.yaml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-managed/base/elastic-agent-managed-daemonset.yaml b/deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-managed/base/elastic-agent-managed-daemonset.yaml index 088500628f0..6025bbd233a 100644 --- a/deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-managed/base/elastic-agent-managed-daemonset.yaml +++ b/deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-managed/base/elastic-agent-managed-daemonset.yaml @@ -75,7 +75,7 @@ spec: # - SYS_ADMIN resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi diff --git a/deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-standalone/base/elastic-agent-standalone-daemonset.yaml b/deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-standalone/base/elastic-agent-standalone-daemonset.yaml index cd77952846f..f9fcd5ace6a 100644 --- a/deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-standalone/base/elastic-agent-standalone-daemonset.yaml +++ b/deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-standalone/base/elastic-agent-standalone-daemonset.yaml @@ -80,7 +80,7 @@ spec: # - SYS_ADMIN resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi diff --git a/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-managed/base/elastic-agent-managed-daemonset.yaml b/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-managed/base/elastic-agent-managed-daemonset.yaml index 59e6b345c0e..be2b2e611e7 100644 --- a/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-managed/base/elastic-agent-managed-daemonset.yaml +++ b/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-managed/base/elastic-agent-managed-daemonset.yaml @@ -75,7 +75,7 @@ spec: # - SYS_ADMIN resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi diff --git a/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-managed/extra/elastic-agent-managed-statefulset.yaml b/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-managed/extra/elastic-agent-managed-statefulset.yaml index 5fc6e6c8115..88a0b4825e5 100644 --- a/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-managed/extra/elastic-agent-managed-statefulset.yaml +++ b/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-managed/extra/elastic-agent-managed-statefulset.yaml @@ -75,7 +75,7 @@ spec: # - SYS_ADMIN resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi diff --git a/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-standalone/base/elastic-agent-standalone-daemonset.yaml b/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-standalone/base/elastic-agent-standalone-daemonset.yaml index 94ff19e0c8f..84cdbc5190d 100644 --- a/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-standalone/base/elastic-agent-standalone-daemonset.yaml +++ b/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-standalone/base/elastic-agent-standalone-daemonset.yaml @@ -80,7 +80,7 @@ spec: # - SYS_ADMIN resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi diff --git a/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-standalone/extra/elastic-agent-standalone-statefulset.yaml b/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-standalone/extra/elastic-agent-standalone-statefulset.yaml index f1828de98ca..049c1044514 100644 --- a/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-standalone/extra/elastic-agent-standalone-statefulset.yaml +++ b/deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-standalone/extra/elastic-agent-standalone-statefulset.yaml @@ -80,7 +80,7 @@ spec: # - SYS_ADMIN resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi diff --git a/deploy/kubernetes/elastic-agent-managed-kubernetes.yaml b/deploy/kubernetes/elastic-agent-managed-kubernetes.yaml index 4d1fedae39a..31dea796b9d 100644 --- a/deploy/kubernetes/elastic-agent-managed-kubernetes.yaml +++ b/deploy/kubernetes/elastic-agent-managed-kubernetes.yaml @@ -75,7 +75,7 @@ spec: # - SYS_ADMIN resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi diff --git a/deploy/kubernetes/elastic-agent-managed/elastic-agent-managed-daemonset.yaml b/deploy/kubernetes/elastic-agent-managed/elastic-agent-managed-daemonset.yaml index 6864b2ede54..306b9fd2d4d 100644 --- a/deploy/kubernetes/elastic-agent-managed/elastic-agent-managed-daemonset.yaml +++ b/deploy/kubernetes/elastic-agent-managed/elastic-agent-managed-daemonset.yaml @@ -75,7 +75,7 @@ spec: # - SYS_ADMIN resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi diff --git a/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml b/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml index 75f2e0069b4..64d1b976cad 100644 --- a/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml +++ b/deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml @@ -756,7 +756,7 @@ spec: # - SYS_ADMIN resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi diff --git a/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-daemonset.yaml b/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-daemonset.yaml index 1bf8de3e934..d505b6644c9 100644 --- a/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-daemonset.yaml +++ b/deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-daemonset.yaml @@ -80,7 +80,7 @@ spec: # - SYS_ADMIN resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi diff --git a/testing/integration/k8s/testdata/elastic-agent-kustomize.yaml b/testing/integration/k8s/testdata/elastic-agent-kustomize.yaml index 415f217275c..f33a75ea622 100644 --- a/testing/integration/k8s/testdata/elastic-agent-kustomize.yaml +++ b/testing/integration/k8s/testdata/elastic-agent-kustomize.yaml @@ -734,7 +734,7 @@ spec: name: elastic-agent-standalone resources: limits: - memory: 1Gi + memory: 1200Mi requests: cpu: 100m memory: 500Mi From 99cdb1a97c16a90603ca79bacead694a970ac618 Mon Sep 17 00:00:00 2001 From: Panos Koutsovasilis Date: Thu, 19 Jun 2025 09:34:54 +0300 Subject: [PATCH 5/9] fix: fabricate paths leveraging filepath --- testing/integration/k8s/k8s.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/integration/k8s/k8s.go b/testing/integration/k8s/k8s.go index c620dabf29f..62b7933f056 100644 --- a/testing/integration/k8s/k8s.go +++ b/testing/integration/k8s/k8s.go @@ -7,14 +7,14 @@ package k8s import "path/filepath" const ( - AgentKustomizePath = "./testdata/elastic-agent-kustomize.yaml" - AgentHelmChartPath = "../../../deploy/helm/elastic-agent" - KubeStackChartVersion = "0.3.9" KubeStackChartName = "opentelemetry-kube-stack-" + KubeStackChartVersion + ".tgz" KubeStackChartURL = "https://github.com/open-telemetry/opentelemetry-helm-charts/releases/download/opentelemetry-kube-stack-" + KubeStackChartVersion + "/" + KubeStackChartName ) var ( + AgentKustomizePath = filepath.Join("testdata", "elastic-agent-kustomize.yaml") + AgentHelmChartPath = filepath.Join("..", "..", "..", "deploy", "helm", "elastic-agent") + KubeStackChartPath = filepath.Join("testdata", KubeStackChartName) ) From 1196468261caa53561a80512368327bd58e3753d Mon Sep 17 00:00:00 2001 From: Panos Koutsovasilis Date: Thu, 19 Jun 2025 09:39:39 +0300 Subject: [PATCH 6/9] fix: remove redundant file moving when downloading kube stack helm chart --- magefile.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/magefile.go b/magefile.go index af06e56913f..2904184a7e3 100644 --- a/magefile.go +++ b/magefile.go @@ -2382,12 +2382,14 @@ func (Integration) BuildKubernetesTestData(ctx context.Context) error { mg.Deps(Helm.BuildDependencies) // download opentelemetry-kube-stack helm chart - kubeStackHelmChartPath, err := devtools.DownloadFile(k8s.KubeStackChartURL, filepath.Join("testing", "integration", "k8s", "testdata")) + kubeStackHelmChartTargetPath := filepath.Join("testing", "integration", "k8s", k8s.KubeStackChartPath) + kubeStackHelmChartTargetDir := filepath.Dir(kubeStackHelmChartTargetPath) + downloadedKubeStackHelmChartPath, err := devtools.DownloadFile(k8s.KubeStackChartURL, kubeStackHelmChartTargetDir) if err != nil { return fmt.Errorf("failed to download opentelemetry-kube-stack helm chart: %w", err) } - if err := os.Rename(kubeStackHelmChartPath, filepath.Join("testing", "integration", "k8s", k8s.KubeStackChartPath)); err != nil { - return fmt.Errorf("failed to move elastic-agent helm chart package to testing dir: %w", err) + if downloadedKubeStackHelmChartPath != kubeStackHelmChartTargetPath { + return fmt.Errorf("expected opentelemetry-kube-stack helm chart to be downloaded to %q, got %q", kubeStackHelmChartTargetPath, downloadedKubeStackHelmChartPath) } // render elastic-agent-standalone kustomize From 08906de9df995263eb39de72e076056f13e74e20 Mon Sep 17 00:00:00 2001 From: Panos Koutsovasilis Date: Thu, 19 Jun 2025 18:39:19 +0300 Subject: [PATCH 7/9] feat: vendor expanded archives --- .../charts/kube-state-metrics-5.30.1.tgz | Bin 14581 -> 0 bytes .../charts/kube-state-metrics/.helmignore | 21 + .../charts/kube-state-metrics/Chart.yaml | 29 + .../charts/kube-state-metrics/README.md | 85 + .../kube-state-metrics/templates/NOTES.txt | 23 + .../kube-state-metrics/templates/_helpers.tpl | 156 + .../templates/ciliumnetworkpolicy.yaml | 33 + .../templates/clusterrolebinding.yaml | 20 + .../templates/crs-configmap.yaml | 16 + .../templates/deployment.yaml | 366 + .../templates/extra-manifests.yaml | 4 + .../templates/kubeconfig-secret.yaml | 12 + .../templates/networkpolicy.yaml | 43 + .../kube-state-metrics/templates/pdb.yaml | 18 + .../templates/podsecuritypolicy.yaml | 39 + .../templates/psp-clusterrole.yaml | 19 + .../templates/psp-clusterrolebinding.yaml | 16 + .../templates/rbac-configmap.yaml | 22 + .../kube-state-metrics/templates/role.yaml | 236 + .../templates/rolebinding.yaml | 24 + .../kube-state-metrics/templates/service.yaml | 53 + .../templates/serviceaccount.yaml | 18 + .../templates/servicemonitor.yaml | 120 + .../templates/stsdiscovery-role.yaml | 26 + .../templates/stsdiscovery-rolebinding.yaml | 17 + .../templates/verticalpodautoscaler.yaml | 44 + .../charts/kube-state-metrics/values.yaml | 561 + dev-tools/mage/common.go | 2 +- magefile.go | 161 +- pkg/testing/helm/helm.go | 135 - testing/integration/k8s/k8s.go | 8 +- .../opentelemetry-kube-stack-0.3.9.tgz | Bin 196265 -> 0 bytes .../opentelemetry-kube-stack/.helmignore | 23 + .../opentelemetry-kube-stack/Chart.lock | 15 + .../opentelemetry-kube-stack/Chart.yaml | 33 + .../opentelemetry-kube-stack/README.md | 147 + .../charts/crds/Chart.yaml | 3 + .../charts/crds/README.md | 23 + .../monitoring.coreos.com_podmonitors.yaml | 904 ++ ...monitoring.coreos.com_servicemonitors.yaml | 928 ++ .../opentelemetry.io_instrumentations.yaml | 1099 ++ .../crds/opentelemetry.io_opampbridges.yaml | 1755 +++ ...ntelemetry.io_opentelemetrycollectors.yaml | 9216 ++++++++++++ .../charts/kube-state-metrics/.helmignore | 21 + .../charts/kube-state-metrics/Chart.yaml | 26 + .../charts/kube-state-metrics/README.md | 85 + .../kube-state-metrics/templates/NOTES.txt | 23 + .../kube-state-metrics/templates/_helpers.tpl | 156 + .../templates/ciliumnetworkpolicy.yaml | 33 + .../templates/clusterrolebinding.yaml | 20 + .../templates/crs-configmap.yaml | 16 + .../templates/deployment.yaml | 313 + .../templates/extra-manifests.yaml | 4 + .../templates/kubeconfig-secret.yaml | 12 + .../templates/networkpolicy.yaml | 43 + .../kube-state-metrics/templates/pdb.yaml | 18 + .../templates/podsecuritypolicy.yaml | 39 + .../templates/psp-clusterrole.yaml | 19 + .../templates/psp-clusterrolebinding.yaml | 16 + .../templates/rbac-configmap.yaml | 22 + .../kube-state-metrics/templates/role.yaml | 212 + .../templates/rolebinding.yaml | 24 + .../kube-state-metrics/templates/service.yaml | 53 + .../templates/serviceaccount.yaml | 18 + .../templates/servicemonitor.yaml | 120 + .../templates/stsdiscovery-role.yaml | 26 + .../templates/stsdiscovery-rolebinding.yaml | 17 + .../templates/verticalpodautoscaler.yaml | 44 + .../charts/kube-state-metrics/values.yaml | 522 + .../charts/opentelemetry-operator/.helmignore | 25 + .../opentelemetry-operator/CONTRIBUTING.md | 10 + .../charts/opentelemetry-operator/Chart.yaml | 15 + .../charts/opentelemetry-operator/README.md | 300 + .../opentelemetry-operator/UPGRADING.md | 108 + ...t-manager-disable-nameoverride-values.yaml | 9 + .../ci/cert-manager-disable-values.yaml | 7 + .../ci/nameoverride-values.yaml | 5 + .../ci/secret-name-nameoverride-values.yaml | 8 + .../ci/secret-name-values.yaml | 6 + .../crd-opentelemetry.io_opampbridges.yaml | 1766 +++ .../conf/crds/crd-opentelemetrycollector.yaml | 9242 ++++++++++++ .../crd-opentelemetryinstrumentation.yaml | 1096 ++ .../opentelemetry-operator/examples/README.md | 7 + .../operator-webhook-with-cert-manager.yaml | 192 + .../admission-webhooks/operator-webhook.yaml | 12102 ++++++++++++++++ .../default/rendered/certmanager.yaml | 43 + .../default/rendered/clusterrole.yaml | 265 + .../default/rendered/clusterrolebinding.yaml | 44 + .../examples/default/rendered/deployment.yaml | 105 + .../examples/default/rendered/role.yaml | 43 + .../default/rendered/rolebinding.yaml | 23 + .../examples/default/rendered/service.yaml | 51 + .../default/rendered/serviceaccount.yaml | 15 + .../tests/test-certmanager-connection.yaml | 38 + .../tests/test-service-connection.yaml | 76 + .../examples/default/values.yaml | 3 + .../templates/NOTES.txt | 8 + .../templates/_helpers.tpl | 152 + .../operator-webhook-with-cert-manager.yaml | 237 + .../admission-webhooks/operator-webhook.yaml | 282 + .../templates/certmanager.yaml | 52 + .../templates/clusterrole.yaml | 275 + .../templates/clusterrolebinding.yaml | 36 + .../templates/deployment.yaml | 181 + .../opentelemetry-operator/templates/pdb.yaml | 21 + .../templates/prometheusrule.yaml | 54 + .../templates/role.yaml | 38 + .../templates/rolebinding.yaml | 18 + .../templates/service.yaml | 51 + .../templates/serviceaccount.yaml | 16 + .../templates/servicemonitor.yaml | 37 + .../tests/test-certmanager-connection.yaml | 42 + .../tests/test-service-connection.yaml | 84 + .../templates/verticalpodautoscaler.yaml | 38 + .../opentelemetry-operator/values.schema.json | 2051 +++ .../charts/opentelemetry-operator/values.yaml | 329 + .../prometheus-node-exporter/.helmignore | 21 + .../prometheus-node-exporter/Chart.yaml | 25 + .../charts/prometheus-node-exporter/README.md | 96 + .../ci/port-values.yaml | 3 + .../templates/NOTES.txt | 29 + .../templates/_helpers.tpl | 202 + .../templates/clusterrole.yaml | 19 + .../templates/clusterrolebinding.yaml | 20 + .../templates/daemonset.yaml | 312 + .../templates/endpoints.yaml | 18 + .../templates/extra-manifests.yaml | 4 + .../templates/networkpolicy.yaml | 23 + .../templates/podmonitor.yaml | 91 + .../templates/psp-clusterrole.yaml | 14 + .../templates/psp-clusterrolebinding.yaml | 16 + .../templates/psp.yaml | 49 + .../templates/rbac-configmap.yaml | 16 + .../templates/service.yaml | 35 + .../templates/serviceaccount.yaml | 18 + .../templates/servicemonitor.yaml | 61 + .../templates/verticalpodautoscaler.yaml | 40 + .../prometheus-node-exporter/values.yaml | 537 + .../daemon_scrape_configs.yaml | 176 + .../examples/cloud-demo/rendered/bridge.yaml | 60 + .../cloud-demo/rendered/clusterrole.yaml | 175 + .../cloud-demo/rendered/collector.yaml | 658 + .../examples/cloud-demo/rendered/hooks.yaml | 65 + .../cloud-demo/rendered/instrumentation.yaml | 34 + .../operator-webhook-with-cert-manager.yaml | 192 + .../admission-webhooks/operator-webhook.yaml | 3 + .../opentelemetry-operator/certmanager.yaml | 43 + .../opentelemetry-operator/clusterrole.yaml | 265 + .../clusterrolebinding.yaml | 44 + .../opentelemetry-operator/deployment.yaml | 105 + .../rendered/opentelemetry-operator/role.yaml | 43 + .../opentelemetry-operator/rolebinding.yaml | 23 + .../opentelemetry-operator/service.yaml | 51 + .../serviceaccount.yaml | 15 + .../tests/test-certmanager-connection.yaml | 38 + .../tests/test-service-connection.yaml | 76 + .../examples/cloud-demo/values.yaml | 62 + .../examples/prometheus-otel/README.md | 5 + .../kubelet_scrape_configs.yaml | 244 + .../prometheus-otel/rendered/clusterrole.yaml | 128 + .../prometheus-otel/rendered/collector.yaml | 349 + .../kube-api-server/servicemonitor.yaml | 37 + .../kube-controller-manager/service.yaml | 24 + .../servicemonitor.yaml | 30 + .../rendered/exporters/kube-dns/service.yaml | 27 + .../exporters/kube-dns/servicemonitor.yaml | 28 + .../rendered/exporters/kube-etcd/service.yaml | 24 + .../exporters/kube-etcd/servicemonitor.yaml | 26 + .../exporters/kube-proxy/service.yaml | 24 + .../exporters/kube-proxy/servicemonitor.yaml | 26 + .../exporters/kube-scheduler/service.yaml | 24 + .../kube-scheduler/servicemonitor.yaml | 30 + .../prometheus-otel/rendered/hooks.yaml | 65 + .../clusterrolebinding.yaml | 23 + .../kube-state-metrics/deployment.yaml | 87 + .../rendered/kube-state-metrics/role.yaml | 156 + .../rendered/kube-state-metrics/service.yaml | 29 + .../kube-state-metrics/serviceaccount.yaml | 17 + .../kube-state-metrics/servicemonitor.yaml | 25 + .../operator-webhook-with-cert-manager.yaml | 192 + .../admission-webhooks/operator-webhook.yaml | 3 + .../opentelemetry-operator/certmanager.yaml | 43 + .../opentelemetry-operator/clusterrole.yaml | 265 + .../clusterrolebinding.yaml | 44 + .../opentelemetry-operator/deployment.yaml | 105 + .../rendered/opentelemetry-operator/role.yaml | 43 + .../opentelemetry-operator/rolebinding.yaml | 23 + .../opentelemetry-operator/service.yaml | 51 + .../serviceaccount.yaml | 15 + .../tests/test-certmanager-connection.yaml | 38 + .../tests/test-service-connection.yaml | 76 + .../prometheus-node-exporter/daemonset.yaml | 121 + .../prometheus-node-exporter/service.yaml | 29 + .../serviceaccount.yaml | 18 + .../servicemonitor.yaml | 29 + .../examples/prometheus-otel/values.yaml | 70 + .../templates/_config.tpl | 345 + .../templates/_helpers.tpl | 307 + .../templates/bridge.yaml | 127 + .../templates/clusterrole.yaml | 128 + .../templates/collector.yaml | 222 + .../templates/exporters/core-dns/service.yaml | 24 + .../exporters/core-dns/servicemonitor.yaml | 48 + .../kube-api-server/servicemonitor.yaml | 47 + .../kube-controller-manager/endpoints.yaml | 22 + .../kube-controller-manager/service.yaml | 29 + .../servicemonitor.yaml | 59 + .../templates/exporters/kube-dns/service.yaml | 28 + .../exporters/kube-dns/servicemonitor.yaml | 61 + .../exporters/kube-etcd/endpoints.yaml | 20 + .../exporters/kube-etcd/service.yaml | 27 + .../exporters/kube-etcd/servicemonitor.yaml | 65 + .../exporters/kube-proxy/endpoints.yaml | 20 + .../exporters/kube-proxy/service.yaml | 27 + .../exporters/kube-proxy/servicemonitor.yaml | 53 + .../exporters/kube-scheduler/endpoints.yaml | 22 + .../exporters/kube-scheduler/service.yaml | 29 + .../kube-scheduler/servicemonitor.yaml | 59 + .../templates/hooks.yaml | 63 + .../templates/instrumentation.yaml | 57 + .../values.schema.json | 3963 +++++ .../opentelemetry-kube-stack/values.yaml | 1725 +++ 222 files changed, 61783 insertions(+), 145 deletions(-) delete mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics-5.30.1.tgz create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/.helmignore create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/Chart.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/README.md create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/NOTES.txt create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/_helpers.tpl create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/clusterrolebinding.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/crs-configmap.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/deployment.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/extra-manifests.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/kubeconfig-secret.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/networkpolicy.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/pdb.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/podsecuritypolicy.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/psp-clusterrole.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/rbac-configmap.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/role.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/rolebinding.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/service.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/serviceaccount.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/servicemonitor.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/stsdiscovery-role.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml create mode 100644 deploy/helm/elastic-agent/charts/kube-state-metrics/values.yaml delete mode 100644 pkg/testing/helm/helm.go delete mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack-0.3.9.tgz create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/.helmignore create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/Chart.lock create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/Chart.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/README.md create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/Chart.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/README.md create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/monitoring.coreos.com_podmonitors.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/monitoring.coreos.com_servicemonitors.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_instrumentations.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_opampbridges.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_opentelemetrycollectors.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/.helmignore create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/Chart.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/README.md create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/NOTES.txt create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/_helpers.tpl create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/clusterrolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/crs-configmap.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/deployment.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/extra-manifests.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/kubeconfig-secret.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/networkpolicy.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/pdb.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/podsecuritypolicy.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/psp-clusterrole.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/rbac-configmap.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/role.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/rolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/serviceaccount.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/stsdiscovery-role.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/.helmignore create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/CONTRIBUTING.md create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/Chart.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/README.md create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/UPGRADING.md create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/cert-manager-disable-nameoverride-values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/cert-manager-disable-values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/nameoverride-values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/secret-name-nameoverride-values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/secret-name-values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetry.io_opampbridges.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetrycollector.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetryinstrumentation.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/README.md create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/admission-webhooks/operator-webhook-with-cert-manager.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/admission-webhooks/operator-webhook.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/certmanager.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/clusterrole.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/clusterrolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/deployment.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/role.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/rolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/serviceaccount.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/tests/test-certmanager-connection.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/tests/test-service-connection.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/NOTES.txt create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/_helpers.tpl create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/certmanager.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrole.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/deployment.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/pdb.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/prometheusrule.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/role.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/rolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/serviceaccount.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-certmanager-connection.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-service-connection.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/verticalpodautoscaler.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/values.schema.json create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/.helmignore create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/Chart.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/README.md create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/ci/port-values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/NOTES.txt create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/_helpers.tpl create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/clusterrole.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/daemonset.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/endpoints.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/extra-manifests.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/networkpolicy.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/podmonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/rbac-configmap.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/serviceaccount.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/daemon_scrape_configs.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/bridge.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/clusterrole.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/collector.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/hooks.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/instrumentation.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/admission-webhooks/operator-webhook-with-cert-manager.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/admission-webhooks/operator-webhook.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/certmanager.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/clusterrole.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/clusterrolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/deployment.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/role.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/rolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/serviceaccount.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/tests/test-certmanager-connection.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/tests/test-service-connection.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/README.md create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/kubelet_scrape_configs.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/clusterrole.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/collector.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-api-server/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-controller-manager/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-controller-manager/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-dns/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-dns/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-etcd/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-etcd/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-proxy/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-proxy/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-scheduler/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-scheduler/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/hooks.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/clusterrolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/deployment.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/role.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/serviceaccount.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/admission-webhooks/operator-webhook-with-cert-manager.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/admission-webhooks/operator-webhook.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/certmanager.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/clusterrole.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/clusterrolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/deployment.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/role.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/rolebinding.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/serviceaccount.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/tests/test-certmanager-connection.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/tests/test-service-connection.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/daemonset.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/serviceaccount.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/values.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/_config.tpl create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/_helpers.tpl create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/bridge.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/clusterrole.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/collector.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/core-dns/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/core-dns/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-api-server/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/endpoints.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-dns/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-dns/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/endpoints.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/endpoints.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/endpoints.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/service.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/servicemonitor.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/hooks.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/instrumentation.yaml create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/values.schema.json create mode 100644 testing/integration/k8s/testdata/opentelemetry-kube-stack/values.yaml diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics-5.30.1.tgz b/deploy/helm/elastic-agent/charts/kube-state-metrics-5.30.1.tgz deleted file mode 100644 index 05bd6fd564702bc7052277f56af5d55dc0b220a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14581 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 diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/.helmignore b/deploy/helm/elastic-agent/charts/kube-state-metrics/.helmignore new file mode 100644 index 00000000000..f0c13194444 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/Chart.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/Chart.yaml new file mode 100644 index 00000000000..cb98805b66f --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/Chart.yaml @@ -0,0 +1,29 @@ +annotations: + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Chart Source + url: https://github.com/prometheus-community/helm-charts +apiVersion: v2 +appVersion: 2.15.0 +description: Install kube-state-metrics to generate and expose cluster-level metrics +home: https://github.com/kubernetes/kube-state-metrics/ +keywords: +- metric +- monitoring +- prometheus +- kubernetes +maintainers: +- email: tariq.ibrahim@mulesoft.com + name: tariq1890 + url: https://github.com/tariq1890 +- email: manuel@rueg.eu + name: mrueg + url: https://github.com/mrueg +- email: david@0xdc.me + name: dotdc + url: https://github.com/dotdc +name: kube-state-metrics +sources: +- https://github.com/kubernetes/kube-state-metrics/ +type: application +version: 5.30.1 diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/README.md b/deploy/helm/elastic-agent/charts/kube-state-metrics/README.md new file mode 100644 index 00000000000..843be89e69f --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/README.md @@ -0,0 +1,85 @@ +# kube-state-metrics Helm Chart + +Installs the [kube-state-metrics agent](https://github.com/kubernetes/kube-state-metrics). + +## Get Repository Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + + +## Install Chart + +```console +helm install [RELEASE_NAME] prometheus-community/kube-state-metrics [flags] +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] prometheus-community/kube-state-metrics [flags] +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Migrating from stable/kube-state-metrics and kubernetes/kube-state-metrics + +You can upgrade in-place: + +1. [get repository info](#get-repository-info) +1. [upgrade](#upgrading-chart) your existing release name using the new chart repository + +## Upgrading to v3.0.0 + +v3.0.0 includes kube-state-metrics v2.0, see the [changelog](https://github.com/kubernetes/kube-state-metrics/blob/release-2.0/CHANGELOG.md) for major changes on the application-side. + +The upgraded chart now the following changes: + +* Dropped support for helm v2 (helm v3 or later is required) +* collectors key was renamed to resources +* namespace key was renamed to namespaces + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments: + +```console +helm show values prometheus-community/kube-state-metrics +``` + +### kube-rbac-proxy + +You can enable `kube-state-metrics` endpoint protection using `kube-rbac-proxy`. By setting `kubeRBACProxy.enabled: true`, this chart will deploy one RBAC proxy container per endpoint (metrics & telemetry). +To authorize access, authenticate your requests (via a `ServiceAccount` for example) with a `ClusterRole` attached such as: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kube-state-metrics-read +rules: + - apiGroups: [ "" ] + resources: ["services/kube-state-metrics"] + verbs: + - get +``` + +See [kube-rbac-proxy examples](https://github.com/brancz/kube-rbac-proxy/tree/master/examples/resource-attributes) for more details. diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/NOTES.txt b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/NOTES.txt new file mode 100644 index 00000000000..3589c24ec39 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/NOTES.txt @@ -0,0 +1,23 @@ +kube-state-metrics is a simple service that listens to the Kubernetes API server and generates metrics about the state of the objects. +The exposed metrics can be found here: +https://github.com/kubernetes/kube-state-metrics/blob/master/docs/README.md#exposed-metrics + +The metrics are exported on the HTTP endpoint /metrics on the listening port. +In your case, {{ template "kube-state-metrics.fullname" . }}.{{ template "kube-state-metrics.namespace" . }}.svc.cluster.local:{{ .Values.service.port }}/metrics + +They are served either as plaintext or protobuf depending on the Accept header. +They are designed to be consumed either by Prometheus itself or by a scraper that is compatible with scraping a Prometheus client endpoint. + +{{- if .Values.kubeRBACProxy.enabled}} + +kube-rbac-proxy endpoint protections is enabled: +- Metrics endpoints are now HTTPS +- Ensure that the client authenticates the requests (e.g. via service account) with the following role permissions: +``` +rules: + - apiGroups: [ "" ] + resources: ["services/{{ template "kube-state-metrics.fullname" . }}"] + verbs: + - get +``` +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/_helpers.tpl b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/_helpers.tpl new file mode 100644 index 00000000000..3dd326da4ec --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/_helpers.tpl @@ -0,0 +1,156 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "kube-state-metrics.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kube-state-metrics.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "kube-state-metrics.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "kube-state-metrics.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "kube-state-metrics.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kube-state-metrics.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Generate basic labels +*/}} +{{- define "kube-state-metrics.labels" }} +helm.sh/chart: {{ template "kube-state-metrics.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: metrics +app.kubernetes.io/part-of: {{ template "kube-state-metrics.name" . }} +{{- include "kube-state-metrics.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Values.customLabels }} +{{ tpl (toYaml .Values.customLabels) . }} +{{- end }} +{{- if .Values.releaseLabel }} +release: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kube-state-metrics.selectorLabels" }} +{{- if .Values.selectorOverride }} +{{ toYaml .Values.selectorOverride }} +{{- else }} +app.kubernetes.io/name: {{ include "kube-state-metrics.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* Sets default scrape limits for servicemonitor */}} +{{- define "servicemonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end -}} + +{{/* +Formats imagePullSecrets. Input is (dict "Values" .Values "imagePullSecrets" .{specific imagePullSecrets}) +*/}} +{{- define "kube-state-metrics.imagePullSecrets" -}} +{{- range (concat .Values.global.imagePullSecrets .imagePullSecrets) }} + {{- if eq (typeOf .) "map[string]interface {}" }} +- {{ toYaml . | trim }} + {{- else }} +- name: {{ . }} + {{- end }} +{{- end }} +{{- end -}} + +{{/* +The image to use for kube-state-metrics +*/}} +{{- define "kube-state-metrics.image" -}} +{{- if .Values.image.sha }} +{{- if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s@%s" .Values.global.imageRegistry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.sha }} +{{- else }} +{{- printf "%s/%s:%s@%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.sha }} +{{- end }} +{{- else }} +{{- if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s" .Values.global.imageRegistry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- else }} +{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +The image to use for kubeRBACProxy +*/}} +{{- define "kubeRBACProxy.image" -}} +{{- if .Values.kubeRBACProxy.image.sha }} +{{- if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s@%s" .Values.global.imageRegistry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) .Values.kubeRBACProxy.image.sha }} +{{- else }} +{{- printf "%s/%s:%s@%s" .Values.kubeRBACProxy.image.registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) .Values.kubeRBACProxy.image.sha }} +{{- end }} +{{- else }} +{{- if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s" .Values.global.imageRegistry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) }} +{{- else }} +{{- printf "%s/%s:%s" .Values.kubeRBACProxy.image.registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) }} +{{- end }} +{{- end }} +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml new file mode 100644 index 00000000000..025cd47a880 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.networkPolicy.enabled (eq .Values.networkPolicy.flavor "cilium") }} +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +spec: + endpointSelector: + matchLabels: + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + egress: + {{- if and .Values.networkPolicy.cilium .Values.networkPolicy.cilium.kubeApiServerSelector }} + {{ toYaml .Values.networkPolicy.cilium.kubeApiServerSelector | nindent 6 }} + {{- else }} + - toEntities: + - kube-apiserver + {{- end }} + ingress: + - toPorts: + - ports: + - port: {{ .Values.service.port | quote }} + protocol: TCP + {{- if .Values.selfMonitor.enabled }} + - port: {{ .Values.selfMonitor.telemetryPort | default 8081 | quote }} + protocol: TCP + {{ end }} +{{ end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/clusterrolebinding.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/clusterrolebinding.yaml new file mode 100644 index 00000000000..cf9f628d041 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.rbac.create .Values.rbac.useClusterRole -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole +{{- if .Values.rbac.useExistingRole }} + name: {{ .Values.rbac.useExistingRole }} +{{- else }} + name: {{ template "kube-state-metrics.fullname" . }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end -}} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/crs-configmap.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/crs-configmap.yaml new file mode 100644 index 00000000000..d38a75a51df --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/crs-configmap.yaml @@ -0,0 +1,16 @@ +{{- if .Values.customResourceState.enabled}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kube-state-metrics.fullname" . }}-customresourcestate-config + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} +data: + config.yaml: | + {{- toYaml .Values.customResourceState.config | nindent 4 }} +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/deployment.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/deployment.yaml new file mode 100644 index 00000000000..936640857bd --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/deployment.yaml @@ -0,0 +1,366 @@ +apiVersion: apps/v1 +{{- if .Values.autosharding.enabled }} +kind: StatefulSet +{{- else }} +kind: Deployment +{{- end }} +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- if .Values.annotations }} + annotations: +{{ toYaml .Values.annotations | indent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + replicas: {{ .Values.replicas }} + {{- if not .Values.autosharding.enabled }} + strategy: + type: {{ .Values.updateStrategy | default "RollingUpdate" }} + {{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- if .Values.autosharding.enabled }} + serviceName: {{ template "kube-state-metrics.fullname" . }} + volumeClaimTemplates: [] + {{- end }} + template: + metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.podAnnotations }} + annotations: + {{ toYaml .Values.podAnnotations | nindent 8 }} + {{- end }} + spec: + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + hostNetwork: {{ .Values.hostNetwork }} + serviceAccountName: {{ template "kube-state-metrics.serviceAccountName" . }} + {{- if .Values.securityContext.enabled }} + securityContext: {{- omit .Values.securityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- with .Values.initContainers }} + initContainers: + {{- toYaml . | nindent 6 }} + {{- end }} + containers: + {{- $servicePort := ternary 9090 (.Values.service.port | default 8080) .Values.kubeRBACProxy.enabled}} + {{- $telemetryPort := ternary 9091 (.Values.selfMonitor.telemetryPort | default 8081) .Values.kubeRBACProxy.enabled}} + - name: {{ template "kube-state-metrics.name" . }} + {{- if .Values.autosharding.enabled }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.env }} + {{- toYaml .Values.env | nindent 8 }} + {{- end }} + {{ else }} + {{- if .Values.env }} + env: + {{- toYaml .Values.env | nindent 8 }} + {{- end }} + {{- end }} + args: + {{- if .Values.extraArgs }} + {{- .Values.extraArgs | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - --host=127.0.0.1 + {{- end }} + - --port={{ $servicePort }} + {{- if .Values.collectors }} + - --resources={{ .Values.collectors | join "," }} + {{- end }} + {{- if .Values.metricLabelsAllowlist }} + - --metric-labels-allowlist={{ .Values.metricLabelsAllowlist | join "," }} + {{- end }} + {{- if .Values.metricAnnotationsAllowList }} + - --metric-annotations-allowlist={{ .Values.metricAnnotationsAllowList | join "," }} + {{- end }} + {{- if .Values.metricAllowlist }} + - --metric-allowlist={{ .Values.metricAllowlist | join "," }} + {{- end }} + {{- if .Values.metricDenylist }} + - --metric-denylist={{ .Values.metricDenylist | join "," }} + {{- end }} + {{- $namespaces := list }} + {{- if .Values.namespaces }} + {{- range $ns := join "," .Values.namespaces | split "," }} + {{- $namespaces = append $namespaces (tpl $ns $) }} + {{- end }} + {{- end }} + {{- if .Values.releaseNamespace }} + {{- $namespaces = append $namespaces ( include "kube-state-metrics.namespace" . ) }} + {{- end }} + {{- if $namespaces }} + - --namespaces={{ $namespaces | mustUniq | join "," }} + {{- end }} + {{- if .Values.namespacesDenylist }} + - --namespaces-denylist={{ tpl (.Values.namespacesDenylist | join ",") $ }} + {{- end }} + {{- if .Values.autosharding.enabled }} + - --pod=$(POD_NAME) + - --pod-namespace=$(POD_NAMESPACE) + {{- end }} + {{- if .Values.kubeconfig.enabled }} + - --kubeconfig=/opt/k8s/.kube/config + {{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - --telemetry-host=127.0.0.1 + - --telemetry-port={{ $telemetryPort }} + {{- else }} + {{- if .Values.selfMonitor.telemetryHost }} + - --telemetry-host={{ .Values.selfMonitor.telemetryHost }} + {{- end }} + {{- if .Values.selfMonitor.telemetryPort }} + - --telemetry-port={{ $telemetryPort }} + {{- end }} + {{- end }} + {{- if .Values.customResourceState.enabled }} + - --custom-resource-state-config-file=/etc/customresourcestate/config.yaml + {{- end }} + {{- if or (.Values.kubeconfig.enabled) (.Values.customResourceState.enabled) (.Values.volumeMounts) }} + volumeMounts: + {{- if .Values.kubeconfig.enabled }} + - name: kubeconfig + mountPath: /opt/k8s/.kube/ + readOnly: true + {{- end }} + {{- if .Values.customResourceState.enabled }} + - name: customresourcestate-config + mountPath: /etc/customresourcestate + readOnly: true + {{- end }} + {{- if .Values.volumeMounts }} +{{ toYaml .Values.volumeMounts | indent 8 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + image: {{ include "kube-state-metrics.image" . }} + {{- if eq .Values.kubeRBACProxy.enabled false }} + ports: + - containerPort: {{ .Values.service.port | default 8080}} + name: "http" + {{- if .Values.selfMonitor.enabled }} + - containerPort: {{ $telemetryPort }} + name: "metrics" + {{- end }} + {{- end }} + {{- if .Values.startupProbe.enabled }} + startupProbe: + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + httpGet: + {{- if .Values.hostNetwork }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.startupProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: /healthz + {{- if .Values.kubeRBACProxy.enabled }} + port: {{ .Values.service.port | default 8080 }} + scheme: HTTPS + {{- else }} + port: {{ $servicePort }} + scheme: {{ upper .Values.startupProbe.httpGet.scheme }} + {{- end }} + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + successThreshold: {{ .Values.startupProbe.successThreshold }} + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + {{- end }} + livenessProbe: + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + httpGet: + {{- if .Values.hostNetwork }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.livenessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: /livez + {{- if .Values.kubeRBACProxy.enabled }} + port: {{ .Values.service.port | default 8080 }} + scheme: HTTPS + {{- else }} + port: {{ $servicePort }} + scheme: {{ upper .Values.livenessProbe.httpGet.scheme }} + {{- end }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + readinessProbe: + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + httpGet: + {{- if .Values.hostNetwork }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.readinessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: /readyz + {{- if .Values.kubeRBACProxy.enabled }} + port: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + scheme: HTTPS + {{- else }} + port: {{ $telemetryPort }} + scheme: {{ upper .Values.readinessProbe.httpGet.scheme }} + {{- end }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + resources: +{{ toYaml .Values.resources | indent 10 }} +{{- if .Values.containerSecurityContext }} + securityContext: +{{ toYaml .Values.containerSecurityContext | indent 10 }} +{{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - name: kube-rbac-proxy-http + args: + {{- if .Values.kubeRBACProxy.extraArgs }} + {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 8 }} + {{- end }} + - --secure-listen-address=:{{ .Values.service.port | default 8080}} + - --upstream=http://127.0.0.1:{{ $servicePort }}/ + - --proxy-endpoints-port=8888 + - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml + volumeMounts: + - name: kube-rbac-proxy-config + mountPath: /etc/kube-rbac-proxy-config + {{- with .Values.kubeRBACProxy.volumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} + image: {{ include "kubeRBACProxy.image" . }} + ports: + - containerPort: {{ .Values.service.port | default 8080}} + name: "http" + - containerPort: 8888 + name: "http-healthz" + readinessProbe: + httpGet: + scheme: HTTPS + port: 8888 + path: healthz + initialDelaySeconds: 5 + timeoutSeconds: 5 + {{- if .Values.kubeRBACProxy.resources }} + resources: +{{ toYaml .Values.kubeRBACProxy.resources | indent 10 }} +{{- end }} +{{- if .Values.kubeRBACProxy.containerSecurityContext }} + securityContext: +{{ toYaml .Values.kubeRBACProxy.containerSecurityContext | indent 10 }} +{{- end }} + {{- if .Values.selfMonitor.enabled }} + - name: kube-rbac-proxy-telemetry + args: + {{- if .Values.kubeRBACProxy.extraArgs }} + {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 8 }} + {{- end }} + - --secure-listen-address=:{{ .Values.selfMonitor.telemetryPort | default 8081 }} + - --upstream=http://127.0.0.1:{{ $telemetryPort }}/ + - --proxy-endpoints-port=8889 + - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml + volumeMounts: + - name: kube-rbac-proxy-config + mountPath: /etc/kube-rbac-proxy-config + {{- with .Values.kubeRBACProxy.volumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} + image: {{ include "kubeRBACProxy.image" . }} + ports: + - containerPort: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + name: "metrics" + - containerPort: 8889 + name: "metrics-healthz" + readinessProbe: + httpGet: + scheme: HTTPS + port: 8889 + path: healthz + initialDelaySeconds: 5 + timeoutSeconds: 5 + {{- if .Values.kubeRBACProxy.resources }} + resources: +{{ toYaml .Values.kubeRBACProxy.resources | indent 10 }} +{{- end }} +{{- if .Values.kubeRBACProxy.containerSecurityContext }} + securityContext: +{{ toYaml .Values.kubeRBACProxy.containerSecurityContext | indent 10 }} +{{- end }} + {{- end }} + {{- end }} + {{- with .Values.containers }} + {{- toYaml . | nindent 6 }} + {{- end }} +{{- if or .Values.imagePullSecrets .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- include "kube-state-metrics.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.imagePullSecrets) | indent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: + {{- if kindIs "map" .Values.affinity }} + {{- toYaml .Values.affinity | nindent 8 }} + {{- else }} + {{- tpl .Values.affinity $ | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ tpl (toYaml .) $ | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ tpl (toYaml .) $ | indent 8 }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.topologySpreadConstraints | indent 8 }} + {{- end }} + {{- if or (.Values.kubeconfig.enabled) (.Values.customResourceState.enabled) (.Values.volumes) (.Values.kubeRBACProxy.enabled) }} + volumes: + {{- if .Values.kubeconfig.enabled}} + - name: kubeconfig + secret: + secretName: {{ template "kube-state-metrics.fullname" . }}-kubeconfig + {{- end }} + {{- if .Values.kubeRBACProxy.enabled}} + - name: kube-rbac-proxy-config + configMap: + name: {{ template "kube-state-metrics.fullname" . }}-rbac-config + {{- end }} + {{- if .Values.customResourceState.enabled}} + - name: customresourcestate-config + configMap: + name: {{ template "kube-state-metrics.fullname" . }}-customresourcestate-config + {{- end }} + {{- if .Values.volumes }} +{{ toYaml .Values.volumes | indent 8 }} + {{- end }} + {{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/extra-manifests.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/extra-manifests.yaml new file mode 100644 index 00000000000..567f7bf3297 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraManifests }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/kubeconfig-secret.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/kubeconfig-secret.yaml new file mode 100644 index 00000000000..6af00845029 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/kubeconfig-secret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.kubeconfig.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kube-state-metrics.fullname" . }}-kubeconfig + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +type: Opaque +data: + config: '{{ .Values.kubeconfig.secret }}' +{{- end -}} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/networkpolicy.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/networkpolicy.yaml new file mode 100644 index 00000000000..309b38ec54e --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/networkpolicy.yaml @@ -0,0 +1,43 @@ +{{- if and .Values.networkPolicy.enabled (eq .Values.networkPolicy.flavor "kubernetes") }} +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +spec: + {{- if .Values.networkPolicy.egress }} + ## Deny all egress by default + egress: + {{- toYaml .Values.networkPolicy.egress | nindent 4 }} + {{- end }} + ingress: + {{- if .Values.networkPolicy.ingress }} + {{- toYaml .Values.networkPolicy.ingress | nindent 4 }} + {{- else }} + ## Allow ingress on default ports by default + - ports: + - port: {{ .Values.service.port | default 8080 }} + protocol: TCP + {{- if .Values.selfMonitor.enabled }} + {{- $telemetryPort := ternary 9091 (.Values.selfMonitor.telemetryPort | default 8081) .Values.kubeRBACProxy.enabled}} + - port: {{ $telemetryPort }} + protocol: TCP + {{- end }} + {{- end }} + podSelector: + {{- if .Values.networkPolicy.podSelector }} + {{- toYaml .Values.networkPolicy.podSelector | nindent 4 }} + {{- else }} + matchLabels: + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + {{- end }} + policyTypes: + - Ingress + - Egress +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/pdb.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/pdb.yaml new file mode 100644 index 00000000000..3771b511de0 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/pdb.yaml @@ -0,0 +1,18 @@ +{{- if .Values.podDisruptionBudget -}} +{{ if $.Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" -}} +apiVersion: policy/v1 +{{- else -}} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "kube-state-metrics.name" . }} +{{ toYaml .Values.podDisruptionBudget | indent 2 }} +{{- end -}} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/podsecuritypolicy.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/podsecuritypolicy.yaml new file mode 100644 index 00000000000..8905e113e84 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/podsecuritypolicy.yaml @@ -0,0 +1,39 @@ +{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +{{- if .Values.podSecurityPolicy.annotations }} + annotations: +{{ toYaml .Values.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + volumes: + - 'secret' +{{- if .Values.podSecurityPolicy.additionalVolumes }} +{{ toYaml .Values.podSecurityPolicy.additionalVolumes | indent 4 }} +{{- end }} + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAsNonRoot' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/psp-clusterrole.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/psp-clusterrole.yaml new file mode 100644 index 00000000000..654e4a3d57f --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/psp-clusterrole.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: psp-{{ template "kube-state-metrics.fullname" . }} +rules: +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} +- apiGroups: ['policy'] +{{- else }} +- apiGroups: ['extensions'] +{{- end }} + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "kube-state-metrics.fullname" . }} +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml new file mode 100644 index 00000000000..5b62a18bdf1 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: psp-{{ template "kube-state-metrics.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: psp-{{ template "kube-state-metrics.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/rbac-configmap.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/rbac-configmap.yaml new file mode 100644 index 00000000000..671dc9d6604 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/rbac-configmap.yaml @@ -0,0 +1,22 @@ +{{- if .Values.kubeRBACProxy.enabled}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kube-state-metrics.fullname" . }}-rbac-config + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} +data: + config-file.yaml: |+ + authorization: + resourceAttributes: + namespace: {{ template "kube-state-metrics.namespace" . }} + apiVersion: v1 + resource: services + subresource: {{ template "kube-state-metrics.fullname" . }} + name: {{ template "kube-state-metrics.fullname" . }} +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/role.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/role.yaml new file mode 100644 index 00000000000..ff7ea1b4c15 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/role.yaml @@ -0,0 +1,236 @@ +{{- if and (eq .Values.rbac.create true) (not .Values.rbac.useExistingRole) -}} +{{- range (ternary (join "," .Values.namespaces | split "," ) (list "") (eq $.Values.rbac.useClusterRole false)) }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +{{- if eq $.Values.rbac.useClusterRole false }} +kind: Role +{{- else }} +kind: ClusterRole +{{- end }} +metadata: + labels: + {{- include "kube-state-metrics.labels" $ | indent 4 }} + name: {{ template "kube-state-metrics.fullname" $ }} +{{- if eq $.Values.rbac.useClusterRole false }} + namespace: {{ . }} +{{- end }} +rules: +{{ if has "certificatesigningrequests" $.Values.collectors }} +- apiGroups: ["certificates.k8s.io"] + resources: + - certificatesigningrequests + verbs: ["list", "watch"] +{{ end -}} +{{ if has "configmaps" $.Values.collectors }} +- apiGroups: [""] + resources: + - configmaps + verbs: ["list", "watch"] +{{ end -}} +{{ if has "cronjobs" $.Values.collectors }} +- apiGroups: ["batch"] + resources: + - cronjobs + verbs: ["list", "watch"] +{{ end -}} +{{ if has "daemonsets" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - daemonsets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "deployments" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - deployments + verbs: ["list", "watch"] +{{ end -}} +{{ if has "endpoints" $.Values.collectors }} +- apiGroups: [""] + resources: + - endpoints + verbs: ["list", "watch"] +{{ end -}} +{{ if has "endpointslices" $.Values.collectors }} +- apiGroups: ["discovery.k8s.io"] + resources: + - endpointslices + verbs: ["list", "watch"] +{{ end -}} +{{ if has "horizontalpodautoscalers" $.Values.collectors }} +- apiGroups: ["autoscaling"] + resources: + - horizontalpodautoscalers + verbs: ["list", "watch"] +{{ end -}} +{{ if has "ingresses" $.Values.collectors }} +- apiGroups: ["extensions", "networking.k8s.io"] + resources: + - ingresses + verbs: ["list", "watch"] +{{ end -}} +{{ if has "jobs" $.Values.collectors }} +- apiGroups: ["batch"] + resources: + - jobs + verbs: ["list", "watch"] +{{ end -}} +{{ if has "leases" $.Values.collectors }} +- apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: ["list", "watch"] +{{ end -}} +{{ if has "limitranges" $.Values.collectors }} +- apiGroups: [""] + resources: + - limitranges + verbs: ["list", "watch"] +{{ end -}} +{{ if has "mutatingwebhookconfigurations" $.Values.collectors }} +- apiGroups: ["admissionregistration.k8s.io"] + resources: + - mutatingwebhookconfigurations + verbs: ["list", "watch"] +{{ end -}} +{{ if has "namespaces" $.Values.collectors }} +- apiGroups: [""] + resources: + - namespaces + verbs: ["list", "watch"] +{{ end -}} +{{ if has "networkpolicies" $.Values.collectors }} +- apiGroups: ["networking.k8s.io"] + resources: + - networkpolicies + verbs: ["list", "watch"] +{{ end -}} +{{ if has "ingressclasses" $.Values.collectors }} +- apiGroups: ["networking.k8s.io"] + resources: + - ingressclasses + verbs: ["list", "watch"] +{{ end -}} +{{ if has "clusterrolebindings" $.Values.collectors }} +- apiGroups: ["rbac.authorization.k8s.io"] + resources: + - clusterrolebindings + verbs: ["list", "watch"] +{{ end -}} +{{ if has "clusterroles" $.Values.collectors }} +- apiGroups: ["rbac.authorization.k8s.io"] + resources: + - clusterroles + verbs: ["list", "watch"] +{{ end -}} +{{ if has "roles" $.Values.collectors }} +- apiGroups: ["rbac.authorization.k8s.io"] + resources: + - roles + verbs: ["list", "watch"] +{{ end -}} +{{ if has "nodes" $.Values.collectors }} +- apiGroups: [""] + resources: + - nodes + verbs: ["list", "watch"] +{{ end -}} +{{ if has "persistentvolumeclaims" $.Values.collectors }} +- apiGroups: [""] + resources: + - persistentvolumeclaims + verbs: ["list", "watch"] +{{ end -}} +{{ if has "persistentvolumes" $.Values.collectors }} +- apiGroups: [""] + resources: + - persistentvolumes + verbs: ["list", "watch"] +{{ end -}} +{{ if has "poddisruptionbudgets" $.Values.collectors }} +- apiGroups: ["policy"] + resources: + - poddisruptionbudgets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "pods" $.Values.collectors }} +- apiGroups: [""] + resources: + - pods + verbs: ["list", "watch"] +{{ end -}} +{{ if has "replicasets" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - replicasets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "replicationcontrollers" $.Values.collectors }} +- apiGroups: [""] + resources: + - replicationcontrollers + verbs: ["list", "watch"] +{{ end -}} +{{ if has "resourcequotas" $.Values.collectors }} +- apiGroups: [""] + resources: + - resourcequotas + verbs: ["list", "watch"] +{{ end -}} +{{ if has "secrets" $.Values.collectors }} +- apiGroups: [""] + resources: + - secrets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "services" $.Values.collectors }} +- apiGroups: [""] + resources: + - services + verbs: ["list", "watch"] +{{ end -}} +{{ if has "statefulsets" $.Values.collectors }} +- apiGroups: ["apps"] + resources: + - statefulsets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "storageclasses" $.Values.collectors }} +- apiGroups: ["storage.k8s.io"] + resources: + - storageclasses + verbs: ["list", "watch"] +{{ end -}} +{{ if has "validatingwebhookconfigurations" $.Values.collectors }} +- apiGroups: ["admissionregistration.k8s.io"] + resources: + - validatingwebhookconfigurations + verbs: ["list", "watch"] +{{ end -}} +{{ if has "volumeattachments" $.Values.collectors }} +- apiGroups: ["storage.k8s.io"] + resources: + - volumeattachments + verbs: ["list", "watch"] +{{ end -}} +{{- if $.Values.kubeRBACProxy.enabled }} +- apiGroups: ["authentication.k8s.io"] + resources: + - tokenreviews + verbs: ["create"] +- apiGroups: ["authorization.k8s.io"] + resources: + - subjectaccessreviews + verbs: ["create"] +{{- end }} +{{- if $.Values.customResourceState.enabled }} +- apiGroups: ["apiextensions.k8s.io"] + resources: + - customresourcedefinitions + verbs: ["list", "watch"] +{{- end }} +{{ if $.Values.rbac.extraRules }} +{{ toYaml $.Values.rbac.extraRules }} +{{ end }} +{{- end -}} +{{- end -}} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/rolebinding.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/rolebinding.yaml new file mode 100644 index 00000000000..330651b73f4 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/rolebinding.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.rbac.create true) (eq .Values.rbac.useClusterRole false) -}} +{{- range (join "," $.Values.namespaces) | split "," }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" $ | indent 4 }} + name: {{ template "kube-state-metrics.fullname" $ }} + namespace: {{ . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role +{{- if (not $.Values.rbac.useExistingRole) }} + name: {{ template "kube-state-metrics.fullname" $ }} +{{- else }} + name: {{ $.Values.rbac.useExistingRole }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" $ }} + namespace: {{ template "kube-state-metrics.namespace" $ }} +{{- end -}} +{{- end -}} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/service.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/service.yaml new file mode 100644 index 00000000000..90c235148f2 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/service.yaml @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + annotations: + {{- if .Values.prometheusScrape }} + prometheus.io/scrape: '{{ .Values.prometheusScrape }}' + {{- end }} + {{- if .Values.service.annotations }} + {{- toYaml .Values.service.annotations | nindent 4 }} + {{- end }} +spec: + type: "{{ .Values.service.type }}" + {{- if .Values.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.service.ipDualStack.ipFamilyPolicy }} + {{- end }} + ports: + - name: "http" + protocol: TCP + port: {{ .Values.service.port | default 8080}} + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + targetPort: {{ .Values.service.port | default 8080}} + {{ if .Values.selfMonitor.enabled }} + - name: "metrics" + protocol: TCP + port: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + targetPort: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + {{- if .Values.selfMonitor.telemetryNodePort }} + nodePort: {{ .Values.selfMonitor.telemetryNodePort }} + {{- end }} + {{ end }} +{{- if .Values.service.loadBalancerIP }} + loadBalancerIP: "{{ .Values.service.loadBalancerIP }}" +{{- end }} +{{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} +{{- if .Values.autosharding.enabled }} + clusterIP: None +{{- else if .Values.service.clusterIP }} + clusterIP: "{{ .Values.service.clusterIP }}" +{{- end }} + selector: + {{- include "kube-state-metrics.selectorLabels" . | indent 4 }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/serviceaccount.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/serviceaccount.yaml new file mode 100644 index 00000000000..c302bc7ca03 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- if .Values.serviceAccount.annotations }} + annotations: +{{ toYaml .Values.serviceAccount.annotations | indent 4 }} +{{- end }} +{{- if or .Values.serviceAccount.imagePullSecrets .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- include "kube-state-metrics.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.serviceAccount.imagePullSecrets) | indent 2 }} +{{- end }} +{{- end -}} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/servicemonitor.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/servicemonitor.yaml new file mode 100644 index 00000000000..99d7fa92464 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/servicemonitor.yaml @@ -0,0 +1,120 @@ +{{- if .Values.prometheus.monitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- with .Values.prometheus.monitor.additionalLabels }} + {{- tpl (toYaml . | nindent 4) $ }} + {{- end }} + {{- with .Values.prometheus.monitor.annotations }} + annotations: + {{- tpl (toYaml . | nindent 4) $ }} + {{- end }} +spec: + jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.monitor.jobLabel }} + {{- with .Values.prometheus.monitor.targetLabels }} + targetLabels: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + {{- with .Values.prometheus.monitor.podTargetLabels }} + podTargetLabels: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + {{- include "servicemonitor.scrapeLimits" .Values.prometheus.monitor | indent 2 }} + {{- if .Values.prometheus.monitor.namespaceSelector }} + namespaceSelector: + matchNames: + {{- with .Values.prometheus.monitor.namespaceSelector }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + selector: + matchLabels: + {{- with .Values.prometheus.monitor.selectorOverride }} + {{- toYaml . | nindent 6 }} + {{- else }} + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + {{- end }} + endpoints: + - port: http + {{- if or .Values.prometheus.monitor.http.interval .Values.prometheus.monitor.interval }} + interval: {{ .Values.prometheus.monitor.http.interval | default .Values.prometheus.monitor.interval }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.scrapeTimeout .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.monitor.http.scrapeTimeout | default .Values.prometheus.monitor.scrapeTimeout }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.proxyUrl .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ .Values.prometheus.monitor.http.proxyUrl | default .Values.prometheus.monitor.proxyUrl }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.enableHttp2 .Values.prometheus.monitor.enableHttp2 }} + enableHttp2: {{ .Values.prometheus.monitor.http.enableHttp2 | default .Values.prometheus.monitor.enableHttp2 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.honorLabels .Values.prometheus.monitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if or .Values.prometheus.monitor.http.metricRelabelings .Values.prometheus.monitor.metricRelabelings }} + metricRelabelings: + {{- toYaml (.Values.prometheus.monitor.http.metricRelabelings | default .Values.prometheus.monitor.metricRelabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.relabelings .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml (.Values.prometheus.monitor.http.relabelings | default .Values.prometheus.monitor.relabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.scheme .Values.prometheus.monitor.scheme }} + scheme: {{ .Values.prometheus.monitor.http.scheme | default .Values.prometheus.monitor.scheme }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.tlsConfig .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml (.Values.prometheus.monitor.http.tlsConfig | default .Values.prometheus.monitor.tlsConfig) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.bearerTokenFile .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.prometheus.monitor.http.bearerTokenFile | default .Values.prometheus.monitor.bearerTokenFile }} + {{- end }} + {{- with (.Values.prometheus.monitor.http.bearerTokenSecret | default .Values.prometheus.monitor.bearerTokenSecret) }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.selfMonitor.enabled }} + - port: metrics + {{- if or .Values.prometheus.monitor.metrics.interval .Values.prometheus.monitor.interval }} + interval: {{ .Values.prometheus.monitor.metrics.interval | default .Values.prometheus.monitor.interval }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.scrapeTimeout .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.monitor.metrics.scrapeTimeout | default .Values.prometheus.monitor.scrapeTimeout }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.proxyUrl .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ .Values.prometheus.monitor.metrics.proxyUrl | default .Values.prometheus.monitor.proxyUrl }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.enableHttp2 .Values.prometheus.monitor.enableHttp2 }} + enableHttp2: {{ .Values.prometheus.monitor.metrics.enableHttp2 | default .Values.prometheus.monitor.enableHttp2 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.honorLabels .Values.prometheus.monitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.metricRelabelings .Values.prometheus.monitor.metricRelabelings }} + metricRelabelings: + {{- toYaml (.Values.prometheus.monitor.metrics.metricRelabelings | default .Values.prometheus.monitor.metricRelabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.relabelings .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml (.Values.prometheus.monitor.metrics.relabelings | default .Values.prometheus.monitor.relabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.scheme .Values.prometheus.monitor.scheme }} + scheme: {{ .Values.prometheus.monitor.metrics.scheme | default .Values.prometheus.monitor.scheme }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.tlsConfig .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml (.Values.prometheus.monitor.metrics.tlsConfig | default .Values.prometheus.monitor.tlsConfig) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.bearerTokenFile .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.prometheus.monitor.metrics.bearerTokenFile | default .Values.prometheus.monitor.bearerTokenFile }} + {{- end }} + {{- with (.Values.prometheus.monitor.metrics.bearerTokenSecret | default .Values.prometheus.monitor.bearerTokenSecret) }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/stsdiscovery-role.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/stsdiscovery-role.yaml new file mode 100644 index 00000000000..489de147c15 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/stsdiscovery-role.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.autosharding.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - get +- apiGroups: + - apps + resourceNames: + - {{ template "kube-state-metrics.fullname" . }} + resources: + - statefulsets + verbs: + - get + - list + - watch +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml new file mode 100644 index 00000000000..73b37a4f647 --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.autosharding.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml new file mode 100644 index 00000000000..f46305b517a --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml @@ -0,0 +1,44 @@ +{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (.Values.verticalPodAutoscaler.enabled) }} +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +spec: + {{- with .Values.verticalPodAutoscaler.recommenders }} + recommenders: + {{- toYaml . | nindent 4 }} + {{- end }} + resourcePolicy: + containerPolicies: + - containerName: {{ template "kube-state-metrics.name" . }} + {{- with .Values.verticalPodAutoscaler.controlledResources }} + controlledResources: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.verticalPodAutoscaler.controlledValues }} + controlledValues: {{ .Values.verticalPodAutoscaler.controlledValues }} + {{- end }} + {{- if .Values.verticalPodAutoscaler.maxAllowed }} + maxAllowed: + {{ toYaml .Values.verticalPodAutoscaler.maxAllowed | nindent 8 }} + {{- end }} + {{- if .Values.verticalPodAutoscaler.minAllowed }} + minAllowed: + {{ toYaml .Values.verticalPodAutoscaler.minAllowed | nindent 8 }} + {{- end }} + targetRef: + apiVersion: apps/v1 + {{- if .Values.autosharding.enabled }} + kind: StatefulSet + {{- else }} + kind: Deployment + {{- end }} + name: {{ template "kube-state-metrics.fullname" . }} + {{- with .Values.verticalPodAutoscaler.updatePolicy }} + updatePolicy: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/deploy/helm/elastic-agent/charts/kube-state-metrics/values.yaml b/deploy/helm/elastic-agent/charts/kube-state-metrics/values.yaml new file mode 100644 index 00000000000..49571fbc56d --- /dev/null +++ b/deploy/helm/elastic-agent/charts/kube-state-metrics/values.yaml @@ -0,0 +1,561 @@ +# Default values for kube-state-metrics. +prometheusScrape: true +image: + registry: registry.k8s.io + repository: kube-state-metrics/kube-state-metrics + # If unset use v + .Charts.appVersion + tag: "" + sha: "" + pullPolicy: IfNotPresent + +imagePullSecrets: [] +# - name: "image-pull-secret" + +global: + # To help compatibility with other charts which use global.imagePullSecrets. + # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). + # global: + # imagePullSecrets: + # - name: pullSecret1 + # - name: pullSecret2 + # or + # global: + # imagePullSecrets: + # - pullSecret1 + # - pullSecret2 + imagePullSecrets: [] + # + # Allow parent charts to override registry hostname + imageRegistry: "" + +# If set to true, this will deploy kube-state-metrics as a StatefulSet and the data +# will be automatically sharded across <.Values.replicas> pods using the built-in +# autodiscovery feature: https://github.com/kubernetes/kube-state-metrics#automated-sharding +# This is an experimental feature and there are no stability guarantees. +autosharding: + enabled: false + +replicas: 1 + +# Change the deployment strategy when autosharding is disabled. +# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy +# The default is "RollingUpdate" as per Kubernetes defaults. +# During a release, 'RollingUpdate' can lead to two running instances for a short period of time while 'Recreate' can create a small gap in data. +# updateStrategy: Recreate + +# Number of old history to retain to allow rollback +# Default Kubernetes value is set to 10 +revisionHistoryLimit: 10 + +# List of additional cli arguments to configure kube-state-metrics +# for example: --enable-gzip-encoding, --log-file, etc. +# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md +extraArgs: [] + +# If false then the user will opt out of automounting API credentials. +automountServiceAccountToken: true + +service: + port: 8080 + # Default to clusterIP for backward compatibility + type: ClusterIP + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + nodePort: 0 + loadBalancerIP: "" + # Only allow access to the loadBalancerIP from these IPs + loadBalancerSourceRanges: [] + clusterIP: "" + annotations: {} + +## Additional labels to add to all resources +customLabels: {} + # app: kube-state-metrics + +## Override selector labels +selectorOverride: {} + +## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box +releaseLabel: false + +hostNetwork: false + +rbac: + # If true, create & use RBAC resources + create: true + + # Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here. + # useExistingRole: your-existing-role + + # If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to) + useClusterRole: true + + # Add permissions for CustomResources' apiGroups in Role/ClusterRole. Should be used in conjunction with Custom Resource State Metrics configuration + # Example: + # - apiGroups: ["monitoring.coreos.com"] + # resources: ["prometheuses"] + # verbs: ["list", "watch"] + extraRules: [] + +# Configure kube-rbac-proxy. When enabled, creates one kube-rbac-proxy container per exposed HTTP endpoint (metrics and telemetry if enabled). +# The requests are served through the same service but requests are then HTTPS. +kubeRBACProxy: + enabled: false + image: + registry: quay.io + repository: brancz/kube-rbac-proxy + tag: v0.18.2 + sha: "" + pullPolicy: IfNotPresent + + # List of additional cli arguments to configure kube-rbac-prxy + # for example: --tls-cipher-suites, --log-file, etc. + # all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage + extraArgs: [] + + ## Specify security settings for a Container + ## Allows overrides and additional options compared to (Pod) securityContext + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + containerSecurityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + + resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + + ## volumeMounts enables mounting custom volumes in rbac-proxy containers + ## Useful for TLS certificates and keys + volumeMounts: [] + # - mountPath: /etc/tls + # name: kube-rbac-proxy-tls + # readOnly: true + +serviceAccount: + # Specifies whether a ServiceAccount should be created, require rbac true + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + # Reference to one or more secrets to be used when pulling images + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + imagePullSecrets: [] + # ServiceAccount annotations. + # Use case: AWS EKS IAM roles for service accounts + # ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html + annotations: {} + # If false then the user will opt out of automounting API credentials. + automountServiceAccountToken: true + +# Additional Environment variables +env: {} + # - name: GOMAXPROCS + # valueFrom: + # resourceFieldRef: + # resource: limits.cpu + +prometheus: + monitor: + enabled: false + annotations: {} + additionalLabels: {} + namespace: "" + namespaceSelector: [] + jobLabel: "" + targetLabels: [] + podTargetLabels: [] + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + selectorOverride: {} + + ## kube-state-metrics endpoint + http: + interval: "" + scrapeTimeout: "" + proxyUrl: "" + ## Whether to enable HTTP2 for servicemonitor + enableHttp2: false + honorLabels: false + metricRelabelings: [] + relabelings: [] + scheme: "" + ## File to read bearer token for scraping targets + bearerTokenFile: "" + ## Secret to mount to read bearer token for scraping targets. The secret needs + ## to be in the same namespace as the service monitor and accessible by the + ## Prometheus Operator + bearerTokenSecret: {} + # name: secret-name + # key: key-name + tlsConfig: {} + + ## selfMonitor endpoint + metrics: + interval: "" + scrapeTimeout: "" + proxyUrl: "" + ## Whether to enable HTTP2 for servicemonitor + enableHttp2: false + honorLabels: false + metricRelabelings: [] + relabelings: [] + scheme: "" + ## File to read bearer token for scraping targets + bearerTokenFile: "" + ## Secret to mount to read bearer token for scraping targets. The secret needs + ## to be in the same namespace as the service monitor and accessible by the + ## Prometheus Operator + bearerTokenSecret: {} + # name: secret-name + # key: key-name + tlsConfig: {} + +## Specify if a Pod Security Policy for kube-state-metrics must be created +## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +## +podSecurityPolicy: + enabled: false + annotations: {} + ## Specify pod annotations + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + ## + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + + additionalVolumes: [] + +## Configure network policy for kube-state-metrics +networkPolicy: + enabled: false + # networkPolicy.flavor -- Flavor of the network policy to use. + # Can be: + # * kubernetes for networking.k8s.io/v1/NetworkPolicy + # * cilium for cilium.io/v2/CiliumNetworkPolicy + flavor: kubernetes + + ## Configure the cilium network policy kube-apiserver selector + # cilium: + # kubeApiServerSelector: + # - toEntities: + # - kube-apiserver + + # egress: + # - {} + # ingress: + # - {} + # podSelector: + # matchLabels: + # app.kubernetes.io/name: kube-state-metrics + +securityContext: + enabled: true + runAsGroup: 65534 + runAsUser: 65534 + fsGroup: 65534 + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + +## Specify security settings for a Container +## Allows overrides and additional options compared to (Pod) securityContext +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +containerSecurityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + +## Node labels for pod assignment +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +## Affinity settings for pod assignment +## Can be defined as either a dict or string. String is useful for `tpl` templating. +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +affinity: {} +# affinity: | +# podAntiAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# - labelSelector: +# matchLabels: +# {{- include "kube-state-metrics.selectorLabels" . | indent 10 }} +# topologyKey: kubernetes.io/hostname + +## Tolerations for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +## Topology spread constraints for pod assignment +## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +topologySpreadConstraints: [] + +# Annotations to be added to the deployment/statefulset +annotations: {} + +# Annotations to be added to the pod +podAnnotations: {} + +# Labels to be added to the pod +podLabels: {} + +## Assign a PriorityClassName to pods if set +# priorityClassName: "" + +# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +podDisruptionBudget: {} + +# Comma-separated list of metrics to be exposed. +# This list comprises of exact metric names and/or regex patterns. +# The allowlist and denylist are mutually exclusive. +metricAllowlist: [] + +# Comma-separated list of metrics not to be enabled. +# This list comprises of exact metric names and/or regex patterns. +# The allowlist and denylist are mutually exclusive. +metricDenylist: [] + +# Comma-separated list of additional Kubernetes label keys that will be used in the resource's +# labels metric. By default the metric contains only name and namespace labels. +# To include additional labels, provide a list of resource names in their plural form and Kubernetes +# label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. +# A single '*' can be provided per resource instead to allow any labels, but that has +# severe performance implications (Example: '=pods=[*]'). +metricLabelsAllowlist: [] + # - namespaces=[k8s-label-1,k8s-label-n] + +# Comma-separated list of Kubernetes annotations keys that will be used in the resource' +# labels metric. By default the metric contains only name and namespace labels. +# To include additional annotations provide a list of resource names in their plural form and Kubernetes +# annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. +# A single '*' can be provided per resource instead to allow any annotations, but that has +# severe performance implications (Example: '=pods=[*]'). +metricAnnotationsAllowList: [] + # - pods=[k8s-annotation-1,k8s-annotation-n] + +# Available collectors for kube-state-metrics. +# By default, all available resources are enabled, comment out to disable. +collectors: + - certificatesigningrequests + - configmaps + - cronjobs + - daemonsets + - deployments + - endpoints + - horizontalpodautoscalers + - ingresses + - jobs + - leases + - limitranges + - mutatingwebhookconfigurations + - namespaces + - networkpolicies + - nodes + - persistentvolumeclaims + - persistentvolumes + - poddisruptionbudgets + - pods + - replicasets + - replicationcontrollers + - resourcequotas + - secrets + - services + - statefulsets + - storageclasses + - validatingwebhookconfigurations + - volumeattachments + # - ingressclasses + # - clusterrolebindings + # - clusterroles + # - roles + +# Enabling kubeconfig will pass the --kubeconfig argument to the container +kubeconfig: + enabled: false + # base64 encoded kube-config file + secret: + +# Enabling support for customResourceState, will create a configMap including your config that will be read from kube-state-metrics +customResourceState: + enabled: false + # Add (Cluster)Role permissions to list/watch the customResources defined in the config to rbac.extraRules + config: {} + +# Enable only the release namespace for collecting resources. By default all namespaces are collected. +# If releaseNamespace and namespaces are both set a merged list will be collected. +releaseNamespace: false + +# Comma-separated list(string) or yaml list of namespaces to be enabled for collecting resources. By default all namespaces are collected. +namespaces: "" + +# Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set, +# only namespaces that are excluded in namespaces-denylist will be used. +namespacesDenylist: "" + +## Override the deployment namespace +## +namespaceOverride: "" + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + +## Provide a k8s version to define apiGroups for podSecurityPolicy Cluster Role. +## For example: kubeTargetVersionOverride: 1.14.9 +## +kubeTargetVersionOverride: "" + +# Enable self metrics configuration for service and Service Monitor +# Default values for telemetry configuration can be overridden +# If you set telemetryNodePort, you must also set service.type to NodePort +selfMonitor: + enabled: false + # telemetryHost: 0.0.0.0 + # telemetryPort: 8081 + # telemetryNodePort: 0 + +# Enable vertical pod autoscaler support for kube-state-metrics +verticalPodAutoscaler: + enabled: false + + # Recommender responsible for generating recommendation for the object. + # List should be empty (then the default recommender will generate the recommendation) + # or contain exactly one recommender. + # recommenders: [] + # - name: custom-recommender-performance + + # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory + controlledResources: [] + # Specifies which resource values should be controlled: RequestsOnly or RequestsAndLimits. + # controlledValues: RequestsAndLimits + + # Define the max allowed resources for the pod + maxAllowed: {} + # cpu: 200m + # memory: 100Mi + # Define the min allowed resources for the pod + minAllowed: {} + # cpu: 200m + # memory: 100Mi + + # updatePolicy: + # Specifies minimal number of replicas which need to be alive for VPA Updater to attempt pod eviction + # minReplicas: 1 + # Specifies whether recommended updates are applied when a Pod is started and whether recommended updates + # are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto". + # updateMode: Auto + +# volumeMounts are used to add custom volume mounts to deployment. +# See example below +volumeMounts: [] +# - mountPath: /etc/config +# name: config-volume + +# volumes are used to add custom volumes to deployment +# See example below +volumes: [] +# - configMap: +# name: cm-for-volume +# name: config-volume + +# Extra manifests to deploy as an array +extraManifests: [] + # - apiVersion: v1 + # kind: ConfigMap + # metadata: + # labels: + # name: prometheus-extra + # data: + # extra-data: "value" + +## Containers allows injecting additional containers. +containers: [] + # - name: crd-init + # image: kiwigrid/k8s-sidecar:latest + +## InitContainers allows injecting additional initContainers. +initContainers: [] + # - name: crd-sidecar + # image: kiwigrid/k8s-sidecar:latest + +## Settings for startup, liveness and readiness probes +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +## + +## Startup probe can optionally be enabled. +## +startupProbe: + enabled: false + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + +## Liveness probe +## +livenessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + +## Readiness probe +## +readinessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 diff --git a/dev-tools/mage/common.go b/dev-tools/mage/common.go index 749efac162a..d107e1f91c5 100644 --- a/dev-tools/mage/common.go +++ b/dev-tools/mage/common.go @@ -435,7 +435,7 @@ func untar(sourceFile, destinationDir string) error { var fileReader io.ReadCloser = file - if strings.HasSuffix(sourceFile, ".gz") { + if strings.HasSuffix(sourceFile, ".gz") || strings.HasSuffix(sourceFile, ".tgz") { if fileReader, err = gzip.NewReader(file); err != nil { return err } diff --git a/magefile.go b/magefile.go index 2904184a7e3..63a3c82d3c9 100644 --- a/magefile.go +++ b/magefile.go @@ -8,6 +8,7 @@ package main import ( "bufio" + "bytes" "context" "crypto/sha512" "encoding/json" @@ -49,7 +50,6 @@ import ( tcommon "github.com/elastic/elastic-agent/pkg/testing/common" "github.com/elastic/elastic-agent/pkg/testing/define" "github.com/elastic/elastic-agent/pkg/testing/ess" - "github.com/elastic/elastic-agent/pkg/testing/helm" "github.com/elastic/elastic-agent/pkg/testing/kubernetes" "github.com/elastic/elastic-agent/pkg/testing/kubernetes/kind" "github.com/elastic/elastic-agent/pkg/testing/multipass" @@ -81,6 +81,10 @@ import ( "helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/cli" + "helm.sh/helm/v3/pkg/downloader" + "helm.sh/helm/v3/pkg/getter" + "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v3/pkg/repo" ) const ( @@ -2383,13 +2387,20 @@ func (Integration) BuildKubernetesTestData(ctx context.Context) error { // download opentelemetry-kube-stack helm chart kubeStackHelmChartTargetPath := filepath.Join("testing", "integration", "k8s", k8s.KubeStackChartPath) + if err := os.RemoveAll(kubeStackHelmChartTargetPath); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to remove %q: %w", kubeStackHelmChartTargetPath, err) + } + kubeStackHelmChartTargetDir := filepath.Dir(kubeStackHelmChartTargetPath) downloadedKubeStackHelmChartPath, err := devtools.DownloadFile(k8s.KubeStackChartURL, kubeStackHelmChartTargetDir) if err != nil { - return fmt.Errorf("failed to download opentelemetry-kube-stack helm chart: %w", err) + return fmt.Errorf("failed to download opentelemetry-kube-stack helm chart %q: %w", k8s.KubeStackChartURL, err) + } + if err := devtools.Extract(downloadedKubeStackHelmChartPath, kubeStackHelmChartTargetDir); err != nil { + return fmt.Errorf("failed to extract opentelemetry-kube-stack helm chart %q: %w", downloadedKubeStackHelmChartPath, err) } - if downloadedKubeStackHelmChartPath != kubeStackHelmChartTargetPath { - return fmt.Errorf("expected opentelemetry-kube-stack helm chart to be downloaded to %q, got %q", kubeStackHelmChartTargetPath, downloadedKubeStackHelmChartPath) + if err := os.Remove(downloadedKubeStackHelmChartPath); err != nil { + return fmt.Errorf("failed to remove downloaded opentelemetry-kube-stack helm chart %q: %w", downloadedKubeStackHelmChartPath, err) } // render elastic-agent-standalone kustomize @@ -3861,9 +3872,147 @@ func updateYamlFile(path string, keyVal ...struct { return nil } +func (Helm) ensureRepository(repoName, repoURL string, settings *cli.EnvSettings) error { + repoFile := settings.RepositoryConfig + // Load existing repositories + file, err := repo.LoadFile(repoFile) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + file = repo.NewFile() + } else { + return fmt.Errorf("could not load Helm repository config: %w", err) + } + } + + // Check if the repository is already added + for _, entry := range file.Repositories { + if entry.URL == repoURL { + // repository already exists + return nil + } + } + + // Add the repository + entry := &repo.Entry{ + Name: repoName, + URL: repoURL, + } + + chartRepo, err := repo.NewChartRepository(entry, getter.All(settings)) + if err != nil { + return fmt.Errorf("could not create repo %s: %w", repoURL, err) + } + + _, err = chartRepo.DownloadIndexFile() + if err != nil { + return fmt.Errorf("could not download index file for repo %s: %w", repoURL, err) + } + + file.Update(entry) + if err := file.WriteFile(repoFile, 0o644); err != nil { + return fmt.Errorf("could not write Helm repository config: %w", err) + } + + return nil +} + // BuildDependencies builds the dependencies for the Elastic-Agent Helm chart. -func (Helm) BuildDependencies() error { - return helm.BuildChartDependencies(helmChartPath) +func (h Helm) BuildDependencies() error { + settings := cli.New() + settings.SetNamespace("") + actionConfig := &action.Configuration{} + + chartFile, err := os.ReadFile(fmt.Sprintf("%s/Chart.yaml", helmChartPath)) + if err != nil { + return fmt.Errorf("could not read %s/Chart.yaml: %w", helmChartPath, err) + } + + dependencies := struct { + Entry []struct { + Name string `yaml:"name"` + Repository string `yaml:"repository"` + } `yaml:"dependencies"` + }{} + + if err := os.RemoveAll(filepath.Join(helmChartPath, "charts")); err != nil && !errors.Is(err, os.ErrNotExist) { + return fmt.Errorf("could not remove %s/charts: %w", helmChartPath, err) + } + + err = yaml.Unmarshal(chartFile, &dependencies) + if err != nil { + return fmt.Errorf("could not unmarshal %s/Chart.yaml: %w", helmChartPath, err) + } + + for _, dep := range dependencies.Entry { + err := h.ensureRepository(dep.Name, dep.Repository, settings) + if err != nil { + return err + } + } + + err = actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), "", + func(format string, v ...interface{}) {}) + if err != nil { + return fmt.Errorf("failed to init helm action config: %w", err) + } + + client := action.NewDependency() + + registryClient, err := registry.NewClient( + registry.ClientOptDebug(settings.Debug), + registry.ClientOptEnableCache(true), + registry.ClientOptWriter(os.Stderr), + registry.ClientOptCredentialsFile(settings.RegistryConfig), + ) + if err != nil { + return fmt.Errorf("failed to create helm registry client: %w", err) + } + + buffer := bytes.Buffer{} + + man := &downloader.Manager{ + Out: bufio.NewWriter(&buffer), + ChartPath: helmChartPath, + Keyring: client.Keyring, + SkipUpdate: true, + Getters: getter.All(settings), + RegistryClient: registryClient, + RepositoryConfig: settings.RepositoryConfig, + RepositoryCache: settings.RepositoryCache, + Debug: settings.Debug, + } + if client.Verify { + man.Verify = downloader.VerifyIfPossible + } + err = man.Build() + if err != nil { + return fmt.Errorf("failed to build helm dependencies: %w", err) + } + + subChartDir := filepath.Join(helmChartPath, "charts") + + subChartArchives, err := filepath.Glob(filepath.Join(subChartDir, "*.tgz")) + if err != nil { + return fmt.Errorf("failed to get subchart archives: %w", err) + } + + if len(subChartArchives) != len(dependencies.Entry) { + return fmt.Errorf("expected %d subchart archives, got %d", len(dependencies.Entry), len(subChartArchives)) + } + + for _, subChartArchive := range subChartArchives { + err := mage.Extract(subChartArchive, subChartDir) + if err != nil { + return fmt.Errorf("failed to extract %q: %w", subChartArchive, err) + } + + err = os.Remove(subChartArchive) + if err != nil { + return fmt.Errorf("failed to remove %q: %w", subChartArchive, err) + } + } + + return nil } // Package packages the Elastic-Agent Helm chart. Note that you need to set SNAPSHOT="false" to build a production-ready package. diff --git a/pkg/testing/helm/helm.go b/pkg/testing/helm/helm.go deleted file mode 100644 index 9c3b18e7966..00000000000 --- a/pkg/testing/helm/helm.go +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License 2.0; -// you may not use this file except in compliance with the Elastic License 2.0. - -package helm - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "os" - - "gopkg.in/yaml.v2" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/cli" - "helm.sh/helm/v3/pkg/downloader" - "helm.sh/helm/v3/pkg/getter" - "helm.sh/helm/v3/pkg/registry" - "helm.sh/helm/v3/pkg/repo" -) - -func ensureRepository(repoName, repoURL string, settings *cli.EnvSettings) error { - repoFile := settings.RepositoryConfig - // Load existing repositories - file, err := repo.LoadFile(repoFile) - if err != nil { - if errors.Is(err, os.ErrNotExist) { - file = repo.NewFile() - } else { - return fmt.Errorf("could not load Helm repository config: %w", err) - } - } - - // Check if the repository is already added - for _, entry := range file.Repositories { - if entry.URL == repoURL { - // repository already exists - return nil - } - } - - // Add the repository - entry := &repo.Entry{ - Name: repoName, - URL: repoURL, - } - - chartRepo, err := repo.NewChartRepository(entry, getter.All(settings)) - if err != nil { - return fmt.Errorf("could not create repo %s: %w", repoURL, err) - } - - _, err = chartRepo.DownloadIndexFile() - if err != nil { - return fmt.Errorf("could not download index file for repo %s: %w", repoURL, err) - } - - file.Update(entry) - if err := file.WriteFile(repoFile, 0o644); err != nil { - return fmt.Errorf("could not write Helm repository config: %w", err) - } - - return nil -} - -func BuildChartDependencies(chartPath string) error { - settings := cli.New() - settings.SetNamespace("") - actionConfig := &action.Configuration{} - - chartFile, err := os.ReadFile(fmt.Sprintf("%s/Chart.yaml", chartPath)) - if err != nil { - return fmt.Errorf("could not read %s/Chart.yaml: %w", chartPath, err) - } - - dependencies := struct { - Entry []struct { - Name string `yaml:"name"` - Repository string `yaml:"repository"` - } `yaml:"dependencies"` - }{} - - err = yaml.Unmarshal(chartFile, &dependencies) - if err != nil { - return fmt.Errorf("could not unmarshal %s/Chart.yaml: %w", chartPath, err) - } - - for _, dep := range dependencies.Entry { - err := ensureRepository(dep.Name, dep.Repository, settings) - if err != nil { - return err - } - } - - err = actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), "", - func(format string, v ...interface{}) {}) - if err != nil { - return fmt.Errorf("failed to init helm action config: %w", err) - } - - client := action.NewDependency() - - registryClient, err := registry.NewClient( - registry.ClientOptDebug(settings.Debug), - registry.ClientOptEnableCache(true), - registry.ClientOptWriter(os.Stderr), - registry.ClientOptCredentialsFile(settings.RegistryConfig), - ) - if err != nil { - return fmt.Errorf("failed to create helm registry client: %w", err) - } - - buffer := bytes.Buffer{} - - man := &downloader.Manager{ - Out: bufio.NewWriter(&buffer), - ChartPath: chartPath, - Keyring: client.Keyring, - SkipUpdate: true, - Getters: getter.All(settings), - RegistryClient: registryClient, - RepositoryConfig: settings.RepositoryConfig, - RepositoryCache: settings.RepositoryCache, - Debug: settings.Debug, - } - if client.Verify { - man.Verify = downloader.VerifyIfPossible - } - err = man.Build() - if err != nil { - return fmt.Errorf("failed to build helm dependencies: %w", err) - } - return nil -} diff --git a/testing/integration/k8s/k8s.go b/testing/integration/k8s/k8s.go index 62b7933f056..a896a62bb50 100644 --- a/testing/integration/k8s/k8s.go +++ b/testing/integration/k8s/k8s.go @@ -7,9 +7,11 @@ package k8s import "path/filepath" const ( - KubeStackChartVersion = "0.3.9" - KubeStackChartName = "opentelemetry-kube-stack-" + KubeStackChartVersion + ".tgz" - KubeStackChartURL = "https://github.com/open-telemetry/opentelemetry-helm-charts/releases/download/opentelemetry-kube-stack-" + KubeStackChartVersion + "/" + KubeStackChartName + KubeStackChartVersion = "0.3.9" + KubeStackChartName = "opentelemetry-kube-stack" + KubeStackChartNameWithVersion = KubeStackChartName + "-" + KubeStackChartVersion + KubeStackChartArchiveName = KubeStackChartNameWithVersion + ".tgz" + KubeStackChartURL = "https://github.com/open-telemetry/opentelemetry-helm-charts/releases/download/" + KubeStackChartNameWithVersion + "/" + KubeStackChartArchiveName ) var ( diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack-0.3.9.tgz b/testing/integration/k8s/testdata/opentelemetry-kube-stack-0.3.9.tgz deleted file mode 100644 index 66c8f0f82b014669b9845d93e43b4a95a8a6aefc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196265 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ğ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�GzoO60XI>fhV-CZy&~MSDvTb~I(zxUk9(MOy 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

3+6HohgNCqzYL{3_O$arUYs* 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 [!NOTE] +> More work is needed for full compatibility. Specifically, the exporter configuration provided for various kubernetes infrastructure components. + +> [!NOTE] +> This chart aims to provide compatibility for scrape targets from the kube-prometheus-stack chart. This chart is not responsible for applying Prometheus Rules, Alertmanager, or a Prometheus instance. + +### Image versioning + +The appVersion of the chart is aligned to the latest image version of the operator. Images are upgraded within the chart manually by setting the image tag to the latest release of each image used. This will be the latest patch release for the chart's appVersion. example: +``` +appVersion: 0.103.0 +collector.image.tag: 0.103.1 +bridge.image.tag: 0.103.0 +``` + +### scrape_configs_file Details + +By default, the daemonset collector will load in the daemon_scrape_configs.yaml file which collects prometheus metrics from applications on the same node that have the prometheus.io/scrape=true annotation, kubernetes node metrics, and cadvisor metrics. Users can disable this by settings collectors.daemon.scrape_configs_file: "" OR they can provide their own promethues scrape config file for the daemonset by supplying collectors.daemon.scrape_configs_file: ".yaml" + +## Prerequisites + +- Kubernetes 1.24+ is required for OpenTelemetry Operator installation +- Helm 3.9+ + +### TLS Certificate Requirement + +

+Cert Manager Dependendency +
+In Kubernetes, in order for the API server to communicate with the webhook component, the webhook requires a TLS +certificate that the API server is configured to trust. There are a few different ways you can use to generate/configure the required TLS certificate. + +- The easiest and default method is to install the [cert-manager](https://cert-manager.io/docs/) and set `opentelemetry-operator.admissionWebhooks.certManager.enabled` to `true`. + In this way, cert-manager will generate a self-signed certificate. _See [cert-manager installation](https://cert-manager.io/docs/installation/kubernetes/) for more details._ +- You can provide your own Issuer by configuring the `opentelemetry-operator.admissionWebhooks.certManager.issuerRef` value. You will need + to specify the `kind` (Issuer or ClusterIssuer) and the `name`. Note that this method also requires the installation of cert-manager. +- You can use an automatically generated self-signed certificate by setting `opentelemetry-operator.admissionWebhooks.certManager.enabled` to `false` and `opentelemetry-operator.admissionWebhooks.autoGenerateCert.enabled` to `true`. Helm will create a self-signed cert and a secret for you. +- You can use your own generated self-signed certificate by setting both `opentelemetry-operator.admissionWebhooks.certManager.enabled` and `opentelemetry-operator.admissionWebhooks.autoGenerateCert.enabled` to `false`. You should provide the necessary values to `opentelemetry-operator.admissionWebhooks.cert_file`, `opentelemetry-operator.admissionWebhooks.key_file`, and `opentelemetry-operator.admissionWebhooks.ca_file`. +- You can sideload custom webhooks and certificate by disabling `.Values.opentelemetry-operator.admissionWebhooks.create` and `opentelemetry-operator.admissionWebhooks.certManager.enabled` while setting your custom cert secret name in `opentelemetry-operator.admissionWebhooks.secretName` +- You can disable webhooks altogether by disabling `.Values.opentelemetry-operator.admissionWebhooks.create` and setting env var to `ENABLE_WEBHOOKS: "false"` +
+ +## Add Repository + +```console +$ helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts +$ helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +```console +$ helm install \ + opentelemetry-kube-stack open-telemetry/opentelemetry-kube-stack +``` + +If you created a custom namespace, like in the TLS Certificate Requirement section above, you will need to specify the namespace with the `--namespace` helm option: + +```console +$ helm install --namespace opentelemetry-operator-system \ + opentelemetry-kube-stack open-telemetry/opentelemetry-kube-stack +``` + +If you wish for helm to create an automatically generated self-signed certificate, make sure to set the appropriate values when installing the chart: + +```console +$ helm install --set opentelemetry-operator.admissionWebhooks.certManager.enabled=false --set admissionWebhooks.autoGenerateCert.enabled=true \ + opentelemetry-kube-stack open-telemetry/opentelemetry-kube-stack +``` + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +The following command uninstalls the chart whose release name is opentelemetry-kube-stack. + +```console +$ helm uninstall opentelemetry-kube-stack +``` + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +This will remove all the Kubernetes components associated with the chart and deletes the release. + +The OpenTelemetry Collector CRD created by this chart won't be removed by default and should be manually deleted: + +```console +$ kubectl delete crd opentelemetrycollectors.opentelemetry.io +$ kubectl delete crd opampbridges.opentelemetry.io +$ kubectl delete crd instrumentations.opentelemetry.io +``` + +## Upgrade Chart + +```console +$ helm upgrade opentelemetry-kube-stack open-telemetry/opentelemetry-kube-stack +``` + +Please note that by default, the chart will be upgraded to the latest version. If you want to upgrade to a specific version, +use `--version` flag. + +With Helm v3.0, CRDs created by this chart are not updated by default and should be manually updated. +Consult also the [Helm Documentation on CRDs](https://helm.sh/docs/chart_best_practices/custom_resource_definitions). + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +## Configuration + +The following command will show all the configurable options with detailed comments. + +```console +$ helm show values open-telemetry/opentelemetry-kube-stack +``` + +When using this chart as a subchart, you may want to unset certain default values. Since Helm v3.13 values handling is improved and null can now consistently be used to remove values (e.g. to remove the default CPU limits). diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/Chart.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/Chart.yaml new file mode 100644 index 00000000000..adb9e4a5d36 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: crds +version: 0.0.0 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/README.md b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/README.md new file mode 100644 index 00000000000..0f21052f8d5 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/README.md @@ -0,0 +1,23 @@ +# OpenTelemetry Collector CRDs + +This chart contains the CRDs for _*installation*_ only right now for the opentelemetry-operator. This allows the OpenTelemetry Kubernetes Stack chart to work on install. You can see more discussion about this [here](https://github.com/open-telemetry/opentelemetry-helm-charts/issues/677) and [here](https://github.com/open-telemetry/opentelemetry-helm-charts/pull/1203). + +This approach is inspired by the kube-prometheus-stack approach which you can see discussion on [here](https://github.com/prometheus-community/helm-charts/issues/3548). + +> [!NOTE] +> This chart explicitly _does not_ support the conversion webhook that is currently in the opentelemetry-operator chart. This is because the opentelemetry-kube-stack chart will only work with v1beta1 CRDs. This chart is not meant for use with v1alpha1 Collector CRDs. + +# Upgrade Notes + +Right now, upgrades are NOT handled by this chart, however that could change in the future. This is what is run to bring in the CRDs today. + +> [!NOTE] +> The prometheus operator version should be equal to what is documented in the opentelemetry operator's compatability matrix [here](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#opentelemetry-operator-vs-kubernetes-vs-cert-manager-vs-prometheus-operator) + +```bash +wget https://raw.githubusercontent.com/open-telemetry/opentelemetry-operator/main/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml +wget https://raw.githubusercontent.com/open-telemetry/opentelemetry-operator/main/config/crd/bases/opentelemetry.io_opampbridges.yaml +wget https://raw.githubusercontent.com/open-telemetry/opentelemetry-operator/main/config/crd/bases/opentelemetry.io_instrumentations.yaml +wget https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +wget https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +``` diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/monitoring.coreos.com_podmonitors.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/monitoring.coreos.com_podmonitors.yaml new file mode 100644 index 00000000000..6a820a61acd --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/monitoring.coreos.com_podmonitors.yaml @@ -0,0 +1,904 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + operator.prometheus.io/version: 0.74.0 + name: podmonitors.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: PodMonitor + listKind: PodMonitorList + plural: podmonitors + shortNames: + - pmon + singular: podmonitor + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: PodMonitor defines monitoring for a set of pods. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of desired Pod selection for target discovery + by Prometheus. + properties: + attachMetadata: + description: |- + `attachMetadata` defines additional metadata which is added to the + discovered targets. + + + It requires Prometheus >= v2.37.0. + properties: + node: + description: |- + When set to true, Prometheus must have the `get` permission on the + `Nodes` objects. + type: boolean + type: object + bodySizeLimit: + description: |- + When defined, bodySizeLimit specifies a job level limit on the size + of uncompressed response body that will be accepted by Prometheus. + + + It requires Prometheus >= v2.28.0. + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string + jobLabel: + description: |- + The label to use to retrieve the job name from. + `jobLabel` selects the label from the associated Kubernetes `Pod` + object which will be used as the `job` label for all metrics. + + + For example if `jobLabel` is set to `foo` and the Kubernetes `Pod` + object is labeled with `foo: bar`, then Prometheus adds the `job="bar"` + label to all ingested metrics. + + + If the value of this field is empty, the `job` label of the metrics + defaults to the namespace and name of the PodMonitor object (e.g. `/`). + type: string + keepDroppedTargets: + description: |- + Per-scrape limit on the number of targets dropped by relabeling + that will be kept in memory. 0 means no limit. + + + It requires Prometheus >= v2.47.0. + format: int64 + type: integer + labelLimit: + description: |- + Per-scrape limit on number of labels that will be accepted for a sample. + + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + labelNameLengthLimit: + description: |- + Per-scrape limit on length of labels name that will be accepted for a sample. + + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + labelValueLengthLimit: + description: |- + Per-scrape limit on length of labels value that will be accepted for a sample. + + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + namespaceSelector: + description: |- + Selector to select which namespaces the Kubernetes `Pods` objects + are discovered from. + properties: + any: + description: |- + Boolean describing whether all namespaces are selected in contrast to a + list restricting them. + type: boolean + matchNames: + description: List of namespace names to select from. + items: + type: string + type: array + type: object + podMetricsEndpoints: + description: List of endpoints part of this PodMonitor. + items: + description: |- + PodMetricsEndpoint defines an endpoint serving Prometheus metrics to be scraped by + Prometheus. + properties: + authorization: + description: |- + `authorization` configures the Authorization header credentials to use when + scraping the target. + + + Cannot be set at the same time as `basicAuth`, or `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace + that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + + "Basic" is not a supported value. + + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + `basicAuth` configures the Basic Authentication credentials to use when + scraping the target. + + + Cannot be set at the same time as `authorization`, or `oauth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: |- + `bearerTokenSecret` specifies a key of a Secret containing the bearer + token for scraping targets. The secret needs to be in the same namespace + as the PodMonitor object and readable by the Prometheus Operator. + + + Deprecated: use `authorization` instead. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + description: '`enableHttp2` can be used to disable HTTP2 when + scraping the target.' + type: boolean + filterRunning: + description: |- + When true, the pods which are not running (e.g. either in Failed or + Succeeded state) are dropped during the target discovery. + + + If unset, the filtering is enabled. + + + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase + type: boolean + followRedirects: + description: |- + `followRedirects` defines whether the scrape requests should follow HTTP + 3xx redirects. + type: boolean + honorLabels: + description: |- + When true, `honorLabels` preserves the metric's labels when they collide + with the target's labels. + type: boolean + honorTimestamps: + description: |- + `honorTimestamps` controls whether Prometheus preserves the timestamps + when exposed by the target. + type: boolean + interval: + description: |- + Interval at which Prometheus scrapes the metrics from the target. + + + If empty, Prometheus uses the global scrape interval. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + description: |- + `metricRelabelings` configures the relabeling rules to apply to the + samples before ingestion. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated + SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + + Regex capture groups are available. + type: string + type: object + type: array + oauth2: + description: |- + `oauth2` configures the OAuth2 settings to use when scraping the target. + + + It requires Prometheus >= 2.27.0. + + + Cannot be set at the same time as `authorization`, or `basicAuth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + scopes: + description: '`scopes` defines the OAuth2 scopes used for + the token request.' + items: + type: string + type: array + tokenUrl: + description: '`tokenURL` configures the URL to fetch the + token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + description: '`params` define optional HTTP URL parameters.' + type: object + path: + description: |- + HTTP path from which to scrape for metrics. + + + If empty, Prometheus uses the default value (e.g. `/metrics`). + type: string + port: + description: |- + Name of the Pod port which this endpoint refers to. + + + It takes precedence over `targetPort`. + type: string + proxyUrl: + description: |- + `proxyURL` configures the HTTP Proxy URL (e.g. + "http://proxyserver:2195") to go through when scraping the target. + type: string + relabelings: + description: |- + `relabelings` configures the relabeling rules to apply the target's + metadata labels. + + + The Operator automatically adds relabelings for a few standard Kubernetes fields. + + + The original scrape job's name is available via the `__tmp_prometheus_job_name` label. + + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated + SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + + Regex capture groups are available. + type: string + type: object + type: array + scheme: + description: |- + HTTP scheme to use for scraping. + + + `http` and `https` are the expected values unless you rewrite the + `__scheme__` label via relabeling. + + + If empty, Prometheus uses the default value `http`. + enum: + - http + - https + type: string + scrapeTimeout: + description: |- + Timeout after which Prometheus considers the scrape to be failed. + + + If empty, Prometheus uses the global scrape timeout unless it is less + than the target's scrape interval value in which the latter is used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the target port of the `Pod` object behind the Service, the + port must be specified with container port property. + + + Deprecated: use 'port' instead. + x-kubernetes-int-or-string: true + tlsConfig: + description: TLS configuration to use when scraping the target. + properties: + ca: + description: Certificate authority used when verifying server + certificates. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the + targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + trackTimestampsStaleness: + description: |- + `trackTimestampsStaleness` defines whether Prometheus tracks staleness of + the metrics that have an explicit timestamp present in scraped data. + Has no effect if `honorTimestamps` is false. + + + It requires Prometheus >= v2.48.0. + type: boolean + type: object + type: array + podTargetLabels: + description: |- + `podTargetLabels` defines the labels which are transferred from the + associated Kubernetes `Pod` object onto the ingested metrics. + items: + type: string + type: array + sampleLimit: + description: |- + `sampleLimit` defines a per-scrape limit on the number of scraped samples + that will be accepted. + format: int64 + type: integer + scrapeClass: + description: The scrape class to apply. + minLength: 1 + type: string + scrapeProtocols: + description: |- + `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the + protocols supported by Prometheus in order of preference (from most to least preferred). + + + If unset, Prometheus uses its default value. + + + It requires Prometheus >= v2.49.0. + items: + description: |- + ScrapeProtocol represents a protocol used by Prometheus for scraping metrics. + Supported values are: + * `OpenMetricsText0.0.1` + * `OpenMetricsText1.0.0` + * `PrometheusProto` + * `PrometheusText0.0.4` + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + type: string + type: array + x-kubernetes-list-type: set + selector: + description: Label selector to select the Kubernetes `Pod` objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + targetLimit: + description: |- + `targetLimit` defines a limit on the number of scraped targets that will + be accepted. + format: int64 + type: integer + required: + - selector + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/monitoring.coreos.com_servicemonitors.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/monitoring.coreos.com_servicemonitors.yaml new file mode 100644 index 00000000000..5219ea48beb --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/monitoring.coreos.com_servicemonitors.yaml @@ -0,0 +1,928 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + operator.prometheus.io/version: 0.74.0 + name: servicemonitors.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: ServiceMonitor + listKind: ServiceMonitorList + plural: servicemonitors + shortNames: + - smon + singular: servicemonitor + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ServiceMonitor defines monitoring for a set of services. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + Specification of desired Service selection for target discovery by + Prometheus. + properties: + attachMetadata: + description: |- + `attachMetadata` defines additional metadata which is added to the + discovered targets. + + + It requires Prometheus >= v2.37.0. + properties: + node: + description: |- + When set to true, Prometheus must have the `get` permission on the + `Nodes` objects. + type: boolean + type: object + bodySizeLimit: + description: |- + When defined, bodySizeLimit specifies a job level limit on the size + of uncompressed response body that will be accepted by Prometheus. + + + It requires Prometheus >= v2.28.0. + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string + endpoints: + description: List of endpoints part of this ServiceMonitor. + items: + description: |- + Endpoint defines an endpoint serving Prometheus metrics to be scraped by + Prometheus. + properties: + authorization: + description: |- + `authorization` configures the Authorization header credentials to use when + scraping the target. + + + Cannot be set at the same time as `basicAuth`, or `oauth2`. + properties: + credentials: + description: Selects a key of a Secret in the namespace + that contains the credentials for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: |- + Defines the authentication type. The value is case-insensitive. + + + "Basic" is not a supported value. + + + Default: "Bearer" + type: string + type: object + basicAuth: + description: |- + `basicAuth` configures the Basic Authentication credentials to use when + scraping the target. + + + Cannot be set at the same time as `authorization`, or `oauth2`. + properties: + password: + description: |- + `password` specifies a key of a Secret containing the password for + authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: |- + `username` specifies a key of a Secret containing the username for + authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenFile: + description: |- + File to read bearer token for scraping the target. + + + Deprecated: use `authorization` instead. + type: string + bearerTokenSecret: + description: |- + `bearerTokenSecret` specifies a key of a Secret containing the bearer + token for scraping targets. The secret needs to be in the same namespace + as the ServiceMonitor object and readable by the Prometheus Operator. + + + Deprecated: use `authorization` instead. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + description: '`enableHttp2` can be used to disable HTTP2 when + scraping the target.' + type: boolean + filterRunning: + description: |- + When true, the pods which are not running (e.g. either in Failed or + Succeeded state) are dropped during the target discovery. + + + If unset, the filtering is enabled. + + + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase + type: boolean + followRedirects: + description: |- + `followRedirects` defines whether the scrape requests should follow HTTP + 3xx redirects. + type: boolean + honorLabels: + description: |- + When true, `honorLabels` preserves the metric's labels when they collide + with the target's labels. + type: boolean + honorTimestamps: + description: |- + `honorTimestamps` controls whether Prometheus preserves the timestamps + when exposed by the target. + type: boolean + interval: + description: |- + Interval at which Prometheus scrapes the metrics from the target. + + + If empty, Prometheus uses the global scrape interval. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + description: |- + `metricRelabelings` configures the relabeling rules to apply to the + samples before ingestion. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated + SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + + Regex capture groups are available. + type: string + type: object + type: array + oauth2: + description: |- + `oauth2` configures the OAuth2 settings to use when scraping the target. + + + It requires Prometheus >= 2.27.0. + + + Cannot be set at the same time as `authorization`, or `basicAuth`. + properties: + clientId: + description: |- + `clientId` specifies a key of a Secret or ConfigMap containing the + OAuth2 client's ID. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: |- + `clientSecret` specifies a key of a Secret containing the OAuth2 + client's secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: |- + `endpointParams` configures the HTTP parameters to append to the token + URL. + type: object + scopes: + description: '`scopes` defines the OAuth2 scopes used for + the token request.' + items: + type: string + type: array + tokenUrl: + description: '`tokenURL` configures the URL to fetch the + token from.' + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + description: params define optional HTTP URL parameters. + type: object + path: + description: |- + HTTP path from which to scrape for metrics. + + + If empty, Prometheus uses the default value (e.g. `/metrics`). + type: string + port: + description: |- + Name of the Service port which this endpoint refers to. + + + It takes precedence over `targetPort`. + type: string + proxyUrl: + description: |- + `proxyURL` configures the HTTP Proxy URL (e.g. + "http://proxyserver:2195") to go through when scraping the target. + type: string + relabelings: + description: |- + `relabelings` configures the relabeling rules to apply the target's + metadata labels. + + + The Operator automatically adds relabelings for a few standard Kubernetes fields. + + + The original scrape job's name is available via the `__tmp_prometheus_job_name` label. + + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated + SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + + Regex capture groups are available. + type: string + type: object + type: array + scheme: + description: |- + HTTP scheme to use for scraping. + + + `http` and `https` are the expected values unless you rewrite the + `__scheme__` label via relabeling. + + + If empty, Prometheus uses the default value `http`. + enum: + - http + - https + type: string + scrapeTimeout: + description: |- + Timeout after which Prometheus considers the scrape to be failed. + + + If empty, Prometheus uses the global scrape timeout unless it is less + than the target's scrape interval value in which the latter is used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the target port of the `Pod` object behind the + Service. The port must be specified with the container's port property. + x-kubernetes-int-or-string: true + tlsConfig: + description: TLS configuration to use when scraping the target. + properties: + ca: + description: Certificate authority used when verifying server + certificates. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container + to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus + container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus + container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + trackTimestampsStaleness: + description: |- + `trackTimestampsStaleness` defines whether Prometheus tracks staleness of + the metrics that have an explicit timestamp present in scraped data. + Has no effect if `honorTimestamps` is false. + + + It requires Prometheus >= v2.48.0. + type: boolean + type: object + type: array + jobLabel: + description: |- + `jobLabel` selects the label from the associated Kubernetes `Service` + object which will be used as the `job` label for all metrics. + + + For example if `jobLabel` is set to `foo` and the Kubernetes `Service` + object is labeled with `foo: bar`, then Prometheus adds the `job="bar"` + label to all ingested metrics. + + + If the value of this field is empty or if the label doesn't exist for + the given Service, the `job` label of the metrics defaults to the name + of the associated Kubernetes `Service`. + type: string + keepDroppedTargets: + description: |- + Per-scrape limit on the number of targets dropped by relabeling + that will be kept in memory. 0 means no limit. + + + It requires Prometheus >= v2.47.0. + format: int64 + type: integer + labelLimit: + description: |- + Per-scrape limit on number of labels that will be accepted for a sample. + + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + labelNameLengthLimit: + description: |- + Per-scrape limit on length of labels name that will be accepted for a sample. + + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + labelValueLengthLimit: + description: |- + Per-scrape limit on length of labels value that will be accepted for a sample. + + + It requires Prometheus >= v2.27.0. + format: int64 + type: integer + namespaceSelector: + description: |- + Selector to select which namespaces the Kubernetes `Endpoints` objects + are discovered from. + properties: + any: + description: |- + Boolean describing whether all namespaces are selected in contrast to a + list restricting them. + type: boolean + matchNames: + description: List of namespace names to select from. + items: + type: string + type: array + type: object + podTargetLabels: + description: |- + `podTargetLabels` defines the labels which are transferred from the + associated Kubernetes `Pod` object onto the ingested metrics. + items: + type: string + type: array + sampleLimit: + description: |- + `sampleLimit` defines a per-scrape limit on the number of scraped samples + that will be accepted. + format: int64 + type: integer + scrapeClass: + description: The scrape class to apply. + minLength: 1 + type: string + scrapeProtocols: + description: |- + `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the + protocols supported by Prometheus in order of preference (from most to least preferred). + + + If unset, Prometheus uses its default value. + + + It requires Prometheus >= v2.49.0. + items: + description: |- + ScrapeProtocol represents a protocol used by Prometheus for scraping metrics. + Supported values are: + * `OpenMetricsText0.0.1` + * `OpenMetricsText1.0.0` + * `PrometheusProto` + * `PrometheusText0.0.4` + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + type: string + type: array + x-kubernetes-list-type: set + selector: + description: Label selector to select the Kubernetes `Endpoints` objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + targetLabels: + description: |- + `targetLabels` defines the labels which are transferred from the + associated Kubernetes `Service` object onto the ingested metrics. + items: + type: string + type: array + targetLimit: + description: |- + `targetLimit` defines a limit on the number of scraped targets that will + be accepted. + format: int64 + type: integer + required: + - selector + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_instrumentations.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_instrumentations.yaml new file mode 100644 index 00000000000..3065e245a19 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_instrumentations.yaml @@ -0,0 +1,1099 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: instrumentations.opentelemetry.io +spec: + group: opentelemetry.io + names: + kind: Instrumentation + listKind: InstrumentationList + plural: instrumentations + shortNames: + - otelinst + - otelinsts + singular: instrumentation + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.exporter.endpoint + name: Endpoint + type: string + - jsonPath: .spec.sampler.type + name: Sampler + type: string + - jsonPath: .spec.sampler.argument + name: Sampler Arg + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + apacheHttpd: + properties: + attrs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + configPath: + type: string + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + version: + type: string + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + defaults: + properties: + useLabelsForResourceAttributes: + type: boolean + type: object + dotnet: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + exporter: + properties: + endpoint: + type: string + tls: + properties: + ca: + type: string + cert: + type: string + configMapName: + type: string + key: + type: string + secretName: + type: string + type: object + type: object + go: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + java: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + extensions: + items: + properties: + dir: + type: string + image: + type: string + required: + - dir + - image + type: object + type: array + image: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + nginx: + properties: + attrs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + configFile: + type: string + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + nodejs: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + propagators: + items: + enum: + - tracecontext + - baggage + - b3 + - b3multi + - jaeger + - xray + - ottrace + - none + type: string + type: array + python: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + resource: + properties: + addK8sUIDAttributes: + type: boolean + resourceAttributes: + additionalProperties: + type: string + type: object + type: object + sampler: + properties: + argument: + type: string + type: + enum: + - always_on + - always_off + - traceidratio + - parentbased_always_on + - parentbased_always_off + - parentbased_traceidratio + - jaeger_remote + - xray + type: string + type: object + type: object + status: + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_opampbridges.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_opampbridges.yaml new file mode 100644 index 00000000000..5d37004d5ec --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_opampbridges.yaml @@ -0,0 +1,1755 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: opampbridges.opentelemetry.io +spec: + group: opentelemetry.io + names: + kind: OpAMPBridge + listKind: OpAMPBridgeList + plural: opampbridges + singular: opampbridge + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: OpenTelemetry Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .spec.endpoint + name: Endpoint + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + capabilities: + additionalProperties: + type: boolean + type: object + componentsAllowed: + additionalProperties: + items: + type: string + type: array + type: object + endpoint: + type: string + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + headers: + additionalProperties: + type: string + type: object + hostNetwork: + type: boolean + image: + type: string + imagePullPolicy: + type: string + ipFamilies: + items: + type: string + type: array + ipFamilyPolicy: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + podAnnotations: + additionalProperties: + type: string + type: object + podDnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + priorityClassName: + type: string + replicas: + format: int32 + maximum: 1 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + upgradeStrategy: + enum: + - automatic + - none + type: string + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + required: + - capabilities + - endpoint + type: object + status: + properties: + version: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_opentelemetrycollectors.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_opentelemetrycollectors.yaml new file mode 100644 index 00000000000..05baaaa5df8 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/crds/crds/opentelemetry.io_opentelemetrycollectors.yaml @@ -0,0 +1,9216 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: opentelemetrycollectors.opentelemetry.io +spec: + group: opentelemetry.io + names: + kind: OpenTelemetryCollector + listKind: OpenTelemetryCollectorList + plural: opentelemetrycollectors + shortNames: + - otelcol + - otelcols + singular: opentelemetrycollector + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Deployment Mode + jsonPath: .spec.mode + name: Mode + type: string + - description: OpenTelemetry Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .status.scale.statusReplicas + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.image + name: Image + type: string + - description: Management State + jsonPath: .spec.managementState + name: Management + type: string + deprecated: true + deprecationWarning: OpenTelemetryCollector v1alpha1 is deprecated. Migrate to + v1beta1. + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + args: + additionalProperties: + type: string + type: object + autoscaler: + properties: + behavior: + properties: + scaleDown: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + scaleUp: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + type: object + maxReplicas: + format: int32 + type: integer + metrics: + items: + properties: + pods: + properties: + metric: + properties: + name: + type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + target: + properties: + averageUtilization: + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + type: string + value: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - metric + - target + type: object + type: + type: string + required: + - type + type: object + type: array + minReplicas: + format: int32 + type: integer + targetCPUUtilization: + format: int32 + type: integer + targetMemoryUtilization: + format: int32 + type: integer + type: object + config: + type: string + configmaps: + items: + properties: + mountpath: + type: string + name: + type: string + required: + - mountpath + - name + type: object + type: array + deploymentUpdateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + hostNetwork: + type: boolean + image: + type: string + imagePullPolicy: + type: string + ingress: + properties: + annotations: + additionalProperties: + type: string + type: object + hostname: + type: string + ingressClassName: + type: string + route: + properties: + termination: + enum: + - insecure + - edge + - passthrough + - reencrypt + type: string + type: object + ruleType: + enum: + - path + - subdomain + type: string + tls: + items: + properties: + hosts: + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + type: string + type: object + type: array + type: + enum: + - ingress + - route + type: string + type: object + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + managementState: + default: managed + enum: + - managed + - unmanaged + type: string + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + mode: + enum: + - daemonset + - deployment + - sidecar + - statefulset + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + DisablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podAnnotations: + additionalProperties: + type: string + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + priorityClassName: + type: string + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + shareProcessNamespace: + type: boolean + targetAllocator: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + allocationStrategy: + default: consistent-hashing + enum: + - least-weighted + - consistent-hashing + - per-node + type: string + enabled: + type: boolean + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + filterStrategy: + default: relabel-config + type: string + image: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + DisablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + prometheusCR: + properties: + enabled: + type: boolean + podMonitorSelector: + additionalProperties: + type: string + type: object + scrapeInterval: + default: 30s + format: duration + type: string + serviceMonitorSelector: + additionalProperties: + type: string + type: object + type: object + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + updateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + upgradeStrategy: + enum: + - automatic + - none + type: string + volumeClaimTemplates: + items: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + required: + - status + type: object + phase: + type: string + type: object + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + required: + - config + - managementState + type: object + status: + properties: + image: + type: string + messages: + items: + type: string + type: array + x-kubernetes-list-type: atomic + replicas: + format: int32 + type: integer + scale: + properties: + replicas: + format: int32 + type: integer + selector: + type: string + statusReplicas: + type: string + type: object + version: + type: string + type: object + type: object + served: true + storage: false + subresources: + scale: + labelSelectorPath: .status.scale.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.scale.replicas + status: {} + - additionalPrinterColumns: + - description: Deployment Mode + jsonPath: .spec.mode + name: Mode + type: string + - description: OpenTelemetry Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .status.scale.statusReplicas + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.image + name: Image + type: string + - description: Management State + jsonPath: .spec.managementState + name: Management + type: string + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + args: + additionalProperties: + type: string + type: object + autoscaler: + properties: + behavior: + properties: + scaleDown: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + scaleUp: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + type: object + maxReplicas: + format: int32 + type: integer + metrics: + items: + properties: + pods: + properties: + metric: + properties: + name: + type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + target: + properties: + averageUtilization: + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + type: string + value: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - metric + - target + type: object + type: + type: string + required: + - type + type: object + type: array + minReplicas: + format: int32 + type: integer + targetCPUUtilization: + format: int32 + type: integer + targetMemoryUtilization: + format: int32 + type: integer + type: object + config: + properties: + connectors: + type: object + x-kubernetes-preserve-unknown-fields: true + exporters: + type: object + x-kubernetes-preserve-unknown-fields: true + extensions: + type: object + x-kubernetes-preserve-unknown-fields: true + processors: + type: object + x-kubernetes-preserve-unknown-fields: true + receivers: + type: object + x-kubernetes-preserve-unknown-fields: true + service: + properties: + extensions: + items: + type: string + type: array + pipelines: + additionalProperties: + properties: + exporters: + items: + type: string + type: array + processors: + items: + type: string + type: array + receivers: + items: + type: string + type: array + required: + - exporters + - receivers + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + telemetry: + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - pipelines + type: object + required: + - exporters + - receivers + - service + type: object + x-kubernetes-preserve-unknown-fields: true + configVersions: + default: 3 + minimum: 1 + type: integer + configmaps: + items: + properties: + mountpath: + type: string + name: + type: string + required: + - mountpath + - name + type: object + type: array + daemonSetUpdateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + deploymentUpdateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + hostNetwork: + type: boolean + image: + type: string + imagePullPolicy: + type: string + ingress: + properties: + annotations: + additionalProperties: + type: string + type: object + hostname: + type: string + ingressClassName: + type: string + route: + properties: + termination: + enum: + - insecure + - edge + - passthrough + - reencrypt + type: string + type: object + ruleType: + enum: + - path + - subdomain + type: string + tls: + items: + properties: + hosts: + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + type: string + type: object + type: array + type: + enum: + - ingress + - route + type: string + type: object + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + ipFamilies: + items: + type: string + type: array + ipFamilyPolicy: + default: SingleStack + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + managementState: + default: managed + enum: + - managed + - unmanaged + type: string + mode: + enum: + - daemonset + - deployment + - sidecar + - statefulset + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + disablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podAnnotations: + additionalProperties: + type: string + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podDnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + priorityClassName: + type: string + readinessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + shareProcessNamespace: + type: boolean + targetAllocator: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + allocationStrategy: + default: consistent-hashing + enum: + - least-weighted + - consistent-hashing + - per-node + type: string + enabled: + type: boolean + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + filterStrategy: + default: relabel-config + enum: + - "" + - relabel-config + type: string + image: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + disablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + prometheusCR: + properties: + enabled: + type: boolean + podMonitorSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + scrapeInterval: + default: 30s + format: duration + type: string + serviceMonitorSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + upgradeStrategy: + enum: + - automatic + - none + type: string + volumeClaimTemplates: + items: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + required: + - status + type: object + phase: + type: string + type: object + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + required: + - config + - managementState + type: object + status: + properties: + image: + type: string + scale: + properties: + replicas: + format: int32 + type: integer + selector: + type: string + statusReplicas: + type: string + type: object + version: + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.scale.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.scale.replicas + status: {} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/.helmignore b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/.helmignore new file mode 100644 index 00000000000..f0c13194444 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/Chart.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/Chart.yaml new file mode 100644 index 00000000000..9dea6594980 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/Chart.yaml @@ -0,0 +1,26 @@ +annotations: + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Chart Source + url: https://github.com/prometheus-community/helm-charts +apiVersion: v2 +appVersion: 2.12.0 +description: Install kube-state-metrics to generate and expose cluster-level metrics +home: https://github.com/kubernetes/kube-state-metrics/ +keywords: +- metric +- monitoring +- prometheus +- kubernetes +maintainers: +- email: tariq.ibrahim@mulesoft.com + name: tariq1890 +- email: manuel@rueg.eu + name: mrueg +- email: david@0xdc.me + name: dotdc +name: kube-state-metrics +sources: +- https://github.com/kubernetes/kube-state-metrics/ +type: application +version: 5.21.0 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/README.md b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/README.md new file mode 100644 index 00000000000..843be89e69f --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/README.md @@ -0,0 +1,85 @@ +# kube-state-metrics Helm Chart + +Installs the [kube-state-metrics agent](https://github.com/kubernetes/kube-state-metrics). + +## Get Repository Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + + +## Install Chart + +```console +helm install [RELEASE_NAME] prometheus-community/kube-state-metrics [flags] +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] prometheus-community/kube-state-metrics [flags] +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Migrating from stable/kube-state-metrics and kubernetes/kube-state-metrics + +You can upgrade in-place: + +1. [get repository info](#get-repository-info) +1. [upgrade](#upgrading-chart) your existing release name using the new chart repository + +## Upgrading to v3.0.0 + +v3.0.0 includes kube-state-metrics v2.0, see the [changelog](https://github.com/kubernetes/kube-state-metrics/blob/release-2.0/CHANGELOG.md) for major changes on the application-side. + +The upgraded chart now the following changes: + +* Dropped support for helm v2 (helm v3 or later is required) +* collectors key was renamed to resources +* namespace key was renamed to namespaces + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments: + +```console +helm show values prometheus-community/kube-state-metrics +``` + +### kube-rbac-proxy + +You can enable `kube-state-metrics` endpoint protection using `kube-rbac-proxy`. By setting `kubeRBACProxy.enabled: true`, this chart will deploy one RBAC proxy container per endpoint (metrics & telemetry). +To authorize access, authenticate your requests (via a `ServiceAccount` for example) with a `ClusterRole` attached such as: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kube-state-metrics-read +rules: + - apiGroups: [ "" ] + resources: ["services/kube-state-metrics"] + verbs: + - get +``` + +See [kube-rbac-proxy examples](https://github.com/brancz/kube-rbac-proxy/tree/master/examples/resource-attributes) for more details. diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/NOTES.txt b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/NOTES.txt new file mode 100644 index 00000000000..3589c24ec39 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/NOTES.txt @@ -0,0 +1,23 @@ +kube-state-metrics is a simple service that listens to the Kubernetes API server and generates metrics about the state of the objects. +The exposed metrics can be found here: +https://github.com/kubernetes/kube-state-metrics/blob/master/docs/README.md#exposed-metrics + +The metrics are exported on the HTTP endpoint /metrics on the listening port. +In your case, {{ template "kube-state-metrics.fullname" . }}.{{ template "kube-state-metrics.namespace" . }}.svc.cluster.local:{{ .Values.service.port }}/metrics + +They are served either as plaintext or protobuf depending on the Accept header. +They are designed to be consumed either by Prometheus itself or by a scraper that is compatible with scraping a Prometheus client endpoint. + +{{- if .Values.kubeRBACProxy.enabled}} + +kube-rbac-proxy endpoint protections is enabled: +- Metrics endpoints are now HTTPS +- Ensure that the client authenticates the requests (e.g. via service account) with the following role permissions: +``` +rules: + - apiGroups: [ "" ] + resources: ["services/{{ template "kube-state-metrics.fullname" . }}"] + verbs: + - get +``` +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/_helpers.tpl b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/_helpers.tpl new file mode 100644 index 00000000000..a4358c87a10 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/_helpers.tpl @@ -0,0 +1,156 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "kube-state-metrics.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kube-state-metrics.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "kube-state-metrics.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "kube-state-metrics.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "kube-state-metrics.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kube-state-metrics.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Generate basic labels +*/}} +{{- define "kube-state-metrics.labels" }} +helm.sh/chart: {{ template "kube-state-metrics.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: metrics +app.kubernetes.io/part-of: {{ template "kube-state-metrics.name" . }} +{{- include "kube-state-metrics.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- if .Values.releaseLabel }} +release: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kube-state-metrics.selectorLabels" }} +{{- if .Values.selectorOverride }} +{{ toYaml .Values.selectorOverride }} +{{- else }} +app.kubernetes.io/name: {{ include "kube-state-metrics.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* Sets default scrape limits for servicemonitor */}} +{{- define "servicemonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end -}} + +{{/* +Formats imagePullSecrets. Input is (dict "Values" .Values "imagePullSecrets" .{specific imagePullSecrets}) +*/}} +{{- define "kube-state-metrics.imagePullSecrets" -}} +{{- range (concat .Values.global.imagePullSecrets .imagePullSecrets) }} + {{- if eq (typeOf .) "map[string]interface {}" }} +- {{ toYaml . | trim }} + {{- else }} +- name: {{ . }} + {{- end }} +{{- end }} +{{- end -}} + +{{/* +The image to use for kube-state-metrics +*/}} +{{- define "kube-state-metrics.image" -}} +{{- if .Values.image.sha }} +{{- if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s@%s" .Values.global.imageRegistry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.sha }} +{{- else }} +{{- printf "%s/%s:%s@%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.sha }} +{{- end }} +{{- else }} +{{- if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s" .Values.global.imageRegistry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- else }} +{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +The image to use for kubeRBACProxy +*/}} +{{- define "kubeRBACProxy.image" -}} +{{- if .Values.kubeRBACProxy.image.sha }} +{{- if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s@%s" .Values.global.imageRegistry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) .Values.kubeRBACProxy.image.sha }} +{{- else }} +{{- printf "%s/%s:%s@%s" .Values.kubeRBACProxy.image.registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) .Values.kubeRBACProxy.image.sha }} +{{- end }} +{{- else }} +{{- if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s" .Values.global.imageRegistry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) }} +{{- else }} +{{- printf "%s/%s:%s" .Values.kubeRBACProxy.image.registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) }} +{{- end }} +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml new file mode 100644 index 00000000000..025cd47a880 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.networkPolicy.enabled (eq .Values.networkPolicy.flavor "cilium") }} +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +spec: + endpointSelector: + matchLabels: + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + egress: + {{- if and .Values.networkPolicy.cilium .Values.networkPolicy.cilium.kubeApiServerSelector }} + {{ toYaml .Values.networkPolicy.cilium.kubeApiServerSelector | nindent 6 }} + {{- else }} + - toEntities: + - kube-apiserver + {{- end }} + ingress: + - toPorts: + - ports: + - port: {{ .Values.service.port | quote }} + protocol: TCP + {{- if .Values.selfMonitor.enabled }} + - port: {{ .Values.selfMonitor.telemetryPort | default 8081 | quote }} + protocol: TCP + {{ end }} +{{ end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/clusterrolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/clusterrolebinding.yaml new file mode 100644 index 00000000000..cf9f628d041 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.rbac.create .Values.rbac.useClusterRole -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole +{{- if .Values.rbac.useExistingRole }} + name: {{ .Values.rbac.useExistingRole }} +{{- else }} + name: {{ template "kube-state-metrics.fullname" . }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/crs-configmap.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/crs-configmap.yaml new file mode 100644 index 00000000000..d38a75a51df --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/crs-configmap.yaml @@ -0,0 +1,16 @@ +{{- if .Values.customResourceState.enabled}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kube-state-metrics.fullname" . }}-customresourcestate-config + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} +data: + config.yaml: | + {{- toYaml .Values.customResourceState.config | nindent 4 }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/deployment.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/deployment.yaml new file mode 100644 index 00000000000..5d32f82fa78 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/deployment.yaml @@ -0,0 +1,313 @@ +apiVersion: apps/v1 +{{- if .Values.autosharding.enabled }} +kind: StatefulSet +{{- else }} +kind: Deployment +{{- end }} +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- if .Values.annotations }} + annotations: +{{ toYaml .Values.annotations | indent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + replicas: {{ .Values.replicas }} + {{- if not .Values.autosharding.enabled }} + strategy: + type: {{ .Values.updateStrategy | default "RollingUpdate" }} + {{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- if .Values.autosharding.enabled }} + serviceName: {{ template "kube-state-metrics.fullname" . }} + volumeClaimTemplates: [] + {{- end }} + template: + metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 8 }} + {{- if .Values.podAnnotations }} + annotations: +{{ toYaml .Values.podAnnotations | indent 8 }} + {{- end }} + spec: + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + hostNetwork: {{ .Values.hostNetwork }} + serviceAccountName: {{ template "kube-state-metrics.serviceAccountName" . }} + {{- if .Values.securityContext.enabled }} + securityContext: {{- omit .Values.securityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- with .Values.initContainers }} + initContainers: + {{- toYaml . | nindent 6 }} + {{- end }} + containers: + {{- $servicePort := ternary 9090 (.Values.service.port | default 8080) .Values.kubeRBACProxy.enabled}} + {{- $telemetryPort := ternary 9091 (.Values.selfMonitor.telemetryPort | default 8081) .Values.kubeRBACProxy.enabled}} + - name: {{ template "kube-state-metrics.name" . }} + {{- if .Values.autosharding.enabled }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- end }} + args: + {{- if .Values.extraArgs }} + {{- .Values.extraArgs | toYaml | nindent 8 }} + {{- end }} + - --port={{ $servicePort }} + {{- if .Values.collectors }} + - --resources={{ .Values.collectors | join "," }} + {{- end }} + {{- if .Values.metricLabelsAllowlist }} + - --metric-labels-allowlist={{ .Values.metricLabelsAllowlist | join "," }} + {{- end }} + {{- if .Values.metricAnnotationsAllowList }} + - --metric-annotations-allowlist={{ .Values.metricAnnotationsAllowList | join "," }} + {{- end }} + {{- if .Values.metricAllowlist }} + - --metric-allowlist={{ .Values.metricAllowlist | join "," }} + {{- end }} + {{- if .Values.metricDenylist }} + - --metric-denylist={{ .Values.metricDenylist | join "," }} + {{- end }} + {{- $namespaces := list }} + {{- if .Values.namespaces }} + {{- range $ns := join "," .Values.namespaces | split "," }} + {{- $namespaces = append $namespaces (tpl $ns $) }} + {{- end }} + {{- end }} + {{- if .Values.releaseNamespace }} + {{- $namespaces = append $namespaces ( include "kube-state-metrics.namespace" . ) }} + {{- end }} + {{- if $namespaces }} + - --namespaces={{ $namespaces | mustUniq | join "," }} + {{- end }} + {{- if .Values.namespacesDenylist }} + - --namespaces-denylist={{ tpl (.Values.namespacesDenylist | join ",") $ }} + {{- end }} + {{- if .Values.autosharding.enabled }} + - --pod=$(POD_NAME) + - --pod-namespace=$(POD_NAMESPACE) + {{- end }} + {{- if .Values.kubeconfig.enabled }} + - --kubeconfig=/opt/k8s/.kube/config + {{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - --telemetry-host=127.0.0.1 + - --telemetry-port={{ $telemetryPort }} + {{- else }} + {{- if .Values.selfMonitor.telemetryHost }} + - --telemetry-host={{ .Values.selfMonitor.telemetryHost }} + {{- end }} + {{- if .Values.selfMonitor.telemetryPort }} + - --telemetry-port={{ $telemetryPort }} + {{- end }} + {{- end }} + {{- if .Values.customResourceState.enabled }} + - --custom-resource-state-config-file=/etc/customresourcestate/config.yaml + {{- end }} + {{- if or (.Values.kubeconfig.enabled) (.Values.customResourceState.enabled) (.Values.volumeMounts) }} + volumeMounts: + {{- if .Values.kubeconfig.enabled }} + - name: kubeconfig + mountPath: /opt/k8s/.kube/ + readOnly: true + {{- end }} + {{- if .Values.customResourceState.enabled }} + - name: customresourcestate-config + mountPath: /etc/customresourcestate + readOnly: true + {{- end }} + {{- if .Values.volumeMounts }} +{{ toYaml .Values.volumeMounts | indent 8 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + image: {{ include "kube-state-metrics.image" . }} + {{- if eq .Values.kubeRBACProxy.enabled false }} + ports: + - containerPort: {{ .Values.service.port | default 8080}} + name: "http" + {{- if .Values.selfMonitor.enabled }} + - containerPort: {{ $telemetryPort }} + name: "metrics" + {{- end }} + {{- end }} + livenessProbe: + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + httpGet: + {{- if .Values.hostNetwork }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.livenessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: /healthz + port: {{ $servicePort }} + scheme: {{ upper .Values.livenessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + readinessProbe: + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + httpGet: + {{- if .Values.hostNetwork }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.readinessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: / + port: {{ $servicePort }} + scheme: {{ upper .Values.readinessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + resources: +{{ toYaml .Values.resources | indent 10 }} +{{- if .Values.containerSecurityContext }} + securityContext: +{{ toYaml .Values.containerSecurityContext | indent 10 }} +{{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - name: kube-rbac-proxy-http + args: + {{- if .Values.kubeRBACProxy.extraArgs }} + {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 8 }} + {{- end }} + - --secure-listen-address=:{{ .Values.service.port | default 8080}} + - --upstream=http://127.0.0.1:{{ $servicePort }}/ + - --proxy-endpoints-port=8888 + - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml + volumeMounts: + - name: kube-rbac-proxy-config + mountPath: /etc/kube-rbac-proxy-config + {{- with .Values.kubeRBACProxy.volumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} + image: {{ include "kubeRBACProxy.image" . }} + ports: + - containerPort: {{ .Values.service.port | default 8080}} + name: "http" + - containerPort: 8888 + name: "http-healthz" + readinessProbe: + httpGet: + scheme: HTTPS + port: 8888 + path: healthz + initialDelaySeconds: 5 + timeoutSeconds: 5 + {{- if .Values.kubeRBACProxy.resources }} + resources: +{{ toYaml .Values.kubeRBACProxy.resources | indent 10 }} +{{- end }} +{{- if .Values.kubeRBACProxy.containerSecurityContext }} + securityContext: +{{ toYaml .Values.kubeRBACProxy.containerSecurityContext | indent 10 }} +{{- end }} + {{- if .Values.selfMonitor.enabled }} + - name: kube-rbac-proxy-telemetry + args: + {{- if .Values.kubeRBACProxy.extraArgs }} + {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 8 }} + {{- end }} + - --secure-listen-address=:{{ .Values.selfMonitor.telemetryPort | default 8081 }} + - --upstream=http://127.0.0.1:{{ $telemetryPort }}/ + - --proxy-endpoints-port=8889 + - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml + volumeMounts: + - name: kube-rbac-proxy-config + mountPath: /etc/kube-rbac-proxy-config + {{- with .Values.kubeRBACProxy.volumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} + image: {{ include "kubeRBACProxy.image" . }} + ports: + - containerPort: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + name: "metrics" + - containerPort: 8889 + name: "metrics-healthz" + readinessProbe: + httpGet: + scheme: HTTPS + port: 8889 + path: healthz + initialDelaySeconds: 5 + timeoutSeconds: 5 + {{- if .Values.kubeRBACProxy.resources }} + resources: +{{ toYaml .Values.kubeRBACProxy.resources | indent 10 }} +{{- end }} +{{- if .Values.kubeRBACProxy.containerSecurityContext }} + securityContext: +{{ toYaml .Values.kubeRBACProxy.containerSecurityContext | indent 10 }} +{{- end }} + {{- end }} + {{- end }} + {{- with .Values.containers }} + {{- toYaml . | nindent 6 }} + {{- end }} +{{- if or .Values.imagePullSecrets .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- include "kube-state-metrics.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.imagePullSecrets) | indent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.topologySpreadConstraints | indent 8 }} + {{- end }} + {{- if or (.Values.kubeconfig.enabled) (.Values.customResourceState.enabled) (.Values.volumes) (.Values.kubeRBACProxy.enabled) }} + volumes: + {{- if .Values.kubeconfig.enabled}} + - name: kubeconfig + secret: + secretName: {{ template "kube-state-metrics.fullname" . }}-kubeconfig + {{- end }} + {{- if .Values.kubeRBACProxy.enabled}} + - name: kube-rbac-proxy-config + configMap: + name: {{ template "kube-state-metrics.fullname" . }}-rbac-config + {{- end }} + {{- if .Values.customResourceState.enabled}} + - name: customresourcestate-config + configMap: + name: {{ template "kube-state-metrics.fullname" . }}-customresourcestate-config + {{- end }} + {{- if .Values.volumes }} +{{ toYaml .Values.volumes | indent 8 }} + {{- end }} + {{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/extra-manifests.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/extra-manifests.yaml new file mode 100644 index 00000000000..567f7bf3297 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraManifests }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/kubeconfig-secret.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/kubeconfig-secret.yaml new file mode 100644 index 00000000000..6af00845029 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/kubeconfig-secret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.kubeconfig.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kube-state-metrics.fullname" . }}-kubeconfig + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +type: Opaque +data: + config: '{{ .Values.kubeconfig.secret }}' +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/networkpolicy.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/networkpolicy.yaml new file mode 100644 index 00000000000..309b38ec54e --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/networkpolicy.yaml @@ -0,0 +1,43 @@ +{{- if and .Values.networkPolicy.enabled (eq .Values.networkPolicy.flavor "kubernetes") }} +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +spec: + {{- if .Values.networkPolicy.egress }} + ## Deny all egress by default + egress: + {{- toYaml .Values.networkPolicy.egress | nindent 4 }} + {{- end }} + ingress: + {{- if .Values.networkPolicy.ingress }} + {{- toYaml .Values.networkPolicy.ingress | nindent 4 }} + {{- else }} + ## Allow ingress on default ports by default + - ports: + - port: {{ .Values.service.port | default 8080 }} + protocol: TCP + {{- if .Values.selfMonitor.enabled }} + {{- $telemetryPort := ternary 9091 (.Values.selfMonitor.telemetryPort | default 8081) .Values.kubeRBACProxy.enabled}} + - port: {{ $telemetryPort }} + protocol: TCP + {{- end }} + {{- end }} + podSelector: + {{- if .Values.networkPolicy.podSelector }} + {{- toYaml .Values.networkPolicy.podSelector | nindent 4 }} + {{- else }} + matchLabels: + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + {{- end }} + policyTypes: + - Ingress + - Egress +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/pdb.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/pdb.yaml new file mode 100644 index 00000000000..3771b511de0 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/pdb.yaml @@ -0,0 +1,18 @@ +{{- if .Values.podDisruptionBudget -}} +{{ if $.Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" -}} +apiVersion: policy/v1 +{{- else -}} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "kube-state-metrics.name" . }} +{{ toYaml .Values.podDisruptionBudget | indent 2 }} +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/podsecuritypolicy.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/podsecuritypolicy.yaml new file mode 100644 index 00000000000..8905e113e84 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/podsecuritypolicy.yaml @@ -0,0 +1,39 @@ +{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +{{- if .Values.podSecurityPolicy.annotations }} + annotations: +{{ toYaml .Values.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + volumes: + - 'secret' +{{- if .Values.podSecurityPolicy.additionalVolumes }} +{{ toYaml .Values.podSecurityPolicy.additionalVolumes | indent 4 }} +{{- end }} + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAsNonRoot' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/psp-clusterrole.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/psp-clusterrole.yaml new file mode 100644 index 00000000000..654e4a3d57f --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/psp-clusterrole.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: psp-{{ template "kube-state-metrics.fullname" . }} +rules: +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} +- apiGroups: ['policy'] +{{- else }} +- apiGroups: ['extensions'] +{{- end }} + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "kube-state-metrics.fullname" . }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml new file mode 100644 index 00000000000..5b62a18bdf1 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: psp-{{ template "kube-state-metrics.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: psp-{{ template "kube-state-metrics.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/rbac-configmap.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/rbac-configmap.yaml new file mode 100644 index 00000000000..671dc9d6604 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/rbac-configmap.yaml @@ -0,0 +1,22 @@ +{{- if .Values.kubeRBACProxy.enabled}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kube-state-metrics.fullname" . }}-rbac-config + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} +data: + config-file.yaml: |+ + authorization: + resourceAttributes: + namespace: {{ template "kube-state-metrics.namespace" . }} + apiVersion: v1 + resource: services + subresource: {{ template "kube-state-metrics.fullname" . }} + name: {{ template "kube-state-metrics.fullname" . }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/role.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/role.yaml new file mode 100644 index 00000000000..d33687f2d12 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/role.yaml @@ -0,0 +1,212 @@ +{{- if and (eq .Values.rbac.create true) (not .Values.rbac.useExistingRole) -}} +{{- range (ternary (join "," .Values.namespaces | split "," ) (list "") (eq $.Values.rbac.useClusterRole false)) }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +{{- if eq $.Values.rbac.useClusterRole false }} +kind: Role +{{- else }} +kind: ClusterRole +{{- end }} +metadata: + labels: + {{- include "kube-state-metrics.labels" $ | indent 4 }} + name: {{ template "kube-state-metrics.fullname" $ }} +{{- if eq $.Values.rbac.useClusterRole false }} + namespace: {{ . }} +{{- end }} +rules: +{{ if has "certificatesigningrequests" $.Values.collectors }} +- apiGroups: ["certificates.k8s.io"] + resources: + - certificatesigningrequests + verbs: ["list", "watch"] +{{ end -}} +{{ if has "configmaps" $.Values.collectors }} +- apiGroups: [""] + resources: + - configmaps + verbs: ["list", "watch"] +{{ end -}} +{{ if has "cronjobs" $.Values.collectors }} +- apiGroups: ["batch"] + resources: + - cronjobs + verbs: ["list", "watch"] +{{ end -}} +{{ if has "daemonsets" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - daemonsets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "deployments" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - deployments + verbs: ["list", "watch"] +{{ end -}} +{{ if has "endpoints" $.Values.collectors }} +- apiGroups: [""] + resources: + - endpoints + verbs: ["list", "watch"] +{{ end -}} +{{ if has "endpointslices" $.Values.collectors }} +- apiGroups: ["discovery.k8s.io"] + resources: + - endpointslices + verbs: ["list", "watch"] +{{ end -}} +{{ if has "horizontalpodautoscalers" $.Values.collectors }} +- apiGroups: ["autoscaling"] + resources: + - horizontalpodautoscalers + verbs: ["list", "watch"] +{{ end -}} +{{ if has "ingresses" $.Values.collectors }} +- apiGroups: ["extensions", "networking.k8s.io"] + resources: + - ingresses + verbs: ["list", "watch"] +{{ end -}} +{{ if has "jobs" $.Values.collectors }} +- apiGroups: ["batch"] + resources: + - jobs + verbs: ["list", "watch"] +{{ end -}} +{{ if has "leases" $.Values.collectors }} +- apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: ["list", "watch"] +{{ end -}} +{{ if has "limitranges" $.Values.collectors }} +- apiGroups: [""] + resources: + - limitranges + verbs: ["list", "watch"] +{{ end -}} +{{ if has "mutatingwebhookconfigurations" $.Values.collectors }} +- apiGroups: ["admissionregistration.k8s.io"] + resources: + - mutatingwebhookconfigurations + verbs: ["list", "watch"] +{{ end -}} +{{ if has "namespaces" $.Values.collectors }} +- apiGroups: [""] + resources: + - namespaces + verbs: ["list", "watch"] +{{ end -}} +{{ if has "networkpolicies" $.Values.collectors }} +- apiGroups: ["networking.k8s.io"] + resources: + - networkpolicies + verbs: ["list", "watch"] +{{ end -}} +{{ if has "nodes" $.Values.collectors }} +- apiGroups: [""] + resources: + - nodes + verbs: ["list", "watch"] +{{ end -}} +{{ if has "persistentvolumeclaims" $.Values.collectors }} +- apiGroups: [""] + resources: + - persistentvolumeclaims + verbs: ["list", "watch"] +{{ end -}} +{{ if has "persistentvolumes" $.Values.collectors }} +- apiGroups: [""] + resources: + - persistentvolumes + verbs: ["list", "watch"] +{{ end -}} +{{ if has "poddisruptionbudgets" $.Values.collectors }} +- apiGroups: ["policy"] + resources: + - poddisruptionbudgets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "pods" $.Values.collectors }} +- apiGroups: [""] + resources: + - pods + verbs: ["list", "watch"] +{{ end -}} +{{ if has "replicasets" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - replicasets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "replicationcontrollers" $.Values.collectors }} +- apiGroups: [""] + resources: + - replicationcontrollers + verbs: ["list", "watch"] +{{ end -}} +{{ if has "resourcequotas" $.Values.collectors }} +- apiGroups: [""] + resources: + - resourcequotas + verbs: ["list", "watch"] +{{ end -}} +{{ if has "secrets" $.Values.collectors }} +- apiGroups: [""] + resources: + - secrets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "services" $.Values.collectors }} +- apiGroups: [""] + resources: + - services + verbs: ["list", "watch"] +{{ end -}} +{{ if has "statefulsets" $.Values.collectors }} +- apiGroups: ["apps"] + resources: + - statefulsets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "storageclasses" $.Values.collectors }} +- apiGroups: ["storage.k8s.io"] + resources: + - storageclasses + verbs: ["list", "watch"] +{{ end -}} +{{ if has "validatingwebhookconfigurations" $.Values.collectors }} +- apiGroups: ["admissionregistration.k8s.io"] + resources: + - validatingwebhookconfigurations + verbs: ["list", "watch"] +{{ end -}} +{{ if has "volumeattachments" $.Values.collectors }} +- apiGroups: ["storage.k8s.io"] + resources: + - volumeattachments + verbs: ["list", "watch"] +{{ end -}} +{{- if $.Values.kubeRBACProxy.enabled }} +- apiGroups: ["authentication.k8s.io"] + resources: + - tokenreviews + verbs: ["create"] +- apiGroups: ["authorization.k8s.io"] + resources: + - subjectaccessreviews + verbs: ["create"] +{{- end }} +{{- if $.Values.customResourceState.enabled }} +- apiGroups: ["apiextensions.k8s.io"] + resources: + - customresourcedefinitions + verbs: ["list", "watch"] +{{- end }} +{{ if $.Values.rbac.extraRules }} +{{ toYaml $.Values.rbac.extraRules }} +{{ end }} +{{- end -}} +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/rolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/rolebinding.yaml new file mode 100644 index 00000000000..330651b73f4 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/rolebinding.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.rbac.create true) (eq .Values.rbac.useClusterRole false) -}} +{{- range (join "," $.Values.namespaces) | split "," }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" $ | indent 4 }} + name: {{ template "kube-state-metrics.fullname" $ }} + namespace: {{ . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role +{{- if (not $.Values.rbac.useExistingRole) }} + name: {{ template "kube-state-metrics.fullname" $ }} +{{- else }} + name: {{ $.Values.rbac.useExistingRole }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" $ }} + namespace: {{ template "kube-state-metrics.namespace" $ }} +{{- end -}} +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/service.yaml new file mode 100644 index 00000000000..90c235148f2 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/service.yaml @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + annotations: + {{- if .Values.prometheusScrape }} + prometheus.io/scrape: '{{ .Values.prometheusScrape }}' + {{- end }} + {{- if .Values.service.annotations }} + {{- toYaml .Values.service.annotations | nindent 4 }} + {{- end }} +spec: + type: "{{ .Values.service.type }}" + {{- if .Values.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.service.ipDualStack.ipFamilyPolicy }} + {{- end }} + ports: + - name: "http" + protocol: TCP + port: {{ .Values.service.port | default 8080}} + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + targetPort: {{ .Values.service.port | default 8080}} + {{ if .Values.selfMonitor.enabled }} + - name: "metrics" + protocol: TCP + port: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + targetPort: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + {{- if .Values.selfMonitor.telemetryNodePort }} + nodePort: {{ .Values.selfMonitor.telemetryNodePort }} + {{- end }} + {{ end }} +{{- if .Values.service.loadBalancerIP }} + loadBalancerIP: "{{ .Values.service.loadBalancerIP }}" +{{- end }} +{{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} +{{- if .Values.autosharding.enabled }} + clusterIP: None +{{- else if .Values.service.clusterIP }} + clusterIP: "{{ .Values.service.clusterIP }}" +{{- end }} + selector: + {{- include "kube-state-metrics.selectorLabels" . | indent 4 }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/serviceaccount.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/serviceaccount.yaml new file mode 100644 index 00000000000..c302bc7ca03 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- if .Values.serviceAccount.annotations }} + annotations: +{{ toYaml .Values.serviceAccount.annotations | indent 4 }} +{{- end }} +{{- if or .Values.serviceAccount.imagePullSecrets .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- include "kube-state-metrics.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.serviceAccount.imagePullSecrets) | indent 2 }} +{{- end }} +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/servicemonitor.yaml new file mode 100644 index 00000000000..99d7fa92464 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/servicemonitor.yaml @@ -0,0 +1,120 @@ +{{- if .Values.prometheus.monitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- with .Values.prometheus.monitor.additionalLabels }} + {{- tpl (toYaml . | nindent 4) $ }} + {{- end }} + {{- with .Values.prometheus.monitor.annotations }} + annotations: + {{- tpl (toYaml . | nindent 4) $ }} + {{- end }} +spec: + jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.monitor.jobLabel }} + {{- with .Values.prometheus.monitor.targetLabels }} + targetLabels: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + {{- with .Values.prometheus.monitor.podTargetLabels }} + podTargetLabels: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + {{- include "servicemonitor.scrapeLimits" .Values.prometheus.monitor | indent 2 }} + {{- if .Values.prometheus.monitor.namespaceSelector }} + namespaceSelector: + matchNames: + {{- with .Values.prometheus.monitor.namespaceSelector }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + selector: + matchLabels: + {{- with .Values.prometheus.monitor.selectorOverride }} + {{- toYaml . | nindent 6 }} + {{- else }} + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + {{- end }} + endpoints: + - port: http + {{- if or .Values.prometheus.monitor.http.interval .Values.prometheus.monitor.interval }} + interval: {{ .Values.prometheus.monitor.http.interval | default .Values.prometheus.monitor.interval }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.scrapeTimeout .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.monitor.http.scrapeTimeout | default .Values.prometheus.monitor.scrapeTimeout }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.proxyUrl .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ .Values.prometheus.monitor.http.proxyUrl | default .Values.prometheus.monitor.proxyUrl }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.enableHttp2 .Values.prometheus.monitor.enableHttp2 }} + enableHttp2: {{ .Values.prometheus.monitor.http.enableHttp2 | default .Values.prometheus.monitor.enableHttp2 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.honorLabels .Values.prometheus.monitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if or .Values.prometheus.monitor.http.metricRelabelings .Values.prometheus.monitor.metricRelabelings }} + metricRelabelings: + {{- toYaml (.Values.prometheus.monitor.http.metricRelabelings | default .Values.prometheus.monitor.metricRelabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.relabelings .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml (.Values.prometheus.monitor.http.relabelings | default .Values.prometheus.monitor.relabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.scheme .Values.prometheus.monitor.scheme }} + scheme: {{ .Values.prometheus.monitor.http.scheme | default .Values.prometheus.monitor.scheme }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.tlsConfig .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml (.Values.prometheus.monitor.http.tlsConfig | default .Values.prometheus.monitor.tlsConfig) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.bearerTokenFile .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.prometheus.monitor.http.bearerTokenFile | default .Values.prometheus.monitor.bearerTokenFile }} + {{- end }} + {{- with (.Values.prometheus.monitor.http.bearerTokenSecret | default .Values.prometheus.monitor.bearerTokenSecret) }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.selfMonitor.enabled }} + - port: metrics + {{- if or .Values.prometheus.monitor.metrics.interval .Values.prometheus.monitor.interval }} + interval: {{ .Values.prometheus.monitor.metrics.interval | default .Values.prometheus.monitor.interval }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.scrapeTimeout .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.monitor.metrics.scrapeTimeout | default .Values.prometheus.monitor.scrapeTimeout }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.proxyUrl .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ .Values.prometheus.monitor.metrics.proxyUrl | default .Values.prometheus.monitor.proxyUrl }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.enableHttp2 .Values.prometheus.monitor.enableHttp2 }} + enableHttp2: {{ .Values.prometheus.monitor.metrics.enableHttp2 | default .Values.prometheus.monitor.enableHttp2 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.honorLabels .Values.prometheus.monitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.metricRelabelings .Values.prometheus.monitor.metricRelabelings }} + metricRelabelings: + {{- toYaml (.Values.prometheus.monitor.metrics.metricRelabelings | default .Values.prometheus.monitor.metricRelabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.relabelings .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml (.Values.prometheus.monitor.metrics.relabelings | default .Values.prometheus.monitor.relabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.scheme .Values.prometheus.monitor.scheme }} + scheme: {{ .Values.prometheus.monitor.metrics.scheme | default .Values.prometheus.monitor.scheme }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.tlsConfig .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml (.Values.prometheus.monitor.metrics.tlsConfig | default .Values.prometheus.monitor.tlsConfig) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.bearerTokenFile .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.prometheus.monitor.metrics.bearerTokenFile | default .Values.prometheus.monitor.bearerTokenFile }} + {{- end }} + {{- with (.Values.prometheus.monitor.metrics.bearerTokenSecret | default .Values.prometheus.monitor.bearerTokenSecret) }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/stsdiscovery-role.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/stsdiscovery-role.yaml new file mode 100644 index 00000000000..489de147c15 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/stsdiscovery-role.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.autosharding.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - get +- apiGroups: + - apps + resourceNames: + - {{ template "kube-state-metrics.fullname" . }} + resources: + - statefulsets + verbs: + - get + - list + - watch +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml new file mode 100644 index 00000000000..73b37a4f647 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.autosharding.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml new file mode 100644 index 00000000000..f46305b517a --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml @@ -0,0 +1,44 @@ +{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (.Values.verticalPodAutoscaler.enabled) }} +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +spec: + {{- with .Values.verticalPodAutoscaler.recommenders }} + recommenders: + {{- toYaml . | nindent 4 }} + {{- end }} + resourcePolicy: + containerPolicies: + - containerName: {{ template "kube-state-metrics.name" . }} + {{- with .Values.verticalPodAutoscaler.controlledResources }} + controlledResources: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.verticalPodAutoscaler.controlledValues }} + controlledValues: {{ .Values.verticalPodAutoscaler.controlledValues }} + {{- end }} + {{- if .Values.verticalPodAutoscaler.maxAllowed }} + maxAllowed: + {{ toYaml .Values.verticalPodAutoscaler.maxAllowed | nindent 8 }} + {{- end }} + {{- if .Values.verticalPodAutoscaler.minAllowed }} + minAllowed: + {{ toYaml .Values.verticalPodAutoscaler.minAllowed | nindent 8 }} + {{- end }} + targetRef: + apiVersion: apps/v1 + {{- if .Values.autosharding.enabled }} + kind: StatefulSet + {{- else }} + kind: Deployment + {{- end }} + name: {{ template "kube-state-metrics.fullname" . }} + {{- with .Values.verticalPodAutoscaler.updatePolicy }} + updatePolicy: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/values.yaml new file mode 100644 index 00000000000..2a9781138ad --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/kube-state-metrics/values.yaml @@ -0,0 +1,522 @@ +# Default values for kube-state-metrics. +prometheusScrape: true +image: + registry: registry.k8s.io + repository: kube-state-metrics/kube-state-metrics + # If unset use v + .Charts.appVersion + tag: "" + sha: "" + pullPolicy: IfNotPresent + +imagePullSecrets: [] +# - name: "image-pull-secret" + +global: + # To help compatibility with other charts which use global.imagePullSecrets. + # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). + # global: + # imagePullSecrets: + # - name: pullSecret1 + # - name: pullSecret2 + # or + # global: + # imagePullSecrets: + # - pullSecret1 + # - pullSecret2 + imagePullSecrets: [] + # + # Allow parent charts to override registry hostname + imageRegistry: "" + +# If set to true, this will deploy kube-state-metrics as a StatefulSet and the data +# will be automatically sharded across <.Values.replicas> pods using the built-in +# autodiscovery feature: https://github.com/kubernetes/kube-state-metrics#automated-sharding +# This is an experimental feature and there are no stability guarantees. +autosharding: + enabled: false + +replicas: 1 + +# Change the deployment strategy when autosharding is disabled. +# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy +# The default is "RollingUpdate" as per Kubernetes defaults. +# During a release, 'RollingUpdate' can lead to two running instances for a short period of time while 'Recreate' can create a small gap in data. +# updateStrategy: Recreate + +# Number of old history to retain to allow rollback +# Default Kubernetes value is set to 10 +revisionHistoryLimit: 10 + +# List of additional cli arguments to configure kube-state-metrics +# for example: --enable-gzip-encoding, --log-file, etc. +# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md +extraArgs: [] + +# If false then the user will opt out of automounting API credentials. +automountServiceAccountToken: true + +service: + port: 8080 + # Default to clusterIP for backward compatibility + type: ClusterIP + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + nodePort: 0 + loadBalancerIP: "" + # Only allow access to the loadBalancerIP from these IPs + loadBalancerSourceRanges: [] + clusterIP: "" + annotations: {} + +## Additional labels to add to all resources +customLabels: {} + # app: kube-state-metrics + +## Override selector labels +selectorOverride: {} + +## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box +releaseLabel: false + +hostNetwork: false + +rbac: + # If true, create & use RBAC resources + create: true + + # Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here. + # useExistingRole: your-existing-role + + # If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to) + useClusterRole: true + + # Add permissions for CustomResources' apiGroups in Role/ClusterRole. Should be used in conjunction with Custom Resource State Metrics configuration + # Example: + # - apiGroups: ["monitoring.coreos.com"] + # resources: ["prometheuses"] + # verbs: ["list", "watch"] + extraRules: [] + +# Configure kube-rbac-proxy. When enabled, creates one kube-rbac-proxy container per exposed HTTP endpoint (metrics and telemetry if enabled). +# The requests are served through the same service but requests are then HTTPS. +kubeRBACProxy: + enabled: false + image: + registry: quay.io + repository: brancz/kube-rbac-proxy + tag: v0.18.0 + sha: "" + pullPolicy: IfNotPresent + + # List of additional cli arguments to configure kube-rbac-prxy + # for example: --tls-cipher-suites, --log-file, etc. + # all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage + extraArgs: [] + + ## Specify security settings for a Container + ## Allows overrides and additional options compared to (Pod) securityContext + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + containerSecurityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + + resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + + ## volumeMounts enables mounting custom volumes in rbac-proxy containers + ## Useful for TLS certificates and keys + volumeMounts: [] + # - mountPath: /etc/tls + # name: kube-rbac-proxy-tls + # readOnly: true + +serviceAccount: + # Specifies whether a ServiceAccount should be created, require rbac true + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + # Reference to one or more secrets to be used when pulling images + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + imagePullSecrets: [] + # ServiceAccount annotations. + # Use case: AWS EKS IAM roles for service accounts + # ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html + annotations: {} + # If false then the user will opt out of automounting API credentials. + automountServiceAccountToken: true + +prometheus: + monitor: + enabled: false + annotations: {} + additionalLabels: {} + namespace: "" + namespaceSelector: [] + jobLabel: "" + targetLabels: [] + podTargetLabels: [] + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + selectorOverride: {} + + ## kube-state-metrics endpoint + http: + interval: "" + scrapeTimeout: "" + proxyUrl: "" + ## Whether to enable HTTP2 for servicemonitor + enableHttp2: false + honorLabels: false + metricRelabelings: [] + relabelings: [] + scheme: "" + ## File to read bearer token for scraping targets + bearerTokenFile: "" + ## Secret to mount to read bearer token for scraping targets. The secret needs + ## to be in the same namespace as the service monitor and accessible by the + ## Prometheus Operator + bearerTokenSecret: {} + # name: secret-name + # key: key-name + tlsConfig: {} + + ## selfMonitor endpoint + metrics: + interval: "" + scrapeTimeout: "" + proxyUrl: "" + ## Whether to enable HTTP2 for servicemonitor + enableHttp2: false + honorLabels: false + metricRelabelings: [] + relabelings: [] + scheme: "" + ## File to read bearer token for scraping targets + bearerTokenFile: "" + ## Secret to mount to read bearer token for scraping targets. The secret needs + ## to be in the same namespace as the service monitor and accessible by the + ## Prometheus Operator + bearerTokenSecret: {} + # name: secret-name + # key: key-name + tlsConfig: {} + +## Specify if a Pod Security Policy for kube-state-metrics must be created +## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +## +podSecurityPolicy: + enabled: false + annotations: {} + ## Specify pod annotations + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + ## + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + + additionalVolumes: [] + +## Configure network policy for kube-state-metrics +networkPolicy: + enabled: false + # networkPolicy.flavor -- Flavor of the network policy to use. + # Can be: + # * kubernetes for networking.k8s.io/v1/NetworkPolicy + # * cilium for cilium.io/v2/CiliumNetworkPolicy + flavor: kubernetes + + ## Configure the cilium network policy kube-apiserver selector + # cilium: + # kubeApiServerSelector: + # - toEntities: + # - kube-apiserver + + # egress: + # - {} + # ingress: + # - {} + # podSelector: + # matchLabels: + # app.kubernetes.io/name: kube-state-metrics + +securityContext: + enabled: true + runAsGroup: 65534 + runAsUser: 65534 + fsGroup: 65534 + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + +## Specify security settings for a Container +## Allows overrides and additional options compared to (Pod) securityContext +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +containerSecurityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + +## Node labels for pod assignment +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +## Affinity settings for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +affinity: {} + +## Tolerations for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +## Topology spread constraints for pod assignment +## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +topologySpreadConstraints: [] + +# Annotations to be added to the deployment/statefulset +annotations: {} + +# Annotations to be added to the pod +podAnnotations: {} + +## Assign a PriorityClassName to pods if set +# priorityClassName: "" + +# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +podDisruptionBudget: {} + +# Comma-separated list of metrics to be exposed. +# This list comprises of exact metric names and/or regex patterns. +# The allowlist and denylist are mutually exclusive. +metricAllowlist: [] + +# Comma-separated list of metrics not to be enabled. +# This list comprises of exact metric names and/or regex patterns. +# The allowlist and denylist are mutually exclusive. +metricDenylist: [] + +# Comma-separated list of additional Kubernetes label keys that will be used in the resource's +# labels metric. By default the metric contains only name and namespace labels. +# To include additional labels, provide a list of resource names in their plural form and Kubernetes +# label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. +# A single '*' can be provided per resource instead to allow any labels, but that has +# severe performance implications (Example: '=pods=[*]'). +metricLabelsAllowlist: [] + # - namespaces=[k8s-label-1,k8s-label-n] + +# Comma-separated list of Kubernetes annotations keys that will be used in the resource' +# labels metric. By default the metric contains only name and namespace labels. +# To include additional annotations provide a list of resource names in their plural form and Kubernetes +# annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. +# A single '*' can be provided per resource instead to allow any annotations, but that has +# severe performance implications (Example: '=pods=[*]'). +metricAnnotationsAllowList: [] + # - pods=[k8s-annotation-1,k8s-annotation-n] + +# Available collectors for kube-state-metrics. +# By default, all available resources are enabled, comment out to disable. +collectors: + - certificatesigningrequests + - configmaps + - cronjobs + - daemonsets + - deployments + - endpoints + - horizontalpodautoscalers + - ingresses + - jobs + - leases + - limitranges + - mutatingwebhookconfigurations + - namespaces + - networkpolicies + - nodes + - persistentvolumeclaims + - persistentvolumes + - poddisruptionbudgets + - pods + - replicasets + - replicationcontrollers + - resourcequotas + - secrets + - services + - statefulsets + - storageclasses + - validatingwebhookconfigurations + - volumeattachments + +# Enabling kubeconfig will pass the --kubeconfig argument to the container +kubeconfig: + enabled: false + # base64 encoded kube-config file + secret: + +# Enabling support for customResourceState, will create a configMap including your config that will be read from kube-state-metrics +customResourceState: + enabled: false + # Add (Cluster)Role permissions to list/watch the customResources defined in the config to rbac.extraRules + config: {} + +# Enable only the release namespace for collecting resources. By default all namespaces are collected. +# If releaseNamespace and namespaces are both set a merged list will be collected. +releaseNamespace: false + +# Comma-separated list(string) or yaml list of namespaces to be enabled for collecting resources. By default all namespaces are collected. +namespaces: "" + +# Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set, +# only namespaces that are excluded in namespaces-denylist will be used. +namespacesDenylist: "" + +## Override the deployment namespace +## +namespaceOverride: "" + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + +## Provide a k8s version to define apiGroups for podSecurityPolicy Cluster Role. +## For example: kubeTargetVersionOverride: 1.14.9 +## +kubeTargetVersionOverride: "" + +# Enable self metrics configuration for service and Service Monitor +# Default values for telemetry configuration can be overridden +# If you set telemetryNodePort, you must also set service.type to NodePort +selfMonitor: + enabled: false + # telemetryHost: 0.0.0.0 + # telemetryPort: 8081 + # telemetryNodePort: 0 + +# Enable vertical pod autoscaler support for kube-state-metrics +verticalPodAutoscaler: + enabled: false + + # Recommender responsible for generating recommendation for the object. + # List should be empty (then the default recommender will generate the recommendation) + # or contain exactly one recommender. + # recommenders: [] + # - name: custom-recommender-performance + + # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory + controlledResources: [] + # Specifies which resource values should be controlled: RequestsOnly or RequestsAndLimits. + # controlledValues: RequestsAndLimits + + # Define the max allowed resources for the pod + maxAllowed: {} + # cpu: 200m + # memory: 100Mi + # Define the min allowed resources for the pod + minAllowed: {} + # cpu: 200m + # memory: 100Mi + + # updatePolicy: + # Specifies minimal number of replicas which need to be alive for VPA Updater to attempt pod eviction + # minReplicas: 1 + # Specifies whether recommended updates are applied when a Pod is started and whether recommended updates + # are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto". + # updateMode: Auto + +# volumeMounts are used to add custom volume mounts to deployment. +# See example below +volumeMounts: [] +# - mountPath: /etc/config +# name: config-volume + +# volumes are used to add custom volumes to deployment +# See example below +volumes: [] +# - configMap: +# name: cm-for-volume +# name: config-volume + +# Extra manifests to deploy as an array +extraManifests: [] + # - apiVersion: v1 + # kind: ConfigMap + # metadata: + # labels: + # name: prometheus-extra + # data: + # extra-data: "value" + +## Containers allows injecting additional containers. +containers: [] + # - name: crd-init + # image: kiwigrid/k8s-sidecar:latest + +## InitContainers allows injecting additional initContainers. +initContainers: [] + # - name: crd-sidecar + # image: kiwigrid/k8s-sidecar:latest + +## Liveness probe +## +livenessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + +## Readiness probe +## +readinessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/.helmignore b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/.helmignore new file mode 100644 index 00000000000..7e96254a2ec --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +# Release related files +release/ diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/CONTRIBUTING.md b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/CONTRIBUTING.md new file mode 100644 index 00000000000..85441d5dc48 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/CONTRIBUTING.md @@ -0,0 +1,10 @@ +# Operator Chart Contributing Guide + +## Bumping Default Operator Version + +1. Increase the minor version of the chart by one and set the patch version to zero. +1. Update the chart's `appVersion` to match the new operator version. +1. In the values.yaml, update `manager.collectorImage.tag` to match the version of the collector managed by default by the operator. +1. Run `make generate-examples CHARTS=opentelemetry-operator`. +1. Run `make update-operator-crds` to update the CRDs in this chart to match the operator's. +1. Review the [Operator release notes](https://github.com/open-telemetry/opentelemetry-operator/releases). If any changes affect the helm chart, adjust the helm chart accordingly. diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/Chart.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/Chart.yaml new file mode 100644 index 00000000000..ef4e762858a --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/Chart.yaml @@ -0,0 +1,15 @@ +apiVersion: v2 +appVersion: 0.110.0 +description: OpenTelemetry Operator Helm chart for Kubernetes +home: https://opentelemetry.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/a718fa97fffec1b9fd14147682e9e3ac0c8817cb/projects/opentelemetry/icon/color/opentelemetry-icon-color.png +maintainers: +- name: Allex1 +- name: dmitryax +- name: jaronoff97 +- name: TylerHelmuth +name: opentelemetry-operator +sources: +- https://github.com/open-telemetry/opentelemetry-operator +type: application +version: 0.71.1 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/README.md b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/README.md new file mode 100644 index 00000000000..9d3ebd1bcb0 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/README.md @@ -0,0 +1,300 @@ +# OpenTelemetry Operator Helm Chart + +> [!WARNING] +> Version 0.58.0 of this Chart includes a new version of the `OpenTelemetryCollector` CRD. See [this document][v1beta1_migration] for upgrade instructions for the new Operator CRD. Please make sure you also follow the [helm upgrade instructions](./UPGRADING.md#0560-to-0570) for helm chart 0.57.0. + +The Helm chart installs [OpenTelemetry Operator](https://github.com/open-telemetry/opentelemetry-operator) in Kubernetes cluster. +The OpenTelemetry Operator is an implementation of a [Kubernetes Operator](https://www.openshift.com/learn/topics/operators). +At this point, it has [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector) as the only managed component. + +## Prerequisites + +- Kubernetes 1.24+ is required for OpenTelemetry Operator installation +- Helm 3.9+ + +### TLS Certificate Requirement + +In Kubernetes, in order for the API server to communicate with the webhook component, the webhook requires a TLS +certificate that the API server is configured to trust. There are a few different ways you can use to generate/configure the required TLS certificate. + + - The easiest and default method is to install the [cert-manager](https://cert-manager.io/docs/) and set `admissionWebhooks.certManager.enabled` to `true`. + In this way, cert-manager will generate a self-signed certificate. _See [cert-manager installation](https://cert-manager.io/docs/installation/kubernetes/) for more details._ + - You can provide your own Issuer by configuring the `admissionWebhooks.certManager.issuerRef` value. You will need + to specify the `kind` (Issuer or ClusterIssuer) and the `name`. Note that this method also requires the installation of cert-manager. + - You can use an automatically generated self-signed certificate by setting `admissionWebhooks.certManager.enabled` to `false` and `admissionWebhooks.autoGenerateCert.enabled` to `true`. Helm will create a self-signed cert and a secret for you. + - You can use your own generated self-signed certificate by setting both `admissionWebhooks.certManager.enabled` and `admissionWebhooks.autoGenerateCert.enabled` to `false`. You should provide the necessary values to `admissionWebhooks.certFile`, `admissionWebhooks.keyFile`, and `admissionWebhooks.caFile`. + - You can sideload custom webhooks and certificate by disabling `.Values.admissionWebhooks.create` and `admissionWebhooks.certManager.enabled` while setting your custom cert secret name in `admissionWebhooks.secretName` + - You can disable webhooks altogether by disabling `.Values.admissionWebhooks.create` and setting env var to `ENABLE_WEBHOOKS: "false"` + +## Add Repository + +```console +$ helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts +$ helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +> [!NOTE] +> This Chart uses templated CRDs, and therefore does not support `--skip-crds`. Use `crds.create=false` instead if you do not want the chart to install the OpenTelemetry Operator's CRDs. + +```console +$ helm install opentelemetry-operator open-telemetry/opentelemetry-operator \ +--set "manager.collectorImage.repository=otel/opentelemetry-collector-k8s" +``` + +If you created a custom namespace, like in the TLS Certificate Requirement section above, you will need to specify the namespace with the `--namespace` helm option: + +```console +$ helm install opentelemetry-operator open-telemetry/opentelemetry-operator \ +--namespace opentelemetry-operator-system \ +--set "manager.collectorImage.repository=otel/opentelemetry-collector-k8s" +``` + +If you wish for helm to create an automatically generated self-signed certificate, make sure to set the appropriate values when installing the chart: + +```console +$ helm install opentelemetry-operator open-telemetry/opentelemetry-operator \ +--set "manager.collectorImage.repository=otel/opentelemetry-collector-k8s" \ +--set admissionWebhooks.certManager.enabled=false \ +--set admissionWebhooks.autoGenerateCert.enabled=true +``` + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +The following command uninstalls the chart whose release name is my-opentelemetry-operator. + +```console +$ helm uninstall opentelemetry-operator +``` + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +This will remove all the Kubernetes components associated with the chart and deletes the release. + +The OpenTelemetry Collector CRD created by this chart won't be removed by default and should be manually deleted: + +```console +$ kubectl delete crd opentelemetrycollectors.opentelemetry.io +$ kubectl delete crd opampbridges.opentelemetry.io +$ kubectl delete crd instrumentations.opentelemetry.io +``` + +## Upgrade Chart + +```console +$ helm upgrade my-opentelemetry-operator open-telemetry/opentelemetry-operator +``` + +Please note that by default, the chart will be upgraded to the latest version. If you want to upgrade to a specific version, +use `--version` flag. + +With Helm v3.0, CRDs created by this chart are not updated by default and should be manually updated. +Consult also the [Helm Documentation on CRDs](https://helm.sh/docs/chart_best_practices/custom_resource_definitions). + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +## Configuration + +The following command will show all the configurable options with detailed comments. + +```console +$ helm show values open-telemetry/opentelemetry-operator +``` + +When using this chart as a subchart, you may want to unset certain default values. Since Helm v3.13 values handling is improved and null can now consistently be used to remove values (e.g. to remove the default CPU limits). + +### Role-based Access Control (RBAC) Configuration + +The OpenTelemetry Collector requires specific RBAC permissions to function correctly, especially when using the `k8sattributesprocessor`. Depending on your deployment's scope, you may need to configure Cluster-scoped or Namespace-scoped RBAC permissions. + +- **Cluster-scoped RBAC**: Necessary if the collector is to receive telemetry from across multiple namespaces. This setup requires `get`, `watch`, and `list` permissions on `pods`, `namespaces`, and `nodes`, plus `replicasets` if using deployment-related attributes. + +- **Namespace-scoped RBAC**: Suitable for collecting telemetry within a specific namespace. This requires setting up a `Role` and `RoleBinding` to grant access to `pods` and `replicasets` within the target namespace. This setup limits the collector's access to resources within the specified namespace only. + +**Important**: The `manager.createRbacPermissions` flag in the Helm chart values should be set to `false` if you are manually configuring RBAC permissions for the collector. Manual configuration allows for more granular control over the permissions granted to the OpenTelemetry Collector, ensuring it has exactly the access it needs based on your specific deployment requirements. Conversely, setting `manager.createRbacPermissions` to `true` will allow the operator to automatically configure RBAC for your collectors. + +For detailed instructions and examples on configuring RBAC permissions, please refer to the [official documentation](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/k8sattributesprocessor/README.md). + +## Install OpenTelemetry Collector + +_See [OpenTelemetry website](https://opentelemetry.io/docs/collector/) for more details about the Collector_ + +Once the opentelemetry-operator deployment is ready, you can deploy OpenTelemetry Collector in our Kubernetes +cluster. + +The Collector can be deployed as one of four modes: Deployment, DaemonSet, StatefulSet and Sidecar. The default +mode is Deployment. We will introduce the benefits and use cases of each mode as well as giving an example for each. + +### Deployment Mode + +If you want to get more control of the OpenTelemetry Collector and create a standalone application, Deployment would +be your choice. With Deployment, you can relatively easily scale up the Collector to monitor more targets, roll back +to an early version if anything unexpected happens, pause the Collector, etc. In general, you can manage your Collector +instance just as an application. + +The following example configuration deploys the Collector as Deployment resource. The receiver is Jaeger receiver and +the exporter is [debug exporter](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/debugexporter). + +```console +$ kubectl apply -f - < [!WARNING] +> As part of working towards using the [OpenTelemetry Collector Kubernetes Distro](https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-k8s) by default, the chart now requires users to explicitly set a collector image repository. If you are already explicitly setting a collector image repository this breaking change does not affect you. + +If you are using a OpenTelemetry Community distribution of the Collector we recommend you use `otel/opentelemetry-collector-k8s`, but carefully review the [components included in this distribution](https://github.com/open-telemetry/opentelemetry-collector-releases/blob/main/distributions/otelcol-k8s/manifest.yaml) to make sure it includes all the components you use in your configuration. In the future this distribution will become the default image used for the chart. + +You can use the OpenTelemetry Collector Kubernetes Distro by adding these lines to your values.yaml: + +```yaml +manager: + collectorImage: + repository: "otel/opentelemetry-collector-k8s" +``` + +If you want to stick with using the Contrib distribution, add these lines to your values.yaml: + +```yaml +manager: + collectorImage: + repository: "otel/opentelemetry-collector-contrib" +``` + +For more details see [#1153](https://github.com/open-telemetry/opentelemetry-helm-charts/issues/1153). + +## <0.54.0 to 0.55.2 + +> **_NOTE:_** Versions 0.54.0 to 0.55.1 of the opentelemetry-operator helm chart should be avoided if providing user-managed certificates as file paths. + +[Changes to functionality, and variable names used for providing user-managed webhook certificates](https://github.com/open-telemetry/opentelemetry-helm-charts/pull/1121) + +Below variables have been renamed to be consistent with the chart's naming format. v0.54.0 also has a bug fix which makes the chart now read the contents of the file paths provided by these variables, instead of just using the value of the variables. +``` +admissionWebhooks.ca_file -> admissionWebhooks.caFile +admissionWebhooks.cert_file -> admissionWebhooks.certFile +admissionWebhooks.key_file -> admissionWebhooks.keyFile +``` + +## <0.50.0 to 0.50.0 + +Additional properties are not allowed anymore, so care must be taken that no old or misspelled ones are present anymore. +`helm show values open-telemetry/opentelemetry-operator --version 0.50.0` can be used to list the allowed values. + +## <0.42.3 to 0.42.3 + +A type of flag `autoGenerateCert` has been changed, now it is an object with two attributes `enabled` and `recreate`. +If you previously set `autoGenerateCert` to `true` or `false` you have to set `autoGenerateCert.enabled` accordingly. + +## <0.35.0 to 0.35.0 +OpenTelemetry Operator [0.82.0](https://github.com/open-telemetry/opentelemetry-operator/releases/tag/v0.82.0) includes a change that allows setting the management state of custom resources [PR 1888](https://github.com/open-telemetry/opentelemetry-operator/pull/1888). Since helm doesn't upgrade CRDs ([documented](https://github.com/open-telemetry/opentelemetry-helm-charts/tree/main/charts/opentelemetry-operator#upgrade-chart)) it is critical to manually update CRDs from chart `0.35.0` or above, possibly using [this procedure](https://github.com/open-telemetry/opentelemetry-helm-charts/issues/69#issuecomment-1567285625). If this step isn't taken existing otelcol CRs won't be reconciled by the operator. + +## 0.27 to 0.28 +[Allow using own self-signed certificate](https://github.com/open-telemetry/opentelemetry-helm-charts/pull/760) + +A new flag `admissionWebhooks.autoGenerateCert` has been added. If you want to keep benefiting from the helm generated certificate as in previous versions, you must set `admissionWebhooks.certManager.enabled` to `false` and `admissionWebhooks.autoGenerateCert` to `true`. + +## 0.21 to 0.22.0 +Kubernetes resource names will now use `{{opentelemetry-operator.fullname}}` as the default value which will change the name of many resources. +Some CI/CD tools might create duplicate resources when upgrading from an older version because of this change. +`fullnameOverride` can be used to keep `deployment` resource consistent with the same name during an upgrade. + +## 0.16.0 to 0.17.0 + +The v0.17.0 helm chart version changes OpenTelemetry Collector image to the contrib version. If you want to use the core version, set `manager.collectorImage.repository` to `otel/opentelemetry-collector`. + +## 0.15.0 to 0.16.0 + +Jaeger receiver no longer supports remote sampling. To be able to perform an update, it must be deactivated or replaced by a configuration of the [jaegerremotesampling](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/v0.61.0/extension/jaegerremotesampling) extension.
+It is important that the `jaegerremotesampling` extension and the `jaegerreceiver` do not use the same port.
To increase the collector version afterwards, the update must be triggered again by restarting the operator. Alternatively, the `OpenTelemetryCollector` CRD can be re-created. [otel-contrib#14707](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/14707) + +## 0.13.0 to 0.14.0 + +[Allow byo webhooks and cert](https://github.com/open-telemetry/opentelemetry-helm-charts/pull/411) + +The ability to use admission webhooks has been moved from `admissionWebhooks.enabled` to `admissionWebhooks.create` as it now supports more use cases. + +In order to completely disable admission webhooks you need to explicitly set the environment variable `ENABLE_WEBHOOKS: "false"` in `.Values.manager.env` . + +[v1beta1_migration]: https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/crd-changelog.md#opentelemetrycollectoropentelemetryiov1beta1 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/cert-manager-disable-nameoverride-values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/cert-manager-disable-nameoverride-values.yaml new file mode 100644 index 00000000000..80b20ceba3d --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/cert-manager-disable-nameoverride-values.yaml @@ -0,0 +1,9 @@ +nameOverride: no-cert-manager + +admissionWebhooks: + certManager: + enabled: false + +manager: + collectorImage: + repository: "otel/opentelemetry-collector-k8s" diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/cert-manager-disable-values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/cert-manager-disable-values.yaml new file mode 100644 index 00000000000..44363e26f3b --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/cert-manager-disable-values.yaml @@ -0,0 +1,7 @@ +admissionWebhooks: + certManager: + enabled: false + +manager: + collectorImage: + repository: "otel/opentelemetry-collector-k8s" diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/nameoverride-values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/nameoverride-values.yaml new file mode 100644 index 00000000000..004b2265aa1 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/nameoverride-values.yaml @@ -0,0 +1,5 @@ +nameOverride: foobar + +manager: + collectorImage: + repository: "otel/opentelemetry-collector-k8s" diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/secret-name-nameoverride-values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/secret-name-nameoverride-values.yaml new file mode 100644 index 00000000000..3657ce9a861 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/secret-name-nameoverride-values.yaml @@ -0,0 +1,8 @@ +nameOverride: secret-name + +admissionWebhooks: + secretName: random-name + +manager: + collectorImage: + repository: "otel/opentelemetry-collector-k8s" diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/secret-name-values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/secret-name-values.yaml new file mode 100644 index 00000000000..709c5ce1161 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/ci/secret-name-values.yaml @@ -0,0 +1,6 @@ +admissionWebhooks: + secretName: random-name + +manager: + collectorImage: + repository: "otel/opentelemetry-collector-k8s" diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetry.io_opampbridges.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetry.io_opampbridges.yaml new file mode 100644 index 00000000000..7b06bf73506 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetry.io_opampbridges.yaml @@ -0,0 +1,1766 @@ +{{- if .Values.crds.create }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ include "opentelemetry-operator.webhookCertAnnotation" . }} + controller-gen.kubebuilder.io/version: v0.16.1 + creationTimestamp: null + labels: + app.kubernetes.io/name: opentelemetry-operator + name: opampbridges.opentelemetry.io +spec: + group: opentelemetry.io + names: + kind: OpAMPBridge + listKind: OpAMPBridgeList + plural: opampbridges + singular: opampbridge + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: OpenTelemetry Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .spec.endpoint + name: Endpoint + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + capabilities: + additionalProperties: + type: boolean + type: object + componentsAllowed: + additionalProperties: + items: + type: string + type: array + type: object + endpoint: + type: string + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + headers: + additionalProperties: + type: string + type: object + hostNetwork: + type: boolean + image: + type: string + imagePullPolicy: + type: string + ipFamilies: + items: + type: string + type: array + ipFamilyPolicy: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + podAnnotations: + additionalProperties: + type: string + type: object + podDnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + priorityClassName: + type: string + replicas: + format: int32 + maximum: 1 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + upgradeStrategy: + enum: + - automatic + - none + type: string + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + required: + - capabilities + - endpoint + type: object + status: + properties: + version: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetrycollector.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetrycollector.yaml new file mode 100644 index 00000000000..95d16b8b42f --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetrycollector.yaml @@ -0,0 +1,9242 @@ +{{- if .Values.crds.create }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ include "opentelemetry-operator.webhookCertAnnotation" . }} + controller-gen.kubebuilder.io/version: v0.16.1 + creationTimestamp: null + labels: + app.kubernetes.io/name: opentelemetry-operator + name: opentelemetrycollectors.opentelemetry.io +spec: +{{- if .Values.admissionWebhooks.create }} + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /convert + port: {{ .Values.admissionWebhooks.servicePort }} +{{ if .caBundle }}{{ cat "caBundle:" .caBundle | indent 8 }}{{ end }} + conversionReviewVersions: + - v1alpha1 + - v1beta1 +{{- end }} + group: opentelemetry.io + names: + kind: OpenTelemetryCollector + listKind: OpenTelemetryCollectorList + plural: opentelemetrycollectors + shortNames: + - otelcol + - otelcols + singular: opentelemetrycollector + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Deployment Mode + jsonPath: .spec.mode + name: Mode + type: string + - description: OpenTelemetry Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .status.scale.statusReplicas + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.image + name: Image + type: string + - description: Management State + jsonPath: .spec.managementState + name: Management + type: string + deprecated: true + deprecationWarning: OpenTelemetryCollector v1alpha1 is deprecated. Migrate to + v1beta1. + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + args: + additionalProperties: + type: string + type: object + autoscaler: + properties: + behavior: + properties: + scaleDown: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + scaleUp: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + type: object + maxReplicas: + format: int32 + type: integer + metrics: + items: + properties: + pods: + properties: + metric: + properties: + name: + type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + target: + properties: + averageUtilization: + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + type: string + value: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - metric + - target + type: object + type: + type: string + required: + - type + type: object + type: array + minReplicas: + format: int32 + type: integer + targetCPUUtilization: + format: int32 + type: integer + targetMemoryUtilization: + format: int32 + type: integer + type: object + config: + type: string + configmaps: + items: + properties: + mountpath: + type: string + name: + type: string + required: + - mountpath + - name + type: object + type: array + deploymentUpdateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + hostNetwork: + type: boolean + image: + type: string + imagePullPolicy: + type: string + ingress: + properties: + annotations: + additionalProperties: + type: string + type: object + hostname: + type: string + ingressClassName: + type: string + route: + properties: + termination: + enum: + - insecure + - edge + - passthrough + - reencrypt + type: string + type: object + ruleType: + enum: + - path + - subdomain + type: string + tls: + items: + properties: + hosts: + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + type: string + type: object + type: array + type: + enum: + - ingress + - route + type: string + type: object + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + managementState: + default: managed + enum: + - managed + - unmanaged + type: string + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + mode: + enum: + - daemonset + - deployment + - sidecar + - statefulset + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + DisablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podAnnotations: + additionalProperties: + type: string + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + priorityClassName: + type: string + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + shareProcessNamespace: + type: boolean + targetAllocator: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + allocationStrategy: + default: consistent-hashing + enum: + - least-weighted + - consistent-hashing + - per-node + type: string + enabled: + type: boolean + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + filterStrategy: + default: relabel-config + type: string + image: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + DisablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + prometheusCR: + properties: + enabled: + type: boolean + podMonitorSelector: + additionalProperties: + type: string + type: object + scrapeInterval: + default: 30s + format: duration + type: string + serviceMonitorSelector: + additionalProperties: + type: string + type: object + type: object + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + updateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + upgradeStrategy: + enum: + - automatic + - none + type: string + volumeClaimTemplates: + items: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + required: + - status + type: object + phase: + type: string + type: object + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + required: + - config + - managementState + type: object + status: + properties: + image: + type: string + messages: + items: + type: string + type: array + x-kubernetes-list-type: atomic + replicas: + format: int32 + type: integer + scale: + properties: + replicas: + format: int32 + type: integer + selector: + type: string + statusReplicas: + type: string + type: object + version: + type: string + type: object + type: object + served: true + storage: false + subresources: + scale: + labelSelectorPath: .status.scale.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.scale.replicas + status: {} + - additionalPrinterColumns: + - description: Deployment Mode + jsonPath: .spec.mode + name: Mode + type: string + - description: OpenTelemetry Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .status.scale.statusReplicas + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.image + name: Image + type: string + - description: Management State + jsonPath: .spec.managementState + name: Management + type: string + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + args: + additionalProperties: + type: string + type: object + autoscaler: + properties: + behavior: + properties: + scaleDown: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + scaleUp: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + type: object + maxReplicas: + format: int32 + type: integer + metrics: + items: + properties: + pods: + properties: + metric: + properties: + name: + type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + target: + properties: + averageUtilization: + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + type: string + value: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - metric + - target + type: object + type: + type: string + required: + - type + type: object + type: array + minReplicas: + format: int32 + type: integer + targetCPUUtilization: + format: int32 + type: integer + targetMemoryUtilization: + format: int32 + type: integer + type: object + config: + properties: + connectors: + type: object + x-kubernetes-preserve-unknown-fields: true + exporters: + type: object + x-kubernetes-preserve-unknown-fields: true + extensions: + type: object + x-kubernetes-preserve-unknown-fields: true + processors: + type: object + x-kubernetes-preserve-unknown-fields: true + receivers: + type: object + x-kubernetes-preserve-unknown-fields: true + service: + properties: + extensions: + items: + type: string + type: array + pipelines: + additionalProperties: + properties: + exporters: + items: + type: string + type: array + processors: + items: + type: string + type: array + receivers: + items: + type: string + type: array + required: + - exporters + - receivers + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + telemetry: + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - pipelines + type: object + required: + - exporters + - receivers + - service + type: object + x-kubernetes-preserve-unknown-fields: true + configVersions: + default: 3 + minimum: 1 + type: integer + configmaps: + items: + properties: + mountpath: + type: string + name: + type: string + required: + - mountpath + - name + type: object + type: array + daemonSetUpdateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + deploymentUpdateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + hostNetwork: + type: boolean + image: + type: string + imagePullPolicy: + type: string + ingress: + properties: + annotations: + additionalProperties: + type: string + type: object + hostname: + type: string + ingressClassName: + type: string + route: + properties: + termination: + enum: + - insecure + - edge + - passthrough + - reencrypt + type: string + type: object + ruleType: + enum: + - path + - subdomain + type: string + tls: + items: + properties: + hosts: + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + type: string + type: object + type: array + type: + enum: + - ingress + - route + type: string + type: object + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + ipFamilies: + items: + type: string + type: array + ipFamilyPolicy: + default: SingleStack + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + managementState: + default: managed + enum: + - managed + - unmanaged + type: string + mode: + enum: + - daemonset + - deployment + - sidecar + - statefulset + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + disablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podAnnotations: + additionalProperties: + type: string + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podDnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + priorityClassName: + type: string + readinessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + shareProcessNamespace: + type: boolean + targetAllocator: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + allocationStrategy: + default: consistent-hashing + enum: + - least-weighted + - consistent-hashing + - per-node + type: string + enabled: + type: boolean + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + filterStrategy: + default: relabel-config + enum: + - "" + - relabel-config + type: string + image: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + disablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + prometheusCR: + properties: + enabled: + type: boolean + podMonitorSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + scrapeInterval: + default: 30s + format: duration + type: string + serviceMonitorSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + upgradeStrategy: + enum: + - automatic + - none + type: string + volumeClaimTemplates: + items: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + required: + - status + type: object + phase: + type: string + type: object + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + required: + - config + - managementState + type: object + status: + properties: + image: + type: string + scale: + properties: + replicas: + format: int32 + type: integer + selector: + type: string + statusReplicas: + type: string + type: object + version: + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.scale.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.scale.replicas + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetryinstrumentation.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetryinstrumentation.yaml new file mode 100644 index 00000000000..580c0f96bed --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/conf/crds/crd-opentelemetryinstrumentation.yaml @@ -0,0 +1,1096 @@ +{{- if .Values.crds.create }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + creationTimestamp: null + labels: + app.kubernetes.io/name: opentelemetry-operator + name: instrumentations.opentelemetry.io +spec: + group: opentelemetry.io + names: + kind: Instrumentation + listKind: InstrumentationList + plural: instrumentations + shortNames: + - otelinst + - otelinsts + singular: instrumentation + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.exporter.endpoint + name: Endpoint + type: string + - jsonPath: .spec.sampler.type + name: Sampler + type: string + - jsonPath: .spec.sampler.argument + name: Sampler Arg + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + apacheHttpd: + properties: + attrs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + configPath: + type: string + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + version: + type: string + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + defaults: + properties: + useLabelsForResourceAttributes: + type: boolean + type: object + dotnet: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + exporter: + properties: + endpoint: + type: string + type: object + go: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + java: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + extensions: + items: + properties: + dir: + type: string + image: + type: string + required: + - dir + - image + type: object + type: array + image: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + nginx: + properties: + attrs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + configFile: + type: string + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + nodejs: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + propagators: + items: + enum: + - tracecontext + - baggage + - b3 + - b3multi + - jaeger + - xray + - ottrace + - none + type: string + type: array + python: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + resource: + properties: + addK8sUIDAttributes: + type: boolean + resourceAttributes: + additionalProperties: + type: string + type: object + type: object + sampler: + properties: + argument: + type: string + type: + enum: + - always_on + - always_off + - traceidratio + - parentbased_always_on + - parentbased_always_off + - parentbased_traceidratio + - jaeger_remote + - xray + type: string + type: object + type: object + status: + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/README.md b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/README.md new file mode 100644 index 00000000000..3bfe3ab8731 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/README.md @@ -0,0 +1,7 @@ +# Examples of chart configuration + +Here is a collection of common configurations for the OpenTelemetry Operator. Each folder contains an example `values.yaml` and the resulting configurations that are generated by the opentelemetry-operator helm chart. + +- [Default configuration](default) + +The manifests are rendered using the `helm template` command and the specific example folder's values.yaml. diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/admission-webhooks/operator-webhook-with-cert-manager.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/admission-webhooks/operator-webhook-with-cert-manager.yaml new file mode 100644 index 00000000000..6d1e0d9fe40 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/admission-webhooks/operator-webhook-with-cert-manager.yaml @@ -0,0 +1,192 @@ +--- +# Source: opentelemetry-operator/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: default/example-opentelemetry-operator-serving-cert + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-mutation +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /mutate-opentelemetry-io-v1alpha1-instrumentation + port: 443 + failurePolicy: Fail + name: minstrumentation.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /mutate-opentelemetry-io-v1beta1-opentelemetrycollector + port: 443 + failurePolicy: Fail + name: mopentelemetrycollectorbeta.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /mutate-v1-pod + port: 443 + failurePolicy: Ignore + name: mpod.kb.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 +--- +# Source: opentelemetry-operator/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: default/example-opentelemetry-operator-serving-cert + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-validation +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1alpha1-instrumentation + port: 443 + failurePolicy: Fail + name: vinstrumentationcreateupdate.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1alpha1-instrumentation + port: 443 + failurePolicy: Ignore + name: vinstrumentationdelete.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - DELETE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1beta1-opentelemetrycollector + port: 443 + failurePolicy: Fail + name: vopentelemetrycollectorcreateupdatebeta.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1beta1-opentelemetrycollector + port: 443 + failurePolicy: Ignore + name: vopentelemetrycollectordeletebeta.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - DELETE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/admission-webhooks/operator-webhook.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/admission-webhooks/operator-webhook.yaml new file mode 100644 index 00000000000..2407f3cde2b --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/admission-webhooks/operator-webhook.yaml @@ -0,0 +1,12102 @@ +--- +# Source: opentelemetry-operator/templates/admission-webhooks/operator-webhook.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: default/example-opentelemetry-operator-serving-cert + controller-gen.kubebuilder.io/version: v0.16.1 + creationTimestamp: null + labels: + app.kubernetes.io/name: opentelemetry-operator + name: opampbridges.opentelemetry.io +spec: + group: opentelemetry.io + names: + kind: OpAMPBridge + listKind: OpAMPBridgeList + plural: opampbridges + singular: opampbridge + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: OpenTelemetry Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .spec.endpoint + name: Endpoint + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + capabilities: + additionalProperties: + type: boolean + type: object + componentsAllowed: + additionalProperties: + items: + type: string + type: array + type: object + endpoint: + type: string + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + headers: + additionalProperties: + type: string + type: object + hostNetwork: + type: boolean + image: + type: string + imagePullPolicy: + type: string + ipFamilies: + items: + type: string + type: array + ipFamilyPolicy: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + podAnnotations: + additionalProperties: + type: string + type: object + podDnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + priorityClassName: + type: string + replicas: + format: int32 + maximum: 1 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + upgradeStrategy: + enum: + - automatic + - none + type: string + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + required: + - capabilities + - endpoint + type: object + status: + properties: + version: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# Source: opentelemetry-operator/templates/admission-webhooks/operator-webhook.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: default/example-opentelemetry-operator-serving-cert + controller-gen.kubebuilder.io/version: v0.16.1 + creationTimestamp: null + labels: + app.kubernetes.io/name: opentelemetry-operator + name: opentelemetrycollectors.opentelemetry.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /convert + port: 443 + + conversionReviewVersions: + - v1alpha1 + - v1beta1 + group: opentelemetry.io + names: + kind: OpenTelemetryCollector + listKind: OpenTelemetryCollectorList + plural: opentelemetrycollectors + shortNames: + - otelcol + - otelcols + singular: opentelemetrycollector + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Deployment Mode + jsonPath: .spec.mode + name: Mode + type: string + - description: OpenTelemetry Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .status.scale.statusReplicas + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.image + name: Image + type: string + - description: Management State + jsonPath: .spec.managementState + name: Management + type: string + deprecated: true + deprecationWarning: OpenTelemetryCollector v1alpha1 is deprecated. Migrate to + v1beta1. + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + args: + additionalProperties: + type: string + type: object + autoscaler: + properties: + behavior: + properties: + scaleDown: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + scaleUp: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + type: object + maxReplicas: + format: int32 + type: integer + metrics: + items: + properties: + pods: + properties: + metric: + properties: + name: + type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + target: + properties: + averageUtilization: + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + type: string + value: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - metric + - target + type: object + type: + type: string + required: + - type + type: object + type: array + minReplicas: + format: int32 + type: integer + targetCPUUtilization: + format: int32 + type: integer + targetMemoryUtilization: + format: int32 + type: integer + type: object + config: + type: string + configmaps: + items: + properties: + mountpath: + type: string + name: + type: string + required: + - mountpath + - name + type: object + type: array + deploymentUpdateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + hostNetwork: + type: boolean + image: + type: string + imagePullPolicy: + type: string + ingress: + properties: + annotations: + additionalProperties: + type: string + type: object + hostname: + type: string + ingressClassName: + type: string + route: + properties: + termination: + enum: + - insecure + - edge + - passthrough + - reencrypt + type: string + type: object + ruleType: + enum: + - path + - subdomain + type: string + tls: + items: + properties: + hosts: + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + type: string + type: object + type: array + type: + enum: + - ingress + - route + type: string + type: object + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + managementState: + default: managed + enum: + - managed + - unmanaged + type: string + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + mode: + enum: + - daemonset + - deployment + - sidecar + - statefulset + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + DisablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podAnnotations: + additionalProperties: + type: string + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + priorityClassName: + type: string + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + shareProcessNamespace: + type: boolean + targetAllocator: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + allocationStrategy: + default: consistent-hashing + enum: + - least-weighted + - consistent-hashing + - per-node + type: string + enabled: + type: boolean + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + filterStrategy: + default: relabel-config + type: string + image: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + DisablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + prometheusCR: + properties: + enabled: + type: boolean + podMonitorSelector: + additionalProperties: + type: string + type: object + scrapeInterval: + default: 30s + format: duration + type: string + serviceMonitorSelector: + additionalProperties: + type: string + type: object + type: object + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + updateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + upgradeStrategy: + enum: + - automatic + - none + type: string + volumeClaimTemplates: + items: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + required: + - status + type: object + phase: + type: string + type: object + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + required: + - config + - managementState + type: object + status: + properties: + image: + type: string + messages: + items: + type: string + type: array + x-kubernetes-list-type: atomic + replicas: + format: int32 + type: integer + scale: + properties: + replicas: + format: int32 + type: integer + selector: + type: string + statusReplicas: + type: string + type: object + version: + type: string + type: object + type: object + served: true + storage: false + subresources: + scale: + labelSelectorPath: .status.scale.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.scale.replicas + status: {} + - additionalPrinterColumns: + - description: Deployment Mode + jsonPath: .spec.mode + name: Mode + type: string + - description: OpenTelemetry Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .status.scale.statusReplicas + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.image + name: Image + type: string + - description: Management State + jsonPath: .spec.managementState + name: Management + type: string + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + args: + additionalProperties: + type: string + type: object + autoscaler: + properties: + behavior: + properties: + scaleDown: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + scaleUp: + properties: + policies: + items: + properties: + periodSeconds: + format: int32 + type: integer + type: + type: string + value: + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + type: string + stabilizationWindowSeconds: + format: int32 + type: integer + type: object + type: object + maxReplicas: + format: int32 + type: integer + metrics: + items: + properties: + pods: + properties: + metric: + properties: + name: + type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + target: + properties: + averageUtilization: + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + type: string + value: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - metric + - target + type: object + type: + type: string + required: + - type + type: object + type: array + minReplicas: + format: int32 + type: integer + targetCPUUtilization: + format: int32 + type: integer + targetMemoryUtilization: + format: int32 + type: integer + type: object + config: + properties: + connectors: + type: object + x-kubernetes-preserve-unknown-fields: true + exporters: + type: object + x-kubernetes-preserve-unknown-fields: true + extensions: + type: object + x-kubernetes-preserve-unknown-fields: true + processors: + type: object + x-kubernetes-preserve-unknown-fields: true + receivers: + type: object + x-kubernetes-preserve-unknown-fields: true + service: + properties: + extensions: + items: + type: string + type: array + pipelines: + additionalProperties: + properties: + exporters: + items: + type: string + type: array + processors: + items: + type: string + type: array + receivers: + items: + type: string + type: array + required: + - exporters + - receivers + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + telemetry: + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - pipelines + type: object + required: + - exporters + - receivers + - service + type: object + x-kubernetes-preserve-unknown-fields: true + configVersions: + default: 3 + minimum: 1 + type: integer + configmaps: + items: + properties: + mountpath: + type: string + name: + type: string + required: + - mountpath + - name + type: object + type: array + daemonSetUpdateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + deploymentUpdateStrategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + hostNetwork: + type: boolean + image: + type: string + imagePullPolicy: + type: string + ingress: + properties: + annotations: + additionalProperties: + type: string + type: object + hostname: + type: string + ingressClassName: + type: string + route: + properties: + termination: + enum: + - insecure + - edge + - passthrough + - reencrypt + type: string + type: object + ruleType: + enum: + - path + - subdomain + type: string + tls: + items: + properties: + hosts: + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + type: string + type: object + type: array + type: + enum: + - ingress + - route + type: string + type: object + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + ipFamilies: + items: + type: string + type: array + ipFamilyPolicy: + default: SingleStack + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + managementState: + default: managed + enum: + - managed + - unmanaged + type: string + mode: + enum: + - daemonset + - deployment + - sidecar + - statefulset + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + disablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podAnnotations: + additionalProperties: + type: string + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podDnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + priorityClassName: + type: string + readinessProbe: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + shareProcessNamespace: + type: boolean + targetAllocator: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + allocationStrategy: + default: consistent-hashing + enum: + - least-weighted + - consistent-hashing + - per-node + type: string + enabled: + type: boolean + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + filterStrategy: + default: relabel-config + enum: + - "" + - relabel-config + type: string + image: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + observability: + properties: + metrics: + properties: + disablePrometheusAnnotations: + type: boolean + enableMetrics: + type: boolean + type: object + type: object + podDisruptionBudget: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + podSecurityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + prometheusCR: + properties: + enabled: + type: boolean + podMonitorSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + scrapeInterval: + default: 30s + format: duration + type: string + serviceMonitorSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + upgradeStrategy: + enum: + - automatic + - none + type: string + volumeClaimTemplates: + items: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + required: + - status + type: object + phase: + type: string + type: object + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + required: + - config + - managementState + type: object + status: + properties: + image: + type: string + scale: + properties: + replicas: + format: int32 + type: integer + selector: + type: string + statusReplicas: + type: string + type: object + version: + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.scale.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.scale.replicas + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# Source: opentelemetry-operator/templates/admission-webhooks/operator-webhook.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + creationTimestamp: null + labels: + app.kubernetes.io/name: opentelemetry-operator + name: instrumentations.opentelemetry.io +spec: + group: opentelemetry.io + names: + kind: Instrumentation + listKind: InstrumentationList + plural: instrumentations + shortNames: + - otelinst + - otelinsts + singular: instrumentation + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.exporter.endpoint + name: Endpoint + type: string + - jsonPath: .spec.sampler.type + name: Sampler + type: string + - jsonPath: .spec.sampler.argument + name: Sampler Arg + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + apacheHttpd: + properties: + attrs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + configPath: + type: string + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + version: + type: string + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + defaults: + properties: + useLabelsForResourceAttributes: + type: boolean + type: object + dotnet: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + exporter: + properties: + endpoint: + type: string + type: object + go: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + java: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + extensions: + items: + properties: + dir: + type: string + image: + type: string + required: + - dir + - image + type: object + type: array + image: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + nginx: + properties: + attrs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + configFile: + type: string + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + nodejs: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + propagators: + items: + enum: + - tracecontext + - baggage + - b3 + - b3multi + - jaeger + - xray + - ottrace + - none + type: string + type: array + python: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + type: string + resourceRequirements: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + resource: + properties: + addK8sUIDAttributes: + type: boolean + resourceAttributes: + additionalProperties: + type: string + type: object + type: object + sampler: + properties: + argument: + type: string + type: + enum: + - always_on + - always_off + - traceidratio + - parentbased_always_on + - parentbased_always_off + - parentbased_traceidratio + - jaeger_remote + - xray + type: string + type: object + type: object + status: + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/certmanager.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/certmanager.yaml new file mode 100644 index 00000000000..387939c1779 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/certmanager.yaml @@ -0,0 +1,43 @@ +--- +# Source: opentelemetry-operator/templates/certmanager.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-serving-cert + namespace: default +spec: + dnsNames: + - example-opentelemetry-operator-webhook.default.svc + - example-opentelemetry-operator-webhook.default.svc.cluster.local + issuerRef: + kind: Issuer + name: example-opentelemetry-operator-selfsigned-issuer + secretName: example-opentelemetry-operator-controller-manager-service-cert + subject: + organizationalUnits: + - example-opentelemetry-operator +--- +# Source: opentelemetry-operator/templates/certmanager.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-selfsigned-issuer + namespace: default +spec: + selfSigned: {} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/clusterrole.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/clusterrole.yaml new file mode 100644 index 00000000000..6a2b8666682 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/clusterrole.yaml @@ -0,0 +1,265 @@ +--- +# Source: opentelemetry-operator/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-manager +rules: + - apiGroups: + - "" + resources: + - configmaps + - persistentvolumeclaims + - persistentvolumes + - pods + - serviceaccounts + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - list + - watch + - apiGroups: + - apps + resources: + - daemonsets + - deployments + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + - extensions + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - batch + resources: + - jobs + verbs: + - get + - list + - watch + - apiGroups: + - config.openshift.io + resources: + - infrastructures + - infrastructures/status + verbs: + - get + - list + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - list + - update + - apiGroups: + - monitoring.coreos.com + resources: + - podmonitors + - servicemonitors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - instrumentations + verbs: + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opampbridges + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opampbridges/finalizers + verbs: + - update + - apiGroups: + - opentelemetry.io + resources: + - opampbridges/status + verbs: + - get + - patch + - update + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors + verbs: + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors/finalizers + verbs: + - get + - patch + - update + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors/status + verbs: + - get + - patch + - update + - apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +# Source: opentelemetry-operator/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-metrics +rules: + - nonResourceURLs: + - /metrics + verbs: + - get +--- +# Source: opentelemetry-operator/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-proxy +rules: + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/clusterrolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/clusterrolebinding.yaml new file mode 100644 index 00000000000..c6c314a74d7 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/clusterrolebinding.yaml @@ -0,0 +1,44 @@ +--- +# Source: opentelemetry-operator/templates/clusterrolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: example-opentelemetry-operator-manager +subjects: + - kind: ServiceAccount + name: opentelemetry-operator + namespace: default +--- +# Source: opentelemetry-operator/templates/clusterrolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-proxy +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: example-opentelemetry-operator-proxy +subjects: + - kind: ServiceAccount + name: opentelemetry-operator + namespace: default diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/deployment.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/deployment.yaml new file mode 100644 index 00000000000..b631aafbd32 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/deployment.yaml @@ -0,0 +1,105 @@ +--- +# Source: opentelemetry-operator/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager + spec: + hostNetwork: false + containers: + - args: + - --metrics-addr=0.0.0.0:8080 + - --enable-leader-election + - --health-probe-addr=:8081 + - --webhook-port=9443 + - --collector-image=otel/opentelemetry-collector-k8s:0.110.0 + command: + - /manager + env: + - name: ENABLE_WEBHOOKS + value: "true" + image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.110.0" + name: manager + ports: + - containerPort: 8080 + name: metrics + protocol: TCP + - containerPort: 9443 + name: webhook-server + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 64Mi + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: "quay.io/brancz/kube-rbac-proxy:v0.15.0" + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + serviceAccountName: opentelemetry-operator + terminationGracePeriodSeconds: 10 + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: example-opentelemetry-operator-controller-manager-service-cert + securityContext: + fsGroup: 65532 + runAsGroup: 65532 + runAsNonRoot: true + runAsUser: 65532 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/role.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/role.yaml new file mode 100644 index 00000000000..347ff79a4f1 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/role.yaml @@ -0,0 +1,43 @@ +--- +# Source: opentelemetry-operator/templates/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-leader-election + namespace: default +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/rolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/rolebinding.yaml new file mode 100644 index 00000000000..43d9d25ab75 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/rolebinding.yaml @@ -0,0 +1,23 @@ +--- +# Source: opentelemetry-operator/templates/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-leader-election + namespace: default +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: example-opentelemetry-operator-leader-election +subjects: + - kind: ServiceAccount + name: opentelemetry-operator + namespace: default diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/service.yaml new file mode 100644 index 00000000000..1073fce0d5d --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/service.yaml @@ -0,0 +1,51 @@ +--- +# Source: opentelemetry-operator/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator + namespace: default +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + - name: metrics + port: 8080 + protocol: TCP + targetPort: metrics + selector: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager +--- +# Source: opentelemetry-operator/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-webhook + namespace: default +spec: + ports: + - port: 443 + protocol: TCP + targetPort: webhook-server + selector: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/serviceaccount.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/serviceaccount.yaml new file mode 100644 index 00000000000..3d53ee9524a --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/serviceaccount.yaml @@ -0,0 +1,15 @@ +--- +# Source: opentelemetry-operator/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: opentelemetry-operator + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/tests/test-certmanager-connection.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/tests/test-certmanager-connection.yaml new file mode 100644 index 00000000000..8e36b512e8e --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/tests/test-certmanager-connection.yaml @@ -0,0 +1,38 @@ +--- +# Source: opentelemetry-operator/templates/tests/test-certmanager-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "example-opentelemetry-operator-cert-manager" + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "busybox:latest" + env: + - name: CERT_MANAGER_CLUSTERIP + value: "cert-manager-webhook" + - name: CERT_MANAGER_PORT + value: "443" + command: + - sh + - -c + # The following shell script tests if the cert-manager service is up. If the service is up, when we try + # to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$CERT_MANAGER_CLUSTERIP:$CERT_MANAGER_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/tests/test-service-connection.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/tests/test-service-connection.yaml new file mode 100644 index 00000000000..9e77139fabe --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/rendered/tests/test-service-connection.yaml @@ -0,0 +1,76 @@ +--- +# Source: opentelemetry-operator/templates/tests/test-service-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "example-opentelemetry-operator-metrics" + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "busybox:latest" + env: + - name: MANAGER_METRICS_SERVICE_CLUSTERIP + value: "example-opentelemetry-operator" + - name: MANAGER_METRICS_SERVICE_PORT + value: "8443" + command: + - sh + - -c + # The following shell script tests if the controller-manager-metrics-service is up. + # If the service is up, when we try to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$MANAGER_METRICS_SERVICE_CLUSTERIP:$MANAGER_METRICS_SERVICE_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never +--- +# Source: opentelemetry-operator/templates/tests/test-service-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "example-opentelemetry-operator-webhook" + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "busybox:latest" + env: + - name: WEBHOOK_SERVICE_CLUSTERIP + value: "example-opentelemetry-operator-webhook" + - name: WEBHOOK_SERVICE_PORT + value: "443" + command: + - sh + - -c + # The following shell script tests if the webhook service is up. If the service is up, when we try + # to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$WEBHOOK_SERVICE_CLUSTERIP:$WEBHOOK_SERVICE_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/values.yaml new file mode 100644 index 00000000000..0913ed1f07f --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/examples/default/values.yaml @@ -0,0 +1,3 @@ +manager: + collectorImage: + repository: "otel/opentelemetry-collector-k8s" diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/NOTES.txt b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/NOTES.txt new file mode 100644 index 00000000000..227ecfef88f --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/NOTES.txt @@ -0,0 +1,8 @@ +{{- if not .Values.manager.collectorImage.repository }} +{{ fail "[ERROR] 'manager.collectorImage.repository' must be set. See https://github.com/open-telemetry/opentelemetry-helm-charts/blob/main/charts/opentelemetry-operator/UPGRADING.md for instructions." }} +{{ end }} + +{{ $.Chart.Name }} has been installed. Check its status by running: + kubectl --namespace {{ .Release.Namespace }} get pods -l "release={{ $.Release.Name }}" + +Visit https://github.com/open-telemetry/opentelemetry-operator for instructions on how to create & configure OpenTelemetryCollector and Instrumentation custom resources by using the Operator. diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/_helpers.tpl b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/_helpers.tpl new file mode 100644 index 00000000000..6539a73f50c --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/_helpers.tpl @@ -0,0 +1,152 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "opentelemetry-operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "opentelemetry-operator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "opentelemetry-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "opentelemetry-operator.labels" -}} +helm.sh/chart: {{ include "opentelemetry-operator.chart" . }} +{{ include "opentelemetry-operator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{ include "opentelemetry-operator.additionalLabels" . }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "opentelemetry-operator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "opentelemetry-operator.name" . }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "opentelemetry-operator.serviceAccountName" -}} +{{- if .Values.manager.serviceAccount.create }} +{{- default (include "opentelemetry-operator.name" .) .Values.manager.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.manager.serviceAccount.name }} +{{- end }} +{{- end }} + +{{- define "opentelemetry-operator.podAnnotations" -}} +{{- if .Values.manager.podAnnotations }} +{{- .Values.manager.podAnnotations | toYaml }} +{{- end }} +{{- end }} + +{{- define "opentelemetry-operator.podLabels" -}} +{{- if .Values.manager.podLabels }} +{{- .Values.manager.podLabels | toYaml }} +{{- end }} +{{- end }} + +{{- define "opentelemetry-operator.additionalLabels" -}} +{{- if .Values.additionalLabels }} +{{- tpl (.Values.additionalLabels | toYaml) . }} +{{- end }} +{{- end }} + +{{/* +Create an ordered name of the MutatingWebhookConfiguration +*/}} +{{- define "opentelemetry-operator.MutatingWebhookName" -}} +{{- printf "%s-%s" (.Values.admissionWebhooks.namePrefix | toString) (include "opentelemetry-operator.fullname" .) | trimPrefix "-" }} +{{- end }} + +{{/* +Return certificate and CA for Webhooks. +It handles variants when a cert has to be generated by Helm, +a cert is loaded from an existing secret or is provided via `.Values` +*/}} +{{- define "opentelemetry-operator.WebhookCert" -}} +{{- $caCertEnc := "" }} +{{- $certCrtEnc := "" }} +{{- $certKeyEnc := "" }} +{{- if .Values.admissionWebhooks.autoGenerateCert.enabled }} +{{- $prevSecret := (lookup "v1" "Secret" .Release.Namespace (default (printf "%s-controller-manager-service-cert" (include "opentelemetry-operator.fullname" .)) .Values.admissionWebhooks.secretName )) }} +{{- if and (not .Values.admissionWebhooks.autoGenerateCert.recreate) $prevSecret }} +{{- $certCrtEnc = index $prevSecret "data" "tls.crt" }} +{{- $certKeyEnc = index $prevSecret "data" "tls.key" }} +{{- $caCertEnc = index $prevSecret "data" "ca.crt" }} +{{- if not $caCertEnc }} +{{- $prevHook := (lookup "admissionregistration.k8s.io/v1" "MutatingWebhookConfiguration" .Release.Namespace (print (include "opentelemetry-operator.MutatingWebhookName" . ) "-mutation")) }} +{{- if not (eq (toString $prevHook) "") }} +{{- $caCertEnc = (first $prevHook.webhooks).clientConfig.caBundle }} +{{- end }} +{{- end }} +{{- else }} +{{- $altNames := list ( printf "%s-webhook.%s" (include "opentelemetry-operator.fullname" .) .Release.Namespace ) ( printf "%s-webhook.%s.svc" (include "opentelemetry-operator.fullname" .) .Release.Namespace ) -}} +{{- $tmpperioddays := int .Values.admissionWebhooks.autoGenerateCert.certPeriodDays | default 365 }} +{{- $ca := genCA "opentelemetry-operator-operator-ca" $tmpperioddays }} +{{- $cert := genSignedCert (include "opentelemetry-operator.fullname" .) nil $altNames $tmpperioddays $ca }} +{{- $certCrtEnc = b64enc $cert.Cert }} +{{- $certKeyEnc = b64enc $cert.Key }} +{{- $caCertEnc = b64enc $ca.Cert }} +{{- end }} +{{- else }} +{{- $certCrtEnc = .Files.Get .Values.admissionWebhooks.certFile | b64enc }} +{{- $certKeyEnc = .Files.Get .Values.admissionWebhooks.keyFile | b64enc }} +{{- $caCertEnc = .Files.Get .Values.admissionWebhooks.caFile | b64enc }} +{{- end }} +{{- $result := dict "crt" $certCrtEnc "key" $certKeyEnc "ca" $caCertEnc }} +{{- $result | toYaml }} +{{- end }} + +{{/* +Return the name of cert-manager's Certificate resources for webhooks. +*/}} +{{- define "opentelemetry-operator.webhookCertName" -}} +{{ template "opentelemetry-operator.fullname" . }}-serving-cert +{{- end }} + +{{/* +Return the name of the cert-manager.io/inject-ca-from annotation for webhooks and CRDs. +*/}} +{{- define "opentelemetry-operator.webhookCertAnnotation" -}} +{{- if not .Values.admissionWebhooks.certManager.enabled }} +{{- "none" }} +{{- else }} +{{- printf "%s/%s" .Release.Namespace (include "opentelemetry-operator.webhookCertName" .) }} +{{- end }} +{{- end }} + +{{/* +The image to use for opentelemetry-operator. +*/}} +{{- define "opentelemetry-operator.image" -}} +{{- printf "%s:%s" .Values.manager.image.repository (default .Chart.AppVersion .Values.manager.image.tag) }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml new file mode 100644 index 00000000000..fc8fec220b8 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml @@ -0,0 +1,237 @@ +{{- if and (.Values.admissionWebhooks.create) (.Values.admissionWebhooks.certManager.enabled) }} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ include "opentelemetry-operator.webhookCertAnnotation" . }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: webhook + name: {{ template "opentelemetry-operator.MutatingWebhookName" . }}-mutation +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /mutate-opentelemetry-io-v1alpha1-instrumentation + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: {{ .Values.admissionWebhooks.failurePolicy }} + name: minstrumentation.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /mutate-opentelemetry-io-v1beta1-opentelemetrycollector + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: {{ .Values.admissionWebhooks.failurePolicy }} + name: mopentelemetrycollectorbeta.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /mutate-v1-pod + port: {{ .Values.admissionWebhooks.servicePort }} + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + failurePolicy: {{ .Values.admissionWebhooks.pods.failurePolicy }} + name: mpod.kb.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ include "opentelemetry-operator.webhookCertAnnotation" . }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: webhook + name: {{ template "opentelemetry-operator.fullname" . }}-validation +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /validate-opentelemetry-io-v1alpha1-instrumentation + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: {{ .Values.admissionWebhooks.failurePolicy }} + name: vinstrumentationcreateupdate.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /validate-opentelemetry-io-v1alpha1-instrumentation + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: Ignore + name: vinstrumentationdelete.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - DELETE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /validate-opentelemetry-io-v1beta1-opentelemetrycollector + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: {{ .Values.admissionWebhooks.failurePolicy }} + name: vopentelemetrycollectorcreateupdatebeta.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /validate-opentelemetry-io-v1beta1-opentelemetrycollector + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: Ignore + name: vopentelemetrycollectordeletebeta.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - DELETE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook.yaml new file mode 100644 index 00000000000..9ca27ab3b6a --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook.yaml @@ -0,0 +1,282 @@ +{{- if and (.Values.admissionWebhooks.create) (not .Values.admissionWebhooks.certManager.enabled) }} +{{- $cert := fromYaml (include "opentelemetry-operator.WebhookCert" .) }} +{{- $caCertEnc := $cert.ca }} +{{- $certCrtEnc := $cert.crt }} +{{- $certKeyEnc := $cert.key }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/tls +metadata: + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-delete-policy": "before-hook-creation" + {{- if .Values.admissionWebhooks.secretAnnotations }} + {{- toYaml .Values.admissionWebhooks.secretAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: webhook + {{- if .Values.admissionWebhooks.secretLabels }} + {{- toYaml .Values.admissionWebhooks.secretLabels | nindent 4 }} + {{- end }} + name: {{ default (printf "%s-controller-manager-service-cert" (include "opentelemetry-operator.fullname" .)) .Values.admissionWebhooks.secretName }} + namespace: {{ .Release.Namespace }} +data: + tls.crt: {{ $certCrtEnc }} + tls.key: {{ $certKeyEnc }} + ca.crt: {{ $caCertEnc }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: webhook + name: {{ template "opentelemetry-operator.MutatingWebhookName" . }}-mutation +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caCertEnc }} + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /mutate-opentelemetry-io-v1alpha1-instrumentation + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: {{ .Values.admissionWebhooks.failurePolicy }} + name: minstrumentation.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} + - admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caCertEnc }} + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /mutate-opentelemetry-io-v1beta1-opentelemetrycollector + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: {{ .Values.admissionWebhooks.failurePolicy }} + name: mopentelemetrycollectorbeta.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} + - admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caCertEnc }} + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /mutate-v1-pod + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: {{ .Values.admissionWebhooks.pods.failurePolicy }} + name: mpod.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ include "opentelemetry-operator.webhookCertAnnotation" . }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: webhook + name: {{ template "opentelemetry-operator.fullname" . }}-validation +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caCertEnc }} + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /validate-opentelemetry-io-v1alpha1-instrumentation + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: {{ .Values.admissionWebhooks.failurePolicy }} + name: vinstrumentationcreateupdate.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} + - admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caCertEnc }} + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /validate-opentelemetry-io-v1alpha1-instrumentation + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: Ignore + name: vinstrumentationdelete.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - DELETE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} + - admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caCertEnc }} + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /validate-opentelemetry-io-v1beta1-opentelemetrycollector + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: {{ .Values.admissionWebhooks.failurePolicy }} + name: vopentelemetrycollectorcreateupdatebeta.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} + - admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caCertEnc }} + service: + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} + path: /validate-opentelemetry-io-v1beta1-opentelemetrycollector + port: {{ .Values.admissionWebhooks.servicePort }} + failurePolicy: Ignore + name: vopentelemetrycollectordeletebeta.kb.io + {{- if .Values.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- toYaml .Values.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - DELETE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +--- +{{- $contextWithCaBundle := merge $ (dict "caBundle" $caCertEnc) }} +{{- tpl (.Files.Get "conf/crds/crd-opentelemetry.io_opampbridges.yaml") $contextWithCaBundle }} +--- +{{- tpl (.Files.Get "conf/crds/crd-opentelemetrycollector.yaml") $contextWithCaBundle }} +--- +{{- tpl (.Files.Get "conf/crds/crd-opentelemetryinstrumentation.yaml") $contextWithCaBundle }} +{{- else }} +{{- tpl (.Files.Get "conf/crds/crd-opentelemetry.io_opampbridges.yaml") . }} +--- +{{- tpl (.Files.Get "conf/crds/crd-opentelemetrycollector.yaml") . }} +--- +{{- tpl (.Files.Get "conf/crds/crd-opentelemetryinstrumentation.yaml") . }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/certmanager.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/certmanager.yaml new file mode 100644 index 00000000000..351ec0edf44 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/certmanager.yaml @@ -0,0 +1,52 @@ +{{- if and .Values.admissionWebhooks.create .Values.admissionWebhooks.certManager.enabled }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + {{- if .Values.admissionWebhooks.certManager.certificateAnnotations }} + annotations: + {{- toYaml .Values.admissionWebhooks.certManager.certificateAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: webhook + name: {{ template "opentelemetry-operator.webhookCertName" . }} + namespace: {{ .Release.Namespace }} +spec: + {{- if .Values.admissionWebhooks.certManager.duration }} + duration: {{ .Values.admissionWebhooks.certManager.duration }} + {{- end }} + {{- if .Values.admissionWebhooks.certManager.renewBefore }} + renewBefore: {{ .Values.admissionWebhooks.certManager.renewBefore }} + {{- end }} + dnsNames: + - {{ template "opentelemetry-operator.fullname" . }}-webhook.{{ .Release.Namespace }}.svc + - {{ template "opentelemetry-operator.fullname" . }}-webhook.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + issuerRef: + {{- if .Values.admissionWebhooks.certManager.issuerRef }} + {{- toYaml .Values.admissionWebhooks.certManager.issuerRef | nindent 4 }} + {{- else }} + kind: Issuer + name: {{ template "opentelemetry-operator.fullname" . }}-selfsigned-issuer + {{- end }} + secretName: {{ default (printf "%s-controller-manager-service-cert" (include "opentelemetry-operator.fullname" .)) .Values.admissionWebhooks.secretName }} + subject: + organizationalUnits: + - {{ template "opentelemetry-operator.fullname" . }} +{{- if not .Values.admissionWebhooks.certManager.issuerRef }} +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + {{- if .Values.admissionWebhooks.certManager.issuerAnnotations }} + annotations: + {{- toYaml .Values.admissionWebhooks.certManager.issuerAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: webhook + name: {{ template "opentelemetry-operator.fullname" . }}-selfsigned-issuer + namespace: {{ .Release.Namespace }} +spec: + selfSigned: {} +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrole.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrole.yaml new file mode 100644 index 00000000000..1dd7786a32f --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrole.yaml @@ -0,0 +1,275 @@ +{{- if .Values.clusterRole.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }}-manager +rules: + - apiGroups: + - "" + resources: + - configmaps + - persistentvolumeclaims + - persistentvolumes + - pods + - serviceaccounts + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - list + - watch + - apiGroups: + - apps + resources: + - daemonsets + - deployments + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + - extensions + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + {{- if .Values.manager.createRbacPermissions }} + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + - clusterrolebindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - nodes + - namespaces + verbs: + - get + - list + - watch + {{- end }} + - apiGroups: + - batch + resources: + - jobs + verbs: + - get + - list + - watch + - apiGroups: + - config.openshift.io + resources: + - infrastructures + - infrastructures/status + verbs: + - get + - list + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - list + - update + - apiGroups: + - monitoring.coreos.com + resources: + - podmonitors + - servicemonitors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - instrumentations + verbs: + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opampbridges + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opampbridges/finalizers + verbs: + - update + - apiGroups: + - opentelemetry.io + resources: + - opampbridges/status + verbs: + - get + - patch + - update + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors + verbs: + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors/finalizers + verbs: + - get + - patch + - update + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors/status + verbs: + - get + - patch + - update + - apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + +{{ if .Values.kubeRBACProxy.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }}-metrics +rules: + - nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }}-proxy +rules: + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end }} +{{ end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrolebinding.yaml new file mode 100644 index 00000000000..d87d39ff4c3 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrolebinding.yaml @@ -0,0 +1,36 @@ +{{- if .Values.clusterRole.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }}-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "opentelemetry-operator.fullname" . }}-manager +subjects: + - kind: ServiceAccount + name: {{ template "opentelemetry-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + +{{ if .Values.kubeRBACProxy.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }}-proxy +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "opentelemetry-operator.fullname" . }}-proxy +subjects: + - kind: ServiceAccount + name: {{ template "opentelemetry-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{ end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/deployment.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/deployment.yaml new file mode 100644 index 00000000000..36b3091bef4 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/deployment.yaml @@ -0,0 +1,181 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with .Values.manager.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "opentelemetry-operator.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller-manager + template: + metadata: + annotations: + {{- if .Values.manager.rolling }} + rollme: {{ randAlphaNum 5 | quote }} + {{- end }} + kubectl.kubernetes.io/default-container: manager + {{- if .Values.manager.podAnnotations }} + {{- include "opentelemetry-operator.podAnnotations" . | nindent 8 }} + {{- end }} + labels: + {{- include "opentelemetry-operator.selectorLabels" . | nindent 8 }} + {{- if .Values.manager.podLabels }} + {{- include "opentelemetry-operator.podLabels" . | nindent 8 }} + {{- end }} + app.kubernetes.io/component: controller-manager + spec: + hostNetwork: {{ .Values.hostNetwork }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + containers: + - args: + - --metrics-addr=0.0.0.0:{{ .Values.manager.ports.metricsPort }} + {{- if .Values.manager.leaderElection.enabled }} + - --enable-leader-election + {{- end }} + - --health-probe-addr=:{{ .Values.manager.ports.healthzPort }} + {{- if or .Values.admissionWebhooks.create .Values.admissionWebhooks.secretName }} + - --webhook-port={{ .Values.manager.ports.webhookPort }} + {{- end }} + {{- if and .Values.manager.collectorImage.repository .Values.manager.collectorImage.tag }} + - --collector-image={{ .Values.manager.collectorImage.repository }}:{{ .Values.manager.collectorImage.tag }} + {{- end }} + {{- if and .Values.manager.opampBridgeImage.repository .Values.manager.opampBridgeImage.tag }} + - --operator-opamp-bridge-image={{ .Values.manager.opampBridgeImage.repository }}:{{ .Values.manager.opampBridgeImage.tag }} + {{- end }} + {{- if and .Values.manager.targetAllocatorImage.repository .Values.manager.targetAllocatorImage.tag }} + - --target-allocator-image={{ .Values.manager.targetAllocatorImage.repository }}:{{ .Values.manager.targetAllocatorImage.tag }} + {{- end }} + {{- if and .Values.manager.autoInstrumentationImage.java.repository .Values.manager.autoInstrumentationImage.java.tag }} + - --auto-instrumentation-java-image={{ .Values.manager.autoInstrumentationImage.java.repository }}:{{ .Values.manager.autoInstrumentationImage.java.tag }} + {{- end }} + {{- if and .Values.manager.autoInstrumentationImage.nodejs.repository .Values.manager.autoInstrumentationImage.nodejs.tag }} + - --auto-instrumentation-nodejs-image={{ .Values.manager.autoInstrumentationImage.nodejs.repository }}:{{ .Values.manager.autoInstrumentationImage.nodejs.tag }} + {{- end }} + {{- if and .Values.manager.autoInstrumentationImage.python.repository .Values.manager.autoInstrumentationImage.python.tag }} + - --auto-instrumentation-python-image={{ .Values.manager.autoInstrumentationImage.python.repository }}:{{ .Values.manager.autoInstrumentationImage.python.tag }} + {{- end }} + {{- if and .Values.manager.autoInstrumentationImage.dotnet.repository .Values.manager.autoInstrumentationImage.dotnet.tag }} + - --auto-instrumentation-dotnet-image={{ .Values.manager.autoInstrumentationImage.dotnet.repository }}:{{ .Values.manager.autoInstrumentationImage.dotnet.tag }} + {{- end }} + {{- if and .Values.manager.autoInstrumentationImage.go.repository .Values.manager.autoInstrumentationImage.go.tag }} + - --auto-instrumentation-go-image={{ .Values.manager.autoInstrumentationImage.go.repository }}:{{ .Values.manager.autoInstrumentationImage.go.tag }} + {{- end }} + {{- if and .Values.manager.autoInstrumentationImage.apacheHttpd.repository .Values.manager.autoInstrumentationImage.apacheHttpd.tag }} + - --auto-instrumentation-apache-httpd-image={{ .Values.manager.autoInstrumentationImage.apacheHttpd.repository }}:{{ .Values.manager.autoInstrumentationImage.apacheHttpd.tag }} + {{- end }} + {{- if .Values.manager.featureGates }} + - --feature-gates={{ .Values.manager.featureGates }} + {{- end }} + {{- if .Values.manager.extraArgs }} + {{- .Values.manager.extraArgs | toYaml | nindent 12 }} + {{- end }} + command: + - /manager + {{- if or .Values.manager.env .Values.manager.createRbacPermissions }} + env: + {{- if .Values.manager.env }} + {{- range $name, $value := .Values.manager.env }} + - name: {{ $name }} + value: {{ $value | quote -}} + {{- end }} + {{- end }} + {{- if .Values.manager.createRbacPermissions }} + - name: SERVICE_ACCOUNT_NAME + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + {{- end }} + {{- end }} + image: {{ include "opentelemetry-operator.image" . | quote }} + name: manager + ports: + - containerPort: {{ .Values.manager.ports.metricsPort }} + name: metrics + protocol: TCP + {{- if or .Values.admissionWebhooks.create .Values.admissionWebhooks.secretName }} + - containerPort: {{ .Values.manager.ports.webhookPort }} + name: webhook-server + protocol: TCP + {{- end }} + livenessProbe: + httpGet: + path: /healthz + port: {{ .Values.manager.ports.healthzPort }} + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: {{ .Values.manager.ports.healthzPort }} + initialDelaySeconds: 5 + periodSeconds: 10 + resources: {{ toYaml .Values.manager.resources | nindent 12 }} + {{- if or .Values.admissionWebhooks.create .Values.admissionWebhooks.secretName }} + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + {{- end }} + {{- with .Values.manager.securityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{ if .Values.kubeRBACProxy.enabled }} + - args: + - --secure-listen-address=0.0.0.0:{{ .Values.kubeRBACProxy.ports.proxyPort }} + - --upstream=http://127.0.0.1:{{ .Values.manager.ports.metricsPort }}/ + - --logtostderr=true + - --v=0 + {{- if .Values.kubeRBACProxy.extraArgs }} + {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 12 }} + {{- end }} + image: "{{ .Values.kubeRBACProxy.image.repository }}:{{ .Values.kubeRBACProxy.image.tag }}" + name: kube-rbac-proxy + ports: + - containerPort: {{ .Values.kubeRBACProxy.ports.proxyPort }} + name: https + protocol: TCP + {{- with .Values.kubeRBACProxy.resources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.kubeRBACProxy.securityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{ toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "opentelemetry-operator.serviceAccountName" . }} + terminationGracePeriodSeconds: 10 + {{- if or .Values.admissionWebhooks.create .Values.admissionWebhooks.secretName }} + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: {{ default (printf "%s-controller-manager-service-cert" (include "opentelemetry-operator.fullname" .)) .Values.admissionWebhooks.secretName }} + {{- end }} + securityContext: +{{ toYaml .Values.securityContext | indent 8 }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/pdb.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/pdb.yaml new file mode 100644 index 00000000000..77992304677 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/pdb.yaml @@ -0,0 +1,21 @@ +{{- if .Values.pdb.create }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + {{- if .Values.pdb.minAvailable }} + minAvailable: {{ .Values.pdb.minAvailable }} + {{- end }} + {{- if .Values.pdb.maxUnavailable }} + maxUnavailable: {{ .Values.pdb.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "opentelemetry-operator.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller-manager +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/prometheusrule.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/prometheusrule.yaml new file mode 100644 index 00000000000..3f7b4d2fd73 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/prometheusrule.yaml @@ -0,0 +1,54 @@ +{{- if and .Values.manager.prometheusRule.enabled .Values.manager.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "opentelemetry-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + {{- range $key, $value := .Values.manager.prometheusRule.extraLabels }} + {{- printf "%s: %s" $key (tpl $value $ | quote) | nindent 4 }} + {{- end }} + annotations: + {{- range $key, $value := .Values.manager.prometheusRule.annotations }} + {{- printf "%s: %s" $key (tpl $value $ | quote) | nindent 4 }} + {{- end }} +spec: + groups: +{{- if .Values.manager.prometheusRule.groups }} + {{- toYaml .Values.manager.prometheusRule.groups | nindent 4 }} +{{- end }} +{{- if .Values.manager.prometheusRule.defaultRules.enabled }} + - name: managerRules + rules: + - alert: ReconcileErrors + expr: rate(controller_runtime_reconcile_total{controller="opentelemetrycollector",result="error"}[5m]) > 0 + for: 5m + labels: + severity: warning + {{- with .Values.manager.prometheusRule.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + description: '{{`Reconciliation errors for {{ $labels.controller }} is increasing and has now reached {{ humanize $value }} `}}' + runbook_url: '{{ default "https://opentelemetry.io/docs/kubernetes/operator/troubleshooting/prometheus-alerts-runbooks/" .Values.manager.prometheusRule.runbookUrl }}#reconcileerrors' + {{- with .Values.manager.prometheusRule.defaultRules.additionalRuleAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + - alert: WorkqueueDepth + expr: workqueue_depth{name="opentelemetrycollector"} > 0 + for: 5m + labels: + severity: warning + {{- with .Values.manager.prometheusRule.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + description: '{{`Queue depth for {{ $labels.name }} has reached {{ $value }} `}}' + runbook_url: '{{ default "https://opentelemetry.io/docs/kubernetes/operator/troubleshooting/prometheus-alerts-runbooks/" .Values.manager.prometheusRule.runbookUrl }}#workqueuedepth' + {{- with .Values.manager.prometheusRule.defaultRules.additionalRuleAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/role.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/role.yaml new file mode 100644 index 00000000000..73564ed7684 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/role.yaml @@ -0,0 +1,38 @@ +{{- if and .Values.role.create .Values.manager.leaderElection.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }}-leader-election + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/rolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/rolebinding.yaml new file mode 100644 index 00000000000..7064a1764de --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/rolebinding.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.role.create .Values.manager.leaderElection.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }}-leader-election + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "opentelemetry-operator.fullname" . }}-leader-election +subjects: + - kind: ServiceAccount + name: {{ template "opentelemetry-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/service.yaml new file mode 100644 index 00000000000..d41b53aa7f9 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/service.yaml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: Service +metadata: + {{- with .Values.manager.serviceAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + ports: + {{- if .Values.kubeRBACProxy.enabled }} + - name: https + port: {{ .Values.kubeRBACProxy.ports.proxyPort }} + protocol: TCP + targetPort: https + {{- end }} + - name: metrics + port: {{ .Values.manager.ports.metricsPort }} + protocol: TCP + targetPort: metrics + selector: + {{- include "opentelemetry-operator.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller-manager + +{{- if or .Values.admissionWebhooks.create .Values.admissionWebhooks.secretName }} +--- +apiVersion: v1 +kind: Service +metadata: + {{- with .Values.admissionWebhooks.serviceAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + name: {{ template "opentelemetry-operator.fullname" . }}-webhook + namespace: {{ .Release.Namespace }} +spec: + ports: + - port: {{ .Values.admissionWebhooks.servicePort }} + protocol: TCP + targetPort: webhook-server + selector: + {{- include "opentelemetry-operator.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller-manager +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/serviceaccount.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/serviceaccount.yaml new file mode 100644 index 00000000000..8300ba40271 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.manager.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "opentelemetry-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + {{- if .Values.manager.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.manager.serviceAccount.annotations }} + {{- printf "%s: %s" $key (tpl $value $ | quote) | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/servicemonitor.yaml new file mode 100644 index 00000000000..93964d21c5b --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/servicemonitor.yaml @@ -0,0 +1,37 @@ +{{- if .Values.manager.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "opentelemetry-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + {{- range $key, $value := .Values.manager.serviceMonitor.extraLabels }} + {{- printf "%s: %s" $key (tpl $value $ | quote) | nindent 4 }} + {{- end }} + {{- if .Values.manager.serviceMonitor.annotations }} + annotations: + {{- range $key, $value := .Values.manager.serviceMonitor.annotations }} + {{- printf "%s: %s" $key (tpl $value $ | quote) | nindent 4 }} + {{- end }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "opentelemetry-operator.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller-manager + endpoints: + {{- toYaml .Values.manager.serviceMonitor.metricsEndpoints | nindent 4 }} + {{- with .Values.manager.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.manager.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-certmanager-connection.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-certmanager-connection.yaml new file mode 100644 index 00000000000..f60b10f89fc --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-certmanager-connection.yaml @@ -0,0 +1,42 @@ +{{- if and .Values.admissionWebhooks.create .Values.admissionWebhooks.certManager.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "opentelemetry-operator.fullname" . }}-cert-manager" + namespace: {{ .Release.Namespace }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: webhook + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "{{ .Values.testFramework.image.repository }}:{{ .Values.testFramework.image.tag }}" + env: + - name: CERT_MANAGER_CLUSTERIP + value: "cert-manager-webhook" + - name: CERT_MANAGER_PORT + value: "443" + command: + - sh + - -c + # The following shell script tests if the cert-manager service is up. If the service is up, when we try + # to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$CERT_MANAGER_CLUSTERIP:$CERT_MANAGER_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never + {{- with .Values.affinity }} + affinity: {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-service-connection.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-service-connection.yaml new file mode 100644 index 00000000000..fcceefa5956 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-service-connection.yaml @@ -0,0 +1,84 @@ +{{ if .Values.kubeRBACProxy.enabled }} +--- +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "opentelemetry-operator.fullname" . }}-metrics" + namespace: {{ .Release.Namespace }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "{{ .Values.testFramework.image.repository }}:{{ .Values.testFramework.image.tag }}" + env: + - name: MANAGER_METRICS_SERVICE_CLUSTERIP + value: "{{ include "opentelemetry-operator.fullname" . }}" + - name: MANAGER_METRICS_SERVICE_PORT + value: "{{ .Values.kubeRBACProxy.ports.proxyPort }}" + command: + - sh + - -c + # The following shell script tests if the controller-manager-metrics-service is up. + # If the service is up, when we try to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$MANAGER_METRICS_SERVICE_CLUSTERIP:$MANAGER_METRICS_SERVICE_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never + {{- with .Values.affinity }} + affinity: {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} +--- +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "opentelemetry-operator.fullname" . }}-webhook" + namespace: {{ .Release.Namespace }} + labels: + {{- include "opentelemetry-operator.labels" . | nindent 4 }} + app.kubernetes.io/component: controller-manager + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "{{ .Values.testFramework.image.repository }}:{{ .Values.testFramework.image.tag }}" + env: + - name: WEBHOOK_SERVICE_CLUSTERIP + value: "{{ include "opentelemetry-operator.fullname" . }}-webhook" + - name: WEBHOOK_SERVICE_PORT + value: "{{ .Values.admissionWebhooks.servicePort }}" + command: + - sh + - -c + # The following shell script tests if the webhook service is up. If the service is up, when we try + # to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$WEBHOOK_SERVICE_CLUSTERIP:$WEBHOOK_SERVICE_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never + {{- with .Values.affinity }} + affinity: {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{ toYaml . | nindent 4 }} + {{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/verticalpodautoscaler.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/verticalpodautoscaler.yaml new file mode 100644 index 00000000000..660c535b68f --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/templates/verticalpodautoscaler.yaml @@ -0,0 +1,38 @@ +{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (.Values.manager.verticalPodAutoscaler.enabled) }} +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: {{ template "opentelemetry-operator.fullname" . }}-operator + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "opentelemetry-operator.name" . }}-operator +{{- include "opentelemetry-operator.labels" . | nindent 4 }} +spec: + resourcePolicy: + containerPolicies: + - containerName: manager + {{- if .Values.manager.verticalPodAutoscaler.controlledResources }} + controlledResources: {{ .Values.manager.verticalPodAutoscaler.controlledResources }} + {{- end }} + {{- if .Values.manager.verticalPodAutoscaler.maxAllowed }} + maxAllowed: + {{- toYaml .Values.manager.verticalPodAutoscaler.maxAllowed | nindent 8 }} + {{- end }} + {{- if .Values.manager.verticalPodAutoscaler.minAllowed }} + minAllowed: + {{- toYaml .Values.manager.verticalPodAutoscaler.minAllowed | nindent 8 }} + {{- end }} + targetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "opentelemetry-operator.fullname" . }} + {{- if .Values.manager.verticalPodAutoscaler.updatePolicy }} + updatePolicy: + {{- if .Values.manager.verticalPodAutoscaler.updatePolicy.updateMode }} + updateMode: {{ .Values.manager.verticalPodAutoscaler.updatePolicy.updateMode }} + {{- end }} + {{- if .Values.manager.verticalPodAutoscaler.updatePolicy.minReplicas }} + minReplicas: {{ .Values.manager.verticalPodAutoscaler.updatePolicy.minReplicas }} + {{- end }} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/values.schema.json b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/values.schema.json new file mode 100644 index 00000000000..c96a1b76f7c --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/values.schema.json @@ -0,0 +1,2051 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "http://example.com/example.json", + "type": "object", + "default": {}, + "title": "Root Schema", + "required": [ + "replicaCount", + "nameOverride", + "imagePullSecrets", + "clusterDomain", + "pdb", + "manager", + "kubeRBACProxy", + "admissionWebhooks", + "crds", + "role", + "clusterRole", + "affinity", + "tolerations", + "nodeSelector", + "topologySpreadConstraints", + "hostNetwork", + "priorityClassName", + "securityContext", + "testFramework", + "additionalLabels" + ], + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Usually used when using Opentelemetry-operator as a subchart.", + "type": "boolean" + }, + "global": { + "type": "object" + }, + "replicaCount": { + "type": "integer", + "default": 0, + "title": "The replicaCount Schema", + "examples": [ + 1 + ] + }, + "nameOverride": { + "type": "string", + "default": "", + "title": "The nameOverride Schema", + "examples": [ + "" + ] + }, + "fullnameOverride": { + "type": "string", + "default": "", + "title": "The fullnameOverride Schema", + "examples": [ + "" + ] + }, + "imagePullSecrets": { + "type": "array", + "default": [], + "title": "The imagePullSecrets Schema", + "items": {}, + "examples": [ + [] + ] + }, + "clusterDomain": { + "type": "string", + "default": "cluster.local", + "title": "Kubernetes cluster domain suffix" + }, + "pdb": { + "type": "object", + "default": {}, + "title": "The pdb Schema", + "required": [ + "create", + "minAvailable", + "maxUnavailable" + ], + "additionalProperties": false, + "properties": { + "create": { + "type": "boolean", + "default": false, + "title": "The create Schema", + "examples": [ + false + ] + }, + "minAvailable": { + "oneOf": [ + { + "type": ["string", "null"] + }, + { + "type": ["integer", "null"] + } + ] + }, + "maxUnavailable": { + "oneOf": [ + { + "type": ["string", "null"] + }, + { + "type": ["integer", "null"] + } + ] + } + }, + "examples": [{ + "create": false, + "minAvailable": 1, + "maxUnavailable": "" + }] + }, + "manager": { + "type": "object", + "default": {}, + "title": "The manager Schema", + "required": [ + "image", + "collectorImage", + "opampBridgeImage", + "targetAllocatorImage", + "autoInstrumentationImage", + "featureGates", + "ports", + "env", + "serviceAccount", + "serviceMonitor", + "deploymentAnnotations", + "serviceAnnotations", + "podAnnotations", + "podLabels", + "prometheusRule", + "extraArgs", + "leaderElection", + "verticalPodAutoscaler", + "rolling", + "securityContext" + ], + "additionalProperties": false, + "properties": { + "image": { + "type": "object", + "default": {}, + "title": "The image Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "v0.93.0" + ] + } + }, + "examples": [{ + "repository": "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator", + "tag": "v0.93.0" + }] + }, + "collectorImage": { + "type": "object", + "default": {}, + "title": "The collectorImage Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "otel/opentelemetry-collector-contrib" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "0.93.0" + ] + } + }, + "examples": [{ + "repository": "otel/opentelemetry-collector-contrib", + "tag": "0.93.0" + }] + }, + "opampBridgeImage": { + "type": "object", + "default": {}, + "title": "The opampBridgeImage Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "" + ] + } + }, + "examples": [{ + "repository": "", + "tag": "" + }] + }, + "targetAllocatorImage": { + "type": "object", + "default": {}, + "title": "The targetAllocatorImage Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "" + ] + } + }, + "examples": [{ + "repository": "", + "tag": "" + }] + }, + "autoInstrumentationImage": { + "type": "object", + "default": {}, + "title": "The autoInstrumentationImage Schema", + "required": [ + "java", + "nodejs", + "python", + "dotnet", + "go", + "apacheHttpd" + ], + "additionalProperties": false, + "properties": { + "java": { + "type": "object", + "default": {}, + "title": "The java Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "" + ] + } + }, + "examples": [{ + "repository": "", + "tag": "" + }] + }, + "nodejs": { + "type": "object", + "default": {}, + "title": "The nodejs Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "" + ] + } + }, + "examples": [{ + "repository": "", + "tag": "" + }] + }, + "python": { + "type": "object", + "default": {}, + "title": "The python Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "" + ] + } + }, + "examples": [{ + "repository": "", + "tag": "" + }] + }, + "dotnet": { + "type": "object", + "default": {}, + "title": "The dotnet Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "" + ] + } + }, + "examples": [{ + "repository": "", + "tag": "" + }] + }, + "go": { + "type": "object", + "default": {}, + "title": "The go Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "" + ] + } + }, + "examples": [{ + "repository": "", + "tag": "" + }] + }, + "apacheHttpd": { + "type": "object", + "default": {}, + "title": "The apache-httpd Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "" + ] + } + }, + "examples": [{ + "repository": "", + "tag": "" + }] + } + }, + "examples": [{ + "java": { + "repository": "", + "tag": "" + }, + "nodejs": { + "repository": "", + "tag": "" + }, + "python": { + "repository": "", + "tag": "" + }, + "dotnet": { + "repository": "", + "tag": "" + }, + "go": { + "repository": "", + "tag": "" + }, + "apacheHttpd": { + "repository": "", + "tag": "" + } + }] + }, + "featureGates": { + "type": "string", + "default": "", + "title": "The featureGates Schema", + "examples": [ + "" + ] + }, + "ports": { + "type": "object", + "default": {}, + "title": "The ports Schema", + "required": [ + "metricsPort", + "webhookPort", + "healthzPort" + ], + "additionalProperties": false, + "properties": { + "metricsPort": { + "type": "integer", + "default": 0, + "title": "The metricsPort Schema", + "examples": [ + 8080 + ] + }, + "webhookPort": { + "type": "integer", + "default": 0, + "title": "The webhookPort Schema", + "examples": [ + 9443 + ] + }, + "healthzPort": { + "type": "integer", + "default": 0, + "title": "The healthzPort Schema", + "examples": [ + 8081 + ] + } + }, + "examples": [{ + "metricsPort": 8080, + "webhookPort": 9443, + "healthzPort": 8081 + }] + }, + "resources": { + "type": "object", + "default": {}, + "title": "The resources Schema", + "required": [], + "additionalProperties": false, + "properties": { + "limits": { + "type": "object", + "default": {}, + "title": "The limits Schema", + "required": [], + "additionalProperties": true, + "properties": { + "cpu": { + "type": "string", + "default": "", + "title": "The cpu Schema", + "examples": [ + "100m" + ] + }, + "memory": { + "type": "string", + "default": "", + "title": "The memory Schema", + "examples": [ + "128Mi" + ] + }, + "ephemeral-storage": { + "type": "string", + "default": "", + "title": "The ephemeral-storage Schema", + "examples": [ + "50Mi" + ] + } + }, + "examples": [{ + "cpu": "100m", + "memory": "128Mi" + }] + }, + "requests": { + "type": "object", + "default": {}, + "title": "The requests Schema", + "required": [], + "additionalProperties": true, + "properties": { + "cpu": { + "type": "string", + "default": "", + "title": "The cpu Schema", + "examples": [ + "100m" + ] + }, + "memory": { + "type": "string", + "default": "", + "title": "The memory Schema", + "examples": [ + "64Mi" + ] + }, + "ephemeral-storage": { + "type": "string", + "default": "", + "title": "The ephemeral-storage Schema", + "examples": [ + "50Mi" + ] + } + }, + "examples": [{ + "cpu": "100m", + "memory": "64Mi" + }] + } + }, + "examples": [{ + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "64Mi" + } + }] + }, + "env": { + "type": "object", + "default": {}, + "title": "The env Schema", + "additionalProperties": { + "type": "string" + }, + "examples": [{ + "ENABLE_WEBHOOKS": "true" + }] + }, + "serviceAccount": { + "type": "object", + "default": {}, + "title": "The serviceAccount Schema", + "required": [ + "create", + "annotations" + ], + "additionalProperties": false, + "properties": { + "create": { + "type": "boolean", + "default": false, + "title": "The create Schema", + "examples": [ + true + ] + }, + "annotations": { + "type": "object", + "default": {}, + "title": "The annotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "name": { + "type": "string", + "default": "", + "title": "The name of the service account", + "examples": [ + "opentelemetry-operator" + ] + } + }, + "examples": [{ + "create": true, + "annotations": {} + }] + }, + "serviceMonitor": { + "type": "object", + "default": {}, + "title": "The serviceMonitor Schema", + "required": [ + "enabled", + "extraLabels", + "annotations", + "metricsEndpoints", + "relabelings", + "metricRelabelings" + ], + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + true + ] + }, + "extraLabels": { + "type": "object", + "default": {}, + "title": "The extraLabels Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "annotations": { + "type": "object", + "default": {}, + "title": "The annotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "metricsEndpoints": { + "type": "array", + "default": [], + "title": "The metricsEndpoints Schema", + "items": { + "type": "object", + "default": {}, + "title": "A Schema", + "required": [ + "port" + ], + "properties": { + "port": { + "type": "string", + "default": "", + "title": "The port Schema", + "examples": [ + "metrics" + ] + } + }, + "examples": [{ + "port": "metrics" + }] + }, + "examples": [ + [{ + "port": "metrics" + }] + ] + }, + "relabelings": { + "type": "array", + "description": "Specify general relabeling", + "default": [], + "items": {} + }, + "metricRelabelings": { + "type": "array", + "description": "Specify additional relabeling of metrics", + "default": [], + "items": {} + } + }, + "examples": [{ + "enabled": true, + "extraLabels": {}, + "annotations": {}, + "metricsEndpoints": [{ + "port": "metrics" + }], + "relabelings": [{ + "sourceLabels": [ + "__meta_kubernetes_pod_node_name" + ], + "targetLabel": "node", + "replacement": "${1}" + }], + "metricRelabelings": [] + }] + }, + "deploymentAnnotations": { + "type": "object", + "default": {}, + "title": "The deploymentAnnotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "serviceAnnotations": { + "type": "object", + "default": {}, + "title": "The serviceAnnotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "podAnnotations": { + "type": "object", + "default": {}, + "title": "The podAnnotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "podLabels": { + "type": "object", + "default": {}, + "title": "The podLabels Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "prometheusRule": { + "type": "object", + "default": {}, + "title": "The prometheusRule Schema", + "required": [ + "enabled", + "groups", + "defaultRules", + "extraLabels", + "annotations" + ], + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + false + ] + }, + "groups": { + "type": "array", + "default": [], + "title": "The groups Schema", + "items": {}, + "examples": [ + [] + ] + }, + "defaultRules": { + "type": "object", + "default": {}, + "title": "The defaultRules Schema", + "required": [ + "enabled", + "additionalRuleLabels", + "additionalRuleAnnotations" + ], + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + false + ] + }, + "additionalRuleLabels": { + "type": "object", + "default": {}, + "title": "The additionalRuleLabels Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "additionalRuleAnnotations": { + "type": "object", + "default": {}, + "title": "The additionalRuleAnnotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + } + }, + "examples": [{ + "enabled": false, + "additionalRuleLabels": {}, + "additionalRuleAnnotations": {} + }] + }, + "extraLabels": { + "type": "object", + "default": {}, + "title": "The extraLabels Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "annotations": { + "type": "object", + "default": {}, + "title": "The annotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "runbookUrl": { + "type": "string", + "default": "", + "title": "The runbookUrl Schema", + "required": [], + "properties": {}, + "examples": [{}] + } + }, + "examples": [{ + "enabled": false, + "groups": [], + "defaultRules": { + "enabled": false, + "additionalRuleLabels": {}, + "additionalRuleAnnotations": {} + }, + "extraLabels": {}, + "annotations": {} + }] + }, + "createRbacPermissions": { + "type": "boolean", + "default": false, + "title": "Whether the operator should create RBAC permissions for collector deployments", + "examples": [ + false + ] + }, + "extraArgs": { + "type": "array", + "default": [], + "title": "The extraArgs Schema", + "items": {}, + "examples": [ + [] + ] + }, + "leaderElection": { + "type": "object", + "default": {}, + "title": "The leaderElection Schema", + "required": [ + "enabled" + ], + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + true + ] + } + }, + "examples": [{ + "enabled": true + }] + }, + "verticalPodAutoscaler": { + "type": "object", + "default": {}, + "title": "The verticalPodAutoscaler Schema", + "required": [ + "enabled", + "controlledResources", + "maxAllowed", + "minAllowed", + "updatePolicy" + ], + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + false + ] + }, + "controlledResources": { + "type": "array", + "default": [], + "title": "The controlledResources Schema", + "items": {}, + "examples": [ + [] + ] + }, + "maxAllowed": { + "type": "object", + "default": {}, + "title": "The maxAllowed Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "minAllowed": { + "type": "object", + "default": {}, + "title": "The minAllowed Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "updatePolicy": { + "type": "object", + "default": {}, + "title": "The updatePolicy Schema", + "required": [ + "updateMode", + "minReplicas" + ], + "properties": { + "updateMode": { + "type": "string", + "default": "", + "title": "The updateMode Schema", + "examples": [ + "Auto" + ] + }, + "minReplicas": { + "type": "integer", + "default": 0, + "title": "The minReplicas Schema", + "examples": [ + 2 + ] + } + }, + "examples": [{ + "updateMode": "Auto", + "minReplicas": 2 + }] + } + }, + "examples": [{ + "enabled": false, + "controlledResources": [], + "maxAllowed": {}, + "minAllowed": {}, + "updatePolicy": { + "updateMode": "Auto", + "minReplicas": 2 + } + }] + }, + "rolling": { + "type": "boolean", + "default": false, + "title": "The rolling Schema", + "examples": [ + false + ] + }, + "securityContext": { + "type": "object", + "default": {}, + "title": "The securityContext Schema", + "required": [], + "properties": {}, + "examples": [{}] + } + }, + "examples": [{ + "image": { + "repository": "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator", + "tag": "v0.93.0" + }, + "collectorImage": { + "repository": "otel/opentelemetry-collector-contrib", + "tag": "0.93.0" + }, + "opampBridgeImage": { + "repository": "", + "tag": "" + }, + "targetAllocatorImage": { + "repository": "", + "tag": "" + }, + "autoInstrumentationImage": { + "java": { + "repository": "", + "tag": "" + }, + "nodejs": { + "repository": "", + "tag": "" + }, + "python": { + "repository": "", + "tag": "" + }, + "dotnet": { + "repository": "", + "tag": "" + }, + "go": { + "repository": "", + "tag": "" + }, + "apacheHttpd": { + "repository": "", + "tag": "" + } + }, + "featureGates": "", + "ports": { + "metricsPort": 8080, + "webhookPort": 9443, + "healthzPort": 8081 + }, + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "64Mi" + } + }, + "env": { + "ENABLE_WEBHOOKS": "true" + }, + "serviceAccount": { + "create": true, + "annotations": {} + }, + "serviceMonitor": { + "enabled": false, + "extraLabels": {}, + "annotations": {}, + "metricsEndpoints": [{ + "port": "metrics" + }] + }, + "podAnnotations": {}, + "podLabels": {}, + "prometheusRule": { + "enabled": false, + "groups": [], + "defaultRules": { + "enabled": false, + "additionalRuleLabels": {}, + "additionalRuleAnnotations": {} + }, + "extraLabels": {}, + "annotations": {} + }, + "extraArgs": [], + "leaderElection": { + "enabled": true + }, + "verticalPodAutoscaler": { + "enabled": false, + "controlledResources": [], + "maxAllowed": {}, + "minAllowed": {}, + "updatePolicy": { + "updateMode": "Auto", + "minReplicas": 2 + } + }, + "rolling": false, + "securityContext": {} + }] + }, + "kubeRBACProxy": { + "type": "object", + "default": {}, + "title": "The kubeRBACProxy Schema", + "required": [ + "enabled", + "image", + "ports", + "extraArgs", + "securityContext" + ], + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + true + ] + }, + "image": { + "type": "object", + "default": {}, + "title": "The image Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "quay.io/brancz/kube-rbac-proxy" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "v0.15.0" + ] + } + }, + "examples": [{ + "repository": "quay.io/brancz/kube-rbac-proxy", + "tag": "v0.15.0" + }] + }, + "ports": { + "type": "object", + "default": {}, + "title": "The ports Schema", + "required": [ + "proxyPort" + ], + "additionalProperties": false, + "properties": { + "proxyPort": { + "type": "integer", + "default": 0, + "title": "The proxyPort Schema", + "examples": [ + 8443 + ] + } + }, + "examples": [{ + "proxyPort": 8443 + }] + }, + "resources": { + "type": "object", + "default": {}, + "title": "The resources Schema", + "required": [], + "additionalProperties": false, + "properties": { + "limits": { + "type": "object", + "default": {}, + "title": "The limits Schema", + "required": [], + "additionalProperties": true, + "properties": { + "cpu": { + "type": "string", + "default": "", + "title": "The cpu Schema", + "examples": [ + "500m" + ] + }, + "memory": { + "type": "string", + "default": "", + "title": "The memory Schema", + "examples": [ + "128Mi" + ] + } + }, + "examples": [{ + "cpu": "500m", + "memory": "128Mi" + }] + }, + "requests": { + "type": "object", + "default": {}, + "title": "The requests Schema", + "required": [], + "additionalProperties": true, + "properties": { + "cpu": { + "type": "string", + "default": "", + "title": "The cpu Schema", + "examples": [ + "5m" + ] + }, + "memory": { + "type": "string", + "default": "", + "title": "The memory Schema", + "examples": [ + "64Mi" + ] + } + }, + "examples": [{ + "cpu": "5m", + "memory": "64Mi" + }] + } + }, + "examples": [{ + "limits": { + "cpu": "500m", + "memory": "128Mi" + }, + "requests": { + "cpu": "5m", + "memory": "64Mi" + } + }] + }, + "extraArgs": { + "type": "array", + "default": [], + "title": "The extraArgs Schema", + "items": {}, + "examples": [ + [] + ] + }, + "securityContext": { + "type": "object", + "default": {}, + "title": "The securityContext Schema", + "required": [], + "properties": {}, + "examples": [{}] + } + }, + "examples": [{ + "enabled": true, + "image": { + "repository": "quay.io/brancz/kube-rbac-proxy", + "tag": "v0.15.0" + }, + "ports": { + "proxyPort": 8443 + }, + "resources": { + "limits": { + "cpu": "500m", + "memory": "128Mi" + }, + "requests": { + "cpu": "5m", + "memory": "64Mi" + } + }, + "extraArgs": [], + "securityContext": {} + }] + }, + "admissionWebhooks": { + "type": "object", + "default": {}, + "title": "The admissionWebhooks Schema", + "required": [ + "create", + "failurePolicy", + "secretName", + "pods", + "namePrefix", + "timeoutSeconds", + "namespaceSelector", + "objectSelector", + "certManager", + "autoGenerateCert", + "certFile", + "keyFile", + "caFile", + "serviceAnnotations", + "secretAnnotations", + "secretLabels" + ], + "additionalProperties": false, + "properties": { + "create": { + "type": "boolean", + "default": false, + "title": "The create Schema", + "examples": [ + true + ] + }, + "servicePort": { + "type": "integer", + "default": 443, + "title": "The port for the webhook service", + "examples": [ + 9443 + ] + }, + "failurePolicy": { + "type": "string", + "default": "", + "title": "The failurePolicy Schema", + "examples": [ + "Fail" + ] + }, + "secretName": { + "type": "string", + "default": "", + "title": "The secretName Schema", + "examples": [ + "" + ] + }, + "pods": { + "type": "object", + "default": {}, + "title": "The pods Schema", + "required": [ + "failurePolicy" + ], + "additionalProperties": false, + "properties": { + "failurePolicy": { + "type": "string", + "default": "", + "title": "The failurePolicy Schema", + "examples": [ + "Ignore" + ] + } + }, + "examples": [{ + "failurePolicy": "Ignore" + }] + }, + "namePrefix": { + "type": "string", + "default": "", + "title": "The namePrefix Schema", + "examples": [ + "" + ] + }, + "timeoutSeconds": { + "type": "integer", + "default": 0, + "title": "The timeoutSeconds Schema", + "examples": [ + 10 + ] + }, + "namespaceSelector": { + "type": "object", + "default": {}, + "title": "The namespaceSelector Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "objectSelector": { + "type": "object", + "default": {}, + "title": "The objectSelector Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "certManager": { + "type": "object", + "default": {}, + "title": "The certManager Schema", + "required": [ + "enabled", + "issuerRef", + "certificateAnnotations", + "issuerAnnotations" + ], + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + true + ] + }, + "issuerRef": { + "type": "object", + "default": {}, + "title": "The issuerRef Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "certificateAnnotations": { + "type": "object", + "default": {}, + "title": "The certificateAnnotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "issuerAnnotations": { + "type": "object", + "default": {}, + "title": "The issuerAnnotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "duration": { + "type": "string", + "default": "", + "title": "The duration for the Certificate", + "required": [], + "examples": ["2160h"] + }, + "renewBefore": { + "type": "string", + "default": "", + "title": "The renewBefore time for the Certificate", + "required": [], + "examples": ["360h"] + } + }, + "examples": [{ + "enabled": true, + "issuerRef": {}, + "certificateAnnotations": {}, + "issuerAnnotations": {} + }] + }, + "autoGenerateCert": { + "type": "object", + "default": {}, + "title": "The autoGenerateCert Schema", + "required": [ + "enabled", + "recreate" + ], + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + true + ] + }, + "recreate": { + "type": "boolean", + "default": false, + "title": "The recreate Schema", + "examples": [ + true + ] + }, + "certPeriodDays": { + "type": "integer", + "default": 365, + "title": "Cert period time in days.", + "examples": [ + 365 + ] + } + }, + "examples": [{ + "enabled": true, + "recreate": true, + "certPeriodDays": 365 + }] + }, + "certFile": { + "type": "string", + "default": "", + "title": "File path to self-managed TLS certificate.", + "examples": [ + "" + ] + }, + "keyFile": { + "type": "string", + "default": "", + "title": "File path to self-managed TLS key.", + "examples": [ + "" + ] + }, + "caFile": { + "type": "string", + "default": "", + "title": "File path to self-managed CA bundle.", + "examples": [ + "" + ] + }, + "serviceAnnotations": { + "type": "object", + "default": {}, + "title": "The serviceAnnotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "secretAnnotations": { + "type": "object", + "default": {}, + "title": "The secretAnnotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "secretLabels": { + "type": "object", + "default": {}, + "title": "The secretLabels Schema", + "required": [], + "properties": {}, + "examples": [{}] + } + }, + "examples": [{ + "create": true, + "failurePolicy": "Fail", + "secretName": "", + "pods": { + "failurePolicy": "Ignore" + }, + "namePrefix": "", + "timeoutSeconds": 10, + "namespaceSelector": {}, + "objectSelector": {}, + "certManager": { + "enabled": true, + "issuerRef": {}, + "certificateAnnotations": {}, + "issuerAnnotations": {} + }, + "autoGenerateCert": { + "enabled": true, + "recreate": true + }, + "certFile": "", + "keyFile": "", + "caFile": "", + "secretAnnotations": {}, + "secretLabels": {} + }] + }, + "crds": { + "type": "object", + "default": {}, + "title": "The CRDs Schema", + "required": [ + "create" + ], + "additionalProperties": false, + "properties": { + "create": { + "type": "boolean", + "default": true, + "title": "Create CRDs", + "examples": [ + true + ] + } + }, + "examples": [{ + "create": true + }] + }, + "role": { + "type": "object", + "default": {}, + "title": "The role Schema", + "required": [ + "create" + ], + "additionalProperties": false, + "properties": { + "create": { + "type": "boolean", + "default": false, + "title": "The create Schema", + "examples": [ + true + ] + } + }, + "examples": [{ + "create": true + }] + }, + "clusterRole": { + "type": "object", + "default": {}, + "title": "The clusterRole Schema", + "required": [ + "create" + ], + "additionalProperties": false, + "properties": { + "create": { + "type": "boolean", + "default": false, + "title": "The create Schema", + "examples": [ + true + ] + } + }, + "examples": [{ + "create": true + }] + }, + "affinity": { + "type": "object", + "default": {}, + "title": "The affinity Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "tolerations": { + "type": "array", + "default": [], + "title": "The tolerations Schema", + "items": {}, + "examples": [ + [] + ] + }, + "nodeSelector": { + "type": "object", + "default": {}, + "title": "The nodeSelector Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "topologySpreadConstraints": { + "type": "array", + "default": [], + "title": "The topologySpreadConstraints Schema", + "items": {}, + "examples": [ + [] + ] + }, + "hostNetwork": { + "type": "boolean", + "default": false, + "title": "The hostNetwork Schema", + "examples": [ + false + ] + }, + "priorityClassName": { + "type": "string", + "default": "", + "title": "The priorityClassName Schema", + "examples": [ + "" + ] + }, + "securityContext": { + "type": "object", + "default": {}, + "title": "The securityContext Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "testFramework": { + "type": "object", + "default": {}, + "title": "The testFramework Schema", + "required": [ + "image" + ], + "additionalProperties": false, + "properties": { + "image": { + "type": "object", + "default": {}, + "title": "The image Schema", + "required": [ + "repository", + "tag" + ], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "busybox" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "latest" + ] + } + }, + "examples": [{ + "repository": "busybox", + "tag": "latest" + }] + } + }, + "examples": [{ + "image": { + "repository": "busybox", + "tag": "latest" + } + }] + }, + "additionalLabels": { + "type": "object", + "default": {}, + "title": "The additionalLabels Schema", + "required": [], + "properties": {}, + "examples": [{}] + } + }, + "examples": [{ + "replicaCount": 1, + "nameOverride": "", + "imagePullSecrets": [], + "pdb": { + "create": false, + "minAvailable": 1, + "maxUnavailable": "" + }, + "manager": { + "image": { + "repository": "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator", + "tag": "v0.93.0" + }, + "collectorImage": { + "repository": "otel/opentelemetry-collector-contrib", + "tag": "0.93.0" + }, + "opampBridgeImage": { + "repository": "", + "tag": "" + }, + "targetAllocatorImage": { + "repository": "", + "tag": "" + }, + "autoInstrumentationImage": { + "java": { + "repository": "", + "tag": "" + }, + "nodejs": { + "repository": "", + "tag": "" + }, + "python": { + "repository": "", + "tag": "" + }, + "dotnet": { + "repository": "", + "tag": "" + }, + "go": { + "repository": "", + "tag": "" + }, + "apacheHttpd": + { + "repository": "", + "tag": "" + } + }, + "featureGates": "", + "ports": { + "metricsPort": 8080, + "webhookPort": 9443, + "healthzPort": 8081 + }, + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "64Mi" + } + }, + "env": { + "ENABLE_WEBHOOKS": "true" + }, + "serviceAccount": { + "create": true, + "annotations": {} + }, + "serviceMonitor": { + "enabled": false, + "extraLabels": {}, + "annotations": {}, + "metricsEndpoints": [{ + "port": "metrics" + }] + }, + "podAnnotations": {}, + "podLabels": {}, + "prometheusRule": { + "enabled": false, + "groups": [], + "defaultRules": { + "enabled": false, + "additionalRuleLabels": {}, + "additionalRuleAnnotations": {} + }, + "extraLabels": {}, + "annotations": {} + }, + "extraArgs": [], + "leaderElection": { + "enabled": true + }, + "verticalPodAutoscaler": { + "enabled": false, + "controlledResources": [], + "maxAllowed": {}, + "minAllowed": {}, + "updatePolicy": { + "updateMode": "Auto", + "minReplicas": 2 + } + }, + "rolling": false, + "securityContext": {} + }, + "kubeRBACProxy": { + "enabled": true, + "image": { + "repository": "quay.io/brancz/kube-rbac-proxy", + "tag": "v0.15.0" + }, + "ports": { + "proxyPort": 8443 + }, + "resources": { + "limits": { + "cpu": "500m", + "memory": "128Mi" + }, + "requests": { + "cpu": "5m", + "memory": "64Mi" + } + }, + "extraArgs": [], + "securityContext": {} + }, + "admissionWebhooks": { + "create": true, + "failurePolicy": "Fail", + "secretName": "", + "pods": { + "failurePolicy": "Ignore" + }, + "namePrefix": "", + "timeoutSeconds": 10, + "namespaceSelector": {}, + "objectSelector": {}, + "certManager": { + "enabled": true, + "issuerRef": {}, + "certificateAnnotations": {}, + "issuerAnnotations": {} + }, + "autoGenerateCert": { + "enabled": true, + "recreate": true + }, + "certFile": "", + "keyFile": "", + "caFile": "", + "secretAnnotations": {}, + "secretLabels": {} + }, + "role": { + "create": true + }, + "clusterRole": { + "create": true + }, + "affinity": {}, + "tolerations": [], + "nodeSelector": {}, + "topologySpreadConstraints": [], + "hostNetwork": false, + "priorityClassName": "", + "securityContext": { + "runAsGroup": 65532, + "runAsNonRoot": true, + "runAsUser": 65532, + "fsGroup": 65532 + }, + "testFramework": { + "image": { + "repository": "busybox", + "tag": "latest" + } + } + }] +} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/values.yaml new file mode 100644 index 00000000000..124f2646720 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/opentelemetry-operator/values.yaml @@ -0,0 +1,329 @@ +# Default values for opentelemetry-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +## Provide a name in place of opentelemetry-operator (includes the chart's release name). +## +nameOverride: "" + +## Fully override the name (excludes the chart's release name). +## +fullnameOverride: "" + +## Reference one or more secrets to be used when pulling images from authenticated repositories. +imagePullSecrets: [] + +## Kubernetes cluster domain suffix +clusterDomain: cluster.local + +# Common labels to add to all otel-operator resources. Evaluated as a template. +additionalLabels: {} + +## Pod Disruption Budget configuration +## +pdb: + ## Enable/disable a Pod Disruption Budget creation + ## + create: false + ## Minimum number/percentage of pods that should remain scheduled + ## + minAvailable: 1 + ## Maximum number/percentage of pods that may be made unavailable + ## + maxUnavailable: "" + +## Provide OpenTelemetry Operator manager container image and resources. +## +manager: + image: + repository: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator + tag: "" + collectorImage: + repository: "" + tag: 0.110.0 + opampBridgeImage: + repository: "" + tag: "" + targetAllocatorImage: + repository: "" + tag: "" + autoInstrumentationImage: + java: + repository: "" + tag: "" + nodejs: + repository: "" + tag: "" + python: + repository: "" + tag: "" + dotnet: + repository: "" + tag: "" + apacheHttpd: + repository: "" + tag: "" + # The Go instrumentation support in the operator is disabled by default. + # To enable it, use the operator.autoinstrumentation.go feature gate. + go: + repository: "" + tag: "" + # Feature Gates are a comma-delimited list of feature gate identifiers. + # Prefix a gate with '-' to disable support. + # Prefixing a gate with '+' or no prefix will enable support. + # A full list of valid identifiers can be found here: https://github.com/open-telemetry/opentelemetry-operator/blob/main/pkg/featuregate/featuregate.go + featureGates: "" + ports: + metricsPort: 8080 + webhookPort: 9443 + healthzPort: 8081 + resources: + limits: + cpu: 100m + memory: 128Mi + # ephemeral-storage: 50Mi + requests: + cpu: 100m + memory: 64Mi + # ephemeral-storage: 50Mi + ## Adds additional environment variables + ## e.g ENV_VAR: env_value + env: + ENABLE_WEBHOOKS: "true" + + # -- Create the manager ServiceAccount + serviceAccount: + create: true + annotations: {} + ## Override the default name of the serviceaccount (the name of your installation) + name: "" + + ## Enable ServiceMonitor for Prometheus metrics scrape + serviceMonitor: + enabled: false + # additional labels on the ServiceMonitor + extraLabels: {} + # add annotations on the ServiceMonitor + annotations: {} + metricsEndpoints: + - port: metrics + # Used to set relabeling and metricRelabeling configs on the ServiceMonitor + # https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + relabelings: [] + metricRelabelings: [] + + # Adds additional annotations to the manager Deployment + deploymentAnnotations: {} + # Adds additional annotations to the manager Service + serviceAnnotations: {} + + podAnnotations: {} + podLabels: {} + + prometheusRule: + enabled: false + groups: [] + # Create default rules for monitoring the manager + defaultRules: + enabled: false + ## Additional labels for PrometheusRule alerts + additionalRuleLabels: {} + ## Additional annotations for PrometheusRule alerts + additionalRuleAnnotations: {} + # additional labels on the PrometheusRule object + extraLabels: {} + # add annotations on the PrometheusRule object + annotations: {} + # change the default runbook urls. + # the alert name will get appended at the end of the url as an anchor. + runbookUrl: "" + + # Whether the operator should create RBAC permissions for collectors. See README.md for more information. + createRbacPermissions: false + ## List of additional cli arguments to configure the manager + ## for example: --labels, etc. + extraArgs: [] + + ## Enable leader election mechanism for protecting against split brain if multiple operator pods/replicas are started. + ## See more at https://docs.openshift.com/container-platform/4.10/operators/operator_sdk/osdk-leader-election.html + leaderElection: + enabled: true + + # Enable vertical pod autoscaler support for the manager + verticalPodAutoscaler: + enabled: false + # List of resources that the vertical pod autoscaler can control. Defaults to cpu, memory and ephemeral-storage. + controlledResources: [] + + # Define the max allowed resources for the pod + maxAllowed: {} + # cpu: 200m + # memory: 100Mi + # ephemeral-storage: 50Mi + # Define the min allowed resources for the pod + minAllowed: {} + # cpu: 200m + # memory: 100Mi + # ephemeral-storage: 50Mi + + updatePolicy: + # Specifies whether recommended updates are applied when a Pod is started and whether recommended updates + # are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto". + updateMode: Auto + # Minimal number of replicas which need to be alive for Updater to attempt pod eviction. + # Only positive values are allowed. The default is 2. + minReplicas: 2 + # Enable manager pod automatically rolling + rolling: false + + ## Container specific securityContext + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + securityContext: {} + # allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + +## Provide OpenTelemetry Operator kube-rbac-proxy container image. +## +kubeRBACProxy: + enabled: true + image: + repository: quay.io/brancz/kube-rbac-proxy + tag: v0.15.0 + ports: + proxyPort: 8443 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + + ## List of additional cli arguments to configure the kube-rbac-proxy + ## for example: --tls-cipher-suites, --tls-min-version, etc. + extraArgs: [] + + ## Container specific securityContext + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + securityContext: {} + # allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + +## Admission webhooks make sure only requests with correctly formatted rules will get into the Operator. +## They also enable the sidecar injection for OpenTelemetryCollector and Instrumentation CR's +admissionWebhooks: + create: true + servicePort: 443 + failurePolicy: Fail + secretName: "" + + ## Defines the sidecar injection logic in Pods. + ## - Ignore, the injection is fail-open. The pod will be created, but the sidecar won't be injected. + ## - Fail, the injection is fail-close. If the webhook pod is not ready, pods cannot be created. + pods: + failurePolicy: Ignore + + ## Adds a prefix to the mutating webhook name. + ## This can be used to order this mutating webhook with all your cluster's mutating webhooks. + namePrefix: "" + + ## Customize webhook timeout duration + timeoutSeconds: 10 + + ## Provide selectors for your objects + namespaceSelector: {} + objectSelector: {} + + ## https://github.com/open-telemetry/opentelemetry-helm-charts/blob/main/charts/opentelemetry-operator/README.md#tls-certificate-requirement + ## TLS Certificate Option 1: Use certManager to generate self-signed certificate. + ## certManager must be enabled. If enabled, always takes precedence over options 2 and 3. + certManager: + enabled: true + ## Provide the issuer kind and name to do the cert auth job. + ## By default, OpenTelemetry Operator will use self-signer issuer. + issuerRef: {} + # kind: + # name: + ## Annotations for the cert and issuer if cert-manager is enabled. + certificateAnnotations: {} + issuerAnnotations: {} + # duration must be specified by a Go time.Duration (ending in s, m or h) + duration: "" + # renewBefore must be specified by a Go time.Duration (ending in s, m or h) + # Take care when setting the renewBefore field to be very close to the duration + # as this can lead to a renewal loop, where the Certificate is always in the renewal period. + renewBefore: "" + + ## TLS Certificate Option 2: Use Helm to automatically generate self-signed certificate. + ## certManager must be disabled and autoGenerateCert must be enabled. + ## If true and certManager.enabled is false, Helm will automatically create a self-signed cert and secret for you. + autoGenerateCert: + enabled: true + # If set to true, new webhook key/certificate is generated on helm upgrade. + recreate: true + # Cert period time in days. The default is 365 days. + certPeriodDays: 365 + + ## TLS Certificate Option 3: Use your own self-signed certificate. + ## certManager and autoGenerateCert must be disabled and certFile, keyFile, and caFile must be set. + ## The chart reads the contents of the file paths with the helm .Files.Get function. + ## Refer to this doc https://helm.sh/docs/chart_template_guide/accessing_files/ to understand + ## limitations of file paths accessible to the chart. + ## Path to your own PEM-encoded certificate. + certFile: "" + ## Path to your own PEM-encoded private key. + keyFile: "" + ## Path to the CA cert. + caFile: "" + + # Adds additional annotations to the admissionWebhook Service + serviceAnnotations: {} + + ## Secret annotations + secretAnnotations: {} + ## Secret labels + secretLabels: {} + +## Install CRDS with the right webhook settings +## These are installed as templates, so they will clash with existing OpenTelemetry Operator CRDs in your cluster that are not already managed by the helm chart. +## See https://github.com/open-telemetry/opentelemetry-helm-charts/blob/main/charts/opentelemetry-operator/UPGRADING.md#0560-to-0570 for more details. +crds: + create: true + +## Create the provided Roles and RoleBindings +## +role: + create: true + +## Create the provided ClusterRoles and ClusterRoleBindings +## +clusterRole: + create: true + +affinity: {} +tolerations: [] +nodeSelector: {} +topologySpreadConstraints: [] +hostNetwork: false + +# Allows for pod scheduler prioritisation +priorityClassName: "" + +## SecurityContext holds pod-level security attributes and common container settings. +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: + runAsGroup: 65532 + runAsNonRoot: true + runAsUser: 65532 + fsGroup: 65532 + +testFramework: + image: + repository: busybox + tag: latest diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/.helmignore b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/.helmignore new file mode 100644 index 00000000000..f0c13194444 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/Chart.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/Chart.yaml new file mode 100644 index 00000000000..1f725b51e49 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/Chart.yaml @@ -0,0 +1,25 @@ +annotations: + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Chart Source + url: https://github.com/prometheus-community/helm-charts +apiVersion: v2 +appVersion: 1.8.2 +description: A Helm chart for prometheus node-exporter +home: https://github.com/prometheus/node_exporter/ +keywords: +- node-exporter +- prometheus +- exporter +maintainers: +- email: gianrubio@gmail.com + name: gianrubio +- email: zanhsieh@gmail.com + name: zanhsieh +- email: rootsandtrees@posteo.de + name: zeritti +name: prometheus-node-exporter +sources: +- https://github.com/prometheus/node_exporter/ +type: application +version: 4.37.3 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/README.md b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/README.md new file mode 100644 index 00000000000..ef838441024 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/README.md @@ -0,0 +1,96 @@ +# Prometheus Node Exporter + +Prometheus exporter for hardware and OS metrics exposed by *NIX kernels, written in Go with pluggable metric collectors. + +This chart bootstraps a Prometheus [Node Exporter](http://github.com/prometheus/node_exporter) daemonset on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Get Repository Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +```console +helm install [RELEASE_NAME] prometheus-community/prometheus-node-exporter +``` + +_See [configuration](#configuring) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] prometheus-community/prometheus-node-exporter --install +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### 3.x to 4.x + +Starting from version 4.0.0, the `node exporter` chart is using the [Kubernetes recommended labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/). Therefore you have to delete the daemonset before you upgrade. + +```console +kubectl delete daemonset -l app=prometheus-node-exporter +helm upgrade -i prometheus-node-exporter prometheus-community/prometheus-node-exporter +``` + +If you use your own custom [ServiceMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor) or [PodMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#podmonitor), please ensure to upgrade their `selector` fields accordingly to the new labels. + +### From 2.x to 3.x + +Change the following: + +```yaml +hostRootFsMount: true +``` + +to: + +```yaml +hostRootFsMount: + enabled: true + mountPropagation: HostToContainer +``` + +## Configuring + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +helm show values prometheus-community/prometheus-node-exporter +``` + +### kube-rbac-proxy + +You can enable `prometheus-node-exporter` endpoint protection using `kube-rbac-proxy`. By setting `kubeRBACProxy.enabled: true`, this chart will deploy a RBAC proxy container protecting the node-exporter endpoint. +To authorize access, authenticate your requests (via a `ServiceAccount` for example) with a `ClusterRole` attached such as: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: prometheus-node-exporter-read +rules: + - apiGroups: [ "" ] + resources: ["services/node-exporter-prometheus-node-exporter"] + verbs: + - get +``` + +See [kube-rbac-proxy examples](https://github.com/brancz/kube-rbac-proxy/tree/master/examples/resource-attributes) for more details. diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/ci/port-values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/ci/port-values.yaml new file mode 100644 index 00000000000..dbfb4b67ff6 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/ci/port-values.yaml @@ -0,0 +1,3 @@ +service: + targetPort: 9102 + port: 9102 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/NOTES.txt b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/NOTES.txt new file mode 100644 index 00000000000..db8584def8c --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/NOTES.txt @@ -0,0 +1,29 @@ +1. Get the application URL by running these commands: +{{- if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ template "prometheus-node-exporter.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus-node-exporter.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ template "prometheus-node-exporter.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ template "prometheus-node-exporter.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ template "prometheus-node-exporter.namespace" . }} {{ template "prometheus-node-exporter.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ template "prometheus-node-exporter.namespace" . }} -l "app.kubernetes.io/name={{ template "prometheus-node-exporter.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:9100 to use your application" + kubectl port-forward --namespace {{ template "prometheus-node-exporter.namespace" . }} $POD_NAME 9100 +{{- end }} + +{{- if .Values.kubeRBACProxy.enabled}} + +kube-rbac-proxy endpoint protections is enabled: +- Metrics endpoints is now HTTPS +- Ensure that the client authenticates the requests (e.g. via service account) with the following role permissions: +``` +rules: + - apiGroups: [ "" ] + resources: ["services/{{ template "prometheus-node-exporter.fullname" . }}"] + verbs: + - get +``` +{{- end }} \ No newline at end of file diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/_helpers.tpl b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/_helpers.tpl new file mode 100644 index 00000000000..8e84832cbf7 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/_helpers.tpl @@ -0,0 +1,202 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "prometheus-node-exporter.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "prometheus-node-exporter.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "prometheus-node-exporter.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "prometheus-node-exporter.labels" -}} +helm.sh/chart: {{ include "prometheus-node-exporter.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: metrics +app.kubernetes.io/part-of: {{ include "prometheus-node-exporter.name" . }} +{{ include "prometheus-node-exporter.selectorLabels" . }} +{{- with .Chart.AppVersion }} +app.kubernetes.io/version: {{ . | quote }} +{{- end }} +{{- with .Values.podLabels }} +{{ toYaml . }} +{{- end }} +{{- if .Values.releaseLabel }} +release: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "prometheus-node-exporter.selectorLabels" -}} +app.kubernetes.io/name: {{ include "prometheus-node-exporter.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "prometheus-node-exporter.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "prometheus-node-exporter.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +The image to use +*/}} +{{- define "prometheus-node-exporter.image" -}} +{{- if .Values.image.sha }} +{{- fail "image.sha forbidden. Use image.digest instead" }} +{{- else if .Values.image.digest }} +{{- if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s@%s" .Values.global.imageRegistry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.digest }} +{{- else }} +{{- printf "%s/%s:%s@%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.digest }} +{{- end }} +{{- else }} +{{- if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s" .Values.global.imageRegistry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- else }} +{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "prometheus-node-exporter.namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Create the namespace name of the service monitor +*/}} +{{- define "prometheus-node-exporter.monitor-namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- if .Values.prometheus.monitor.namespace }} +{{- .Values.prometheus.monitor.namespace }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Sets default scrape limits for servicemonitor */}} +{{- define "servicemonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end }} + +{{/* +Formats imagePullSecrets. Input is (dict "Values" .Values "imagePullSecrets" .{specific imagePullSecrets}) +*/}} +{{- define "prometheus-node-exporter.imagePullSecrets" -}} +{{- range (concat .Values.global.imagePullSecrets .imagePullSecrets) }} + {{- if eq (typeOf .) "map[string]interface {}" }} +- {{ toYaml . | trim }} + {{- else }} +- name: {{ . }} + {{- end }} +{{- end }} +{{- end -}} + +{{/* +Create the namespace name of the pod monitor +*/}} +{{- define "prometheus-node-exporter.podmonitor-namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- if .Values.prometheus.podMonitor.namespace }} +{{- .Values.prometheus.podMonitor.namespace }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Sets default scrape limits for podmonitor */}} +{{- define "podmonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end }} + +{{/* Sets sidecar volumeMounts */}} +{{- define "prometheus-node-exporter.sidecarVolumeMounts" -}} +{{- range $_, $mount := $.Values.sidecarVolumeMount }} +- name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: {{ $mount.readOnly }} +{{- end }} +{{- range $_, $mount := $.Values.sidecarHostVolumeMounts }} +- name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: {{ $mount.readOnly }} +{{- if $mount.mountPropagation }} + mountPropagation: {{ $mount.mountPropagation }} +{{- end }} +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/clusterrole.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/clusterrole.yaml new file mode 100644 index 00000000000..c256dba73db --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/clusterrole.yaml @@ -0,0 +1,19 @@ +{{- if and (eq .Values.rbac.create true) (eq .Values.kubeRBACProxy.enabled true) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +rules: + {{- if $.Values.kubeRBACProxy.enabled }} + - apiGroups: [ "authentication.k8s.io" ] + resources: + - tokenreviews + verbs: [ "create" ] + - apiGroups: [ "authorization.k8s.io" ] + resources: + - subjectaccessreviews + verbs: [ "create" ] + {{- end }} +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml new file mode 100644 index 00000000000..653305ad9e7 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and (eq .Values.rbac.create true) (eq .Values.kubeRBACProxy.enabled true) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + name: {{ template "prometheus-node-exporter.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole +{{- if .Values.rbac.useExistingRole }} + name: {{ .Values.rbac.useExistingRole }} +{{- else }} + name: {{ template "prometheus-node-exporter.fullname" . }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "prometheus-node-exporter.serviceAccountName" . }} + namespace: {{ template "prometheus-node-exporter.namespace" . }} +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/daemonset.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/daemonset.yaml new file mode 100644 index 00000000000..e1edb7b7000 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/daemonset.yaml @@ -0,0 +1,312 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + {{- with .Values.daemonsetAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- with .Values.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 8 }} + spec: + automountServiceAccountToken: {{ ternary true false (or .Values.serviceAccount.automountServiceAccountToken .Values.kubeRBACProxy.enabled) }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.extraInitContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "prometheus-node-exporter.serviceAccountName" . }} + {{- with .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ . }} + {{- end }} + containers: + {{- $servicePort := ternary .Values.kubeRBACProxy.port .Values.service.port .Values.kubeRBACProxy.enabled }} + - name: node-exporter + image: {{ include "prometheus-node-exporter.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - --path.procfs=/host/proc + - --path.sysfs=/host/sys + {{- if .Values.hostRootFsMount.enabled }} + - --path.rootfs=/host/root + {{- if semverCompare ">=1.4.0-0" (coalesce .Values.version .Values.image.tag .Chart.AppVersion) }} + - --path.udev.data=/host/root/run/udev/data + {{- end }} + {{- end }} + - --web.listen-address=[$(HOST_IP)]:{{ $servicePort }} + {{- with .Values.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: HOST_IP + {{- if .Values.kubeRBACProxy.enabled }} + value: 127.0.0.1 + {{- else if .Values.service.listenOnAllInterfaces }} + value: 0.0.0.0 + {{- else }} + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.hostIP + {{- end }} + {{- range $key, $value := .Values.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- if eq .Values.kubeRBACProxy.enabled false }} + ports: + - name: {{ .Values.service.portName }} + containerPort: {{ .Values.service.port }} + protocol: TCP + {{- end }} + livenessProbe: + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + httpGet: + {{- if .Values.kubeRBACProxy.enabled }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.livenessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: / + port: {{ $servicePort }} + scheme: {{ upper .Values.livenessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + readinessProbe: + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + httpGet: + {{- if .Values.kubeRBACProxy.enabled }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.readinessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: / + port: {{ $servicePort }} + scheme: {{ upper .Values.readinessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.terminationMessageParams.enabled }} + {{- with .Values.terminationMessageParams }} + terminationMessagePath: {{ .terminationMessagePath }} + terminationMessagePolicy: {{ .terminationMessagePolicy }} + {{- end }} + {{- end }} + volumeMounts: + - name: proc + mountPath: /host/proc + {{- with .Values.hostProcFsMount.mountPropagation }} + mountPropagation: {{ . }} + {{- end }} + readOnly: true + - name: sys + mountPath: /host/sys + {{- with .Values.hostSysFsMount.mountPropagation }} + mountPropagation: {{ . }} + {{- end }} + readOnly: true + {{- if .Values.hostRootFsMount.enabled }} + - name: root + mountPath: /host/root + {{- with .Values.hostRootFsMount.mountPropagation }} + mountPropagation: {{ . }} + {{- end }} + readOnly: true + {{- end }} + {{- range $_, $mount := .Values.extraHostVolumeMounts }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: {{ $mount.readOnly }} + {{- with $mount.mountPropagation }} + mountPropagation: {{ . }} + {{- end }} + {{- end }} + {{- range $_, $mount := .Values.sidecarVolumeMount }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: true + {{- end }} + {{- range $_, $mount := .Values.configmaps }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + {{- end }} + {{- range $_, $mount := .Values.secrets }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + {{- end }} + {{- range .Values.sidecars }} + {{- $overwrites := dict "volumeMounts" (concat (include "prometheus-node-exporter.sidecarVolumeMounts" $ | fromYamlArray) (.volumeMounts | default list) | default list) }} + {{- $defaults := dict "image" (include "prometheus-node-exporter.image" $) "securityContext" $.Values.containerSecurityContext "imagePullPolicy" $.Values.image.pullPolicy }} + - {{- toYaml (merge $overwrites . $defaults) | nindent 10 }} + {{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - name: kube-rbac-proxy + args: + {{- if .Values.kubeRBACProxy.extraArgs }} + {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 12 }} + {{- end }} + - --secure-listen-address=:{{ .Values.service.port}} + - --upstream=http://127.0.0.1:{{ $servicePort }}/ + - --proxy-endpoints-port={{ .Values.kubeRBACProxy.proxyEndpointsPort }} + - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml + volumeMounts: + - name: kube-rbac-proxy-config + mountPath: /etc/kube-rbac-proxy-config + imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} + {{- if .Values.kubeRBACProxy.image.sha }} + image: "{{ .Values.global.imageRegistry | default .Values.kubeRBACProxy.image.registry}}/{{ .Values.kubeRBACProxy.image.repository }}:{{ .Values.kubeRBACProxy.image.tag }}@sha256:{{ .Values.kubeRBACProxy.image.sha }}" + {{- else }} + image: "{{ .Values.global.imageRegistry | default .Values.kubeRBACProxy.image.registry}}/{{ .Values.kubeRBACProxy.image.repository }}:{{ .Values.kubeRBACProxy.image.tag }}" + {{- end }} + ports: + - containerPort: {{ .Values.service.port}} + name: {{ .Values.kubeRBACProxy.portName }} + {{- if .Values.kubeRBACProxy.enableHostPort }} + hostPort: {{ .Values.service.port }} + {{- end }} + - containerPort: {{ .Values.kubeRBACProxy.proxyEndpointsPort }} + {{- if .Values.kubeRBACProxy.enableProxyEndpointsHostPort }} + hostPort: {{ .Values.kubeRBACProxy.proxyEndpointsPort }} + {{- end }} + name: "http-healthz" + readinessProbe: + httpGet: + scheme: HTTPS + port: {{ .Values.kubeRBACProxy.proxyEndpointsPort }} + path: healthz + initialDelaySeconds: 5 + timeoutSeconds: 5 + {{- if .Values.kubeRBACProxy.resources }} + resources: + {{- toYaml .Values.kubeRBACProxy.resources | nindent 12 }} + {{- end }} + {{- if .Values.terminationMessageParams.enabled }} + {{- with .Values.terminationMessageParams }} + terminationMessagePath: {{ .terminationMessagePath }} + terminationMessagePolicy: {{ .terminationMessagePolicy }} + {{- end }} + {{- end }} + {{- with .Values.kubeRBACProxy.env }} + env: + {{- range $key, $value := $.Values.kubeRBACProxy.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.kubeRBACProxy.containerSecurityContext }} + securityContext: + {{ toYaml .Values.kubeRBACProxy.containerSecurityContext | nindent 12 }} + {{- end }} + {{- end }} + {{- if or .Values.imagePullSecrets .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- include "prometheus-node-exporter.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.imagePullSecrets) | indent 8 }} + {{- end }} + hostNetwork: {{ .Values.hostNetwork }} + hostPID: {{ .Values.hostPID }} + hostIPC: {{ .Values.hostIPC }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.restartPolicy }} + restartPolicy: {{ . }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: proc + hostPath: + path: /proc + - name: sys + hostPath: + path: /sys + {{- if .Values.hostRootFsMount.enabled }} + - name: root + hostPath: + path: / + {{- end }} + {{- range $_, $mount := .Values.extraHostVolumeMounts }} + - name: {{ $mount.name }} + hostPath: + path: {{ $mount.hostPath }} + {{- with $mount.type }} + type: {{ . }} + {{- end }} + {{- end }} + {{- range $_, $mount := .Values.sidecarVolumeMount }} + - name: {{ $mount.name }} + emptyDir: + medium: Memory + {{- end }} + {{- range $_, $mount := .Values.sidecarHostVolumeMounts }} + - name: {{ $mount.name }} + hostPath: + path: {{ $mount.hostPath }} + {{- end }} + {{- range $_, $mount := .Values.configmaps }} + - name: {{ $mount.name }} + configMap: + name: {{ $mount.name }} + {{- end }} + {{- range $_, $mount := .Values.secrets }} + - name: {{ $mount.name }} + secret: + secretName: {{ $mount.name }} + {{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - name: kube-rbac-proxy-config + configMap: + name: {{ template "prometheus-node-exporter.fullname" . }}-rbac-config + {{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/endpoints.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/endpoints.yaml new file mode 100644 index 00000000000..45eeb8d9668 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/endpoints.yaml @@ -0,0 +1,18 @@ +{{- if .Values.endpoints }} +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +subsets: + - addresses: + {{- range .Values.endpoints }} + - ip: {{ . }} + {{- end }} + ports: + - name: {{ .Values.service.portName }} + port: 9100 + protocol: TCP +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/extra-manifests.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/extra-manifests.yaml new file mode 100644 index 00000000000..2b21b710621 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraManifests }} +--- +{{ tpl . $ }} +{{ end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/networkpolicy.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/networkpolicy.yaml new file mode 100644 index 00000000000..825722729d3 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/networkpolicy.yaml @@ -0,0 +1,23 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" $ | nindent 4 }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ingress: + - ports: + - port: {{ .Values.service.port }} + policyTypes: + - Egress + - Ingress + podSelector: + matchLabels: + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/podmonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/podmonitor.yaml new file mode 100644 index 00000000000..f88da6a34e6 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/podmonitor.yaml @@ -0,0 +1,91 @@ +{{- if .Values.prometheus.podMonitor.enabled }} +apiVersion: {{ .Values.prometheus.podMonitor.apiVersion | default "monitoring.coreos.com/v1" }} +kind: PodMonitor +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.podmonitor-namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + {{- with .Values.prometheus.podMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.podMonitor.jobLabel }} + {{- include "podmonitor.scrapeLimits" .Values.prometheus.podMonitor | nindent 2 }} + selector: + matchLabels: + {{- with .Values.prometheus.podMonitor.selectorOverride }} + {{- toYaml . | nindent 6 }} + {{- else }} + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "prometheus-node-exporter.namespace" . }} + {{- with .Values.prometheus.podMonitor.attachMetadata }} + attachMetadata: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.podTargetLabels }} + podTargetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} + podMetricsEndpoints: + - port: {{ .Values.service.portName }} + {{- with .Values.prometheus.podMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.path }} + path: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.basicAuth }} + basicAuth: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.bearerTokenSecret }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.authorization }} + authorization: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.oauth2 }} + oauth2: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.proxyUrl }} + proxyUrl: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.honorTimestamps }} + honorTimestamps: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.honorLabels }} + honorLabels: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + enableHttp2: {{ default false .Values.prometheus.podMonitor.enableHttp2 }} + filterRunning: {{ default true .Values.prometheus.podMonitor.filterRunning }} + followRedirects: {{ default false .Values.prometheus.podMonitor.followRedirects }} + {{- with .Values.prometheus.podMonitor.params }} + params: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml new file mode 100644 index 00000000000..89573172435 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: psp-{{ include "prometheus-node-exporter.fullname" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ include "prometheus-node-exporter.fullname" . }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml new file mode 100644 index 00000000000..333370173b8 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: psp-{{ include "prometheus-node-exporter.fullname" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: psp-{{ include "prometheus-node-exporter.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp.yaml new file mode 100644 index 00000000000..4896c84daa3 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/psp.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + {{- with .Values.rbac.pspAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + privileged: false + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + - 'hostPath' + hostNetwork: true + hostIPC: false + hostPID: true + hostPorts: + - min: 0 + max: 65535 + runAsUser: + # Permits the container to run with root privileges as well. + rule: 'RunAsAny' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/rbac-configmap.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/rbac-configmap.yaml new file mode 100644 index 00000000000..814e1103375 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/rbac-configmap.yaml @@ -0,0 +1,16 @@ +{{- if .Values.kubeRBACProxy.enabled}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "prometheus-node-exporter.fullname" . }}-rbac-config + namespace: {{ include "prometheus-node-exporter.namespace" . }} +data: + config-file.yaml: |+ + authorization: + resourceAttributes: + namespace: {{ template "prometheus-node-exporter.namespace" . }} + apiVersion: v1 + resource: services + subresource: {{ template "prometheus-node-exporter.fullname" . }} + name: {{ template "prometheus-node-exporter.fullname" . }} +{{- end }} \ No newline at end of file diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/service.yaml new file mode 100644 index 00000000000..337d00942b3 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/service.yaml @@ -0,0 +1,35 @@ +{{- if .Values.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" $ | nindent 4 }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Values.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.service.ipDualStack.ipFamilyPolicy }} +{{- end }} +{{- if .Values.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} +{{- end }} + type: {{ .Values.service.type }} +{{- if and (eq .Values.service.type "ClusterIP") .Values.service.clusterIP }} + clusterIP: "{{ .Values.service.clusterIP }}" +{{- end }} + ports: + - port: {{ .Values.service.servicePort | default .Values.service.port }} + {{- if ( and (eq .Values.service.type "NodePort" ) (not (empty .Values.service.nodePort)) ) }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + targetPort: {{ .Values.service.targetPort }} + protocol: TCP + name: {{ .Values.service.portName }} + selector: + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/serviceaccount.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/serviceaccount.yaml new file mode 100644 index 00000000000..462b0cda4ba --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.rbac.create .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "prometheus-node-exporter.serviceAccountName" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- if or .Values.serviceAccount.imagePullSecrets .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- include "prometheus-node-exporter.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.serviceAccount.imagePullSecrets) | indent 2 }} +{{- end }} +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/servicemonitor.yaml new file mode 100644 index 00000000000..0d7a42eaece --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/servicemonitor.yaml @@ -0,0 +1,61 @@ +{{- if .Values.prometheus.monitor.enabled }} +apiVersion: {{ .Values.prometheus.monitor.apiVersion | default "monitoring.coreos.com/v1" }} +kind: ServiceMonitor +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.monitor-namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + {{- with .Values.prometheus.monitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.monitor.jobLabel }} + {{- include "servicemonitor.scrapeLimits" .Values.prometheus.monitor | nindent 2 }} + {{- with .Values.prometheus.monitor.podTargetLabels }} + podTargetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- with .Values.prometheus.monitor.selectorOverride }} + {{- toYaml . | nindent 6 }} + {{- else }} + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} + {{- end }} + {{- with .Values.prometheus.monitor.attachMetadata }} + attachMetadata: + {{- toYaml . | nindent 4 }} + {{- end }} + endpoints: + - port: {{ .Values.service.portName }} + scheme: {{ .Values.prometheus.monitor.scheme }} + {{- with .Values.prometheus.monitor.basicAuth }} + basicAuth: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.monitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml new file mode 100644 index 00000000000..2c2705f8724 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml @@ -0,0 +1,40 @@ +{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (.Values.verticalPodAutoscaler.enabled) }} +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +spec: + {{- with .Values.verticalPodAutoscaler.recommenders }} + recommenders: + {{- toYaml . | nindent 4 }} + {{- end }} + resourcePolicy: + containerPolicies: + - containerName: node-exporter + {{- with .Values.verticalPodAutoscaler.controlledResources }} + controlledResources: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.verticalPodAutoscaler.controlledValues }} + controlledValues: {{ . }} + {{- end }} + {{- with .Values.verticalPodAutoscaler.maxAllowed }} + maxAllowed: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.verticalPodAutoscaler.minAllowed }} + minAllowed: + {{- toYaml . | nindent 8 }} + {{- end }} + targetRef: + apiVersion: apps/v1 + kind: DaemonSet + name: {{ include "prometheus-node-exporter.fullname" . }} + {{- with .Values.verticalPodAutoscaler.updatePolicy }} + updatePolicy: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/values.yaml new file mode 100644 index 00000000000..630ef924a65 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/charts/prometheus-node-exporter/values.yaml @@ -0,0 +1,537 @@ +# Default values for prometheus-node-exporter. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +image: + registry: quay.io + repository: prometheus/node-exporter + # Overrides the image tag whose default is {{ printf "v%s" .Chart.AppVersion }} + tag: "" + pullPolicy: IfNotPresent + digest: "" + +imagePullSecrets: [] +# - name: "image-pull-secret" +nameOverride: "" +fullnameOverride: "" + +# Number of old history to retain to allow rollback +# Default Kubernetes value is set to 10 +revisionHistoryLimit: 10 + +global: + # To help compatibility with other charts which use global.imagePullSecrets. + # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). + # global: + # imagePullSecrets: + # - name: pullSecret1 + # - name: pullSecret2 + # or + # global: + # imagePullSecrets: + # - pullSecret1 + # - pullSecret2 + imagePullSecrets: [] + # + # Allow parent charts to override registry hostname + imageRegistry: "" + +# Configure kube-rbac-proxy. When enabled, creates a kube-rbac-proxy to protect the node-exporter http endpoint. +# The requests are served through the same service but requests are HTTPS. +kubeRBACProxy: + enabled: false + ## Set environment variables as name/value pairs + env: {} + # VARIABLE: value + image: + registry: quay.io + repository: brancz/kube-rbac-proxy + tag: v0.18.0 + sha: "" + pullPolicy: IfNotPresent + + # List of additional cli arguments to configure kube-rbac-proxy + # for example: --tls-cipher-suites, --log-file, etc. + # all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage + extraArgs: [] + + ## Specify security settings for a Container + ## Allows overrides and additional options compared to (Pod) securityContext + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + containerSecurityContext: {} + + # Specify the port used for the Node exporter container (upstream port) + port: 8100 + # Specify the name of the container port + portName: http + # Configure a hostPort. If true, hostPort will be enabled in the container and set to service.port. + enableHostPort: false + + # Configure Proxy Endpoints Port + # This is the port being probed for readiness + proxyEndpointsPort: 8888 + # Configure a hostPort. If true, hostPort will be enabled in the container and set to proxyEndpointsPort. + enableProxyEndpointsHostPort: false + + resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + +service: + enabled: true + type: ClusterIP + clusterIP: "" + port: 9100 + servicePort: "" + targetPort: 9100 + nodePort: + portName: metrics + listenOnAllInterfaces: true + annotations: + prometheus.io/scrape: "true" + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + externalTrafficPolicy: "" + +# Set a NetworkPolicy with: +# ingress only on service.port +# no egress permitted +networkPolicy: + enabled: false + +# Additional environment variables that will be passed to the daemonset +env: {} +## env: +## VARIABLE: value + +prometheus: + monitor: + enabled: false + additionalLabels: {} + namespace: "" + + jobLabel: "" + + # List of pod labels to add to node exporter metrics + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor + podTargetLabels: [] + + scheme: http + basicAuth: {} + bearerTokenFile: + tlsConfig: {} + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## Override serviceMonitor selector + ## + selectorOverride: {} + + ## Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above. + ## + attachMetadata: + node: false + + relabelings: [] + metricRelabelings: [] + interval: "" + scrapeTimeout: 10s + ## prometheus.monitor.apiVersion ApiVersion for the serviceMonitor Resource(defaults to "monitoring.coreos.com/v1") + apiVersion: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + # PodMonitor defines monitoring for a set of pods. + # ref. https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.PodMonitor + # Using a PodMonitor may be preferred in some environments where there is very large number + # of Node Exporter endpoints (1000+) behind a single service. + # The PodMonitor is disabled by default. When switching from ServiceMonitor to PodMonitor, + # the time series resulting from the configuration through PodMonitor may have different labels. + # For instance, there will not be the service label any longer which might + # affect PromQL queries selecting that label. + podMonitor: + enabled: false + # Namespace in which to deploy the pod monitor. Defaults to the release namespace. + namespace: "" + # Additional labels, e.g. setting a label for pod monitor selector as set in prometheus + additionalLabels: {} + # release: kube-prometheus-stack + # PodTargetLabels transfers labels of the Kubernetes Pod onto the target. + podTargetLabels: [] + # apiVersion defaults to monitoring.coreos.com/v1. + apiVersion: "" + # Override pod selector to select pod objects. + selectorOverride: {} + # Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above. + attachMetadata: + node: false + # The label to use to retrieve the job name from. Defaults to label app.kubernetes.io/name. + jobLabel: "" + + # Scheme/protocol to use for scraping. + scheme: "http" + # Path to scrape metrics at. + path: "/metrics" + + # BasicAuth allow an endpoint to authenticate over basic authentication. + # More info: https://prometheus.io/docs/operating/configuration/#endpoint + basicAuth: {} + # Secret to mount to read bearer token for scraping targets. + # The secret needs to be in the same namespace as the pod monitor and accessible by the Prometheus Operator. + # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secretkeyselector-v1-core + bearerTokenSecret: {} + # TLS configuration to use when scraping the endpoint. + tlsConfig: {} + # Authorization section for this endpoint. + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.SafeAuthorization + authorization: {} + # OAuth2 for the URL. Only valid in Prometheus versions 2.27.0 and newer. + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.OAuth2 + oauth2: {} + + # ProxyURL eg http://proxyserver:2195. Directs scrapes through proxy to this endpoint. + proxyUrl: "" + # Interval at which endpoints should be scraped. If not specified Prometheus’ global scrape interval is used. + interval: "" + # Timeout after which the scrape is ended. If not specified, the Prometheus global scrape interval is used. + scrapeTimeout: "" + # HonorTimestamps controls whether Prometheus respects the timestamps present in scraped data. + honorTimestamps: true + # HonorLabels chooses the metric’s labels on collisions with target labels. + honorLabels: true + # Whether to enable HTTP2. Default false. + enableHttp2: "" + # Drop pods that are not running. (Failed, Succeeded). + # Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase + filterRunning: "" + # FollowRedirects configures whether scrape requests follow HTTP 3xx redirects. Default false. + followRedirects: "" + # Optional HTTP URL parameters + params: {} + + # RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds + # relabelings for a few standard Kubernetes fields. The original scrape job’s name + # is available via the __tmp_prometheus_job_name label. + # More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + relabelings: [] + # MetricRelabelConfigs to apply to samples before ingestion. + metricRelabelings: [] + + # SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + sampleLimit: 0 + # TargetLimit defines a limit on the number of scraped targets that will be accepted. + targetLimit: 0 + # Per-scrape limit on number of labels that will be accepted for a sample. + # Only valid in Prometheus versions 2.27.0 and newer. + labelLimit: 0 + # Per-scrape limit on length of labels name that will be accepted for a sample. + # Only valid in Prometheus versions 2.27.0 and newer. + labelNameLengthLimit: 0 + # Per-scrape limit on length of labels value that will be accepted for a sample. + # Only valid in Prometheus versions 2.27.0 and newer. + labelValueLengthLimit: 0 + +## Customize the updateStrategy if set +updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 200m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 30Mi + +# Specify the container restart policy passed to the Node Export container +# Possible Values: Always (default)|OnFailure|Never +restartPolicy: null + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + annotations: {} + imagePullSecrets: [] + automountServiceAccountToken: false + +securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + +containerSecurityContext: + readOnlyRootFilesystem: true + # capabilities: + # add: + # - SYS_TIME + +rbac: + ## If true, create & use RBAC resources + ## + create: true + ## If true, create & use Pod Security Policy resources + ## https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + pspEnabled: true + pspAnnotations: {} + +# for deployments that have node_exporter deployed outside of the cluster, list +# their addresses here +endpoints: [] + +# Expose the service to the host network +hostNetwork: true + +# Share the host process ID namespace +hostPID: true + +# Share the host ipc namespace +hostIPC: false + +# Mount the node's root file system (/) at /host/root in the container +hostRootFsMount: + enabled: true + # Defines how new mounts in existing mounts on the node or in the container + # are propagated to the container or node, respectively. Possible values are + # None, HostToContainer, and Bidirectional. If this field is omitted, then + # None is used. More information on: + # https://kubernetes.io/docs/concepts/storage/volumes/#mount-propagation + mountPropagation: HostToContainer + +# Mount the node's proc file system (/proc) at /host/proc in the container +hostProcFsMount: + # Possible values are None, HostToContainer, and Bidirectional + mountPropagation: "" + +# Mount the node's sys file system (/sys) at /host/sys in the container +hostSysFsMount: + # Possible values are None, HostToContainer, and Bidirectional + mountPropagation: "" + +## Assign a group of affinity scheduling rules +## +affinity: {} +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchFields: +# - key: metadata.name +# operator: In +# values: +# - target-host-name + +# Annotations to be added to node exporter pods +podAnnotations: + # Fix for very slow GKE cluster upgrades + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + +# Extra labels to be added to node exporter pods +podLabels: {} + +# Annotations to be added to node exporter daemonset +daemonsetAnnotations: {} + +## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box +releaseLabel: false + +# Custom DNS configuration to be added to prometheus-node-exporter pods +dnsConfig: {} +# nameservers: +# - 1.2.3.4 +# searches: +# - ns1.svc.cluster-domain.example +# - my.dns.search.suffix +# options: +# - name: ndots +# value: "2" +# - name: edns0 + +## Assign a nodeSelector if operating a hybrid cluster +## +nodeSelector: + kubernetes.io/os: linux + # kubernetes.io/arch: amd64 + +# Specify grace period for graceful termination of pods. Defaults to 30 if null or not specified +terminationGracePeriodSeconds: null + +tolerations: + - effect: NoSchedule + operator: Exists + +# Enable or disable container termination message settings +# https://kubernetes.io/docs/tasks/debug/debug-application/determine-reason-pod-failure/ +terminationMessageParams: + enabled: false + # If enabled, specify the path for termination messages + terminationMessagePath: /dev/termination-log + # If enabled, specify the policy for termination messages + terminationMessagePolicy: File + + +## Assign a PriorityClassName to pods if set +# priorityClassName: "" + +## Additional container arguments +## +extraArgs: [] +# - --collector.diskstats.ignored-devices=^(ram|loop|fd|(h|s|v)d[a-z]|nvme\\d+n\\d+p)\\d+$ +# - --collector.textfile.directory=/run/prometheus + +## Additional mounts from the host to node-exporter container +## +extraHostVolumeMounts: [] +# - name: +# hostPath: +# https://kubernetes.io/docs/concepts/storage/volumes/#hostpath-volume-types +# type: "" (Default)|DirectoryOrCreate|Directory|FileOrCreate|File|Socket|CharDevice|BlockDevice +# mountPath: +# readOnly: true|false +# mountPropagation: None|HostToContainer|Bidirectional + +## Additional configmaps to be mounted. +## +configmaps: [] +# - name: +# mountPath: +secrets: [] +# - name: +# mountPath: +## Override the deployment namespace +## +namespaceOverride: "" + +## Additional containers for export metrics to text file; fields image,imagePullPolicy,securityContext take default value from main container +## +sidecars: [] +# - name: nvidia-dcgm-exporter +# image: nvidia/dcgm-exporter:1.4.3 +# volumeMounts: +# - name: tmp +# mountPath: /tmp + +## Volume for sidecar containers +## +sidecarVolumeMount: [] +# - name: collector-textfiles +# mountPath: /run/prometheus +# readOnly: false + +## Additional mounts from the host to sidecar containers +## +sidecarHostVolumeMounts: [] +# - name: +# hostPath: +# mountPath: +# readOnly: true|false +# mountPropagation: None|HostToContainer|Bidirectional + +## Additional InitContainers to initialize the pod +## +extraInitContainers: [] + +## Liveness probe +## +livenessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + +## Readiness probe +## +readinessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + +# Enable vertical pod autoscaler support for prometheus-node-exporter +verticalPodAutoscaler: + enabled: false + + # Recommender responsible for generating recommendation for the object. + # List should be empty (then the default recommender will generate the recommendation) + # or contain exactly one recommender. + # recommenders: + # - name: custom-recommender-performance + + # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory + controlledResources: [] + # Specifies which resource values should be controlled: RequestsOnly or RequestsAndLimits. + # controlledValues: RequestsAndLimits + + # Define the max allowed resources for the pod + maxAllowed: {} + # cpu: 200m + # memory: 100Mi + # Define the min allowed resources for the pod + minAllowed: {} + # cpu: 200m + # memory: 100Mi + + # updatePolicy: + # Specifies minimal number of replicas which need to be alive for VPA Updater to attempt pod eviction + # minReplicas: 1 + # Specifies whether recommended updates are applied when a Pod is started and whether recommended updates + # are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto". + # updateMode: Auto + +# Extra manifests to deploy as an array +extraManifests: [] + # - | + # apiVersion: v1 + # kind: ConfigMap + # metadata: + # name: prometheus-extra + # data: + # extra-data: "value" + +# Override version of app, required if image.tag is defined and does not follow semver +version: "" diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/daemon_scrape_configs.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/daemon_scrape_configs.yaml new file mode 100644 index 00000000000..e1f91812e2b --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/daemon_scrape_configs.yaml @@ -0,0 +1,176 @@ +# Collect all metrics from pods on the daemon set's node with at least this annotation +# prometheus.io/scrape: 'true' +# This can be further customized by setting the following annotations: +# prometheus.io/scheme: 'https' +# prometheus.io/path: '/data/metrics' +# prometheus.io/port: '80' +- job_name: kubernetes-pods + scrape_interval: 30s + kubernetes_sd_configs: + - role: pod + selectors: + - role: pod + # only scrape data from pods running on the same node as collector + field: "spec.nodeName=${env:OTEL_K8S_NODE_NAME}" + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: + [__meta_kubernetes_pod_annotation_prometheus_io_scrape_slow] + action: drop + regex: true + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme] + action: replace + regex: (https?) + target_label: __scheme__ + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: + [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] + action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + # NOTE: otel collector uses env var replacement. $$ is used as a literal $. + replacement: $$1:$$2 + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_annotation_prometheus_io_param_(.+) + replacement: __param_$$1 + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: pod + - source_labels: [__meta_kubernetes_pod_phase] + regex: Pending|Succeeded|Failed|Completed + action: drop + - action: replace + source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name] + target_label: job +# This job is setup to scrape the node metrics on the same host as the daemonset +# https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/29053 +- job_name: node-exporter + scrape_interval: 30s + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - job + target_label: __tmp_prometheus_job_name + static_configs: + - targets: + - ${env:OTEL_K8S_NODE_IP}:9100 +# We still need to scrape kubelet's CAdvisor which isn't supported in any otel collector receiver +# https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/29053 +- authorization: + credentials_file: "/var/run/secrets/kubernetes.io/serviceaccount/token" + type: Bearer + follow_redirects: true + honor_labels: true + honor_timestamps: true + job_name: kubelet + kubernetes_sd_configs: + - follow_redirects: true + role: node + selectors: + - role: node + # only scrape data from pods running on the same node as collector + field: "metadata.name=${env:OTEL_K8S_NODE_NAME}" + metric_relabel_configs: + - action: drop + regex: container_cpu_(load_average_10s|system_seconds_total|user_seconds_total) + replacement: "$$1" + separator: ";" + source_labels: + - __name__ + - action: drop + regex: container_fs_(io_current|reads_merged_total|sector_reads_total|sector_writes_total|writes_merged_total) + replacement: "$$1" + separator: ";" + source_labels: + - __name__ + - action: drop + regex: container_memory_(mapped_file|swap) + replacement: "$$1" + separator: ";" + source_labels: + - __name__ + - action: drop + regex: container_(file_descriptors|tasks_state|threads_max) + replacement: "$$1" + separator: ";" + source_labels: + - __name__ + - action: drop + regex: container_spec.* + replacement: "$$1" + separator: ";" + source_labels: + - __name__ + - action: drop + regex: ".+;" + replacement: "$$1" + separator: ";" + source_labels: + - id + - pod + metrics_path: "/metrics/cadvisor" + relabel_configs: + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - job + target_label: __tmp_prometheus_job_name + - action: replace + replacement: "kubelet" + target_label: job + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __meta_kubernetes_node_name + target_label: node + - action: replace + regex: "(.*)" + replacement: https-metrics + separator: ";" + target_label: endpoint + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __metrics_path__ + target_label: metrics_path + - action: hashmod + modulus: 1 + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __address__ + target_label: __tmp_hash + - action: keep + regex: "$(SHARD)" + replacement: "$$1" + separator: ";" + source_labels: + - __tmp_hash + scheme: https + scrape_interval: 15s + scrape_timeout: 10s + tls_config: + ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" + insecure_skip_verify: true diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/bridge.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/bridge.yaml new file mode 100644 index 00000000000..1182e2059cf --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/bridge.yaml @@ -0,0 +1,60 @@ +--- +# Source: opentelemetry-kube-stack/templates/bridge.yaml +apiVersion: opentelemetry.io/v1alpha1 +kind: OpAMPBridge +metadata: + name: example + labels: + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" +spec: + endpoint: http://opamp-server:8080 + capabilities: + AcceptsOpAMPConnectionSettings: true + AcceptsOtherConnectionSettings: true + AcceptsRemoteConfig: true + AcceptsRestartCommand: true + ReportsEffectiveConfig: true + ReportsHealth: true + ReportsOwnLogs: true + ReportsOwnMetrics: true + ReportsOwnTraces: true + ReportsRemoteConfig: true + ReportsStatus: true + replicas: 1 + image: "ghcr.io/open-telemetry/opentelemetry-operator/operator-opamp-bridge:0.107.0" + upgradeStrategy: automatic + securityContext: + runAsNonRoot: true + runAsUser: 1000 + resources: + limits: + cpu: 250m + memory: 256Mi + requests: + cpu: 250m + memory: 256Mi + env: + - name: OTEL_K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OTEL_K8S_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_K8S_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_K8S_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: OTEL_RESOURCE_ATTRIBUTES + value: "k8s.cluster.name=demo" diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/clusterrole.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/clusterrole.yaml new file mode 100644 index 00000000000..69840470140 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/clusterrole.yaml @@ -0,0 +1,175 @@ +--- +# Source: opentelemetry-kube-stack/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: example-collector +rules: +- apiGroups: [""] + resources: + - namespaces + - nodes + - nodes/proxy + - nodes/metrics + - nodes/stats + - services + - endpoints + - pods + - events + - secrets + - persistentvolumeclaims + verbs: ["get", "list", "watch"] +- apiGroups: ["monitoring.coreos.com"] + resources: + - servicemonitors + - podmonitors + verbs: ["get", "list", "watch"] +- apiGroups: + - extensions + resources: + - ingresses + verbs: ["get", "list", "watch"] +- apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: ["get", "list", "watch"] +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: ["get", "list", "watch"] +- apiGroups: ["discovery.k8s.io"] + resources: + - endpointslices + verbs: ["get", "list", "watch"] +- nonResourceURLs: ["/metrics", "/metrics/cadvisor"] + verbs: ["get"] + +- apiGroups: + - "" + resources: + - events + - namespaces + - namespaces/status + - nodes + - nodes/spec + - pods + - pods/status + - replicationcontrollers + - replicationcontrollers/status + - resourcequotas + - services + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: + - get + - list + - watch +- apiGroups: + - extensions + resources: + - daemonsets + - deployments + - replicasets + verbs: + - get + - list + - watch +- apiGroups: + - batch + resources: + - jobs + - cronjobs + verbs: + - get + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - get + - list + - watch +- apiGroups: ["events.k8s.io"] + resources: ["events"] + verbs: ["watch", "list"] +--- +# Source: opentelemetry-kube-stack/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: example-bridge +rules: + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors + verbs: + - "*" + - apiGroups: + - "" + resources: + - pods + verbs: + - 'list' + - 'get' +--- +# Source: opentelemetry-kube-stack/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: example-cluster-stats +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: example-collector +subjects: +- kind: ServiceAccount + # quirk of the Operator + name: "example-cluster-stats-collector" + namespace: default +--- +# Source: opentelemetry-kube-stack/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: example-daemon +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: example-collector +subjects: +- kind: ServiceAccount + # quirk of the Operator + name: "example-daemon-collector" + namespace: default +--- +# Source: opentelemetry-kube-stack/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: example +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "example-bridge" +subjects: + - kind: ServiceAccount + # quirk of the Operator + name: "example-opamp-bridge" + namespace: "default" diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/collector.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/collector.yaml new file mode 100644 index 00000000000..308cf683185 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/collector.yaml @@ -0,0 +1,658 @@ +--- +# Source: opentelemetry-kube-stack/templates/collector.yaml +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: example-cluster-stats + namespace: default + labels: + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" + opentelemetry.io/opamp-reporting: "true" +spec: + managementState: managed + mode: deployment + config: + exporters: + debug: {} + otlp: + endpoint: ingest.example.com:443 + headers: + access-token: ${ACCESS_TOKEN} + processors: + batch: + send_batch_max_size: 1500 + send_batch_size: 1000 + timeout: 1s + k8sattributes: + extract: + labels: + - from: pod + key: app.kubernetes.io/name + tag_name: service.name + - from: pod + key: k8s-app + tag_name: service.name + - from: pod + key: app.kubernetes.io/instance + tag_name: k8s.app.instance + - from: pod + key: app.kubernetes.io/version + tag_name: service.version + - from: pod + key: app.kubernetes.io/component + tag_name: k8s.app.component + metadata: + - k8s.namespace.name + - k8s.pod.name + - k8s.pod.uid + - k8s.node.name + - k8s.pod.start_time + - k8s.deployment.name + - k8s.replicaset.name + - k8s.replicaset.uid + - k8s.daemonset.name + - k8s.daemonset.uid + - k8s.job.name + - k8s.job.uid + - k8s.container.name + - k8s.cronjob.name + - k8s.statefulset.name + - k8s.statefulset.uid + - container.image.tag + - container.image.name + - k8s.cluster.uid + passthrough: false + pod_association: + - sources: + - from: resource_attribute + name: k8s.pod.uid + - sources: + - from: resource_attribute + name: k8s.pod.name + - from: resource_attribute + name: k8s.namespace.name + - from: resource_attribute + name: k8s.node.name + - sources: + - from: resource_attribute + name: k8s.pod.ip + - sources: + - from: resource_attribute + name: k8s.pod.name + - from: resource_attribute + name: k8s.namespace.name + - sources: + - from: connection + resourcedetection/env: + detectors: + - env + override: false + timeout: 2s + receivers: + k8s_cluster: + allocatable_types_to_report: + - cpu + - memory + - storage + auth_type: serviceAccount + collection_interval: 10s + node_conditions_to_report: + - Ready + - MemoryPressure + - DiskPressure + - NetworkUnavailable + k8sobjects: + objects: + - exclude_watch_type: + - DELETED + group: events.k8s.io + mode: watch + name: events + service: + pipelines: + logs: + exporters: + - debug + processors: + - k8sattributes + - resourcedetection/env + - batch + receivers: + - k8sobjects + metrics: + exporters: + - debug + - otlp + processors: + - k8sattributes + - resourcedetection/env + - batch + receivers: + - k8s_cluster + replicas: 1 + imagePullPolicy: IfNotPresent + upgradeStrategy: automatic + terminationGracePeriodSeconds: 30 + resources: + limits: + cpu: 100m + memory: 500Mi + requests: + cpu: 100m + memory: 500Mi + securityContext: + {} + volumeMounts: + env: + - name: OTEL_K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OTEL_K8S_NODE_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: OTEL_K8S_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_K8S_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_K8S_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: OTEL_RESOURCE_ATTRIBUTES + value: "k8s.cluster.name=demo" + + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + key: access_token + name: otel-collector-secret + volumes: +--- +# Source: opentelemetry-kube-stack/templates/collector.yaml +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: example-daemon + namespace: default + labels: + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" + opentelemetry.io/opamp-reporting: "true" +spec: + managementState: managed + mode: daemonset + config: + exporters: + debug: {} + otlp: + endpoint: ingest.example.com:443 + headers: + access-token: ${ACCESS_TOKEN} + processors: + batch: + send_batch_max_size: 1500 + send_batch_size: 1000 + timeout: 1s + k8sattributes: + extract: + labels: + - from: pod + key: app.kubernetes.io/name + tag_name: service.name + - from: pod + key: k8s-app + tag_name: service.name + - from: pod + key: app.kubernetes.io/instance + tag_name: k8s.app.instance + - from: pod + key: app.kubernetes.io/version + tag_name: service.version + - from: pod + key: app.kubernetes.io/component + tag_name: k8s.app.component + metadata: + - k8s.namespace.name + - k8s.pod.name + - k8s.pod.uid + - k8s.node.name + - k8s.pod.start_time + - k8s.deployment.name + - k8s.replicaset.name + - k8s.replicaset.uid + - k8s.daemonset.name + - k8s.daemonset.uid + - k8s.job.name + - k8s.job.uid + - k8s.container.name + - k8s.cronjob.name + - k8s.statefulset.name + - k8s.statefulset.uid + - container.image.tag + - container.image.name + - k8s.cluster.uid + filter: + node_from_env_var: K8S_NODE_NAME + passthrough: false + pod_association: + - sources: + - from: resource_attribute + name: k8s.pod.uid + - sources: + - from: resource_attribute + name: k8s.pod.name + - from: resource_attribute + name: k8s.namespace.name + - from: resource_attribute + name: k8s.node.name + - sources: + - from: resource_attribute + name: k8s.pod.ip + - sources: + - from: resource_attribute + name: k8s.pod.name + - from: resource_attribute + name: k8s.namespace.name + - sources: + - from: connection + resourcedetection/env: + detectors: + - env + override: false + timeout: 2s + receivers: + filelog: + exclude: [] + include: + - /var/log/pods/*/*/*.log + include_file_name: false + include_file_path: true + operators: + - id: container-parser + max_log_size: 102400 + type: container + retry_on_failure: + enabled: true + start_at: end + hostmetrics: + collection_interval: 10s + root_path: /hostfs + scrapers: + cpu: + metrics: + system.cpu.utilization: + enabled: true + disk: {} + filesystem: + exclude_fs_types: + fs_types: + - autofs + - binfmt_misc + - bpf + - cgroup2 + - configfs + - debugfs + - devpts + - devtmpfs + - fusectl + - hugetlbfs + - iso9660 + - mqueue + - nsfs + - overlay + - proc + - procfs + - pstore + - rpc_pipefs + - securityfs + - selinuxfs + - squashfs + - sysfs + - tracefs + match_type: strict + exclude_mount_points: + match_type: regexp + mount_points: + - /dev/* + - /proc/* + - /sys/* + - /run/k3s/containerd/* + - /var/lib/docker/* + - /var/lib/kubelet/* + - /snap/* + metrics: + system.filesystem.utilization: + enabled: true + load: {} + memory: + metrics: + system.memory.utilization: + enabled: true + network: {} + kubeletstats: + auth_type: serviceAccount + collection_interval: 15s + endpoint: https://${env:OTEL_K8S_NODE_IP}:10250 + extra_metadata_labels: + - container.id + - k8s.volume.type + insecure_skip_verify: true + k8s_api_config: + auth_type: serviceAccount + metric_groups: + - node + - pod + - volume + - container + metrics: + container.cpu.usage: + enabled: true + k8s.node.cpu.usage: + enabled: true + k8s.node.uptime: + enabled: true + k8s.pod.cpu.usage: + enabled: true + k8s.pod.uptime: + enabled: true + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + prometheus: + config: + scrape_configs: + - job_name: kubernetes-pods + kubernetes_sd_configs: + - role: pod + selectors: + - field: spec.nodeName=${env:OTEL_K8S_NODE_NAME} + role: pod + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scrape + - action: drop + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scrape_slow + - action: replace + regex: (https?) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scheme + target_label: __scheme__ + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $$1:$$2 + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_annotation_prometheus_io_param_(.+) + replacement: __param_$$1 + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod + - action: drop + regex: Pending|Succeeded|Failed|Completed + source_labels: + - __meta_kubernetes_pod_phase + - action: replace + source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + target_label: job + scrape_interval: 30s + - job_name: node-exporter + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - job + target_label: __tmp_prometheus_job_name + scrape_interval: 30s + static_configs: + - targets: + - ${env:OTEL_K8S_NODE_IP}:9100 + - authorization: + credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token + type: Bearer + follow_redirects: true + honor_labels: true + honor_timestamps: true + job_name: kubelet + kubernetes_sd_configs: + - follow_redirects: true + role: node + selectors: + - field: metadata.name=${env:OTEL_K8S_NODE_NAME} + role: node + metric_relabel_configs: + - action: drop + regex: container_cpu_(load_average_10s|system_seconds_total|user_seconds_total) + replacement: $$1 + separator: ; + source_labels: + - __name__ + - action: drop + regex: container_fs_(io_current|reads_merged_total|sector_reads_total|sector_writes_total|writes_merged_total) + replacement: $$1 + separator: ; + source_labels: + - __name__ + - action: drop + regex: container_memory_(mapped_file|swap) + replacement: $$1 + separator: ; + source_labels: + - __name__ + - action: drop + regex: container_(file_descriptors|tasks_state|threads_max) + replacement: $$1 + separator: ; + source_labels: + - __name__ + - action: drop + regex: container_spec.* + replacement: $$1 + separator: ; + source_labels: + - __name__ + - action: drop + regex: .+; + replacement: $$1 + separator: ; + source_labels: + - id + - pod + metrics_path: /metrics/cadvisor + relabel_configs: + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - job + target_label: __tmp_prometheus_job_name + - action: replace + replacement: kubelet + target_label: job + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __meta_kubernetes_node_name + target_label: node + - action: replace + regex: (.*) + replacement: https-metrics + separator: ; + target_label: endpoint + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __metrics_path__ + target_label: metrics_path + - action: hashmod + modulus: 1 + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __address__ + target_label: __tmp_hash + - action: keep + regex: $(SHARD) + replacement: $$1 + separator: ; + source_labels: + - __tmp_hash + scheme: https + scrape_interval: 15s + scrape_timeout: 10s + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + service: + pipelines: + logs: + exporters: + - debug + - otlp + processors: + - k8sattributes + - resourcedetection/env + - batch + receivers: + - otlp + - filelog + metrics: + exporters: + - debug + - otlp + processors: + - k8sattributes + - resourcedetection/env + - batch + receivers: + - prometheus + - otlp + - hostmetrics + - kubeletstats + traces: + exporters: + - debug + - otlp + processors: + - k8sattributes + - resourcedetection/env + - batch + receivers: + - otlp + imagePullPolicy: IfNotPresent + upgradeStrategy: automatic + terminationGracePeriodSeconds: 30 + resources: + limits: + cpu: 100m + memory: 250Mi + requests: + cpu: 100m + memory: 128Mi + securityContext: + {} + volumeMounts: + - name: varlogpods + mountPath: /var/log/pods + readOnly: true + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + - name: hostfs + mountPath: /hostfs + readOnly: true + mountPropagation: HostToContainer + ports: + - appProtocol: grpc + hostPort: 4317 + name: otlp-grpc + port: 4317 + protocol: TCP + env: + - name: OTEL_K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OTEL_K8S_NODE_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: OTEL_K8S_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_K8S_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_K8S_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: OTEL_RESOURCE_ATTRIBUTES + value: "k8s.cluster.name=demo" + + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + key: access_token + name: otel-collector-secret + volumes: + - name: varlogpods + hostPath: + path: /var/log/pods + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + - name: hostfs + hostPath: + path: / diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/hooks.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/hooks.yaml new file mode 100644 index 00000000000..9c6738ffdcb --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/hooks.yaml @@ -0,0 +1,65 @@ +--- +# Source: opentelemetry-kube-stack/templates/hooks.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: delete-resources-sa + annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +--- +# Source: opentelemetry-kube-stack/templates/hooks.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: delete-resources-role + annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +rules: + - apiGroups: + - opentelemetry.io + resources: + - instrumentations + - opampbridges + - opentelemetrycollectors + verbs: + - get + - list + - delete +--- +# Source: opentelemetry-kube-stack/templates/hooks.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: delete-resources-rolebinding + annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: delete-resources-role +subjects: + - kind: ServiceAccount + name: delete-resources-sa +--- +# Source: opentelemetry-kube-stack/templates/hooks.yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: opentelemetry-kube-stack-pre-delete-job + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed +spec: + template: + spec: + restartPolicy: Never + serviceAccountName: delete-resources-sa + containers: + - name: delete-resources + image: bitnami/kubectl:latest + command: + - /bin/sh + - -c + - | + kubectl delete instrumentations,opampbridges,opentelemetrycollectors \ + -l helm.sh/chart=opentelemetry-kube-stack-0.3.9 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/instrumentation.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/instrumentation.yaml new file mode 100644 index 00000000000..a03c24d7291 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/instrumentation.yaml @@ -0,0 +1,34 @@ +--- +# Source: opentelemetry-kube-stack/templates/instrumentation.yaml +apiVersion: opentelemetry.io/v1alpha1 +kind: Instrumentation +metadata: + name: example + labels: + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" +spec: + exporter: + endpoint: http://${OTEL_K8S_NODE_NAME}:4317 + propagators: + - tracecontext + - baggage + - b3 + - b3multi + - jaeger + - xray + - ottrace + env: + - name: OTEL_K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + resource: + addK8sUIDAttributes: true + resourceAttributes: {} + python: + env: + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://${OTEL_K8S_NODE_NAME}:4318 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/admission-webhooks/operator-webhook-with-cert-manager.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/admission-webhooks/operator-webhook-with-cert-manager.yaml new file mode 100644 index 00000000000..9e3a9f22cf6 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/admission-webhooks/operator-webhook-with-cert-manager.yaml @@ -0,0 +1,192 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: default/example-opentelemetry-operator-serving-cert + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-mutation +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /mutate-opentelemetry-io-v1alpha1-instrumentation + port: 443 + failurePolicy: Ignore + name: minstrumentation.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /mutate-opentelemetry-io-v1beta1-opentelemetrycollector + port: 443 + failurePolicy: Ignore + name: mopentelemetrycollectorbeta.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /mutate-v1-pod + port: 443 + failurePolicy: Ignore + name: mpod.kb.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: default/example-opentelemetry-operator-serving-cert + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-validation +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1alpha1-instrumentation + port: 443 + failurePolicy: Ignore + name: vinstrumentationcreateupdate.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1alpha1-instrumentation + port: 443 + failurePolicy: Ignore + name: vinstrumentationdelete.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - DELETE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1beta1-opentelemetrycollector + port: 443 + failurePolicy: Ignore + name: vopentelemetrycollectorcreateupdatebeta.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1beta1-opentelemetrycollector + port: 443 + failurePolicy: Ignore + name: vopentelemetrycollectordeletebeta.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - DELETE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/admission-webhooks/operator-webhook.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/admission-webhooks/operator-webhook.yaml new file mode 100644 index 00000000000..5b9ff5511db --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/admission-webhooks/operator-webhook.yaml @@ -0,0 +1,3 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook.yaml +--- diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/certmanager.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/certmanager.yaml new file mode 100644 index 00000000000..55aae15269d --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/certmanager.yaml @@ -0,0 +1,43 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/certmanager.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-serving-cert + namespace: default +spec: + dnsNames: + - example-opentelemetry-operator-webhook.default.svc + - example-opentelemetry-operator-webhook.default.svc.cluster.local + issuerRef: + kind: Issuer + name: example-opentelemetry-operator-selfsigned-issuer + secretName: example-opentelemetry-operator-controller-manager-service-cert + subject: + organizationalUnits: + - example-opentelemetry-operator +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/certmanager.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-selfsigned-issuer + namespace: default +spec: + selfSigned: {} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/clusterrole.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/clusterrole.yaml new file mode 100644 index 00000000000..3a660a25fbf --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/clusterrole.yaml @@ -0,0 +1,265 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-manager +rules: + - apiGroups: + - "" + resources: + - configmaps + - persistentvolumeclaims + - persistentvolumes + - pods + - serviceaccounts + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - list + - watch + - apiGroups: + - apps + resources: + - daemonsets + - deployments + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + - extensions + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - batch + resources: + - jobs + verbs: + - get + - list + - watch + - apiGroups: + - config.openshift.io + resources: + - infrastructures + - infrastructures/status + verbs: + - get + - list + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - list + - update + - apiGroups: + - monitoring.coreos.com + resources: + - podmonitors + - servicemonitors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - instrumentations + verbs: + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opampbridges + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opampbridges/finalizers + verbs: + - update + - apiGroups: + - opentelemetry.io + resources: + - opampbridges/status + verbs: + - get + - patch + - update + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors + verbs: + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors/finalizers + verbs: + - get + - patch + - update + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors/status + verbs: + - get + - patch + - update + - apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-metrics +rules: + - nonResourceURLs: + - /metrics + verbs: + - get +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-proxy +rules: + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/clusterrolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/clusterrolebinding.yaml new file mode 100644 index 00000000000..106408a6d95 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/clusterrolebinding.yaml @@ -0,0 +1,44 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: example-opentelemetry-operator-manager +subjects: + - kind: ServiceAccount + name: opentelemetry-operator + namespace: default +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-proxy +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: example-opentelemetry-operator-proxy +subjects: + - kind: ServiceAccount + name: opentelemetry-operator + namespace: default diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/deployment.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/deployment.yaml new file mode 100644 index 00000000000..300068ce046 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/deployment.yaml @@ -0,0 +1,105 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager + spec: + hostNetwork: false + containers: + - args: + - --metrics-addr=0.0.0.0:8080 + - --enable-leader-election + - --health-probe-addr=:8081 + - --webhook-port=9443 + - --collector-image=otel/opentelemetry-collector-k8s:0.110.0 + command: + - /manager + env: + - name: ENABLE_WEBHOOKS + value: "true" + image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.110.0" + name: manager + ports: + - containerPort: 8080 + name: metrics + protocol: TCP + - containerPort: 9443 + name: webhook-server + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 64Mi + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: "quay.io/brancz/kube-rbac-proxy:v0.15.0" + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + serviceAccountName: opentelemetry-operator + terminationGracePeriodSeconds: 10 + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: example-opentelemetry-operator-controller-manager-service-cert + securityContext: + fsGroup: 65532 + runAsGroup: 65532 + runAsNonRoot: true + runAsUser: 65532 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/role.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/role.yaml new file mode 100644 index 00000000000..a6435f42f9b --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/role.yaml @@ -0,0 +1,43 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-leader-election + namespace: default +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/rolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/rolebinding.yaml new file mode 100644 index 00000000000..65b49be0533 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/rolebinding.yaml @@ -0,0 +1,23 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-leader-election + namespace: default +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: example-opentelemetry-operator-leader-election +subjects: + - kind: ServiceAccount + name: opentelemetry-operator + namespace: default diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/service.yaml new file mode 100644 index 00000000000..8b4ef9a0a9a --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/service.yaml @@ -0,0 +1,51 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator + namespace: default +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + - name: metrics + port: 8080 + protocol: TCP + targetPort: metrics + selector: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-webhook + namespace: default +spec: + ports: + - port: 443 + protocol: TCP + targetPort: webhook-server + selector: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/serviceaccount.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/serviceaccount.yaml new file mode 100644 index 00000000000..e89ef1d2438 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/serviceaccount.yaml @@ -0,0 +1,15 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: opentelemetry-operator + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/tests/test-certmanager-connection.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/tests/test-certmanager-connection.yaml new file mode 100644 index 00000000000..8bc9114a528 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/tests/test-certmanager-connection.yaml @@ -0,0 +1,38 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-certmanager-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "example-opentelemetry-operator-cert-manager" + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "busybox:latest" + env: + - name: CERT_MANAGER_CLUSTERIP + value: "cert-manager-webhook" + - name: CERT_MANAGER_PORT + value: "443" + command: + - sh + - -c + # The following shell script tests if the cert-manager service is up. If the service is up, when we try + # to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$CERT_MANAGER_CLUSTERIP:$CERT_MANAGER_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/tests/test-service-connection.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/tests/test-service-connection.yaml new file mode 100644 index 00000000000..15f120d40da --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/rendered/opentelemetry-operator/tests/test-service-connection.yaml @@ -0,0 +1,76 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-service-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "example-opentelemetry-operator-metrics" + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "busybox:latest" + env: + - name: MANAGER_METRICS_SERVICE_CLUSTERIP + value: "example-opentelemetry-operator" + - name: MANAGER_METRICS_SERVICE_PORT + value: "8443" + command: + - sh + - -c + # The following shell script tests if the controller-manager-metrics-service is up. + # If the service is up, when we try to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$MANAGER_METRICS_SERVICE_CLUSTERIP:$MANAGER_METRICS_SERVICE_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-service-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "example-opentelemetry-operator-webhook" + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "busybox:latest" + env: + - name: WEBHOOK_SERVICE_CLUSTERIP + value: "example-opentelemetry-operator-webhook" + - name: WEBHOOK_SERVICE_PORT + value: "443" + command: + - sh + - -c + # The following shell script tests if the webhook service is up. If the service is up, when we try + # to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$WEBHOOK_SERVICE_CLUSTERIP:$WEBHOOK_SERVICE_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/values.yaml new file mode 100644 index 00000000000..51b6adc326a --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/cloud-demo/values.yaml @@ -0,0 +1,62 @@ +clusterName: demo +collectors: + daemon: + ports: + - appProtocol: grpc + name: otlp-grpc + port: 4317 + protocol: TCP + hostPort: 4317 # Force the hostPort + env: + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + key: access_token + name: otel-collector-secret + config: + exporters: + otlp: + endpoint: ingest.example.com:443 + headers: + "access-token": "${ACCESS_TOKEN}" + service: + pipelines: + metrics: + exporters: [debug, otlp] + traces: + exporters: [debug, otlp] + logs: + exporters: [debug, otlp] + cluster: + env: + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + key: access_token + name: otel-collector-secret + config: + exporters: + otlp: + endpoint: ingest.example.com:443 + headers: + "access-token": "${ACCESS_TOKEN}" + service: + pipelines: + metrics: + exporters: [debug, otlp] +instrumentation: + enabled: true + env: + - name: OTEL_K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + exporter: + endpoint: http://${OTEL_K8S_NODE_NAME}:4317 + python: + env: + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://${OTEL_K8S_NODE_NAME}:4318 +opAMPBridge: + enabled: true + addReportingLabel: true diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/README.md b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/README.md new file mode 100644 index 00000000000..abae0bc2b38 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/README.md @@ -0,0 +1,5 @@ +# Prometheus Replacement example +This example contains files to allow a user to replace an installation of kube-prometheus-stack. The opentelemetry-kube-stack chart aims to make the replacement process straightforward by utilizing the target allocator to pull any servicemonitors and podmonitors. + +> [!INFO] +> This chart has most of the same configurations as the kube-prometheus-stack chart, but requires that kubelet monitoring is done via a manual scrape config. This is because of how the prometheus-operator manages endpoints for the Kubelet service. If you'd like to avoid a scrape-config altogether, it's recommended to use the kubelet receiver in the opentelemetry collector. diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/kubelet_scrape_configs.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/kubelet_scrape_configs.yaml new file mode 100644 index 00000000000..f6a27c2abfa --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/kubelet_scrape_configs.yaml @@ -0,0 +1,244 @@ +# This is used for scrape kubelet +{{- if .kubelet.enabled }} +- authorization: + credentials_file: "/var/run/secrets/kubernetes.io/serviceaccount/token" + type: Bearer + follow_redirects: true + honor_labels: {{ .kubelet.serviceMonitor.honorLabels }} + honor_timestamps: {{ .kubelet.serviceMonitor.honorTimestamps }} + job_name: serviceMonitor/{{ .namespace }}/{{ .Chart.Name }}-kubelet/0 + kubernetes_sd_configs: + - follow_redirects: true + kubeconfig_file: '' + role: node + metrics_path: "/metrics" + relabel_configs: + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - job + target_label: __tmp_prometheus_job_name + - action: replace + replacement: "kubelet" + target_label: job + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __meta_kubernetes_node_name + target_label: node + - action: replace + regex: "(.*)" + replacement: https-metrics + separator: ";" + target_label: endpoint + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __metrics_path__ + target_label: metrics_path + - action: hashmod + modulus: 1 + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __address__ + target_label: __tmp_hash + - action: keep + regex: "$(SHARD)" + replacement: "$$1" + separator: ";" + source_labels: + - __tmp_hash + {{- if .kubelet.serviceMonitor.https }} + scheme: https + {{- else }} + schema: http + {{- end }} + scrape_interval: {{ .kubelet.serviceMonitor.interval | default "30s" }} + scrape_timeout: {{ .kubelet.serviceMonitor.scrapeTimeout | default "10s" }} + tls_config: + ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" + insecure_skip_verify: true +{{- if .kubelet.serviceMonitor.cAdvisor }} +- authorization: + credentials_file: "/var/run/secrets/kubernetes.io/serviceaccount/token" + type: Bearer + follow_redirects: true + honor_labels: true + honor_timestamps: true + job_name: serviceMonitor/{{ .namespace }}/{{ .Chart.Name }}-kubelet/1 + kubernetes_sd_configs: + - follow_redirects: true + kubeconfig_file: '' + role: node + metric_relabel_configs: + - action: drop + regex: container_cpu_(cfs_throttled_seconds_total|load_average_10s|system_seconds_total|user_seconds_total) + replacement: "$$1" + separator: ";" + source_labels: + - __name__ + - action: drop + regex: container_fs_(io_current|io_time_seconds_total|io_time_weighted_seconds_total|reads_merged_total|sector_reads_total|sector_writes_total|writes_merged_total) + replacement: "$$1" + separator: ";" + source_labels: + - __name__ + - action: drop + regex: container_memory_(mapped_file|swap) + replacement: "$$1" + separator: ";" + source_labels: + - __name__ + - action: drop + regex: container_(file_descriptors|tasks_state|threads_max) + replacement: "$$1" + separator: ";" + source_labels: + - __name__ + - action: drop + regex: container_spec.* + replacement: "$$1" + separator: ";" + source_labels: + - __name__ + - action: drop + regex: ".+;" + replacement: "$$1" + separator: ";" + source_labels: + - id + - pod + metrics_path: "/metrics/cadvisor" + relabel_configs: + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - job + target_label: __tmp_prometheus_job_name + - action: replace + replacement: "kubelet" + target_label: job + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __meta_kubernetes_node_name + target_label: node + - action: replace + regex: "(.*)" + replacement: https-metrics + separator: ";" + target_label: endpoint + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __metrics_path__ + target_label: metrics_path + - action: hashmod + modulus: 1 + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __address__ + target_label: __tmp_hash + - action: keep + regex: "$(SHARD)" + replacement: "$$1" + separator: ";" + source_labels: + - __tmp_hash + {{- if .kubelet.serviceMonitor.https }} + scheme: https + {{- else }} + schema: http + {{- end }} + scrape_interval: {{ .kubelet.serviceMonitor.scrapeTimeout | default "30s" }} + scrape_timeout: 10s + tls_config: + ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" + insecure_skip_verify: true + +{{- end }} +{{- if .kubelet.serviceMonitor.probes }} +- authorization: + credentials_file: "/var/run/secrets/kubernetes.io/serviceaccount/token" + type: Bearer + follow_redirects: true + honor_labels: true + honor_timestamps: true + job_name: serviceMonitor/{{ .namespace }}/{{ .Chart.Name }}-kubelet/2 + kubernetes_sd_configs: + - follow_redirects: true + kubeconfig_file: '' + role: node + metrics_path: "/metrics/probes" + relabel_configs: + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - job + target_label: __tmp_prometheus_job_name + - action: replace + replacement: "kubelet" + target_label: job + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __meta_kubernetes_node_name + target_label: node + - action: replace + regex: "(.*)" + replacement: https-metrics + separator: ";" + target_label: endpoint + - action: replace + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __metrics_path__ + target_label: metrics_path + - action: hashmod + modulus: 1 + regex: "(.*)" + replacement: "$$1" + separator: ";" + source_labels: + - __address__ + target_label: __tmp_hash + - action: keep + regex: "$(SHARD)" + replacement: "$$1" + separator: ";" + source_labels: + - __tmp_hash + {{- if .kubelet.serviceMonitor.https }} + scheme: https + {{- else }} + schema: http + {{- end }} + scrape_interval: {{ .kubelet.serviceMonitor.scrapeTimeout | default "30s" }} + scrape_timeout: 10s + tls_config: + ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" + insecure_skip_verify: true +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/clusterrole.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/clusterrole.yaml new file mode 100644 index 00000000000..a4c1669c6fa --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/clusterrole.yaml @@ -0,0 +1,128 @@ +--- +# Source: opentelemetry-kube-stack/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: example-collector +rules: +- apiGroups: [""] + resources: + - namespaces + - nodes + - nodes/proxy + - nodes/metrics + - nodes/stats + - services + - endpoints + - pods + - events + - secrets + - persistentvolumeclaims + verbs: ["get", "list", "watch"] +- apiGroups: ["monitoring.coreos.com"] + resources: + - servicemonitors + - podmonitors + verbs: ["get", "list", "watch"] +- apiGroups: + - extensions + resources: + - ingresses + verbs: ["get", "list", "watch"] +- apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: ["get", "list", "watch"] +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: ["get", "list", "watch"] +- apiGroups: ["discovery.k8s.io"] + resources: + - endpointslices + verbs: ["get", "list", "watch"] +- nonResourceURLs: ["/metrics", "/metrics/cadvisor"] + verbs: ["get"] + +- apiGroups: + - "" + resources: + - events + - namespaces + - namespaces/status + - nodes + - nodes/spec + - pods + - pods/status + - replicationcontrollers + - replicationcontrollers/status + - resourcequotas + - services + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: + - get + - list + - watch +- apiGroups: + - extensions + resources: + - daemonsets + - deployments + - replicasets + verbs: + - get + - list + - watch +- apiGroups: + - batch + resources: + - jobs + - cronjobs + verbs: + - get + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - get + - list + - watch +- apiGroups: ["events.k8s.io"] + resources: ["events"] + verbs: ["watch", "list"] +--- +# Source: opentelemetry-kube-stack/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: example-daemon +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: example-collector +subjects: +- kind: ServiceAccount + # quirk of the Operator + name: "example-daemon-collector" + namespace: default +- kind: ServiceAccount + name: example-daemon-targetallocator + namespace: default diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/collector.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/collector.yaml new file mode 100644 index 00000000000..36f4a8145ea --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/collector.yaml @@ -0,0 +1,349 @@ +--- +# Source: opentelemetry-kube-stack/templates/collector.yaml +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: example-daemon + namespace: default + labels: + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" + otel-collector-type: daemonset-example +spec: + managementState: managed + mode: daemonset + config: + exporters: + debug: {} + otlp: + endpoint: ingest.example.com:443 + headers: + access-token: ${ACCESS_TOKEN} + processors: + batch: + send_batch_max_size: 1500 + send_batch_size: 1000 + timeout: 1s + resourcedetection/env: + detectors: + - env + override: false + timeout: 2s + receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + prometheus: + config: + scrape_configs: + - authorization: + credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token + type: Bearer + follow_redirects: true + honor_labels: true + honor_timestamps: true + job_name: serviceMonitor/default/opentelemetry-kube-stack-kubelet/0 + kubernetes_sd_configs: + - follow_redirects: true + kubeconfig_file: "" + role: node + metrics_path: /metrics + relabel_configs: + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - job + target_label: __tmp_prometheus_job_name + - action: replace + replacement: kubelet + target_label: job + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __meta_kubernetes_node_name + target_label: node + - action: replace + regex: (.*) + replacement: https-metrics + separator: ; + target_label: endpoint + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __metrics_path__ + target_label: metrics_path + - action: hashmod + modulus: 1 + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __address__ + target_label: __tmp_hash + - action: keep + regex: $(SHARD) + replacement: $$1 + separator: ; + source_labels: + - __tmp_hash + scheme: https + scrape_interval: 30s + scrape_timeout: 10s + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + - authorization: + credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token + type: Bearer + follow_redirects: true + honor_labels: true + honor_timestamps: true + job_name: serviceMonitor/default/opentelemetry-kube-stack-kubelet/1 + kubernetes_sd_configs: + - follow_redirects: true + kubeconfig_file: "" + role: node + metric_relabel_configs: + - action: drop + regex: container_cpu_(cfs_throttled_seconds_total|load_average_10s|system_seconds_total|user_seconds_total) + replacement: $$1 + separator: ; + source_labels: + - __name__ + - action: drop + regex: container_fs_(io_current|io_time_seconds_total|io_time_weighted_seconds_total|reads_merged_total|sector_reads_total|sector_writes_total|writes_merged_total) + replacement: $$1 + separator: ; + source_labels: + - __name__ + - action: drop + regex: container_memory_(mapped_file|swap) + replacement: $$1 + separator: ; + source_labels: + - __name__ + - action: drop + regex: container_(file_descriptors|tasks_state|threads_max) + replacement: $$1 + separator: ; + source_labels: + - __name__ + - action: drop + regex: container_spec.* + replacement: $$1 + separator: ; + source_labels: + - __name__ + - action: drop + regex: .+; + replacement: $$1 + separator: ; + source_labels: + - id + - pod + metrics_path: /metrics/cadvisor + relabel_configs: + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - job + target_label: __tmp_prometheus_job_name + - action: replace + replacement: kubelet + target_label: job + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __meta_kubernetes_node_name + target_label: node + - action: replace + regex: (.*) + replacement: https-metrics + separator: ; + target_label: endpoint + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __metrics_path__ + target_label: metrics_path + - action: hashmod + modulus: 1 + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __address__ + target_label: __tmp_hash + - action: keep + regex: $(SHARD) + replacement: $$1 + separator: ; + source_labels: + - __tmp_hash + scheme: https + scrape_interval: 30s + scrape_timeout: 10s + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + - authorization: + credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token + type: Bearer + follow_redirects: true + honor_labels: true + honor_timestamps: true + job_name: serviceMonitor/default/opentelemetry-kube-stack-kubelet/2 + kubernetes_sd_configs: + - follow_redirects: true + kubeconfig_file: "" + role: node + metrics_path: /metrics/probes + relabel_configs: + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - job + target_label: __tmp_prometheus_job_name + - action: replace + replacement: kubelet + target_label: job + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __meta_kubernetes_node_name + target_label: node + - action: replace + regex: (.*) + replacement: https-metrics + separator: ; + target_label: endpoint + - action: replace + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __metrics_path__ + target_label: metrics_path + - action: hashmod + modulus: 1 + regex: (.*) + replacement: $$1 + separator: ; + source_labels: + - __address__ + target_label: __tmp_hash + - action: keep + regex: $(SHARD) + replacement: $$1 + separator: ; + source_labels: + - __tmp_hash + scheme: https + scrape_interval: 30s + scrape_timeout: 10s + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + service: + pipelines: + logs: + exporters: + - debug + processors: + - resourcedetection/env + - batch + receivers: + - otlp + metrics: + exporters: + - debug + - otlp + processors: + - resourcedetection/env + - batch + receivers: + - prometheus + traces: + exporters: + - debug + processors: + - resourcedetection/env + - batch + receivers: + - otlp + imagePullPolicy: IfNotPresent + upgradeStrategy: automatic + terminationGracePeriodSeconds: 30 + resources: + limits: + cpu: 100m + memory: 250Mi + requests: + cpu: 100m + memory: 128Mi + securityContext: + {} + targetAllocator: + allocationStrategy: per-node + enabled: true + image: ghcr.io/open-telemetry/opentelemetry-operator/target-allocator:main + prometheusCR: + enabled: true + podMonitorSelector: {} + scrapeInterval: 30s + serviceMonitorSelector: {} + volumeMounts: + env: + - name: OTEL_K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OTEL_K8S_NODE_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: OTEL_K8S_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_K8S_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_K8S_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: OTEL_RESOURCE_ATTRIBUTES + value: "k8s.cluster.name=demo" + + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + key: access_token + name: otel-collector-secret + volumes: diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-api-server/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-api-server/servicemonitor.yaml new file mode 100644 index 00000000000..c4cbb7e90d1 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-api-server/servicemonitor.yaml @@ -0,0 +1,37 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-api-server/servicemonitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-apiserver + namespace: default + labels: + app: opentelemetry-kube-stack-apiserver + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" +spec: + + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + port: https + scheme: https + metricRelabelings: + - action: drop + regex: apiserver_request_duration_seconds_bucket;(0.15|0.2|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2|3|3.5|4|4.5|6|7|8|9|15|25|40|50) + sourceLabels: + - __name__ + - le + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + serverName: kubernetes + insecureSkipVerify: false + jobLabel: component + namespaceSelector: + matchNames: + - default + selector: + matchLabels: + component: apiserver + provider: kubernetes diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-controller-manager/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-controller-manager/service.yaml new file mode 100644 index 00000000000..e95fdae5613 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-controller-manager/service.yaml @@ -0,0 +1,24 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-controller-manager/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: example-kube-controller-manager + labels: + app: opentelemetry-kube-stack-kube-controller-manager + jobLabel: kube-controller-manager + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" + namespace: kube-system +spec: + clusterIP: None + ports: + - name: http-metrics + port: 10257 + protocol: TCP + targetPort: 10257 + selector: + component: kube-controller-manager + type: ClusterIP diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-controller-manager/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-controller-manager/servicemonitor.yaml new file mode 100644 index 00000000000..1bf75801c31 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-controller-manager/servicemonitor.yaml @@ -0,0 +1,30 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-controller-manager/servicemonitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-kube-controller-manager + namespace: default + labels: + app: opentelemetry-kube-stack-kube-controller-manager + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" +spec: + jobLabel: jobLabel + + selector: + matchLabels: + app: opentelemetry-kube-stack-kube-controller-manager + release: "example" + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: http-metrics + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + scheme: https + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecureSkipVerify: true diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-dns/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-dns/service.yaml new file mode 100644 index 00000000000..17ab69d7d06 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-dns/service.yaml @@ -0,0 +1,27 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-dns/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: example-kube-dns + labels: + app: opentelemetry-kube-stack-kube-dns + jobLabel: kube-dns + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" + namespace: kube-system +spec: + clusterIP: None + ports: + - name: http-metrics-dnsmasq + port: 10054 + protocol: TCP + targetPort: 10054 + - name: http-metrics-skydns + port: 10055 + protocol: TCP + targetPort: 10055 + selector: + k8s-app: kube-dns diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-dns/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-dns/servicemonitor.yaml new file mode 100644 index 00000000000..bd6cc017dcb --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-dns/servicemonitor.yaml @@ -0,0 +1,28 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-dns/servicemonitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-kube-dns + namespace: default + labels: + app: opentelemetry-kube-stack-kube-dns + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" +spec: + jobLabel: jobLabel + + selector: + matchLabels: + app: opentelemetry-kube-stack-kube-dns + release: "example" + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: http-metrics-dnsmasq + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + - port: http-metrics-skydns + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-etcd/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-etcd/service.yaml new file mode 100644 index 00000000000..9ed4bc7250b --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-etcd/service.yaml @@ -0,0 +1,24 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-etcd/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: example-kube-etcd + labels: + app: opentelemetry-kube-stack-kube-etcd + jobLabel: kube-etcd + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" + namespace: kube-system +spec: + clusterIP: None + ports: + - name: http-metrics + port: 2381 + protocol: TCP + targetPort: 2381 + selector: + component: etcd + type: ClusterIP diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-etcd/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-etcd/servicemonitor.yaml new file mode 100644 index 00000000000..f2fde8decc8 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-etcd/servicemonitor.yaml @@ -0,0 +1,26 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-etcd/servicemonitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-kube-etcd + namespace: default + labels: + app: opentelemetry-kube-stack-kube-etcd + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" +spec: + jobLabel: jobLabel + + selector: + matchLabels: + app: opentelemetry-kube-stack-kube-etcd + release: "example" + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: http-metrics + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-proxy/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-proxy/service.yaml new file mode 100644 index 00000000000..550573dc070 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-proxy/service.yaml @@ -0,0 +1,24 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-proxy/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: example-kube-proxy + labels: + app: opentelemetry-kube-stack-kube-proxy + jobLabel: kube-proxy + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" + namespace: kube-system +spec: + clusterIP: None + ports: + - name: http-metrics + port: 10249 + protocol: TCP + targetPort: 10249 + selector: + k8s-app: kube-proxy + type: ClusterIP diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-proxy/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-proxy/servicemonitor.yaml new file mode 100644 index 00000000000..19a539db7cc --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-proxy/servicemonitor.yaml @@ -0,0 +1,26 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-proxy/servicemonitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-kube-proxy + namespace: default + labels: + app: opentelemetry-kube-stack-kube-proxy + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" +spec: + jobLabel: jobLabel + + selector: + matchLabels: + app: opentelemetry-kube-stack-kube-proxy + release: "example" + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: http-metrics + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-scheduler/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-scheduler/service.yaml new file mode 100644 index 00000000000..fa3ff926c74 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-scheduler/service.yaml @@ -0,0 +1,24 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-scheduler/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: example-kube-scheduler + labels: + app: opentelemetry-kube-stack-kube-scheduler + jobLabel: kube-scheduler + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" + namespace: kube-system +spec: + clusterIP: None + ports: + - name: http-metrics + port: 10259 + protocol: TCP + targetPort: 10259 + selector: + component: kube-scheduler + type: ClusterIP diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-scheduler/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-scheduler/servicemonitor.yaml new file mode 100644 index 00000000000..ac7bef196d5 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/exporters/kube-scheduler/servicemonitor.yaml @@ -0,0 +1,30 @@ +--- +# Source: opentelemetry-kube-stack/templates/exporters/kube-scheduler/servicemonitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-kube-scheduler + namespace: default + labels: + app: opentelemetry-kube-stack-kube-scheduler + helm.sh/chart: opentelemetry-kube-stack-0.3.9 + app.kubernetes.io/version: "0.107.0" + app.kubernetes.io/managed-by: Helm + release: "example" +spec: + jobLabel: jobLabel + + selector: + matchLabels: + app: opentelemetry-kube-stack-kube-scheduler + release: "example" + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: http-metrics + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + scheme: https + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecureSkipVerify: true diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/hooks.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/hooks.yaml new file mode 100644 index 00000000000..9c6738ffdcb --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/hooks.yaml @@ -0,0 +1,65 @@ +--- +# Source: opentelemetry-kube-stack/templates/hooks.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: delete-resources-sa + annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +--- +# Source: opentelemetry-kube-stack/templates/hooks.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: delete-resources-role + annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +rules: + - apiGroups: + - opentelemetry.io + resources: + - instrumentations + - opampbridges + - opentelemetrycollectors + verbs: + - get + - list + - delete +--- +# Source: opentelemetry-kube-stack/templates/hooks.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: delete-resources-rolebinding + annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: delete-resources-role +subjects: + - kind: ServiceAccount + name: delete-resources-sa +--- +# Source: opentelemetry-kube-stack/templates/hooks.yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: opentelemetry-kube-stack-pre-delete-job + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed +spec: + template: + spec: + restartPolicy: Never + serviceAccountName: delete-resources-sa + containers: + - name: delete-resources + image: bitnami/kubectl:latest + command: + - /bin/sh + - -c + - | + kubectl delete instrumentations,opampbridges,opentelemetrycollectors \ + -l helm.sh/chart=opentelemetry-kube-stack-0.3.9 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/clusterrolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/clusterrolebinding.yaml new file mode 100644 index 00000000000..54acd1b84c2 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/clusterrolebinding.yaml @@ -0,0 +1,23 @@ +--- +# Source: opentelemetry-kube-stack/charts/kube-state-metrics/templates/clusterrolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + helm.sh/chart: kube-state-metrics-5.21.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: kube-state-metrics + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/instance: example + app.kubernetes.io/version: "2.12.0" + release: example + name: example-kube-state-metrics +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: example-kube-state-metrics +subjects: +- kind: ServiceAccount + name: example-kube-state-metrics + namespace: default diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/deployment.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/deployment.yaml new file mode 100644 index 00000000000..a4836b777d2 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/deployment.yaml @@ -0,0 +1,87 @@ +--- +# Source: opentelemetry-kube-stack/charts/kube-state-metrics/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: example-kube-state-metrics + namespace: default + labels: + helm.sh/chart: kube-state-metrics-5.21.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: kube-state-metrics + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/instance: example + app.kubernetes.io/version: "2.12.0" + release: example +spec: + selector: + matchLabels: + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/instance: example + replicas: 1 + strategy: + type: RollingUpdate + revisionHistoryLimit: 10 + template: + metadata: + labels: + helm.sh/chart: kube-state-metrics-5.21.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: kube-state-metrics + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/instance: example + app.kubernetes.io/version: "2.12.0" + release: example + spec: + automountServiceAccountToken: true + hostNetwork: false + serviceAccountName: example-kube-state-metrics + securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault + containers: + - name: kube-state-metrics + args: + - --port=8080 + - --resources=certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,leases,limitranges,mutatingwebhookconfigurations,namespaces,networkpolicies,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses,validatingwebhookconfigurations,volumeattachments + imagePullPolicy: IfNotPresent + image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.12.0 + ports: + - containerPort: 8080 + name: "http" + livenessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: + path: /healthz + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: + path: / + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + resources: + {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/role.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/role.yaml new file mode 100644 index 00000000000..06ae623aabd --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/role.yaml @@ -0,0 +1,156 @@ +--- +# Source: opentelemetry-kube-stack/charts/kube-state-metrics/templates/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: kube-state-metrics-5.21.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: kube-state-metrics + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/instance: example + app.kubernetes.io/version: "2.12.0" + release: example + name: example-kube-state-metrics +rules: + +- apiGroups: ["certificates.k8s.io"] + resources: + - certificatesigningrequests + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - configmaps + verbs: ["list", "watch"] + +- apiGroups: ["batch"] + resources: + - cronjobs + verbs: ["list", "watch"] + +- apiGroups: ["extensions", "apps"] + resources: + - daemonsets + verbs: ["list", "watch"] + +- apiGroups: ["extensions", "apps"] + resources: + - deployments + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - endpoints + verbs: ["list", "watch"] + +- apiGroups: ["autoscaling"] + resources: + - horizontalpodautoscalers + verbs: ["list", "watch"] + +- apiGroups: ["extensions", "networking.k8s.io"] + resources: + - ingresses + verbs: ["list", "watch"] + +- apiGroups: ["batch"] + resources: + - jobs + verbs: ["list", "watch"] + +- apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - limitranges + verbs: ["list", "watch"] + +- apiGroups: ["admissionregistration.k8s.io"] + resources: + - mutatingwebhookconfigurations + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - namespaces + verbs: ["list", "watch"] + +- apiGroups: ["networking.k8s.io"] + resources: + - networkpolicies + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - nodes + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - persistentvolumeclaims + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - persistentvolumes + verbs: ["list", "watch"] + +- apiGroups: ["policy"] + resources: + - poddisruptionbudgets + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - pods + verbs: ["list", "watch"] + +- apiGroups: ["extensions", "apps"] + resources: + - replicasets + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - replicationcontrollers + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - resourcequotas + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - secrets + verbs: ["list", "watch"] + +- apiGroups: [""] + resources: + - services + verbs: ["list", "watch"] + +- apiGroups: ["apps"] + resources: + - statefulsets + verbs: ["list", "watch"] + +- apiGroups: ["storage.k8s.io"] + resources: + - storageclasses + verbs: ["list", "watch"] + +- apiGroups: ["admissionregistration.k8s.io"] + resources: + - validatingwebhookconfigurations + verbs: ["list", "watch"] + +- apiGroups: ["storage.k8s.io"] + resources: + - volumeattachments + verbs: ["list", "watch"] diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/service.yaml new file mode 100644 index 00000000000..2f7a41887f6 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/service.yaml @@ -0,0 +1,29 @@ +--- +# Source: opentelemetry-kube-stack/charts/kube-state-metrics/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: example-kube-state-metrics + namespace: default + labels: + helm.sh/chart: kube-state-metrics-5.21.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: kube-state-metrics + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/instance: example + app.kubernetes.io/version: "2.12.0" + release: example + annotations: + prometheus.io/scrape: 'true' +spec: + type: "ClusterIP" + ports: + - name: "http" + protocol: TCP + port: 8080 + targetPort: 8080 + + selector: + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/instance: example diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/serviceaccount.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/serviceaccount.yaml new file mode 100644 index 00000000000..9d832c027c4 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/serviceaccount.yaml @@ -0,0 +1,17 @@ +--- +# Source: opentelemetry-kube-stack/charts/kube-state-metrics/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: true +metadata: + labels: + helm.sh/chart: kube-state-metrics-5.21.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: kube-state-metrics + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/instance: example + app.kubernetes.io/version: "2.12.0" + release: example + name: example-kube-state-metrics + namespace: default diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/servicemonitor.yaml new file mode 100644 index 00000000000..15087850739 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/kube-state-metrics/servicemonitor.yaml @@ -0,0 +1,25 @@ +--- +# Source: opentelemetry-kube-stack/charts/kube-state-metrics/templates/servicemonitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-kube-state-metrics + namespace: default + labels: + helm.sh/chart: kube-state-metrics-5.21.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: kube-state-metrics + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/instance: example + app.kubernetes.io/version: "2.12.0" + release: example +spec: + jobLabel: app.kubernetes.io/name + selector: + matchLabels: + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/instance: example + endpoints: + - port: http + honorLabels: true diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/admission-webhooks/operator-webhook-with-cert-manager.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/admission-webhooks/operator-webhook-with-cert-manager.yaml new file mode 100644 index 00000000000..9e3a9f22cf6 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/admission-webhooks/operator-webhook-with-cert-manager.yaml @@ -0,0 +1,192 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: default/example-opentelemetry-operator-serving-cert + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-mutation +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /mutate-opentelemetry-io-v1alpha1-instrumentation + port: 443 + failurePolicy: Ignore + name: minstrumentation.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /mutate-opentelemetry-io-v1beta1-opentelemetrycollector + port: 443 + failurePolicy: Ignore + name: mopentelemetrycollectorbeta.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /mutate-v1-pod + port: 443 + failurePolicy: Ignore + name: mpod.kb.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: default/example-opentelemetry-operator-serving-cert + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-validation +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1alpha1-instrumentation + port: 443 + failurePolicy: Ignore + name: vinstrumentationcreateupdate.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1alpha1-instrumentation + port: 443 + failurePolicy: Ignore + name: vinstrumentationdelete.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1alpha1 + operations: + - DELETE + resources: + - instrumentations + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1beta1-opentelemetrycollector + port: 443 + failurePolicy: Ignore + name: vopentelemetrycollectorcreateupdatebeta.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: example-opentelemetry-operator-webhook + namespace: default + path: /validate-opentelemetry-io-v1beta1-opentelemetrycollector + port: 443 + failurePolicy: Ignore + name: vopentelemetrycollectordeletebeta.kb.io + rules: + - apiGroups: + - opentelemetry.io + apiVersions: + - v1beta1 + operations: + - DELETE + resources: + - opentelemetrycollectors + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/admission-webhooks/operator-webhook.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/admission-webhooks/operator-webhook.yaml new file mode 100644 index 00000000000..5b9ff5511db --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/admission-webhooks/operator-webhook.yaml @@ -0,0 +1,3 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/admission-webhooks/operator-webhook.yaml +--- diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/certmanager.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/certmanager.yaml new file mode 100644 index 00000000000..55aae15269d --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/certmanager.yaml @@ -0,0 +1,43 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/certmanager.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-serving-cert + namespace: default +spec: + dnsNames: + - example-opentelemetry-operator-webhook.default.svc + - example-opentelemetry-operator-webhook.default.svc.cluster.local + issuerRef: + kind: Issuer + name: example-opentelemetry-operator-selfsigned-issuer + secretName: example-opentelemetry-operator-controller-manager-service-cert + subject: + organizationalUnits: + - example-opentelemetry-operator +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/certmanager.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + name: example-opentelemetry-operator-selfsigned-issuer + namespace: default +spec: + selfSigned: {} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/clusterrole.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/clusterrole.yaml new file mode 100644 index 00000000000..3a660a25fbf --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/clusterrole.yaml @@ -0,0 +1,265 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-manager +rules: + - apiGroups: + - "" + resources: + - configmaps + - persistentvolumeclaims + - persistentvolumes + - pods + - serviceaccounts + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - list + - watch + - apiGroups: + - apps + resources: + - daemonsets + - deployments + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + - extensions + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - batch + resources: + - jobs + verbs: + - get + - list + - watch + - apiGroups: + - config.openshift.io + resources: + - infrastructures + - infrastructures/status + verbs: + - get + - list + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - list + - update + - apiGroups: + - monitoring.coreos.com + resources: + - podmonitors + - servicemonitors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - instrumentations + verbs: + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opampbridges + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opampbridges/finalizers + verbs: + - update + - apiGroups: + - opentelemetry.io + resources: + - opampbridges/status + verbs: + - get + - patch + - update + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors + verbs: + - get + - list + - patch + - update + - watch + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors/finalizers + verbs: + - get + - patch + - update + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors/status + verbs: + - get + - patch + - update + - apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-metrics +rules: + - nonResourceURLs: + - /metrics + verbs: + - get +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-proxy +rules: + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/clusterrolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/clusterrolebinding.yaml new file mode 100644 index 00000000000..106408a6d95 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/clusterrolebinding.yaml @@ -0,0 +1,44 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: example-opentelemetry-operator-manager +subjects: + - kind: ServiceAccount + name: opentelemetry-operator + namespace: default +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/clusterrolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-proxy +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: example-opentelemetry-operator-proxy +subjects: + - kind: ServiceAccount + name: opentelemetry-operator + namespace: default diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/deployment.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/deployment.yaml new file mode 100644 index 00000000000..300068ce046 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/deployment.yaml @@ -0,0 +1,105 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager + spec: + hostNetwork: false + containers: + - args: + - --metrics-addr=0.0.0.0:8080 + - --enable-leader-election + - --health-probe-addr=:8081 + - --webhook-port=9443 + - --collector-image=otel/opentelemetry-collector-k8s:0.110.0 + command: + - /manager + env: + - name: ENABLE_WEBHOOKS + value: "true" + image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.110.0" + name: manager + ports: + - containerPort: 8080 + name: metrics + protocol: TCP + - containerPort: 9443 + name: webhook-server + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 64Mi + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: "quay.io/brancz/kube-rbac-proxy:v0.15.0" + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + serviceAccountName: opentelemetry-operator + terminationGracePeriodSeconds: 10 + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: example-opentelemetry-operator-controller-manager-service-cert + securityContext: + fsGroup: 65532 + runAsGroup: 65532 + runAsNonRoot: true + runAsUser: 65532 diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/role.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/role.yaml new file mode 100644 index 00000000000..a6435f42f9b --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/role.yaml @@ -0,0 +1,43 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-leader-election + namespace: default +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/rolebinding.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/rolebinding.yaml new file mode 100644 index 00000000000..65b49be0533 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/rolebinding.yaml @@ -0,0 +1,23 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-leader-election + namespace: default +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: example-opentelemetry-operator-leader-election +subjects: + - kind: ServiceAccount + name: opentelemetry-operator + namespace: default diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/service.yaml new file mode 100644 index 00000000000..8b4ef9a0a9a --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/service.yaml @@ -0,0 +1,51 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator + namespace: default +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + - name: metrics + port: 8080 + protocol: TCP + targetPort: metrics + selector: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + name: example-opentelemetry-operator-webhook + namespace: default +spec: + ports: + - port: 443 + protocol: TCP + targetPort: webhook-server + selector: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/component: controller-manager diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/serviceaccount.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/serviceaccount.yaml new file mode 100644 index 00000000000..e89ef1d2438 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/serviceaccount.yaml @@ -0,0 +1,15 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: opentelemetry-operator + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/tests/test-certmanager-connection.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/tests/test-certmanager-connection.yaml new file mode 100644 index 00000000000..8bc9114a528 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/tests/test-certmanager-connection.yaml @@ -0,0 +1,38 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-certmanager-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "example-opentelemetry-operator-cert-manager" + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: webhook + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "busybox:latest" + env: + - name: CERT_MANAGER_CLUSTERIP + value: "cert-manager-webhook" + - name: CERT_MANAGER_PORT + value: "443" + command: + - sh + - -c + # The following shell script tests if the cert-manager service is up. If the service is up, when we try + # to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$CERT_MANAGER_CLUSTERIP:$CERT_MANAGER_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/tests/test-service-connection.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/tests/test-service-connection.yaml new file mode 100644 index 00000000000..15f120d40da --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/opentelemetry-operator/tests/test-service-connection.yaml @@ -0,0 +1,76 @@ +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-service-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "example-opentelemetry-operator-metrics" + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "busybox:latest" + env: + - name: MANAGER_METRICS_SERVICE_CLUSTERIP + value: "example-opentelemetry-operator" + - name: MANAGER_METRICS_SERVICE_PORT + value: "8443" + command: + - sh + - -c + # The following shell script tests if the controller-manager-metrics-service is up. + # If the service is up, when we try to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$MANAGER_METRICS_SERVICE_CLUSTERIP:$MANAGER_METRICS_SERVICE_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never +--- +# Source: opentelemetry-kube-stack/charts/opentelemetry-operator/templates/tests/test-service-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "example-opentelemetry-operator-webhook" + namespace: default + labels: + helm.sh/chart: opentelemetry-operator-0.71.1 + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/version: "0.110.0" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: example + + app.kubernetes.io/component: controller-manager + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: "busybox:latest" + env: + - name: WEBHOOK_SERVICE_CLUSTERIP + value: "example-opentelemetry-operator-webhook" + - name: WEBHOOK_SERVICE_PORT + value: "443" + command: + - sh + - -c + # The following shell script tests if the webhook service is up. If the service is up, when we try + # to wget its exposed port, we will get an HTTP error 400. + - | + wget_output=$(wget -q "$WEBHOOK_SERVICE_CLUSTERIP:$WEBHOOK_SERVICE_PORT") + if wget_output=="wget: server returned error: HTTP/1.0 400 Bad Request" + then exit 0 + else exit 1 + fi + restartPolicy: Never diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/daemonset.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/daemonset.yaml new file mode 100644 index 00000000000..b3d5941307f --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/daemonset.yaml @@ -0,0 +1,121 @@ +--- +# Source: opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/daemonset.yaml +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: example-prometheus-node-exporter + namespace: default + labels: + helm.sh/chart: prometheus-node-exporter-4.37.3 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: prometheus-node-exporter + app.kubernetes.io/name: prometheus-node-exporter + app.kubernetes.io/instance: example + app.kubernetes.io/version: "1.8.2" + jobLabel: node-exporter + release: example +spec: + selector: + matchLabels: + app.kubernetes.io/name: prometheus-node-exporter + app.kubernetes.io/instance: example + revisionHistoryLimit: 10 + updateStrategy: + rollingUpdate: + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + annotations: + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + labels: + helm.sh/chart: prometheus-node-exporter-4.37.3 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: prometheus-node-exporter + app.kubernetes.io/name: prometheus-node-exporter + app.kubernetes.io/instance: example + app.kubernetes.io/version: "1.8.2" + jobLabel: node-exporter + release: example + spec: + automountServiceAccountToken: false + securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + serviceAccountName: example-prometheus-node-exporter + containers: + - name: node-exporter + image: quay.io/prometheus/node-exporter:v1.8.2 + imagePullPolicy: IfNotPresent + args: + - --path.procfs=/host/proc + - --path.sysfs=/host/sys + - --path.rootfs=/host/root + - --path.udev.data=/host/root/run/udev/data + - --web.listen-address=[$(HOST_IP)]:9100 + - --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/.+)($|/) + - --collector.filesystem.fs-types-exclude=^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$ + securityContext: + readOnlyRootFilesystem: true + env: + - name: HOST_IP + value: 0.0.0.0 + ports: + - name: http-metrics + containerPort: 9100 + protocol: TCP + livenessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: + path: / + port: 9100 + scheme: HTTP + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + readinessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: + path: / + port: 9100 + scheme: HTTP + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + volumeMounts: + - name: proc + mountPath: /host/proc + readOnly: true + - name: sys + mountPath: /host/sys + readOnly: true + - name: root + mountPath: /host/root + mountPropagation: HostToContainer + readOnly: true + hostNetwork: true + hostPID: true + hostIPC: false + nodeSelector: + kubernetes.io/os: linux + tolerations: + - effect: NoSchedule + operator: Exists + volumes: + - name: proc + hostPath: + path: /proc + - name: sys + hostPath: + path: /sys + - name: root + hostPath: + path: / diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/service.yaml new file mode 100644 index 00000000000..5f784543990 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/service.yaml @@ -0,0 +1,29 @@ +--- +# Source: opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: example-prometheus-node-exporter + namespace: default + labels: + helm.sh/chart: prometheus-node-exporter-4.37.3 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: prometheus-node-exporter + app.kubernetes.io/name: prometheus-node-exporter + app.kubernetes.io/instance: example + app.kubernetes.io/version: "1.8.2" + jobLabel: node-exporter + release: example + annotations: + prometheus.io/scrape: "true" +spec: + type: ClusterIP + ports: + - port: 9100 + targetPort: 9100 + protocol: TCP + name: http-metrics + selector: + app.kubernetes.io/name: prometheus-node-exporter + app.kubernetes.io/instance: example diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/serviceaccount.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/serviceaccount.yaml new file mode 100644 index 00000000000..daadacc1030 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/serviceaccount.yaml @@ -0,0 +1,18 @@ +--- +# Source: opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: example-prometheus-node-exporter + namespace: default + labels: + helm.sh/chart: prometheus-node-exporter-4.37.3 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: prometheus-node-exporter + app.kubernetes.io/name: prometheus-node-exporter + app.kubernetes.io/instance: example + app.kubernetes.io/version: "1.8.2" + jobLabel: node-exporter + release: example +automountServiceAccountToken: false diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/servicemonitor.yaml new file mode 100644 index 00000000000..f450d12eb28 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/rendered/prometheus-node-exporter/servicemonitor.yaml @@ -0,0 +1,29 @@ +--- +# Source: opentelemetry-kube-stack/charts/prometheus-node-exporter/templates/servicemonitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-prometheus-node-exporter + namespace: default + labels: + helm.sh/chart: prometheus-node-exporter-4.37.3 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/component: metrics + app.kubernetes.io/part-of: prometheus-node-exporter + app.kubernetes.io/name: prometheus-node-exporter + app.kubernetes.io/instance: example + app.kubernetes.io/version: "1.8.2" + jobLabel: node-exporter + release: example +spec: + jobLabel: jobLabel + + selector: + matchLabels: + app.kubernetes.io/name: prometheus-node-exporter + app.kubernetes.io/instance: example + attachMetadata: + node: false + endpoints: + - port: http-metrics + scheme: http diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/values.yaml new file mode 100644 index 00000000000..e0060ed7d40 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/examples/prometheus-otel/values.yaml @@ -0,0 +1,70 @@ +clusterName: demo +collectors: + daemon: + enabled: true + # because this file is inside the examples folder, we need to reference it directly. + scrape_configs_file: "examples/prometheus-otel/kubelet_scrape_configs.yaml" + # Adding an additional label for this collctor. + labels: + otel-collector-type: daemonset-example + targetAllocator: + enabled: true + image: ghcr.io/open-telemetry/opentelemetry-operator/target-allocator:main + allocationStrategy: per-node + prometheusCR: + enabled: true + podMonitorSelector: {} + scrapeInterval: "30s" + serviceMonitorSelector: {} + config: + exporters: + otlp: + endpoint: ingest.example.com:443 + headers: + "access-token": "${ACCESS_TOKEN}" + service: + pipelines: + metrics: + receivers: [prometheus] + exporters: [debug, otlp] + env: + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + key: access_token + name: otel-collector-secret + presets: + logsCollection: + enabled: false + kubeletMetrics: + enabled: false + hostMetrics: + enabled: false + kubernetesAttributes: + enabled: false + cluster: + enabled: false +instrumentation: + enabled: false +opAMPBridge: + enabled: false +kubernetesServiceMonitors: + enabled: true +kubeApiServer: + enabled: true +kubelet: + enabled: true +kubeControllerManager: + enabled: true +kubeDns: + enabled: true +kubeEtcd: + enabled: true +kubeScheduler: + enabled: true +kubeProxy: + enabled: true +kubeStateMetrics: + enabled: true +nodeExporter: + enabled: true diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/_config.tpl b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/_config.tpl new file mode 100644 index 00000000000..d432767844d --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/_config.tpl @@ -0,0 +1,345 @@ +{{/* +Constructs the final config for the given collector + +This allows a user to supply a scrape_configs_file. This file is templated and loaded as a yaml array. +If a user has already supplied a prometheus receiver config, the file's config is appended. Finally, +the config is written as YAML. +*/}} +{{- define "opentelemetry-kube-stack.config" -}} +{{- $collector := .collector }} +{{- $config := .collector.config }} +{{- if .collector.scrape_configs_file }} +{{- $config = (include "opentelemetry-kube-stack.collector.appendPrometheusScrapeFile" . | fromYaml) }} +{{- $_ := set $collector "config" $config }} +{{- end }} +{{- if .collector.presets.kubernetesAttributes.enabled }} +{{- $config = (include "opentelemetry-kube-stack.collector.applyKubernetesAttributesConfig" (dict "collector" $collector) | fromYaml) }} +{{- $_ := set $collector "config" $config }} +{{- end }} +{{- if .collector.presets.logsCollection.enabled }} +{{- $_ := set $collector "exclude" (printf "/var/log/pods/%s_%s*_*/%s/*.log" .namespace (include "opentelemetry-kube-stack.collectorFullname" .) (.Chart.Name | lower)) }} +{{- $config = (include "opentelemetry-kube-stack.collector.applyLogsCollectionConfig" (dict "collector" $collector) | fromYaml) -}} +{{- $_ := set $collector "config" $config }} +{{- end }} +{{- if .collector.presets.hostMetrics.enabled }} +{{- $config = (include "opentelemetry-kube-stack.collector.applyHostMetricsConfig" (dict "collector" $collector) | fromYaml) -}} +{{- $_ := set $collector "config" $config }} +{{- end }} +{{- if .collector.presets.kubernetesAttributes.enabled }} +{{- $config = (include "opentelemetry-kube-stack.collector.applyKubernetesAttributesConfig" (dict "collector" $collector) | fromYaml) -}} +{{- $_ := set $collector "config" $config }} +{{- end }} +{{- if .collector.presets.kubeletMetrics.enabled }} +{{- $config = (include "opentelemetry-kube-stack.collector.applyKubeletMetricsConfig" (dict "collector" $collector) | fromYaml) -}} +{{- $_ := set $collector "config" $config }} +{{- end }} +{{- if .collector.presets.kubernetesEvents.enabled }} +{{- $config = (include "opentelemetry-kube-stack.collector.applyKubernetesEventsConfig" (dict "collector" $collector) | fromYaml) -}} +{{- $_ := set $collector "config" $config }} +{{- end }} +{{- if .collector.presets.clusterMetrics.enabled }} +{{- $config = (include "opentelemetry-kube-stack.collector.applyClusterMetricsConfig" (dict "collector" $collector) | fromYaml) -}} +{{- $_ := set $collector "config" $config }} +{{- end }} +{{- toYaml $collector.config | nindent 4 }} +{{- end }} + +{{/* +This helper allows a user to load in an external scrape configs file directly from prometheus. +The helper will load and then append the scrape configs list to an existing prometheus scraper. +If no prometheus configuration is present, the prometheus configuration is added. + +This helper ultimately assists users in getting started with Kubernetes infra metrics from scratch +OR helps them easily port prometheus to the otel-kube-stack chart with no changes to their prometheus config. +*/}} +{{- define "opentelemetry-kube-stack.collector.appendPrometheusScrapeFile" -}} +{{- $loaded_file := (.Files.Get .collector.scrape_configs_file) }} +{{- $loaded_config := (fromYamlArray (tpl $loaded_file .)) }} +{{- $prom_override := (dict "receivers" (dict "prometheus" (dict "config" (dict "scrape_configs" $loaded_config)))) }} +{{- if (dig "receivers" "prometheus" "config" "scrape_configs" false .collector.config) }} +{{- $merged_prom_scrape_configs := (concat .collector.config.receivers.prometheus.config.scrape_configs $loaded_config) }} +{{- $prom_override = (dict "receivers" (dict "prometheus" (dict "config" (dict "scrape_configs" $merged_prom_scrape_configs)))) }} +{{- end }} +{{- if and (dig "service" "pipelines" "metrics" false .collector.config) (not (has "prometheus" (dig "service" "pipelines" "metrics" "receivers" list .collector.config))) }} +{{- $_ := set .collector.config.service.pipelines.metrics "receivers" (prepend (.collector.config.service.pipelines.metrics.receivers | default list) "prometheus" | uniq) }} +{{- end }} +{{- (mergeOverwrite .collector.config $prom_override) | toYaml }} +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.applyKubernetesAttributesConfig" -}} +{{- $config := mustMergeOverwrite (include "opentelemetry-kube-stack.collector.kubernetesAttributesConfig" .collector | fromYaml) .collector.config }} +{{- if and (dig "service" "pipelines" "logs" false $config) (not (has "k8sattributes" (dig "service" "pipelines" "logs" "processors" list $config))) }} +{{- $_ := set $config.service.pipelines.logs "processors" (prepend ($config.service.pipelines.logs.processors | default list) "k8sattributes" | uniq) }} +{{- end }} +{{- if and (dig "service" "pipelines" "metrics" false $config) (not (has "k8sattributes" (dig "service" "pipelines" "metrics" "processors" list $config))) }} +{{- $_ := set $config.service.pipelines.metrics "processors" (prepend ($config.service.pipelines.metrics.processors | default list) "k8sattributes" | uniq) }} +{{- end }} +{{- if and (dig "service" "pipelines" "traces" false $config) (not (has "k8sattributes" (dig "service" "pipelines" "traces" "processors" list $config))) }} +{{- $_ := set $config.service.pipelines.traces "processors" (prepend ($config.service.pipelines.traces.processors | default list) "k8sattributes" | uniq) }} +{{- end }} +{{- $config | toYaml }} +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.kubernetesAttributesConfig" -}} +processors: + k8sattributes: + {{- if eq .mode "daemonset" }} + filter: + node_from_env_var: K8S_NODE_NAME + {{- end }} + passthrough: false + pod_association: + - sources: + - from: resource_attribute + name: k8s.pod.uid + - sources: + - from: resource_attribute + name: k8s.pod.name + - from: resource_attribute + name: k8s.namespace.name + - from: resource_attribute + name: k8s.node.name + - sources: + - from: resource_attribute + name: k8s.pod.ip + - sources: + - from: resource_attribute + name: k8s.pod.name + - from: resource_attribute + name: k8s.namespace.name + - sources: + - from: connection + extract: + metadata: + - k8s.namespace.name + - k8s.pod.name + - k8s.pod.uid + - k8s.node.name + - k8s.pod.start_time + - k8s.deployment.name + - k8s.replicaset.name + - k8s.replicaset.uid + - k8s.daemonset.name + - k8s.daemonset.uid + - k8s.job.name + - k8s.job.uid + - k8s.container.name + - k8s.cronjob.name + - k8s.statefulset.name + - k8s.statefulset.uid + - container.image.tag + - container.image.name + - k8s.cluster.uid + labels: + - tag_name: service.name + key: app.kubernetes.io/name + from: pod + - tag_name: service.name + key: k8s-app + from: pod + - tag_name: k8s.app.instance + key: app.kubernetes.io/instance + from: pod + - tag_name: service.version + key: app.kubernetes.io/version + from: pod + - tag_name: k8s.app.component + key: app.kubernetes.io/component + from: pod + {{- if .presets.kubernetesAttributes.extractAllPodLabels }} + - tag_name: $$1 + key_regex: (.*) + from: pod + {{- end }} + {{- if .presets.kubernetesAttributes.extractAllPodAnnotations }} + annotations: + - tag_name: $$1 + key_regex: (.*) + from: pod + {{- end }} +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.applyHostMetricsConfig" -}} +{{- $config := mustMergeOverwrite (include "opentelemetry-kube-stack.collector.hostMetricsConfig" .collector | fromYaml) .collector.config }} +{{- if and (dig "service" "pipelines" "metrics" false $config) (not (has "hostmetrics" (dig "service" "pipelines" "metrics" "receivers" list $config))) }} +{{- $_ := set $config.service.pipelines.metrics "receivers" (append ($config.service.pipelines.metrics.receivers | default list) "hostmetrics" | uniq) }} +{{- end }} +{{- $config | toYaml }} +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.hostMetricsConfig" -}} +receivers: + hostmetrics: + root_path: /hostfs + collection_interval: 10s + scrapers: + cpu: + metrics: + system.cpu.utilization: + enabled: true + load: {} + memory: + metrics: + system.memory.utilization: + enabled: true + disk: {} + filesystem: + metrics: + system.filesystem.utilization: + enabled: true + exclude_mount_points: + mount_points: + - /dev/* + - /proc/* + - /sys/* + - /run/k3s/containerd/* + - /var/lib/docker/* + - /var/lib/kubelet/* + - /snap/* + match_type: regexp + exclude_fs_types: + fs_types: + - autofs + - binfmt_misc + - bpf + - cgroup2 + - configfs + - debugfs + - devpts + - devtmpfs + - fusectl + - hugetlbfs + - iso9660 + - mqueue + - nsfs + - overlay + - proc + - procfs + - pstore + - rpc_pipefs + - securityfs + - selinuxfs + - squashfs + - sysfs + - tracefs + match_type: strict + network: {} +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.applyClusterMetricsConfig" -}} +{{- $config := mustMergeOverwrite (include "opentelemetry-kube-stack.collector.clusterMetricsConfig" .collector | fromYaml) .collector.config }} +{{- if and (dig "service" "pipelines" "metrics" false $config) (not (has "k8s_cluster" (dig "service" "pipelines" "metrics" "receivers" list $config))) }} +{{- $_ := set $config.service.pipelines.metrics "receivers" (append ($config.service.pipelines.metrics.receivers | default list) "k8s_cluster" | uniq) }} +{{- end }} +{{- $config | toYaml }} +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.clusterMetricsConfig" -}} +receivers: + k8s_cluster: + collection_interval: 10s + auth_type: serviceAccount + node_conditions_to_report: [Ready, MemoryPressure, DiskPressure, NetworkUnavailable] + allocatable_types_to_report: [cpu, memory, storage] +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.applyKubeletMetricsConfig" -}} +{{- $config := mustMergeOverwrite (include "opentelemetry-kube-stack.collector.kubeletMetricsConfig" .collector | fromYaml) .collector.config }} +{{- if and (dig "service" "pipelines" "metrics" false $config) (not (has "kubeletstats" (dig "service" "pipelines" "metrics" "receivers" list $config))) }} +{{- $_ := set $config.service.pipelines.metrics "receivers" (append ($config.service.pipelines.metrics.receivers | default list) "kubeletstats" | uniq) }} +{{- end }} +{{- $config | toYaml }} +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.kubeletMetricsConfig" -}} +receivers: + kubeletstats: + collection_interval: "15s" + auth_type: "serviceAccount" + insecure_skip_verify: true + # For this scrape to work, the RBAC must have `nodes/stats` GET access. + endpoint: "https://${env:OTEL_K8S_NODE_IP}:10250" + extra_metadata_labels: + - container.id + - k8s.volume.type + metric_groups: + - node + - pod + - volume + - container + k8s_api_config: + auth_type: serviceAccount + metrics: + # k8s.pod.cpu.utilization is being deprecated + k8s.pod.cpu.usage: + enabled: true + container.cpu.usage: + enabled: true + k8s.node.cpu.usage: + enabled: true + k8s.node.uptime: + enabled: true + k8s.pod.uptime: + enabled: true +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.applyLogsCollectionConfig" -}} +{{- $config := mustMergeOverwrite (include "opentelemetry-kube-stack.collector.logsCollectionConfig" .collector | fromYaml) .collector.config }} +{{- if and (dig "service" "pipelines" "logs" false $config) (not (has "filelog" (dig "service" "pipelines" "logs" "receivers" list $config))) }} +{{- $_ := set $config.service.pipelines.logs "receivers" (append ($config.service.pipelines.logs.receivers | default list) "filelog" | uniq) }} +{{- end }} +{{- if .collector.presets.logsCollection.storeCheckpoints}} +{{- $_ := set $config.service "extensions" (append ($config.service.extensions | default list) "file_storage" | uniq) }} +{{- end }} +{{- $config | toYaml }} +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.logsCollectionConfig" -}} +{{- if .presets.logsCollection.storeCheckpoints }} +extensions: + file_storage: + directory: /var/lib/otelcol +{{- end }} +receivers: + filelog: + include: + - /var/log/pods/*/*/*.log + {{- if .presets.logsCollection.includeCollectorLogs }} + exclude: [] + {{- else }} + # Exclude collector container's logs. The file format is /var/log/pods/__//.log + exclude: {{ .exclude }} + {{- end }} + start_at: end + retry_on_failure: + enabled: true + {{- if .presets.logsCollection.storeCheckpoints}} + storage: file_storage + {{- end }} + include_file_path: true + include_file_name: false + operators: + # parse container logs + - type: container + id: container-parser + max_log_size: {{ .presets.logsCollection.maxRecombineLogSize }} +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.applyKubernetesEventsConfig" -}} +{{- $config := mustMergeOverwrite (include "opentelemetry-kube-stack.collector.kubernetesEventsConfig" .collector | fromYaml) .collector.config }} +{{- if and (dig "service" "pipelines" "logs" false $config) (not (has "k8sobjects" (dig "service" "pipelines" "logs" "receivers" list $config))) }} +{{- $_ := set $config.service.pipelines.logs "receivers" (append ($config.service.pipelines.logs.receivers | default list) "k8sobjects" | uniq) }} +{{- end }} +{{- $config | toYaml }} +{{- end }} + +{{- define "opentelemetry-kube-stack.collector.kubernetesEventsConfig" -}} +receivers: + k8sobjects: + objects: + - name: events + mode: "watch" + group: "events.k8s.io" + exclude_watch_type: + - "DELETED" +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/_helpers.tpl b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/_helpers.tpl new file mode 100644 index 00000000000..f5d18b8a2e4 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/_helpers.tpl @@ -0,0 +1,307 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "opentelemetry-kube-stack.name" -}} +{{- default .Chart.Name | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "opentelemetry-kube-stack.fullname" -}} +{{- if .fullnameOverride }} +{{- .fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + + +{{/* +Add the opamp labels if they're enabled +*/}} +{{- define "opentelemetry-kube-stack.collectorOpAMPLabels" -}} +{{- if and .opAMPBridge.enabled .opAMPBridge.addReportingLabel }} +opentelemetry.io/opamp-reporting: "true" +{{- end }} +{{- if and .opAMPBridge.enabled .opAMPBridge.addManagedLabel }} +opentelemetry.io/opamp-managed: "true" +{{- end }} +{{- end }} + +{{/* +Allow the release namespace to be overridden +*/}} +{{- define "opentelemetry-kube-stack.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Print a map of key values in a YAML block. This is useful for labels and annotations. +*/}} +{{- define "opentelemetry-kube-stack.renderkv" -}} +{{- with . -}} +{{- range $key, $value := . -}} +{{- printf "\n%s: %s" $key $value }} +{{- end -}} +{{- end -}} +{{- end }} + +{{/* +Render a deduped list of environment variables and 'extraEnvs' +*/}} +{{- define "opentelemetry-kube-stack.renderenvs" -}} +{{- $envMap := dict }} +{{- $valueFromMap := dict }} +{{- range $item := .extraEnvs }} +{{- if $item.value }} +{{- $_ := set $envMap $item.name $item.value }} +{{- else }} +{{- $_ := set $valueFromMap $item.name $item.valueFrom }} +{{- end }} +{{- end }} +{{- range $item := .env }} +{{- if $item.value }} +{{- $_ := set $envMap $item.name $item.value }} +{{- else }} +{{- $_ := set $valueFromMap $item.name $item.valueFrom }} +{{- end }} +{{- end }} +{{- range $key, $value := $envMap }} +- name: {{ $key }} + value: {{ $value }} +{{- end }} +{{- range $key, $value := $valueFromMap }} +- name: {{ $key }} + valueFrom: + {{- $value | toYaml | nindent 4 }} +{{- end }} +{{- end }} + +{{/* +Create the name of the instrumentation to use +*/}} +{{- define "opentelemetry-kube-stack.instrumentation" -}} +{{- default .Release.Name .Values.instrumentation.name }} +{{- end }} + +{{/* +Create the name of the bridge to create +*/}} +{{- define "opentelemetry-opamp-bridge.fullname" -}} +{{- default .Release.Name .opAMPBridge.name }} +{{- end }} + +{{/* +Create the name of the clusterRole to use for the opampbridge +*/}} +{{- define "opentelemetry-opamp-bridge.clusterRoleName" -}} +{{- default (printf "%s-bridge" .Release.Name) .Values.opAMPBridge.clusterRole.name }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "opentelemetry-kube-stack.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "opentelemetry-kube-stack.labels" -}} +helm.sh/chart: {{ include "opentelemetry-kube-stack.chart" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +release: {{ .Release.Name | quote }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "opentelemetry-kube-stack.collectorFullname" -}} +{{- if .fullnameOverride }} +{{- .fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else if .collector.fullnameOverride }} +{{- .collector.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $suffix := default .Chart.Name (coalesce .collector.suffix "") }} +{{- if contains $suffix .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $suffix | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create the name of the clusterRole to use +*/}} +{{- define "opentelemetry-kube-stack.clusterRoleName" -}} +{{- default (printf "%s-collector" .Release.Name) .Values.clusterRole.name }} +{{- end }} + +{{/* +Create the name of the clusterRoleBinding to use +*/}} +{{- define "opentelemetry-kube-stack.clusterRoleBindingName" -}} +{{- default (include "opentelemetry-kube-stack.fullname" .) .Values.clusterRole.clusterRoleBinding.name }} +{{- end }} + +{{/* +Optionally include the RBAC for the k8sCluster receiver +*/}} +{{- define "opentelemetry-kube-stack.k8scluster.rules" -}} +{{- if $.Values.clusterRole.rules }} +{{ toYaml $.Values.clusterRole.rules }} +{{- end }} +{{- $clusterMetricsEnabled := false }} +{{- $eventsEnabled := false }} +{{ range $_, $collector := $.Values.collectors -}} +{{- $clusterMetricsEnabled = (any $clusterMetricsEnabled (dig "config" "receivers" "k8s_cluster" false $collector)) }} +{{- if (dig "presets" "clusterMetrics" "enabled" false $collector) }} +{{- $clusterMetricsEnabled = true }} +{{- end }} +{{- $eventsEnabled = (any $eventsEnabled (dig "config" "receivers" "k8s_cluster" false $collector)) }} +{{- if (dig "presets" "kubernetesEvents" "enabled" false $collector) }} +{{- $eventsEnabled = true }} +{{- end }} +{{- end }} +{{- if $clusterMetricsEnabled }} +- apiGroups: + - "" + resources: + - events + - namespaces + - namespaces/status + - nodes + - nodes/spec + - pods + - pods/status + - replicationcontrollers + - replicationcontrollers/status + - resourcequotas + - services + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: + - get + - list + - watch +- apiGroups: + - extensions + resources: + - daemonsets + - deployments + - replicasets + verbs: + - get + - list + - watch +- apiGroups: + - batch + resources: + - jobs + - cronjobs + verbs: + - get + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - get + - list + - watch +{{- end }} +{{- if $eventsEnabled }} +- apiGroups: ["events.k8s.io"] + resources: ["events"] + verbs: ["watch", "list"] +{{- end }} +{{- end }} + +{{/* +Helpers for prometheus servicemonitors +*/}} +{{/* Prometheus specific stuff. */}} +{{/* Allow KubeVersion to be overridden. */}} +{{- define "opentelemetry-kube-stack.kubeVersion" -}} + {{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride -}} +{{- end -}} + +{{/* Get value based on current Kubernetes version */}} +{{- define "opentelemetry-kube-stack.kubeVersionDefaultValue" -}} + {{- $values := index . 0 -}} + {{- $kubeVersion := index . 1 -}} + {{- $old := index . 2 -}} + {{- $new := index . 3 -}} + {{- $default := index . 4 -}} + {{- if kindIs "invalid" $default -}} + {{- if semverCompare $kubeVersion (include "opentelemetry-kube-stack.kubeVersion" $values) -}} + {{- print $new -}} + {{- else -}} + {{- print $old -}} + {{- end -}} + {{- else -}} + {{- print $default }} + {{- end -}} +{{- end -}} + +{{/* Get value for kube-controller-manager depending on insecure scraping availability */}} +{{- define "opentelemetry-kube-stack.kubeControllerManager.insecureScrape" -}} + {{- $values := index . 0 -}} + {{- $insecure := index . 1 -}} + {{- $secure := index . 2 -}} + {{- $userValue := index . 3 -}} + {{- include "opentelemetry-kube-stack.kubeVersionDefaultValue" (list $values ">= 1.22-0" $insecure $secure $userValue) -}} +{{- end -}} + +{{/* Get value for kube-scheduler depending on insecure scraping availability */}} +{{- define "opentelemetry-kube-stack.kubeScheduler.insecureScrape" -}} + {{- $values := index . 0 -}} + {{- $insecure := index . 1 -}} + {{- $secure := index . 2 -}} + {{- $userValue := index . 3 -}} + {{- include "opentelemetry-kube-stack.kubeVersionDefaultValue" (list $values ">= 1.23-0" $insecure $secure $userValue) -}} +{{- end -}} + +{{/* Sets default scrape limits for servicemonitor */}} +{{- define "opentelemetry-kube-stack.servicemonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/bridge.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/bridge.yaml new file mode 100644 index 00000000000..e8ceb43c004 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/bridge.yaml @@ -0,0 +1,127 @@ +{{- if .Values.opAMPBridge.enabled }} +{{- $merged := (dict "Chart" $.Chart "clusterRole" $.Values.clusterRole "opAMPBridge" $.Values.opAMPBridge "Release" $.Release "fullnameOverride" $.Values.fullnameOverride) }} +--- +apiVersion: opentelemetry.io/v1alpha1 +kind: OpAMPBridge +metadata: + name: {{ include "opentelemetry-opamp-bridge.fullname" $merged }} + labels: + {{- include "opentelemetry-kube-stack.labels" $ | nindent 4 }} + {{- include "opentelemetry-kube-stack.renderkv" .Values.opAMPBridge.labels | indent 4 }} + {{- with .Values.opAMPBridge.annotations }} + annotations: + {{- include "opentelemetry-kube-stack.renderkv" . | nindent 4 }} + {{- end }} +spec: + endpoint: {{ required "opamp endpoint required" $.Values.opAMPBridge.endpoint }} + {{- with $.Values.opAMPBridge.headers }} + headers: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $.Values.opAMPBridge.capabilities }} + capabilities: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $.Values.opAMPBridge.componentsAllowed }} + componentsAllowed: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $.Values.opAMPBridge.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 4}} + {{- end }} + replicas: 1 + {{- if $.Values.opAMPBridge.serviceAccount }} + serviceAccount: {{ $.Values.opAMPBridge.serviceAccount }} + {{- end }} + {{- if $.Values.opAMPBridge.image.digest }} + image: "{{ $.Values.opAMPBridge.image.repository }}@{{ $.Values.opAMPBridge.image.digest }}" + {{- else }} + image: "{{ $.Values.opAMPBridge.image.repository }}:{{ $.Values.opAMPBridge.image.tag | default $.Chart.AppVersion }}" + {{- end }} + {{- if $.Values.opAMPBridge.upgradeStrategy }} + upgradeStrategy: {{ $.Values.opAMPBridge.upgradeStrategy }} + {{- end }} + {{- if $.Values.opAMPBridge.imagePullPolicy }} + imagePullPolicy: {{ $.Values.opAMPBridge.imagePullPolicy }} + {{- end }} + {{- if $.Values.opAMPBridge.hostNetwork }} + hostNetwork: {{ $.Values.opAMPBridge.hostNetwork }} + {{- end }} + {{- if $.Values.opAMPBridge.priorityClassName }} + priorityClassName: {{ $.Values.opAMPBridge.priorityClassName }} + {{- end }} + {{- with $.Values.opAMPBridge.securityContext }} + securityContext: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $.Values.opAMPBridge.podAnnotations }} + podAnnotations: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $.Values.opAMPBridge.resources }} + resources: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $.Values.opAMPBridge.affinity }} + affinity: + {{- toYaml . | nindent 4}} + {{- end }} + {{- if $.Values.opAMPBridge.tolerations }} + tolerations: + {{- with $.Values.opAMPBridge.tolerations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + {{- if $.Values.opAMPBridge.volumes }} + volumes: + {{- with $.Values.opAMPBridge.volumes }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + {{- if $.Values.opAMPBridge.topologySpreadConstraints }} + topologySpreadConstraints: + {{- with $.Values.opAMPBridge.topologySpreadConstraints }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + {{- if $.Values.opAMPBridge.volumeMounts }} + volumeMounts: + {{- with $.Values.opAMPBridge.volumeMounts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + {{- if $.Values.opAMPBridge.ports }} + ports: + {{- with $.Values.opAMPBridge.ports }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + env: + - name: OTEL_K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OTEL_K8S_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_K8S_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_K8S_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: OTEL_RESOURCE_ATTRIBUTES + value: "k8s.cluster.name={{ $.Values.clusterName }}" + {{- include "opentelemetry-kube-stack.renderenvs" (dict "extraEnvs" $.Values.extraEnvs "env" .Values.opAMPBridge.env) | nindent 2 }} + {{- with $.Values.opAMPBridge.envFrom }} + envFrom: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/clusterrole.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/clusterrole.yaml new file mode 100644 index 00000000000..a889aaec7b2 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/clusterrole.yaml @@ -0,0 +1,128 @@ +{{- if .Values.clusterRole.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "opentelemetry-kube-stack.clusterRoleName" . }} +rules: +- apiGroups: [""] + resources: + - namespaces + - nodes + - nodes/proxy + - nodes/metrics + - nodes/stats + - services + - endpoints + - pods + - events + - secrets + - persistentvolumeclaims + verbs: ["get", "list", "watch"] +- apiGroups: ["monitoring.coreos.com"] + resources: + - servicemonitors + - podmonitors + verbs: ["get", "list", "watch"] +- apiGroups: + - extensions + resources: + - ingresses + verbs: ["get", "list", "watch"] +- apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: ["get", "list", "watch"] +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: ["get", "list", "watch"] +- apiGroups: ["discovery.k8s.io"] + resources: + - endpointslices + verbs: ["get", "list", "watch"] +- nonResourceURLs: ["/metrics", "/metrics/cadvisor"] + verbs: ["get"] +{{- include "opentelemetry-kube-stack.k8scluster.rules" . }} +{{- end }} +{{ range $_, $collector := $.Values.collectors -}} +{{- if $collector.enabled -}} +{{- $collector := (mergeOverwrite (deepCopy $.Values.defaultCRConfig) $collector) }} +{{- $merged := (dict "Template" $.Template "Files" $.Files "Chart" $.Chart "clusterRole" $.Values.clusterRole "collector" $collector "Release" $.Release "fullnameOverride" $.Values.fullnameOverride "presets" $.Values.presets) }} +{{- $fullname := (include "opentelemetry-kube-stack.collectorFullname" $merged) }} +{{- if and $collector.enabled $collector.clusterRoleBinding.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ $fullname }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "opentelemetry-kube-stack.clusterRoleName" $ }} +subjects: +- kind: ServiceAccount + # quirk of the Operator +{{- if $collector.serviceAccount }} + name: "{{ $collector.serviceAccount }}" +{{- else }} + name: "{{ $fullname }}-collector" +{{- end }} + namespace: {{ $.Release.Namespace }} +{{- if $collector.targetAllocator.enabled }} +- kind: ServiceAccount +{{- if $collector.targetAllocator.serviceAccount }} + name: "{{ $collector.targetAllocator.serviceAccount }}" +{{- else }} + name: {{ $fullname }}-targetallocator +{{- end }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- if and $.Values.opAMPBridge.enabled $.Values.opAMPBridge.clusterRole.enabled }} +{{- $merged := (dict "Chart" $.Chart "clusterRole" $.Values.clusterRole "opAMPBridge" $.Values.opAMPBridge "Release" $.Release "fullnameOverride" $.Values.fullnameOverride) }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "opentelemetry-opamp-bridge.clusterRoleName" . }} +rules: + - apiGroups: + - opentelemetry.io + resources: + - opentelemetrycollectors + verbs: + - "*" + - apiGroups: + - "" + resources: + - pods + verbs: + - 'list' + - 'get' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "opentelemetry-opamp-bridge.fullname" $merged }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "{{ include "opentelemetry-opamp-bridge.clusterRoleName" . }}" +subjects: + - kind: ServiceAccount + # quirk of the Operator + {{- if $.Values.opAMPBridge.serviceAccount }} + name: "{{ $.Values.opAMPBridge.serviceAccount }}" + {{- else }} + name: "{{ (include "opentelemetry-opamp-bridge.fullname" $merged) }}-opamp-bridge" + {{- end }} + namespace: "{{ $.Release.Namespace }}" +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/collector.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/collector.yaml new file mode 100644 index 00000000000..b199132f1f7 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/collector.yaml @@ -0,0 +1,222 @@ +{{ range $_, $collector := $.Values.collectors -}} +{{- if $collector.enabled -}} +{{- $collector := (mergeOverwrite (deepCopy $.Values.defaultCRConfig) $collector) }} +{{- $merged := (dict "Template" $.Template "Files" $.Files "Chart" $.Chart "clusterRole" $.Values.clusterRole "collector" $collector "Release" $.Release "fullnameOverride" $.Values.fullnameOverride "presets" $.Values.presets "namespace" (include "opentelemetry-kube-stack.namespace" $) "kubelet" $.Values.kubelet) }} +{{- $fullname := (include "opentelemetry-kube-stack.collectorFullname" $merged) }} +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: {{ $fullname }} + namespace: {{ include "opentelemetry-kube-stack.namespace" $ }} + labels: + {{- include "opentelemetry-kube-stack.labels" $ | nindent 4 }} + {{- include "opentelemetry-kube-stack.renderkv" $collector.labels | indent 4 }} + {{- include "opentelemetry-kube-stack.collectorOpAMPLabels" $.Values | indent 4 }} + {{- with $collector.annotations }} + annotations: + {{- include "opentelemetry-kube-stack.renderkv" . | nindent 4 }} + {{- end }} +spec: + managementState: {{ $collector.managementState }} + mode: {{ $collector.mode }} + config: + {{- include "opentelemetry-kube-stack.config" $merged }} + {{- if (not (eq $collector.mode "daemonset" )) }} + replicas: {{ $collector.replicas }} + {{- end }} + {{- if $collector.serviceAccount }} + serviceAccount: {{ $collector.serviceAccount }} + {{- end }} + {{- if $collector.image.digest }} + image: "{{ $collector.image.repository }}@{{ $collector.image.digest }}" + {{- else if $collector.image.tag }} + image: "{{ $collector.image.repository }}:{{ $collector.image.tag }}" + {{- end }} + imagePullPolicy: {{ $collector.image.pullPolicy }} + upgradeStrategy: {{ $collector.upgradeStrategy }} + {{- if $collector.hostNetwork }} + hostNetwork: {{ $collector.hostNetwork }} + {{- end }} + {{- if $collector.shareProcessNamespace }} + shareProcessNamespace: {{ $collector.shareProcessNamespace }} + {{- end }} + {{- if $collector.priorityClassName }} + priorityClassName: {{ $collector.priorityClassName }} + {{- end }} + terminationGracePeriodSeconds: {{ $collector.terminationGracePeriodSeconds }} + {{- with $collector.resources }} + resources: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.args }} + args: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.autoscaler }} + autoscaler: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.podDisruptionBudget }} + podDisruptionBudget: + {{- toYaml . | nindent 4}} + {{- end }} + securityContext: + {{- if and (not ($collector.securityContext)) ($collector.presets.logsCollection.storeCheckpoints) }} + runAsUser: 0 + runAsGroup: 0 + {{- else -}} + {{- toYaml $collector.securityContext | nindent 4 }} + {{- end }} + {{- with $collector.podSecurityContext }} + podSecurityContext: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.podAnnotations }} + podAnnotations: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.targetAllocator }} + targetAllocator: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.ingress }} + ingress: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.affinity }} + affinity: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.lifecycle }} + lifecycle: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.observability }} + observability: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with $collector.deploymentUpdateStrategy }} + deploymentUpdateStrategy: + {{- toYaml . | nindent 4}} + {{- end }} + volumeMounts: + {{- if $collector.presets.logsCollection.enabled }} + - name: varlogpods + mountPath: /var/log/pods + readOnly: true + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + {{- if $collector.presets.logsCollection.storeCheckpoints}} + - name: varlibotelcol + mountPath: /var/lib/otelcol + {{- end }} + {{- end }} + {{- if $collector.presets.hostMetrics.enabled }} + - name: hostfs + mountPath: /hostfs + readOnly: true + mountPropagation: HostToContainer + {{- end }} + {{- with $collector.volumeMounts }} + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with $collector.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + env: + - name: OTEL_K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OTEL_K8S_NODE_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: OTEL_K8S_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_K8S_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_K8S_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + {{- if $.Values.clusterName }} + - name: OTEL_RESOURCE_ATTRIBUTES + value: "k8s.cluster.name={{ $.Values.clusterName }}" + {{- end }} + {{- include "opentelemetry-kube-stack.renderenvs" (dict "extraEnvs" $.Values.extraEnvs "env" $collector.env) | nindent 2 }} + {{- with $collector.envFrom }} + envFrom: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $collector.volumeClaimTemplates }} + volumeClaimTemplates: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $collector.tolerations }} + tolerations: + {{- toYaml . | nindent 4 }} + {{- end }} + volumes: + {{- if $collector.presets.logsCollection.enabled }} + - name: varlogpods + hostPath: + path: /var/log/pods + {{- if $collector.presets.logsCollection.storeCheckpoints}} + - name: varlibotelcol + hostPath: + path: /var/lib/otelcol + type: DirectoryOrCreate + {{- end }} + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + {{- end }} + {{- if $collector.presets.hostMetrics.enabled }} + - name: hostfs + hostPath: + path: / + {{- end }} + {{- with $collector.volumes }} + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with $collector.initContainers }} + initContainers: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $collector.additionalContainers }} + additionalContainers: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $collector.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $collector.configmaps }} + configmaps: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/core-dns/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/core-dns/service.yaml new file mode 100644 index 00000000000..04e1c9d1cca --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/core-dns/service.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.coreDns.enabled .Values.coreDns.service.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-coredns + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-coredns + jobLabel: coredns +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + ports: + - name: {{ .Values.coreDns.serviceMonitor.port }} + port: {{ .Values.coreDns.service.port }} + protocol: TCP + targetPort: {{ .Values.coreDns.service.targetPort }} + selector: + {{- if .Values.coreDns.service.selector }} +{{ toYaml .Values.coreDns.service.selector | indent 4 }} + {{- else}} + k8s-app: kube-dns + {{- end}} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/core-dns/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/core-dns/servicemonitor.yaml new file mode 100644 index 00000000000..fdb2cd9473d --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/core-dns/servicemonitor.yaml @@ -0,0 +1,48 @@ +{{- if and .Values.coreDns.enabled .Values.coreDns.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-coredns + {{- if .Values.kubernetesServiceMonitors.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "opentelemetry-kube-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-coredns + {{- with .Values.coreDns.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.coreDns.serviceMonitor.jobLabel }} + {{- include "opentelemetry-kube-stack.servicemonitor.scrapeLimits" .Values.coreDns.serviceMonitor | nindent 2 }} + selector: + {{- if .Values.coreDns.serviceMonitor.selector }} + {{ tpl (toYaml .Values.coreDns.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "opentelemetry-kube-stack.name" . }}-coredns + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: {{ .Values.coreDns.serviceMonitor.port }} + {{- if .Values.coreDns.serviceMonitor.interval}} + interval: {{ .Values.coreDns.serviceMonitor.interval }} + {{- end }} + {{- if .Values.coreDns.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.coreDns.serviceMonitor.proxyUrl}} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token +{{- if .Values.coreDns.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.coreDns.serviceMonitor.metricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.coreDns.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.coreDns.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-api-server/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-api-server/servicemonitor.yaml new file mode 100644 index 00000000000..85a2657d4c8 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-api-server/servicemonitor.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.kubeApiServer.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-apiserver + {{- if .Values.kubernetesServiceMonitors.ignoreNamespaceSelectors }} + namespace: default + {{- else }} + namespace: {{ template "opentelemetry-kube-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-apiserver + {{- with .Values.kubeApiServer.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} +spec: + {{- include "opentelemetry-kube-stack.servicemonitor.scrapeLimits" .Values.kubeApiServer.serviceMonitor | nindent 2 }} + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeApiServer.serviceMonitor.interval }} + interval: {{ .Values.kubeApiServer.serviceMonitor.interval }} + {{- end }} + {{- if .Values.kubeApiServer.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeApiServer.serviceMonitor.proxyUrl }} + {{- end }} + port: https + scheme: https +{{- if .Values.kubeApiServer.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubeApiServer.serviceMonitor.metricRelabelings | indent 6) . }} +{{- end }} +{{- if .Values.kubeApiServer.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeApiServer.serviceMonitor.relabelings | indent 6) . }} +{{- end }} + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + serverName: {{ .Values.kubeApiServer.tlsConfig.serverName }} + insecureSkipVerify: {{ .Values.kubeApiServer.tlsConfig.insecureSkipVerify }} + jobLabel: {{ .Values.kubeApiServer.serviceMonitor.jobLabel }} + namespaceSelector: + matchNames: + - default + selector: +{{ toYaml .Values.kubeApiServer.serviceMonitor.selector | indent 4 }} +{{- end}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/endpoints.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/endpoints.yaml new file mode 100644 index 00000000000..d792766aee5 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/endpoints.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.kubeControllerManager.enabled .Values.kubeControllerManager.endpoints .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-controller-manager + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-controller-manager + k8s-app: kube-controller-manager +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} + namespace: kube-system +subsets: + - addresses: + {{- range .Values.kubeControllerManager.endpoints }} + - ip: {{ . }} + {{- end }} + ports: + - name: {{ .Values.kubeControllerManager.serviceMonitor.port }} + {{- $kubeControllerManagerDefaultInsecurePort := 10252 }} + {{- $kubeControllerManagerDefaultSecurePort := 10257 }} + port: {{ include "opentelemetry-kube-stack.kubeControllerManager.insecureScrape" (list . $kubeControllerManagerDefaultInsecurePort $kubeControllerManagerDefaultSecurePort .Values.kubeControllerManager.service.port) }} + protocol: TCP +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/service.yaml new file mode 100644 index 00000000000..103eeb5d10b --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/service.yaml @@ -0,0 +1,29 @@ +{{- if and .Values.kubeControllerManager.enabled .Values.kubeControllerManager.service.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-controller-manager + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-controller-manager + jobLabel: kube-controller-manager +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + ports: + - name: {{ .Values.kubeControllerManager.serviceMonitor.port }} + {{- $kubeControllerManagerDefaultInsecurePort := 10252 }} + {{- $kubeControllerManagerDefaultSecurePort := 10257 }} + port: {{ include "opentelemetry-kube-stack.kubeControllerManager.insecureScrape" (list . $kubeControllerManagerDefaultInsecurePort $kubeControllerManagerDefaultSecurePort .Values.kubeControllerManager.service.port) }} + protocol: TCP + targetPort: {{ include "opentelemetry-kube-stack.kubeControllerManager.insecureScrape" (list . $kubeControllerManagerDefaultInsecurePort $kubeControllerManagerDefaultSecurePort .Values.kubeControllerManager.service.targetPort) }} +{{- if .Values.kubeControllerManager.endpoints }}{{- else }} + selector: + {{- if .Values.kubeControllerManager.service.selector }} +{{ toYaml .Values.kubeControllerManager.service.selector | indent 4 }} + {{- else}} + component: kube-controller-manager + {{- end}} +{{- end }} + type: ClusterIP +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/servicemonitor.yaml new file mode 100644 index 00000000000..306442e2fd6 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-controller-manager/servicemonitor.yaml @@ -0,0 +1,59 @@ +{{- if and .Values.kubeControllerManager.enabled .Values.kubeControllerManager.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-controller-manager + {{- if .Values.kubernetesServiceMonitors.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "opentelemetry-kube-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-controller-manager + {{- with .Values.kubeControllerManager.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.kubeControllerManager.serviceMonitor.jobLabel }} + {{- include "opentelemetry-kube-stack.servicemonitor.scrapeLimits" .Values.kubeControllerManager.serviceMonitor | nindent 2 }} + selector: + {{- if .Values.kubeControllerManager.serviceMonitor.selector }} + {{ tpl (toYaml .Values.kubeControllerManager.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-controller-manager + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: {{ .Values.kubeControllerManager.serviceMonitor.port }} + {{- if .Values.kubeControllerManager.serviceMonitor.interval }} + interval: {{ .Values.kubeControllerManager.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeControllerManager.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeControllerManager.serviceMonitor.proxyUrl}} + {{- end }} + {{- if eq (include "opentelemetry-kube-stack.kubeControllerManager.insecureScrape" (list . false true .Values.kubeControllerManager.serviceMonitor.https )) "true" }} + scheme: https + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + {{- if eq (include "opentelemetry-kube-stack.kubeControllerManager.insecureScrape" (list . nil true .Values.kubeControllerManager.serviceMonitor.insecureSkipVerify)) "true" }} + insecureSkipVerify: true + {{- end }} + {{- if .Values.kubeControllerManager.serviceMonitor.serverName }} + serverName: {{ .Values.kubeControllerManager.serviceMonitor.serverName }} + {{- end }} + {{- end }} +{{- if .Values.kubeControllerManager.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubeControllerManager.serviceMonitor.metricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubeControllerManager.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeControllerManager.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-dns/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-dns/service.yaml new file mode 100644 index 00000000000..4f35cfcd85a --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-dns/service.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.kubeDns.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-dns + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-dns + jobLabel: kube-dns +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + ports: + - name: http-metrics-dnsmasq + port: {{ .Values.kubeDns.service.dnsmasq.port }} + protocol: TCP + targetPort: {{ .Values.kubeDns.service.dnsmasq.targetPort }} + - name: http-metrics-skydns + port: {{ .Values.kubeDns.service.skydns.port }} + protocol: TCP + targetPort: {{ .Values.kubeDns.service.skydns.targetPort }} + selector: + {{- if .Values.kubeDns.service.selector }} +{{ toYaml .Values.kubeDns.service.selector | indent 4 }} + {{- else}} + k8s-app: kube-dns + {{- end}} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-dns/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-dns/servicemonitor.yaml new file mode 100644 index 00000000000..ce66d9be570 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-dns/servicemonitor.yaml @@ -0,0 +1,61 @@ +{{- if and .Values.kubeDns.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-dns + {{- if .Values.kubernetesServiceMonitors.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "opentelemetry-kube-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-dns + {{- with .Values.kubeDns.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.kubeDns.serviceMonitor.jobLabel }} + {{- include "opentelemetry-kube-stack.servicemonitor.scrapeLimits" .Values.kubeDns.serviceMonitor | nindent 2 }} + selector: + {{- if .Values.kubeDns.serviceMonitor.selector }} + {{ tpl (toYaml .Values.kubeDns.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-dns + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: http-metrics-dnsmasq + {{- if .Values.kubeDns.serviceMonitor.interval }} + interval: {{ .Values.kubeDns.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeDns.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeDns.serviceMonitor.proxyUrl}} + {{- end }} +{{- if .Values.kubeDns.serviceMonitor.dnsmasqMetricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubeDns.serviceMonitor.dnsmasqMetricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubeDns.serviceMonitor.dnsmasqRelabelings }} + relabelings: +{{ toYaml .Values.kubeDns.serviceMonitor.dnsmasqRelabelings | indent 4 }} +{{- end }} + - port: http-metrics-skydns + {{- if .Values.kubeDns.serviceMonitor.interval }} + interval: {{ .Values.kubeDns.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token +{{- if .Values.kubeDns.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubeDns.serviceMonitor.metricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubeDns.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeDns.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/endpoints.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/endpoints.yaml new file mode 100644 index 00000000000..669f538ba0f --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/endpoints.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.kubeEtcd.enabled .Values.kubeEtcd.endpoints .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-etcd + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-etcd + k8s-app: etcd-server +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} + namespace: kube-system +subsets: + - addresses: + {{- range .Values.kubeEtcd.endpoints }} + - ip: {{ . }} + {{- end }} + ports: + - name: {{ .Values.kubeEtcd.serviceMonitor.port }} + port: {{ .Values.kubeEtcd.service.port }} + protocol: TCP +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/service.yaml new file mode 100644 index 00000000000..f0d15545782 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/service.yaml @@ -0,0 +1,27 @@ +{{- if and .Values.kubeEtcd.enabled .Values.kubeEtcd.service.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-etcd + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-etcd + jobLabel: kube-etcd +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + ports: + - name: {{ .Values.kubeEtcd.serviceMonitor.port }} + port: {{ .Values.kubeEtcd.service.port }} + protocol: TCP + targetPort: {{ .Values.kubeEtcd.service.targetPort }} +{{- if .Values.kubeEtcd.endpoints }}{{- else }} + selector: + {{- if .Values.kubeEtcd.service.selector }} +{{ toYaml .Values.kubeEtcd.service.selector | indent 4 }} + {{- else}} + component: etcd + {{- end}} +{{- end }} + type: ClusterIP +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/servicemonitor.yaml new file mode 100644 index 00000000000..65f7f484fae --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-etcd/servicemonitor.yaml @@ -0,0 +1,65 @@ +{{- if and .Values.kubeEtcd.enabled .Values.kubeEtcd.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-etcd + {{- if .Values.kubernetesServiceMonitors.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "opentelemetry-kube-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-etcd + {{- with .Values.kubeEtcd.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.kubeEtcd.serviceMonitor.jobLabel }} + {{- include "opentelemetry-kube-stack.servicemonitor.scrapeLimits" .Values.kubeEtcd.serviceMonitor | nindent 4 }} + selector: + {{- if .Values.kubeEtcd.serviceMonitor.selector }} + {{ tpl (toYaml .Values.kubeEtcd.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-etcd + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: {{ .Values.kubeEtcd.serviceMonitor.port }} + {{- if .Values.kubeEtcd.serviceMonitor.interval }} + interval: {{ .Values.kubeEtcd.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeEtcd.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeEtcd.serviceMonitor.proxyUrl}} + {{- end }} + {{- if eq .Values.kubeEtcd.serviceMonitor.scheme "https" }} + scheme: https + tlsConfig: + {{- if .Values.kubeEtcd.serviceMonitor.serverName }} + serverName: {{ .Values.kubeEtcd.serviceMonitor.serverName }} + {{- end }} + {{- if .Values.kubeEtcd.serviceMonitor.caFile }} + caFile: {{ .Values.kubeEtcd.serviceMonitor.caFile }} + {{- end }} + {{- if .Values.kubeEtcd.serviceMonitor.certFile }} + certFile: {{ .Values.kubeEtcd.serviceMonitor.certFile }} + {{- end }} + {{- if .Values.kubeEtcd.serviceMonitor.keyFile }} + keyFile: {{ .Values.kubeEtcd.serviceMonitor.keyFile }} + {{- end}} + insecureSkipVerify: {{ .Values.kubeEtcd.serviceMonitor.insecureSkipVerify }} + {{- end }} +{{- if .Values.kubeEtcd.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubeEtcd.serviceMonitor.metricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubeEtcd.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeEtcd.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/endpoints.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/endpoints.yaml new file mode 100644 index 00000000000..42c7225a326 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/endpoints.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.kubeProxy.enabled .Values.kubeProxy.endpoints .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-proxy + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-proxy + k8s-app: kube-proxy +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} + namespace: kube-system +subsets: + - addresses: + {{- range .Values.kubeProxy.endpoints }} + - ip: {{ . }} + {{- end }} + ports: + - name: {{ .Values.kubeProxy.serviceMonitor.port }} + port: {{ .Values.kubeProxy.service.port }} + protocol: TCP +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/service.yaml new file mode 100644 index 00000000000..886d87eb87a --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/service.yaml @@ -0,0 +1,27 @@ +{{- if and .Values.kubeProxy.enabled .Values.kubeProxy.service.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-proxy + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-proxy + jobLabel: kube-proxy +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + ports: + - name: {{ .Values.kubeProxy.serviceMonitor.port }} + port: {{ .Values.kubeProxy.service.port }} + protocol: TCP + targetPort: {{ .Values.kubeProxy.service.targetPort }} +{{- if .Values.kubeProxy.endpoints }}{{- else }} + selector: + {{- if .Values.kubeProxy.service.selector }} +{{ toYaml .Values.kubeProxy.service.selector | indent 4 }} + {{- else}} + k8s-app: kube-proxy + {{- end}} +{{- end }} + type: ClusterIP +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/servicemonitor.yaml new file mode 100644 index 00000000000..b15e89a490c --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-proxy/servicemonitor.yaml @@ -0,0 +1,53 @@ +{{- if and .Values.kubeProxy.enabled .Values.kubeProxy.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-proxy + {{- if .Values.kubernetesServiceMonitors.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "opentelemetry-kube-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-proxy + {{- with .Values.kubeProxy.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.kubeProxy.serviceMonitor.jobLabel }} + {{- include "opentelemetry-kube-stack.servicemonitor.scrapeLimits" .Values.kubeProxy.serviceMonitor | nindent 2 }} + selector: + {{- if .Values.kubeProxy.serviceMonitor.selector }} + {{ tpl (toYaml .Values.kubeProxy.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-proxy + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: {{ .Values.kubeProxy.serviceMonitor.port }} + {{- if .Values.kubeProxy.serviceMonitor.interval }} + interval: {{ .Values.kubeProxy.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeProxy.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeProxy.serviceMonitor.proxyUrl}} + {{- end }} + {{- if .Values.kubeProxy.serviceMonitor.https }} + scheme: https + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + {{- end}} +{{- if .Values.kubeProxy.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubeProxy.serviceMonitor.metricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubeProxy.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeProxy.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/endpoints.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/endpoints.yaml new file mode 100644 index 00000000000..b7baccc36f5 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/endpoints.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.kubeScheduler.enabled .Values.kubeScheduler.endpoints .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-scheduler + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-scheduler + k8s-app: kube-scheduler +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} + namespace: kube-system +subsets: + - addresses: + {{- range .Values.kubeScheduler.endpoints }} + - ip: {{ . }} + {{- end }} + ports: + - name: {{ .Values.kubeScheduler.serviceMonitor.port }} + {{- $kubeSchedulerDefaultInsecurePort := 10251 }} + {{- $kubeSchedulerDefaultSecurePort := 10259 }} + port: {{ include "opentelemetry-kube-stack.kubeScheduler.insecureScrape" (list . $kubeSchedulerDefaultInsecurePort $kubeSchedulerDefaultSecurePort .Values.kubeScheduler.service.port) }} + protocol: TCP +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/service.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/service.yaml new file mode 100644 index 00000000000..c4912eb2c36 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/service.yaml @@ -0,0 +1,29 @@ +{{- if and .Values.kubeScheduler.enabled .Values.kubeScheduler.service.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-scheduler + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-scheduler + jobLabel: kube-scheduler +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + ports: + - name: {{ .Values.kubeScheduler.serviceMonitor.port }} + {{- $kubeSchedulerDefaultInsecurePort := 10251 }} + {{- $kubeSchedulerDefaultSecurePort := 10259 }} + port: {{ include "opentelemetry-kube-stack.kubeScheduler.insecureScrape" (list . $kubeSchedulerDefaultInsecurePort $kubeSchedulerDefaultSecurePort .Values.kubeScheduler.service.port) }} + protocol: TCP + targetPort: {{ include "opentelemetry-kube-stack.kubeScheduler.insecureScrape" (list . $kubeSchedulerDefaultInsecurePort $kubeSchedulerDefaultSecurePort .Values.kubeScheduler.service.targetPort) }} +{{- if .Values.kubeScheduler.endpoints }}{{- else }} + selector: + {{- if .Values.kubeScheduler.service.selector }} +{{ toYaml .Values.kubeScheduler.service.selector | indent 4 }} + {{- else}} + component: kube-scheduler + {{- end}} +{{- end }} + type: ClusterIP +{{- end -}} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/servicemonitor.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/servicemonitor.yaml new file mode 100644 index 00000000000..8b19201052e --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/exporters/kube-scheduler/servicemonitor.yaml @@ -0,0 +1,59 @@ +{{- if and .Values.kubeScheduler.enabled .Values.kubeScheduler.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "opentelemetry-kube-stack.fullname" . }}-kube-scheduler + {{- if .Values.kubernetesServiceMonitors.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "opentelemetry-kube-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-scheduler + {{- with .Values.kubeScheduler.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "opentelemetry-kube-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.kubeScheduler.serviceMonitor.jobLabel }} + {{- include "opentelemetry-kube-stack.servicemonitor.scrapeLimits" .Values.kubeScheduler.serviceMonitor | nindent 2 }} + selector: + {{- if .Values.kubeScheduler.serviceMonitor.selector }} + {{ tpl (toYaml .Values.kubeScheduler.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "opentelemetry-kube-stack.name" . }}-kube-scheduler + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: {{ .Values.kubeScheduler.serviceMonitor.port }} + {{- if .Values.kubeScheduler.serviceMonitor.interval }} + interval: {{ .Values.kubeScheduler.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeScheduler.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeScheduler.serviceMonitor.proxyUrl}} + {{- end }} + {{- if eq (include "opentelemetry-kube-stack.kubeScheduler.insecureScrape" (list . false true .Values.kubeScheduler.serviceMonitor.https )) "true" }} + scheme: https + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + {{- if eq (include "opentelemetry-kube-stack.kubeScheduler.insecureScrape" (list . nil true .Values.kubeScheduler.serviceMonitor.insecureSkipVerify)) "true" }} + insecureSkipVerify: true + {{- end }} + {{- if .Values.kubeScheduler.serviceMonitor.serverName }} + serverName: {{ .Values.kubeScheduler.serviceMonitor.serverName }} + {{- end}} + {{- end}} +{{- if .Values.kubeScheduler.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubeScheduler.serviceMonitor.metricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubeScheduler.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeScheduler.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/hooks.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/hooks.yaml new file mode 100644 index 00000000000..95c7898d5c8 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/hooks.yaml @@ -0,0 +1,63 @@ +{{- if .Values.cleanupJob.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: delete-resources-sa + annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: delete-resources-role + annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +rules: + - apiGroups: + - opentelemetry.io + resources: + - instrumentations + - opampbridges + - opentelemetrycollectors + verbs: + - get + - list + - delete +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: delete-resources-rolebinding + annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: delete-resources-role +subjects: + - kind: ServiceAccount + name: delete-resources-sa +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "opentelemetry-kube-stack.name" . }}-pre-delete-job + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed +spec: + template: + spec: + restartPolicy: Never + serviceAccountName: delete-resources-sa + containers: + - name: delete-resources + image: bitnami/kubectl:latest + command: + - /bin/sh + - -c + - | + kubectl delete instrumentations,opampbridges,opentelemetrycollectors \ + -l helm.sh/chart={{ include "opentelemetry-kube-stack.chart" . }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/instrumentation.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/instrumentation.yaml new file mode 100644 index 00000000000..4bb25662083 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/templates/instrumentation.yaml @@ -0,0 +1,57 @@ +{{- if .Values.instrumentation.enabled }} +--- +apiVersion: opentelemetry.io/v1alpha1 +kind: Instrumentation +metadata: + name: {{ include "opentelemetry-kube-stack.instrumentation" . }} + labels: + {{- include "opentelemetry-kube-stack.labels" $ | nindent 4 }} + {{- include "opentelemetry-kube-stack.renderkv" .Values.instrumentation.labels | indent 4 }} + {{- with .Values.instrumentation.annotations }} + annotations: + {{- include "opentelemetry-kube-stack.renderkv" . | indent 4 }} + {{- end }} +spec: + exporter: + endpoint: {{ .Values.instrumentation.exporter.endpoint }} + propagators: + {{- toYaml .Values.instrumentation.propagators | nindent 4 }} + {{- with .Values.instrumentation.sampler }} + sampler: + {{- toYaml . | nindent 4 }} + {{- end }} + env: + {{- include "opentelemetry-kube-stack.renderenvs" (dict "extraEnvs" $.Values.extraEnvs "env" .Values.instrumentation.env) | indent 4 }} + {{- with .Values.instrumentation.resource }} + resource: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.instrumentation.java }} + java: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.instrumentation.nodejs }} + nodejs: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.instrumentation.python }} + python: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.instrumentation.dotnet }} + dotnet: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.instrumentation.go }} + go: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.instrumentation.apacheHttpd }} + apacheHtpd: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.instrumentation.nginx }} + nginx: + {{- toYaml . | nindent 4}} + {{- end }} +{{- end }} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/values.schema.json b/testing/integration/k8s/testdata/opentelemetry-kube-stack/values.schema.json new file mode 100644 index 00000000000..308a63d8a74 --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/values.schema.json @@ -0,0 +1,3963 @@ +{ + "$schema": "http://json-schema.org/schema#", + "$defs": { + "AWSElasticBlockStoreVolumeSource": { + "properties": { + "volumeID": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "partition": { + "type": "integer" + }, + "readOnly": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["volumeID"] + }, + "Affinity": { + "properties": { + "nodeAffinity": { + "$ref": "#/$defs/NodeAffinity" + }, + "podAffinity": { + "$ref": "#/$defs/PodAffinity" + }, + "podAntiAffinity": { + "$ref": "#/$defs/PodAntiAffinity" + } + }, + "additionalProperties": false, + "type": "object" + }, + "AutoscalerSpec": { + "properties": { + "minReplicas": { + "type": "integer" + }, + "maxReplicas": { + "type": "integer" + }, + "behavior": { + "$ref": "#/$defs/HorizontalPodAutoscalerBehavior" + }, + "metrics": { + "items": { + "$ref": "#/$defs/MetricSpec" + }, + "type": "array" + }, + "targetCPUUtilization": { + "type": "integer" + }, + "targetMemoryUtilization": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object" + }, + "AzureDiskVolumeSource": { + "properties": { + "diskName": { + "type": "string" + }, + "diskURI": { + "type": "string" + }, + "cachingMode": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "kind": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["diskName", "diskURI"] + }, + "AzureFileVolumeSource": { + "properties": { + "secretName": { + "type": "string" + }, + "shareName": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["secretName", "shareName"] + }, + "CSIVolumeSource": { + "properties": { + "driver": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "fsType": { + "type": "string" + }, + "volumeAttributes": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "nodePublishSecretRef": { + "$ref": "#/$defs/LocalObjectReference" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["driver"] + }, + "Capabilities": { + "properties": { + "add": { + "items": { + "type": "string" + }, + "type": "array" + }, + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "CephFSVolumeSource": { + "properties": { + "monitors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "path": { + "type": "string" + }, + "user": { + "type": "string" + }, + "secretFile": { + "type": "string" + }, + "secretRef": { + "$ref": "#/$defs/LocalObjectReference" + }, + "readOnly": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["monitors"] + }, + "CinderVolumeSource": { + "properties": { + "volumeID": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "secretRef": { + "$ref": "#/$defs/LocalObjectReference" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["volumeID"] + }, + "ClusterTrustBundleProjection": { + "properties": { + "name": { + "type": "string" + }, + "signerName": { + "type": "string" + }, + "labelSelector": { + "$ref": "#/$defs/LabelSelector" + }, + "optional": { + "type": "boolean" + }, + "path": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["path"] + }, + "ConfigMapEnvSource": { + "properties": { + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ConfigMapKeySelector": { + "properties": { + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["key"] + }, + "ConfigMapProjection": { + "properties": { + "name": { + "type": "string" + }, + "items": { + "items": { + "$ref": "#/$defs/KeyToPath" + }, + "type": "array" + }, + "optional": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ConfigMapVolumeSource": { + "properties": { + "name": { + "type": "string" + }, + "items": { + "items": { + "$ref": "#/$defs/KeyToPath" + }, + "type": "array" + }, + "defaultMode": { + "type": "integer" + }, + "optional": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ConfigMapsSpec": { + "properties": { + "name": { + "type": "string" + }, + "mountPath": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["name", "mountPath"] + }, + "Container": { + "properties": { + "name": { + "type": "string" + }, + "image": { + "type": "string" + }, + "command": { + "items": { + "type": "string" + }, + "type": "array" + }, + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "workingDir": { + "type": "string" + }, + "ports": { + "items": { + "$ref": "#/$defs/ContainerPort" + }, + "type": "array" + }, + "envFrom": { + "items": { + "$ref": "#/$defs/EnvFromSource" + }, + "type": "array" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resources": { + "$ref": "#/$defs/ResourceRequirements" + }, + "resizePolicy": { + "items": { + "$ref": "#/$defs/ContainerResizePolicy" + }, + "type": "array" + }, + "restartPolicy": { + "type": "string" + }, + "volumeMounts": { + "items": { + "$ref": "#/$defs/VolumeMount" + }, + "type": "array" + }, + "volumeDevices": { + "items": { + "$ref": "#/$defs/VolumeDevice" + }, + "type": "array" + }, + "livenessProbe": { + "$ref": "#/$defs/Probe" + }, + "readinessProbe": { + "$ref": "#/$defs/Probe" + }, + "startupProbe": { + "$ref": "#/$defs/Probe" + }, + "lifecycle": { + "$ref": "#/$defs/Lifecycle" + }, + "terminationMessagePath": { + "type": "string" + }, + "terminationMessagePolicy": { + "type": "string" + }, + "imagePullPolicy": { + "type": "string" + }, + "securityContext": { + "$ref": "#/$defs/SecurityContext" + }, + "stdin": { + "type": "boolean" + }, + "stdinOnce": { + "type": "boolean" + }, + "tty": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["name"] + }, + "ContainerPort": { + "properties": { + "name": { + "type": "string" + }, + "hostPort": { + "type": "integer" + }, + "containerPort": { + "type": "integer" + }, + "protocol": { + "type": "string" + }, + "hostIP": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["containerPort"] + }, + "ContainerResizePolicy": { + "properties": { + "resourceName": { + "type": "string" + }, + "restartPolicy": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["resourceName", "restartPolicy"] + }, + "DaemonSetUpdateStrategy": { + "properties": { + "type": { + "type": "string" + }, + "rollingUpdate": { + "$ref": "#/$defs/RollingUpdateDaemonSet" + } + }, + "additionalProperties": false, + "type": "object" + }, + "DeploymentStrategy": { + "properties": { + "type": { + "type": "string" + }, + "rollingUpdate": { + "$ref": "#/$defs/RollingUpdateDeployment" + } + }, + "additionalProperties": false, + "type": "object" + }, + "DownwardAPIProjection": { + "properties": { + "items": { + "items": { + "$ref": "#/$defs/DownwardAPIVolumeFile" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "DownwardAPIVolumeFile": { + "properties": { + "path": { + "type": "string" + }, + "fieldRef": { + "$ref": "#/$defs/ObjectFieldSelector" + }, + "resourceFieldRef": { + "$ref": "#/$defs/ResourceFieldSelector" + }, + "mode": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["path"] + }, + "DownwardAPIVolumeSource": { + "properties": { + "items": { + "items": { + "$ref": "#/$defs/DownwardAPIVolumeFile" + }, + "type": "array" + }, + "defaultMode": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object" + }, + "EmptyDirVolumeSource": { + "properties": { + "medium": { + "type": "string" + }, + "sizeLimit": { + "$ref": "#/$defs/Quantity" + } + }, + "additionalProperties": false, + "type": "object" + }, + "EnvFromSource": { + "properties": { + "prefix": { + "type": "string" + }, + "configMapRef": { + "$ref": "#/$defs/ConfigMapEnvSource" + }, + "secretRef": { + "$ref": "#/$defs/SecretEnvSource" + } + }, + "additionalProperties": false, + "type": "object" + }, + "EnvVar": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "valueFrom": { + "$ref": "#/$defs/EnvVarSource" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["name"] + }, + "EnvVarSource": { + "properties": { + "fieldRef": { + "$ref": "#/$defs/ObjectFieldSelector" + }, + "resourceFieldRef": { + "$ref": "#/$defs/ResourceFieldSelector" + }, + "configMapKeyRef": { + "$ref": "#/$defs/ConfigMapKeySelector" + }, + "secretKeyRef": { + "$ref": "#/$defs/SecretKeySelector" + } + }, + "additionalProperties": false, + "type": "object" + }, + "EphemeralVolumeSource": { + "properties": { + "volumeClaimTemplate": { + "$ref": "#/$defs/PersistentVolumeClaimTemplate" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ExecAction": { + "properties": { + "command": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "FCVolumeSource": { + "properties": { + "targetWWNs": { + "items": { + "type": "string" + }, + "type": "array" + }, + "lun": { + "type": "integer" + }, + "fsType": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "wwids": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "FieldsV1": { + "properties": {}, + "additionalProperties": false, + "type": "object" + }, + "FlexVolumeSource": { + "properties": { + "driver": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "secretRef": { + "$ref": "#/$defs/LocalObjectReference" + }, + "readOnly": { + "type": "boolean" + }, + "options": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["driver"] + }, + "FlockerVolumeSource": { + "properties": { + "datasetName": { + "type": "string" + }, + "datasetUUID": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "GCEPersistentDiskVolumeSource": { + "properties": { + "pdName": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "partition": { + "type": "integer" + }, + "readOnly": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["pdName"] + }, + "GitRepoVolumeSource": { + "properties": { + "repository": { + "type": "string" + }, + "revision": { + "type": "string" + }, + "directory": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["repository"] + }, + "GlusterfsVolumeSource": { + "properties": { + "endpoints": { + "type": "string" + }, + "path": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["endpoints", "path"] + }, + "HPAScalingPolicy": { + "properties": { + "type": { + "type": "string" + }, + "value": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["type", "value", "periodSeconds"] + }, + "HPAScalingRules": { + "properties": { + "stabilizationWindowSeconds": { + "type": "integer" + }, + "selectPolicy": { + "type": "string" + }, + "policies": { + "items": { + "$ref": "#/$defs/HPAScalingPolicy" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "HTTPGetAction": { + "properties": { + "path": { + "type": "string" + }, + "port": { + "type": ["string", "integer"] + }, + "host": { + "type": "string" + }, + "scheme": { + "type": "string" + }, + "httpHeaders": { + "items": { + "$ref": "#/$defs/HTTPHeader" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["port"] + }, + "HTTPHeader": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["name", "value"] + }, + "HorizontalPodAutoscalerBehavior": { + "properties": { + "scaleUp": { + "$ref": "#/$defs/HPAScalingRules" + }, + "scaleDown": { + "$ref": "#/$defs/HPAScalingRules" + } + }, + "additionalProperties": false, + "type": "object" + }, + "HostPathVolumeSource": { + "properties": { + "path": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["path"] + }, + "ISCSIVolumeSource": { + "properties": { + "targetPortal": { + "type": "string" + }, + "iqn": { + "type": "string" + }, + "lun": { + "type": "integer" + }, + "iscsiInterface": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "portals": { + "items": { + "type": "string" + }, + "type": "array" + }, + "chapAuthDiscovery": { + "type": "boolean" + }, + "chapAuthSession": { + "type": "boolean" + }, + "secretRef": { + "$ref": "#/$defs/LocalObjectReference" + }, + "initiatorName": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["targetPortal", "iqn", "lun"] + }, + "Ingress": { + "properties": { + "type": { + "type": "string" + }, + "ruleType": { + "type": "string" + }, + "hostname": { + "type": "string" + }, + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "tls": { + "items": { + "$ref": "#/$defs/IngressTLS" + }, + "type": "array" + }, + "ingressClassName": { + "type": "string" + }, + "route": { + "$ref": "#/$defs/OpenShiftRoute" + } + }, + "additionalProperties": false, + "type": "object" + }, + "IngressTLS": { + "properties": { + "hosts": { + "items": { + "type": "string" + }, + "type": "array" + }, + "secretName": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "IntOrString": { + "properties": { + "Type": { + "type": "integer" + }, + "IntVal": { + "type": "integer" + }, + "StrVal": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["Type", "IntVal", "StrVal"] + }, + "KeyToPath": { + "properties": { + "key": { + "type": "string" + }, + "path": { + "type": "string" + }, + "mode": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["key", "path"] + }, + "LabelSelector": { + "properties": { + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "matchExpressions": { + "items": { + "$ref": "#/$defs/LabelSelectorRequirement" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "LabelSelectorRequirement": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["key", "operator"] + }, + "Lifecycle": { + "properties": { + "postStart": { + "$ref": "#/$defs/LifecycleHandler" + }, + "preStop": { + "$ref": "#/$defs/LifecycleHandler" + } + }, + "additionalProperties": false, + "type": "object" + }, + "LifecycleHandler": { + "properties": { + "exec": { + "$ref": "#/$defs/ExecAction" + }, + "httpGet": { + "$ref": "#/$defs/HTTPGetAction" + }, + "tcpSocket": { + "$ref": "#/$defs/TCPSocketAction" + }, + "sleep": { + "$ref": "#/$defs/SleepAction" + } + }, + "additionalProperties": false, + "type": "object" + }, + "LocalObjectReference": { + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ManagedFieldsEntry": { + "properties": { + "manager": { + "type": "string" + }, + "operation": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "time": { + "$ref": "#/$defs/Time" + }, + "fieldsType": { + "type": "string" + }, + "fieldsV1": { + "$ref": "#/$defs/FieldsV1" + }, + "subresource": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "MetricIdentifier": { + "properties": { + "name": { + "type": "string" + }, + "selector": { + "$ref": "#/$defs/LabelSelector" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["name"] + }, + "MetricSpec": { + "properties": { + "type": { + "type": "string" + }, + "pods": { + "$ref": "#/$defs/PodsMetricSource" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["type"] + }, + "MetricTarget": { + "properties": { + "type": { + "type": "string" + }, + "value": { + "$ref": "#/$defs/Quantity" + }, + "averageValue": { + "$ref": "#/$defs/Quantity" + }, + "averageUtilization": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["type"] + }, + "MetricsConfigSpec": { + "properties": { + "enableMetrics": { + "type": "boolean" + }, + "disablePrometheusAnnotations": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ModifyVolumeStatus": { + "properties": { + "targetVolumeAttributesClassName": { + "type": "string" + }, + "status": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["status"] + }, + "NFSVolumeSource": { + "properties": { + "server": { + "type": "string" + }, + "path": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["server", "path"] + }, + "NodeAffinity": { + "properties": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "$ref": "#/$defs/NodeSelector" + }, + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "$ref": "#/$defs/PreferredSchedulingTerm" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "NodeSelector": { + "properties": { + "nodeSelectorTerms": { + "items": { + "$ref": "#/$defs/NodeSelectorTerm" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["nodeSelectorTerms"] + }, + "NodeSelectorRequirement": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["key", "operator"] + }, + "NodeSelectorTerm": { + "properties": { + "matchExpressions": { + "items": { + "$ref": "#/$defs/NodeSelectorRequirement" + }, + "type": "array" + }, + "matchFields": { + "items": { + "$ref": "#/$defs/NodeSelectorRequirement" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ObjectFieldSelector": { + "properties": { + "apiVersion": { + "type": "string" + }, + "fieldPath": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["fieldPath"] + }, + "ObjectMeta": { + "properties": { + "name": { + "type": "string" + }, + "generateName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "selfLink": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "resourceVersion": { + "type": "string" + }, + "generation": { + "type": "integer" + }, + "creationTimestamp": { + "$ref": "#/$defs/Time" + }, + "deletionTimestamp": { + "$ref": "#/$defs/Time" + }, + "deletionGracePeriodSeconds": { + "type": "integer" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "ownerReferences": { + "items": { + "$ref": "#/$defs/OwnerReference" + }, + "type": "array" + }, + "finalizers": { + "items": { + "type": "string" + }, + "type": "array" + }, + "managedFields": { + "items": { + "$ref": "#/$defs/ManagedFieldsEntry" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ObservabilitySpec": { + "properties": { + "metrics": { + "$ref": "#/$defs/MetricsConfigSpec" + } + }, + "additionalProperties": false, + "type": "object" + }, + "OpenShiftRoute": { + "properties": { + "termination": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "OpenTelemetryCollectorSpec": { + "properties": { + "presets": { + "type": "object", + "additionalProperties": false, + "properties": { + "logsCollection": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Specifies whether the collector should collect logs.", + "type": "boolean" + }, + "includeCollectorLogs": { + "description": "Specifies whether the collector should collect its own logs.", + "type": "boolean" + }, + "storeCheckpoints": { + "description": "Specifies whether logs checkpoints should be stored in /var/lib/otelcol/ host directory.", + "type": "boolean" + }, + "maxRecombineLogSize": { + "description": "Specifies the max recombine log size.", + "type": "integer" + } + } + }, + "hostMetrics": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Specifies whether the collector should collect host metrics.", + "type": "boolean" + } + } + }, + "kubeletMetrics": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Specifies whether the collector should collect kubelet metrics.", + "type": "boolean" + } + } + }, + "kubernetesAttributes": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Specifies whether the collector should add Kubernetes metdata to resource attributes.", + "type": "boolean" + }, + "extractAllPodLabels": { + "description": "Specifies whether the k8sattributes processor should extract all pod labels.", + "type": "boolean" + }, + "extractAllPodAnnotations": { + "description": "Specifies whether the k8sattributes processor should extract all pod annotations.", + "type": "boolean" + } + } + }, + "kubernetesEvents": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Specifies whether the collector should collect Kubernetes objects.", + "type": "boolean" + } + } + }, + "clusterMetrics": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Specifies whether the collector should collect cluster metrics.", + "type": "boolean" + } + } + } + } + }, + "enabled": { + "type": "boolean" + }, + "clusterRoleBinding": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": "true" + }, + "clusterRoleName": { + "type": "string" + } + } + }, + "suffix": { + "type": "string" + }, + "fullnameOverride": { + "type": "string" + }, + "annotations": { + "type": "object" + }, + "labels": { + "type": "object" + }, + "managementState": { + "type": "string" + }, + "scrape_configs_file": { + "type": "string", + "default": "" + }, + "resources": { + "$ref": "#/$defs/ResourceRequirements" + }, + "nodeSelector": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "args": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "replicas": { + "type": "integer" + }, + "minReplicas": { + "type": "integer" + }, + "maxReplicas": { + "type": "integer" + }, + "autoscaler": { + "$ref": "#/$defs/AutoscalerSpec" + }, + "podDisruptionBudget": { + "$ref": "#/$defs/PodDisruptionBudgetSpec" + }, + "securityContext": { + "$ref": "#/$defs/SecurityContext" + }, + "podSecurityContext": { + "$ref": "#/$defs/PodSecurityContext" + }, + "podAnnotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "targetAllocator": { + "$ref": "#/$defs/OpenTelemetryTargetAllocator" + }, + "mode": { + "type": "string" + }, + "serviceAccount": { + "type": "string" + }, + "image": { + "description": "Image use in both standalone and agent configs", + "type": "object", + "additionalProperties": false, + "properties": { + "registry": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + }, + "digest": { + "type": "string" + }, + "pullPolicy": { + "type": "string", + "enum": ["IfNotPresent", "Always", "Never"] + } + } + }, + "upgradeStrategy": { + "type": "string" + }, + "config": { + "type": "object" + }, + "volumeMounts": { + "items": { + "$ref": "#/$defs/VolumeMount" + }, + "type": "array" + }, + "ports": { + "items": { + "$ref": "#/$defs/PortsSpec" + }, + "type": "array" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "envFrom": { + "items": { + "$ref": "#/$defs/EnvFromSource" + }, + "type": "array" + }, + "volumeClaimTemplates": { + "items": { + "$ref": "#/$defs/PersistentVolumeClaim" + }, + "type": "array" + }, + "tolerations": { + "items": { + "$ref": "#/$defs/Toleration" + }, + "type": "array" + }, + "volumes": { + "items": { + "$ref": "#/$defs/Volume" + }, + "type": "array" + }, + "ingress": { + "$ref": "#/$defs/Ingress" + }, + "hostNetwork": { + "type": "boolean" + }, + "shareProcessNamespace": { + "type": "boolean" + }, + "priorityClassName": { + "type": "string" + }, + "affinity": { + "$ref": "#/$defs/Affinity" + }, + "lifecycle": { + "$ref": "#/$defs/Lifecycle" + }, + "terminationGracePeriodSeconds": { + "type": "integer" + }, + "livenessProbe": { + "$ref": "#/$defs/Probe" + }, + "initContainers": { + "items": { + "$ref": "#/$defs/Container" + }, + "type": "array" + }, + "additionalContainers": { + "items": { + "$ref": "#/$defs/Container" + }, + "type": "array" + }, + "observability": { + "$ref": "#/$defs/ObservabilitySpec" + }, + "topologySpreadConstraints": { + "items": { + "$ref": "#/$defs/TopologySpreadConstraint" + }, + "type": "array" + }, + "configmaps": { + "items": { + "$ref": "#/$defs/ConfigMapsSpec" + }, + "type": "array" + }, + "updateStrategy": { + "$ref": "#/$defs/DaemonSetUpdateStrategy" + }, + "deploymentUpdateStrategy": { + "$ref": "#/$defs/DeploymentStrategy" + } + }, + "additionalProperties": true, + "type": "object" + }, + "OpenTelemetryTargetAllocator": { + "properties": { + "replicas": { + "type": "integer" + }, + "nodeSelector": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "resources": { + "$ref": "#/$defs/ResourceRequirements" + }, + "allocationStrategy": { + "type": "string" + }, + "filterStrategy": { + "type": "string" + }, + "serviceAccount": { + "type": "string" + }, + "image": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "affinity": { + "$ref": "#/$defs/Affinity" + }, + "prometheusCR": { + "$ref": "#/$defs/OpenTelemetryTargetAllocatorPrometheusCR" + }, + "securityContext": { + "$ref": "#/$defs/SecurityContext" + }, + "podSecurityContext": { + "$ref": "#/$defs/PodSecurityContext" + }, + "topologySpreadConstraints": { + "items": { + "$ref": "#/$defs/TopologySpreadConstraint" + }, + "type": "array" + }, + "tolerations": { + "items": { + "$ref": "#/$defs/Toleration" + }, + "type": "array" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "observability": { + "$ref": "#/$defs/ObservabilitySpec" + }, + "podDisruptionBudget": { + "$ref": "#/$defs/PodDisruptionBudgetSpec" + } + }, + "additionalProperties": false, + "type": "object" + }, + "OpenTelemetryTargetAllocatorPrometheusCR": { + "properties": { + "enabled": { + "type": "boolean" + }, + "scrapeInterval": { + "type": "string" + }, + "podMonitorSelector": { + "$ref": "#/$defs/LabelSelector" + }, + "serviceMonitorSelector": { + "$ref": "#/$defs/LabelSelector" + } + }, + "additionalProperties": false, + "type": "object" + }, + "OwnerReference": { + "properties": { + "apiVersion": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "controller": { + "type": "boolean" + }, + "blockOwnerDeletion": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["apiVersion", "kind", "name", "uid"] + }, + "PersistentVolumeClaim": { + "properties": { + "kind": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "metadata": { + "$ref": "#/$defs/ObjectMeta" + }, + "spec": { + "$ref": "#/$defs/PersistentVolumeClaimSpec" + }, + "status": { + "$ref": "#/$defs/PersistentVolumeClaimStatus" + } + }, + "additionalProperties": false, + "type": "object" + }, + "PersistentVolumeClaimCondition": { + "properties": { + "type": { + "type": "string" + }, + "status": { + "type": "string" + }, + "lastProbeTime": { + "$ref": "#/$defs/Time" + }, + "lastTransitionTime": { + "$ref": "#/$defs/Time" + }, + "reason": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["type", "status"] + }, + "PersistentVolumeClaimSpec": { + "properties": { + "accessModes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "selector": { + "$ref": "#/$defs/LabelSelector" + }, + "resources": { + "$ref": "#/$defs/VolumeResourceRequirements" + }, + "volumeName": { + "type": "string" + }, + "storageClassName": { + "type": "string" + }, + "volumeMode": { + "type": "string" + }, + "dataSource": { + "$ref": "#/$defs/TypedLocalObjectReference" + }, + "dataSourceRef": { + "$ref": "#/$defs/TypedObjectReference" + }, + "volumeAttributesClassName": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "PersistentVolumeClaimStatus": { + "properties": { + "phase": { + "type": "string" + }, + "accessModes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "capacity": { + "$ref": "#/$defs/ResourceList" + }, + "conditions": { + "items": { + "$ref": "#/$defs/PersistentVolumeClaimCondition" + }, + "type": "array" + }, + "allocatedResources": { + "$ref": "#/$defs/ResourceList" + }, + "allocatedResourceStatuses": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "currentVolumeAttributesClassName": { + "type": "string" + }, + "modifyVolumeStatus": { + "$ref": "#/$defs/ModifyVolumeStatus" + } + }, + "additionalProperties": false, + "type": "object" + }, + "PersistentVolumeClaimTemplate": { + "properties": { + "metadata": { + "$ref": "#/$defs/ObjectMeta" + }, + "spec": { + "$ref": "#/$defs/PersistentVolumeClaimSpec" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["spec"] + }, + "PersistentVolumeClaimVolumeSource": { + "properties": { + "claimName": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["claimName"] + }, + "PhotonPersistentDiskVolumeSource": { + "properties": { + "pdID": { + "type": "string" + }, + "fsType": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["pdID"] + }, + "PodAffinity": { + "properties": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "items": { + "$ref": "#/$defs/PodAffinityTerm" + }, + "type": "array" + }, + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "$ref": "#/$defs/WeightedPodAffinityTerm" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "PodAffinityTerm": { + "properties": { + "labelSelector": { + "$ref": "#/$defs/LabelSelector" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + }, + "namespaceSelector": { + "$ref": "#/$defs/LabelSelector" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["topologyKey"] + }, + "PodAntiAffinity": { + "properties": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "items": { + "$ref": "#/$defs/PodAffinityTerm" + }, + "type": "array" + }, + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "$ref": "#/$defs/WeightedPodAffinityTerm" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, + "PodDisruptionBudgetSpec": { + "properties": { + "minAvailable": { + "type": ["string", "integer"] + }, + "maxUnavailable": { + "type": ["string", "integer"] + } + }, + "additionalProperties": false, + "type": "object" + }, + "PodSecurityContext": { + "properties": { + "seLinuxOptions": { + "$ref": "#/$defs/SELinuxOptions" + }, + "windowsOptions": { + "$ref": "#/$defs/WindowsSecurityContextOptions" + }, + "runAsUser": { + "type": "integer" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "supplementalGroups": { + "items": { + "type": "integer" + }, + "type": "array" + }, + "fsGroup": { + "type": "integer" + }, + "sysctls": { + "items": { + "$ref": "#/$defs/Sysctl" + }, + "type": "array" + }, + "fsGroupChangePolicy": { + "type": "string" + }, + "seccompProfile": { + "$ref": "#/$defs/SeccompProfile" + } + }, + "additionalProperties": false, + "type": "object" + }, + "PodsMetricSource": { + "properties": { + "metric": { + "$ref": "#/$defs/MetricIdentifier" + }, + "target": { + "$ref": "#/$defs/MetricTarget" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["metric", "target"] + }, + "PortworxVolumeSource": { + "properties": { + "volumeID": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["volumeID"] + }, + "PreferredSchedulingTerm": { + "properties": { + "weight": { + "type": "integer" + }, + "preference": { + "$ref": "#/$defs/NodeSelectorTerm" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["weight", "preference"] + }, + "Probe": { + "properties": { + "initialDelaySeconds": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "failureThreshold": { + "type": "integer" + }, + "terminationGracePeriodSeconds": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ProjectedVolumeSource": { + "properties": { + "sources": { + "items": { + "$ref": "#/$defs/VolumeProjection" + }, + "type": "array" + }, + "defaultMode": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["sources"] + }, + "Quantity": { + "properties": { + "Format": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["Format"] + }, + "QuobyteVolumeSource": { + "properties": { + "registry": { + "type": "string" + }, + "volume": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "user": { + "type": "string" + }, + "group": { + "type": "string" + }, + "tenant": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["registry", "volume"] + }, + "RBDVolumeSource": { + "properties": { + "monitors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "image": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "pool": { + "type": "string" + }, + "user": { + "type": "string" + }, + "keyring": { + "type": "string" + }, + "secretRef": { + "$ref": "#/$defs/LocalObjectReference" + }, + "readOnly": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["monitors", "image"] + }, + "ResourceClaim": { + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["name"] + }, + "ResourceFieldSelector": { + "properties": { + "containerName": { + "type": "string" + }, + "resource": { + "type": "string" + }, + "divisor": { + "$ref": "#/$defs/Quantity" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["resource"] + }, + "ResourceList": { + "additionalProperties": { + "$ref": "#/$defs/Quantity" + }, + "type": "object" + }, + "ResourceRequirements": { + "type": "object", + "additionalProperties": false, + "properties": { + "limits": { + "type": "object", + "additionalProperties": false, + "properties": { + "cpu": { + "type": ["string", "integer"] + }, + "memory": { + "type": "string" + } + } + }, + "requests": { + "type": "object", + "additionalProperties": false, + "properties": { + "cpu": { + "type": ["string", "integer"] + }, + "memory": { + "type": "string" + } + } + } + } + }, + "RollingUpdateDaemonSet": { + "properties": { + "maxUnavailable": { + "type": ["string", "integer"] + }, + "maxSurge": { + "type": ["string", "integer"] + } + }, + "additionalProperties": false, + "type": "object" + }, + "RollingUpdateDeployment": { + "properties": { + "maxUnavailable": { + "type": ["string", "integer"] + }, + "maxSurge": { + "type": ["string", "integer"] + } + }, + "additionalProperties": false, + "type": "object" + }, + "SELinuxOptions": { + "properties": { + "user": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "level": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ScaleIOVolumeSource": { + "properties": { + "gateway": { + "type": "string" + }, + "system": { + "type": "string" + }, + "secretRef": { + "$ref": "#/$defs/LocalObjectReference" + }, + "sslEnabled": { + "type": "boolean" + }, + "protectionDomain": { + "type": "string" + }, + "storagePool": { + "type": "string" + }, + "storageMode": { + "type": "string" + }, + "volumeName": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["gateway", "system", "secretRef"] + }, + "SeccompProfile": { + "properties": { + "type": { + "type": "string" + }, + "localhostProfile": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["type"] + }, + "SecretEnvSource": { + "properties": { + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "SecretKeySelector": { + "properties": { + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["key"] + }, + "SecretProjection": { + "properties": { + "name": { + "type": "string" + }, + "items": { + "items": { + "$ref": "#/$defs/KeyToPath" + }, + "type": "array" + }, + "optional": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "SecretVolumeSource": { + "properties": { + "secretName": { + "type": "string" + }, + "items": { + "items": { + "$ref": "#/$defs/KeyToPath" + }, + "type": "array" + }, + "defaultMode": { + "type": "integer" + }, + "optional": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "SecurityContext": { + "properties": { + "capabilities": { + "$ref": "#/$defs/Capabilities" + }, + "privileged": { + "type": "boolean" + }, + "seLinuxOptions": { + "$ref": "#/$defs/SELinuxOptions" + }, + "windowsOptions": { + "$ref": "#/$defs/WindowsSecurityContextOptions" + }, + "runAsUser": { + "type": "integer" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "procMount": { + "type": "string" + }, + "seccompProfile": { + "$ref": "#/$defs/SeccompProfile" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ServiceAccountTokenProjection": { + "properties": { + "audience": { + "type": "string" + }, + "expirationSeconds": { + "type": "integer" + }, + "path": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["path"] + }, + "PortsSpec": { + "properties": { + "name": { + "type": "string" + }, + "protocol": { + "type": "string" + }, + "appProtocol": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "targetPort": { + "type": ["string", "integer"] + }, + "hostPort": { + "type": "integer" + }, + "nodePort": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["port"] + }, + "ServicePort": { + "properties": { + "name": { + "type": "string" + }, + "protocol": { + "type": "string" + }, + "appProtocol": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "targetPort": { + "type": ["string", "integer"] + }, + "nodePort": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["port"] + }, + "SleepAction": { + "properties": { + "seconds": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["seconds"] + }, + "StorageOSVolumeSource": { + "properties": { + "volumeName": { + "type": "string" + }, + "volumeNamespace": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "secretRef": { + "$ref": "#/$defs/LocalObjectReference" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Sysctl": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["name", "value"] + }, + "TCPSocketAction": { + "properties": { + "port": { + "type": ["string", "integer"] + }, + "host": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["port"] + }, + "Time": { + "properties": {}, + "additionalProperties": false, + "type": "object" + }, + "Toleration": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "value": { + "type": "string" + }, + "effect": { + "type": "string" + }, + "tolerationSeconds": { + "type": "integer" + } + }, + "additionalProperties": false, + "type": "object" + }, + "TopologySpreadConstraint": { + "properties": { + "maxSkew": { + "type": "integer" + }, + "topologyKey": { + "type": "string" + }, + "whenUnsatisfiable": { + "type": "string" + }, + "labelSelector": { + "$ref": "#/$defs/LabelSelector" + }, + "minDomains": { + "type": "integer" + }, + "nodeAffinityPolicy": { + "type": "string" + }, + "nodeTaintsPolicy": { + "type": "string" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["maxSkew", "topologyKey", "whenUnsatisfiable"] + }, + "TypedLocalObjectReference": { + "properties": { + "apiGroup": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["apiGroup", "kind", "name"] + }, + "TypedObjectReference": { + "properties": { + "apiGroup": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["apiGroup", "kind", "name"] + }, + "Volume": { + "properties": { + "name": { + "type": "string" + }, + "hostPath": { + "$ref": "#/$defs/HostPathVolumeSource" + }, + "emptyDir": { + "$ref": "#/$defs/EmptyDirVolumeSource" + }, + "gcePersistentDisk": { + "$ref": "#/$defs/GCEPersistentDiskVolumeSource" + }, + "awsElasticBlockStore": { + "$ref": "#/$defs/AWSElasticBlockStoreVolumeSource" + }, + "gitRepo": { + "$ref": "#/$defs/GitRepoVolumeSource" + }, + "secret": { + "$ref": "#/$defs/SecretVolumeSource" + }, + "nfs": { + "$ref": "#/$defs/NFSVolumeSource" + }, + "iscsi": { + "$ref": "#/$defs/ISCSIVolumeSource" + }, + "glusterfs": { + "$ref": "#/$defs/GlusterfsVolumeSource" + }, + "persistentVolumeClaim": { + "$ref": "#/$defs/PersistentVolumeClaimVolumeSource" + }, + "rbd": { + "$ref": "#/$defs/RBDVolumeSource" + }, + "flexVolume": { + "$ref": "#/$defs/FlexVolumeSource" + }, + "cinder": { + "$ref": "#/$defs/CinderVolumeSource" + }, + "cephfs": { + "$ref": "#/$defs/CephFSVolumeSource" + }, + "flocker": { + "$ref": "#/$defs/FlockerVolumeSource" + }, + "downwardAPI": { + "$ref": "#/$defs/DownwardAPIVolumeSource" + }, + "fc": { + "$ref": "#/$defs/FCVolumeSource" + }, + "azureFile": { + "$ref": "#/$defs/AzureFileVolumeSource" + }, + "configMap": { + "$ref": "#/$defs/ConfigMapVolumeSource" + }, + "vsphereVolume": { + "$ref": "#/$defs/VsphereVirtualDiskVolumeSource" + }, + "quobyte": { + "$ref": "#/$defs/QuobyteVolumeSource" + }, + "azureDisk": { + "$ref": "#/$defs/AzureDiskVolumeSource" + }, + "photonPersistentDisk": { + "$ref": "#/$defs/PhotonPersistentDiskVolumeSource" + }, + "projected": { + "$ref": "#/$defs/ProjectedVolumeSource" + }, + "portworxVolume": { + "$ref": "#/$defs/PortworxVolumeSource" + }, + "scaleIO": { + "$ref": "#/$defs/ScaleIOVolumeSource" + }, + "storageos": { + "$ref": "#/$defs/StorageOSVolumeSource" + }, + "csi": { + "$ref": "#/$defs/CSIVolumeSource" + }, + "ephemeral": { + "$ref": "#/$defs/EphemeralVolumeSource" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["name"] + }, + "VolumeDevice": { + "properties": { + "name": { + "type": "string" + }, + "devicePath": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["name", "devicePath"] + }, + "VolumeMount": { + "properties": { + "name": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "mountPath": { + "type": "string" + }, + "subPath": { + "type": "string" + }, + "mountPropagation": { + "type": "string" + }, + "subPathExpr": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["name", "mountPath"] + }, + "VolumeProjection": { + "properties": { + "secret": { + "$ref": "#/$defs/SecretProjection" + }, + "downwardAPI": { + "$ref": "#/$defs/DownwardAPIProjection" + }, + "configMap": { + "$ref": "#/$defs/ConfigMapProjection" + }, + "serviceAccountToken": { + "$ref": "#/$defs/ServiceAccountTokenProjection" + }, + "clusterTrustBundle": { + "$ref": "#/$defs/ClusterTrustBundleProjection" + } + }, + "additionalProperties": false, + "type": "object" + }, + "VolumeResourceRequirements": { + "properties": { + "limits": { + "type": "object" + }, + "requests": { + "type": "object" + } + }, + "additionalProperties": false, + "type": "object" + }, + "VsphereVirtualDiskVolumeSource": { + "properties": { + "volumePath": { + "type": "string" + }, + "fsType": { + "type": "string" + }, + "storagePolicyName": { + "type": "string" + }, + "storagePolicyID": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["volumePath"] + }, + "WeightedPodAffinityTerm": { + "properties": { + "weight": { + "type": "integer" + }, + "podAffinityTerm": { + "$ref": "#/$defs/PodAffinityTerm" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["weight", "podAffinityTerm"] + }, + "WindowsSecurityContextOptions": { + "properties": { + "gmsaCredentialSpecName": { + "type": "string" + }, + "gmsaCredentialSpec": { + "type": "string" + }, + "runAsUserName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "InstrumentationSpec": { + "properties": { + "name": { + "type": "string" + }, + "labels": { + "type": "object" + }, + "annotations": { + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "exporter": { + "$ref": "#/$defs/Exporter" + }, + "resource": { + "$ref": "#/$defs/Resource" + }, + "propagators": { + "items": { + "type": "string" + }, + "type": "array" + }, + "sampler": { + "$ref": "#/$defs/Sampler" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "java": { + "$ref": "#/$defs/Java" + }, + "nodejs": { + "$ref": "#/$defs/NodeJS" + }, + "python": { + "$ref": "#/$defs/Python" + }, + "dotnet": { + "$ref": "#/$defs/DotNet" + }, + "go": { + "$ref": "#/$defs/Go" + }, + "apacheHttpd": { + "$ref": "#/$defs/ApacheHttpd" + }, + "nginx": { + "$ref": "#/$defs/Nginx" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Java": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resources": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Nginx": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "attrs": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "configFile": { + "type": "string" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "NodeJS": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Python": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Resource": { + "properties": { + "resourceAttributes": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "addK8sUIDAttributes": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Sampler": { + "properties": { + "type": { + "type": "string" + }, + "argument": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ApacheHttpd": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "attrs": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "version": { + "type": "string" + }, + "configPath": { + "type": "string" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "DotNet": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Exporter": { + "properties": { + "endpoint": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Go": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "OpAMPBridgeSpec": { + "properties": { + "clusterRole": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "annotations": { + "type": "object" + }, + "name": { + "type": "string" + }, + "rules": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "required": ["enabled"] + }, + "enabled": { + "type": "boolean" + }, + "addReportingLabel": { + "type": "boolean" + }, + "addManagedLabel": { + "type": "boolean" + }, + "endpoint": { + "type": "string" + }, + "annotations": { + "type": "object" + }, + "labels": { + "type": "object" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "capabilities": { + "additionalProperties": { + "type": "boolean" + }, + "type": "object" + }, + "componentsAllowed": { + "additionalProperties": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": "object" + }, + "resources": { + "$ref": "#/$defs/ResourceRequirements" + }, + "nodeSelector": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "securityContext": { + "$ref": "#/$defs/SecurityContext" + }, + "podSecurityContext": { + "$ref": "#/$defs/PodSecurityContext" + }, + "podAnnotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "serviceAccount": { + "type": "string" + }, + "image": { + "description": "Image use in both standalone and agent configs", + "type": "object", + "additionalProperties": false, + "properties": { + "registry": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + }, + "digest": { + "type": "string" + }, + "pullPolicy": { + "type": "string", + "enum": ["IfNotPresent", "Always", "Never"] + } + } + }, + "upgradeStrategy": { + "type": "string" + }, + "volumeMounts": { + "items": { + "$ref": "#/$defs/VolumeMount" + }, + "type": "array" + }, + "ports": { + "items": { + "$ref": "#/$defs/ServicePort" + }, + "type": "array" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "envFrom": { + "items": { + "$ref": "#/$defs/EnvFromSource" + }, + "type": "array" + }, + "tolerations": { + "items": { + "$ref": "#/$defs/Toleration" + }, + "type": "array" + }, + "volumes": { + "items": { + "$ref": "#/$defs/Volume" + }, + "type": "array" + }, + "hostNetwork": { + "type": "boolean" + }, + "priorityClassName": { + "type": "string" + }, + "affinity": { + "$ref": "#/$defs/Affinity" + }, + "topologySpreadConstraints": { + "items": { + "$ref": "#/$defs/TopologySpreadConstraint" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object", + "required": ["endpoint", "capabilities", "upgradeStrategy"] + }, + "AdditionalLabels": { + "type": "object", + "additionalProperties": true, + "title": "AdditionalLabels" + }, + "EnableConfigBlock": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": ["enabled"], + "title": "EnableConfigBlock" + }, + "AttachMetadata": { + "type": "object", + "additionalProperties": false, + "properties": { + "node": { + "type": "boolean" + } + }, + "required": ["node"], + "title": "AttachMetadata" + }, + "KubeAPIServer": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "tlsConfig": { + "$ref": "#/$defs/TLSConfig" + }, + "serviceMonitor": { + "$ref": "#/$defs/Monitor" + } + }, + "required": ["enabled", "serviceMonitor", "tlsConfig"], + "title": "KubeAPIServer" + }, + "TLSConfig": { + "type": "object", + "additionalProperties": false, + "properties": { + "serverName": { + "type": "string" + }, + "insecureSkipVerify": { + "type": "boolean" + } + }, + "required": ["insecureSkipVerify", "serverName"], + "title": "TLSConfig" + }, + "KubeDNS": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "service": { + "$ref": "#/$defs/KubeDNSService" + }, + "serviceMonitor": { + "$ref": "#/$defs/KubeServiceMonitor" + } + }, + "required": ["enabled", "service", "serviceMonitor"], + "title": "KubeDNS" + }, + "KubeDNSService": { + "type": "object", + "additionalProperties": false, + "properties": { + "dnsmasq": { + "$ref": "#/$defs/Dnsmasq" + }, + "skydns": { + "$ref": "#/$defs/Dnsmasq" + } + }, + "required": ["dnsmasq", "skydns"], + "title": "KubeDNSService" + }, + "Dnsmasq": { + "type": "object", + "additionalProperties": false, + "properties": { + "port": { + "type": "integer" + }, + "targetPort": { + "type": "integer" + } + }, + "required": ["port", "targetPort"], + "title": "Dnsmasq" + }, + "Kubelet": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "namespace": { + "type": "string" + }, + "serviceMonitor": { + "$ref": "#/$defs/KubeletServiceMonitor" + } + }, + "required": ["enabled", "namespace", "serviceMonitor"], + "title": "Kubelet" + }, + "KubeletServiceMonitor": { + "type": "object", + "additionalProperties": false, + "properties": { + "attachMetadata": { + "$ref": "#/$defs/AttachMetadata" + }, + "interval": { + "type": "string" + }, + "honorLabels": { + "type": "boolean" + }, + "honorTimestamps": { + "type": "boolean" + }, + "https": { + "type": "boolean" + }, + "cAdvisor": { + "type": "boolean" + }, + "probes": { + "type": "boolean" + } + }, + "required": [ + "cAdvisor", + "honorLabels", + "honorTimestamps", + "https", + "interval", + "probes" + ], + "title": "KubeletServiceMonitor" + }, + "KubeServiceMonitorDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "endpoints": { + "type": "array", + "items": {} + }, + "service": { + "$ref": "#/$defs/KubeService" + }, + "serviceMonitor": { + "$ref": "#/$defs/KubeServiceMonitor" + } + }, + "required": ["enabled", "endpoints", "service", "serviceMonitor"], + "title": "KubeServiceMonitorDefinition" + }, + "KubeService": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "selector": { + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9-]+$": { + "type": "string", + "description": "Selector labels used to match the service to pods." + } + }, + "description": "Labels to select pods for the service." + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "targetPort": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + } + }, + "required": ["enabled"], + "title": "KubeService" + }, + "KubeServiceMonitor": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "interval": { + "type": "string" + }, + "sampleLimit": { + "type": "integer" + }, + "targetLimit": { + "type": "integer" + }, + "labelLimit": { + "type": "integer" + }, + "labelNameLengthLimit": { + "type": "integer" + }, + "labelValueLengthLimit": { + "type": "integer" + }, + "proxyUrl": { + "type": "string" + }, + "port": { + "type": "string" + }, + "jobLabel": { + "type": "string" + }, + "selector": { + "$ref": "#/$defs/AdditionalLabels" + }, + "metricRelabelings": { + "type": "array", + "items": {} + }, + "relabelings": { + "type": "array", + "items": {} + }, + "additionalLabels": { + "$ref": "#/$defs/AdditionalLabels" + }, + "https": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "insecureSkipVerify": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "serverName": { + "anyOf": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "dnsmasqMetricRelabelings": { + "type": "array", + "items": {} + }, + "dnsmasqRelabelings": { + "type": "array", + "items": {} + }, + "scheme": { + "type": "string" + }, + "caFile": { + "type": "string" + }, + "certFile": { + "type": "string" + }, + "keyFile": { + "type": "string" + } + }, + "required": [ + "additionalLabels", + "interval", + "jobLabel", + "labelLimit", + "labelNameLengthLimit", + "labelValueLengthLimit", + "metricRelabelings", + "proxyUrl", + "relabelings", + "sampleLimit", + "selector", + "targetLimit" + ], + "title": "KubeServiceMonitor" + }, + "KubeStateMetrics": { + "type": "object", + "additionalProperties": true, + "properties": { + "enabled": { + "type": "boolean" + }, + "namespaceOverride": { + "type": "string" + }, + "rbac": { + "$ref": "#/$defs/KubeStateMetricsRbac" + }, + "releaseLabel": { + "type": "boolean" + }, + "prometheus": { + "$ref": "#/$defs/Prometheus" + }, + "selfMonitor": { + "$ref": "#/$defs/EnableConfigBlock" + } + }, + "required": [ + "namespaceOverride", + "prometheus", + "rbac", + "releaseLabel", + "selfMonitor" + ], + "title": "KubeStateMetrics" + }, + "Prometheus": { + "type": "object", + "additionalProperties": true, + "properties": { + "monitor": { + "$ref": "#/$defs/Monitor" + } + }, + "required": ["monitor"], + "title": "Prometheus" + }, + "Monitor": { + "type": "object", + "additionalProperties": true, + "properties": { + "enabled": { + "type": "boolean" + }, + "interval": { + "type": "string" + }, + "sampleLimit": { + "type": "integer" + }, + "targetLimit": { + "type": "integer" + }, + "labelLimit": { + "type": "integer" + }, + "labelNameLengthLimit": { + "type": "integer" + }, + "labelValueLengthLimit": { + "type": "integer" + }, + "scrapeTimeout": { + "type": "string" + }, + "proxyUrl": { + "type": "string" + }, + "honorLabels": { + "type": "boolean" + }, + "metricRelabelings": { + "type": "array", + "items": { + "$ref": "#/$defs/MetricRelabeling" + } + }, + "relabelings": { + "type": "array", + "items": {} + }, + "jobLabel": { + "type": "string" + }, + "selector": { + "$ref": "#/$defs/Selector" + }, + "additionalLabels": { + "$ref": "#/$defs/AdditionalLabels" + } + }, + "required": [ + "interval", + "labelLimit", + "labelNameLengthLimit", + "labelValueLengthLimit", + "metricRelabelings", + "proxyUrl", + "relabelings", + "sampleLimit", + "targetLimit" + ], + "title": "Monitor" + }, + "MetricRelabeling": { + "type": "object", + "additionalProperties": false, + "properties": { + "action": { + "type": "string" + }, + "regex": { + "type": "string" + }, + "sourceLabels": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["action", "regex", "sourceLabels"], + "title": "MetricRelabeling" + }, + "Selector": { + "type": "object", + "additionalProperties": false, + "properties": { + "matchLabels": { + "$ref": "#/$defs/MatchLabels" + } + }, + "required": ["matchLabels"], + "title": "Selector" + }, + "MatchLabels": { + "type": "object", + "additionalProperties": false, + "properties": { + "component": { + "type": "string" + }, + "provider": { + "type": "string" + } + }, + "required": ["component", "provider"], + "title": "MatchLabels" + }, + "KubeStateMetricsRbac": { + "type": "object", + "additionalProperties": true, + "properties": { + "create": { + "type": "boolean" + } + }, + "required": ["create"], + "title": "KubeStateMetricsRbac" + }, + "PrometheusNodeExporter": { + "type": "object", + "additionalProperties": true, + "properties": { + "enabled": { + "type": "boolean" + }, + "namespaceOverride": { + "type": "string" + }, + "podLabels": { + "$ref": "#/$defs/PodLabels" + }, + "releaseLabel": { + "type": "boolean" + }, + "extraArgs": { + "type": "array", + "items": { + "type": "string" + } + }, + "service": { + "$ref": "#/$defs/PrometheusNodeExporterService" + }, + "prometheus": { + "$ref": "#/$defs/Prometheus" + }, + "rbac": { + "$ref": "#/$defs/PrometheusNodeExporterRbac" + } + }, + "required": [ + "extraArgs", + "namespaceOverride", + "podLabels", + "prometheus", + "rbac", + "releaseLabel", + "service" + ], + "title": "PrometheusNodeExporter" + }, + "PodLabels": { + "type": "object", + "additionalProperties": false, + "properties": { + "jobLabel": { + "type": "string" + } + }, + "required": ["jobLabel"], + "title": "PodLabels" + }, + "PrometheusNodeExporterRbac": { + "type": "object", + "additionalProperties": true, + "properties": { + "pspEnabled": { + "type": "boolean" + } + }, + "required": ["pspEnabled"], + "title": "PrometheusNodeExporterRbac" + }, + "PrometheusNodeExporterService": { + "type": "object", + "additionalProperties": true, + "properties": { + "portName": { + "type": "string" + } + }, + "required": ["portName"], + "title": "PrometheusNodeExporterService" + } + }, + "properties": { + "cleanupJob": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "crds": { + "type": "object", + "properties": { + "install": { + "type": "boolean" + } + } + }, + "fullnameOverride": { + "type": "string" + }, + "namespaceOverride": { + "type": "string" + }, + "defaultCRConfig": { + "$ref": "#/$defs/OpenTelemetryCollectorSpec" + }, + "collectors": { + "type": "object", + "patternProperties": { + "^[a-z]+[a-zA-Z0-9]+$": { + "$ref": "#/$defs/OpenTelemetryCollectorSpec" + } + } + }, + "clusterName": { + "type": "string" + }, + "clusterRole": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "annotations": { + "type": "object" + }, + "name": { + "type": "string" + }, + "rules": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "required": ["enabled"] + }, + "opAMPBridge": { + "$ref": "#/$defs/OpAMPBridgeSpec" + }, + "instrumentation": { + "$ref": "#/$defs/InstrumentationSpec" + }, + "extraEnvs": { + "type": "array", + "items": { + "type": "object" + } + }, + "opentelemetry-operator": { + "type": "object" + }, + "kubernetesServiceMonitors": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "ignoreNamespaceSelectors": { + "type": "boolean" + } + }, + "required": ["enabled", "ignoreNamespaceSelectors"] + }, + "kubeApiServer": { + "$ref": "#/$defs/KubeAPIServer" + }, + "kubelet": { + "$ref": "#/$defs/Kubelet" + }, + "kubeControllerManager": { + "$ref": "#/$defs/KubeServiceMonitorDefinition" + }, + "coreDns": { + "$ref": "#/$defs/KubeServiceMonitorDefinition" + }, + "kubeDns": { + "$ref": "#/$defs/KubeDNS" + }, + "kubeEtcd": { + "$ref": "#/$defs/KubeServiceMonitorDefinition" + }, + "kubeScheduler": { + "$ref": "#/$defs/KubeServiceMonitorDefinition" + }, + "kubeProxy": { + "$ref": "#/$defs/KubeServiceMonitorDefinition" + }, + "kubeStateMetrics": { + "$ref": "#/$defs/EnableConfigBlock" + }, + "nodeExporter": { + "$ref": "#/$defs/EnableConfigBlock" + }, + "kube-state-metrics": { + "$ref": "#/$defs/KubeStateMetrics" + }, + "prometheus-node-exporter": { + "$ref": "#/$defs/PrometheusNodeExporter" + } + } +} diff --git a/testing/integration/k8s/testdata/opentelemetry-kube-stack/values.yaml b/testing/integration/k8s/testdata/opentelemetry-kube-stack/values.yaml new file mode 100644 index 00000000000..a633e465fbb --- /dev/null +++ b/testing/integration/k8s/testdata/opentelemetry-kube-stack/values.yaml @@ -0,0 +1,1725 @@ +# Top level field indicating an override for fullname +fullnameOverride: "" +# Top level field indicating an override for the namespace +namespaceOverride: "" + +# Top level field specifying the name of the cluster +clusterName: "" + +# Extra environment variables to add to each collector, bridge and instrumentation +extraEnvs: [] + +# Enables a cleanup job to make sure the CRs are uninstalled before the operator +cleanupJob: + # It is recommended to always keep this enabled so that running helm uninstall works properly. + # For non-helm installations i.e. ones created via helm template, it may make sense to disable this. + # For those installations, ensure that uninstallation for the operator happens _after_ the deletion of the CRs. + enabled: true + +# Should the CRDs be installed by this chart. +crds: + # Should the CRDs be installed + install: true + +# Top level field related to the OpenTelemetry Operator +opentelemetry-operator: + # Field indicating whether the operator is enabled or not + enabled: true + manager: + collectorImage: + repository: otel/opentelemetry-collector-k8s + # Sub-field for admission webhooks configuration + admissionWebhooks: + # Policy for handling failures + # Setting this allows for an installation of the otel operator at the same time as the custom resources it manages. + failurePolicy: "Ignore" + + # This is disabled by default, as doing so creates a race condition with helm. + # https://github.com/open-telemetry/opentelemetry-helm-charts/issues/677 + # Users of this chart should _never_ set this to be true. If a user wishes + # to install the CRDs through the opentelemetry-operator chart, it is recommended + # to install the opentelemetry-operator chart separately and prior to the installation + # of this chart. + crds: + create: false + +# This is the default configuration for all collectors generated by the chart. +# Any collectors in the `collectors` are overlayed on top of this configuration. +defaultCRConfig: + enabled: false + + # Suffix for the collector pool, by default the release name is prepended + suffix: "collector" + + # fullnameOverride allows overriding the collector's name + fullnameOverride: "" + + # Annotations for the collector + annotations: {} + # io.opentelemetry.com/resource: hello + + # Labels for the collector + labels: {} + # app: otc + + # scrape_configs_file allows the user to load an external file into + # the collector's prometheus scrape_configs. This is added to assist users + # coming from the prometheus ecosystem by allowing users to simply copy and paste + # directly from prometheus into this file to use the same config. + scrape_configs_file: "" + + # Management state of the collector + managementState: managed + + # Configuration for cluster role binding + clusterRoleBinding: + enabled: true + clusterRoleName: "" + + # Number of replicas for the collector + # replicas: 1 + + # Mode of deployment for the collector + mode: deployment + + # Service account associated with the collector + serviceAccount: "" + + # Image details for the collector + image: + # If you want to use the core image `otel/opentelemetry-collector`, you also need to change `command.name` value to `otelcol`. + repository: otel/opentelemetry-collector-k8s + pullPolicy: IfNotPresent + # By default, the version set for the collector will match the version of the operator being run. + tag: "" + # When digest is set to a non-empty value, images will be pulled by digest (regardless of tag value). + digest: "" + + # Upgrade strategy for the collector + upgradeStrategy: automatic + + # Configuration options for the collector + config: {} + # receivers: + # otlp: + # protocols: + # grpc: + # endpoint: ${env:MY_POD_IP}:4317 + # http: + # endpoint: ${env:MY_POD_IP}:4318 + # exporters: + # otlp: + # endpoint: "otel-collector.default:4317" + # tls: + # insecure: true + # sending_queue: + # num_consumers: 4 + # queue_size: 100 + # retry_on_failure: + # enabled: true + # processors: + # batch: + # memory_limiter: + # # 80% of maximum memory up to 2G + # limit_mib: 400 + # # 25% of limit up to 2G + # spike_limit_mib: 100 + # check_interval: 5s + # extensions: + # zpages: {} + # service: + # extensions: [zpages] + # pipelines: + # traces: + # receivers: [otlp] + # processors: [memory_limiter, batch] + # exporters: [otlp] + + # Whether to use host network for the collector + hostNetwork: false + + # Whether to share process namespace for the collector + shareProcessNamespace: false + + # Priority class name for the collector + priorityClassName: "" + + # Termination grace period for the collector + terminationGracePeriodSeconds: 30 + + # Resource requests and limits for the collector + resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "128Mi" + cpu: "250m" + + # Node selector for the collector + nodeSelector: {} + # nodeType: worker + + # Arguments for the collector + args: {} + # arg1: value1 + # arg2: value2 + + # Autoscaler configuration for the collector + autoscaler: {} + # minReplicas: 1 + # maxReplicas: 10 + # targetCPUUtilization: 50 + + # Pod disruption budget for the collector + podDisruptionBudget: {} + # maxUnavailable: 1 + + # Security context for the collector + securityContext: {} + # runAsUser: 1000 + # capabilities: + # drop: + # - ALL + + # Pod security context for the collector + podSecurityContext: {} + # runAsUser: 1000 + + # Annotations for the collector's pods + podAnnotations: {} + # prometheus.io/scrape: "true" + + # Target allocator configuration + targetAllocator: {} + # replicas: 1 + # nodeSelector: + # nodeType: worker + # resources: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + # allocationStrategy: consistent-hashing + # filterStrategy: relabel-config + # serviceAccount: my-service-account + # image: myregistry/myimage:latest + # enabled: true + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/e2e-az-name + # operator: In + # values: + # - e2e-az1 + # - e2e-az2 + # # Configuration for Prometheus Custom Resources + # prometheusCR: + # enabled: true + # scrapeInterval: 30s + # podMonitorSelector: + # key1: value1 + # key2: value2 + # serviceMonitorSelector: + # key1: value1 + # key2: value2 + # securityContext: + # runAsUser: 1000 + # capabilities: + # drop: + # - ALL + # podSecurityContext: + # runAsUser: 1000 + # # Topology spread constraints for the target allocator + # topologySpreadConstraints: + # - maxSkew: 1 + # topologyKey: kubernetes.io/hostname + # whenUnsatisfiable: DoNotSchedule + # # Tolerations for the collector + # tolerations: + # - key: "key" + # operator: "Equal" + # value: "value" + # effect: "NoSchedule" + # # Environment variables for the target allocator + # env: + # - name: ENV_VAR1 + # value: value1 + # - name: ENV_VAR2 + # value: value2 + # # Observability configuration for the target allocator + # observability: + # metrics: + # enableMetrics: true + + # Affinity configuration for the collector + affinity: {} + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/e2e-az-name + # operator: In + # values: + # - e2e-az1 + # - e2e-az2 + + # Lifecycle configuration for the collector + lifecycle: {} + # preStop: + # exec: + # command: + # [ + # "/bin/sh", + # "-c", + # "echo Hello from the preStop handler > /dev/termination-log", + # ] + + # Liveness probe configuration for the collector + livenessProbe: {} + # initialDelaySeconds: 3 + # periodSeconds: 5 + # timeoutSeconds: 2 + # failureThreshold: 5 + + # Observability configuration for the collector + observability: {} + # metrics: + # enableMetrics: true + + # Update strategy for the collector + updateStrategy: {} + # type: RollingUpdate + + # Volume mounts for the collector + volumeMounts: [] + # - name: data + # mountPath: /data + + # Ports configuration for the collector + # The operator automatically calculates ports for known receivers and exporters + # Set any custom ports here. + ports: [] + # - name: http + # protocol: TCP + # port: 80 + # targetPort: 8080 + + # Environment variables for the collector + env: [] + # - name: ENV_VAR1 + # value: value1 + # - name: ENV_VAR2 + # value: value2 + + # Volume claim templates for the collector + volumeClaimTemplates: [] + # - metadata: + # name: storage + # spec: + # accessModes: ["ReadWriteOnce"] + # resources: + # requests: + # storage: 1Gi + + # Tolerations for the collector + tolerations: [] + # - key: "key" + # operator: "Equal" + # value: "value" + # effect: "NoSchedule" + + # Volumes for the collector + volumes: [] + # - name: config-volume + # configMap: + # name: config + + # Init containers for the collector + initContainers: [] + # - name: init-nginx + # image: nginx + + # Additional containers for the collector + additionalContainers: [] + # - name: additional-container + # image: busybox + + # Topology spread constraints for the collector + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: kubernetes.io/hostname + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app: my-app + + # Config maps for the collector + configmaps: [] + # - name: config + # mountPath: /etc/config + + # Handles basic configuration of components that + # also require k8s modifications to work correctly. + # .Values.config can be used to modify/add to a preset + # component configuration, but CANNOT be used to remove + # preset configuration. If you require removal of any + # sections of a preset configuration, you cannot use + # the preset. Instead, configure the component manually in + # .Values.config and use the other fields supplied in the + # values.yaml to configure k8s as necessary. + presets: + # Configures the collector to collect logs. + # Adds the filelog receiver to the logs pipeline + # and adds the necessary volumes and volume mounts. + # Best used with mode = daemonset. + # See https://opentelemetry.io/docs/kubernetes/collector/components/#filelog-receiver for details on the receiver. + logsCollection: + enabled: false + includeCollectorLogs: true + # Enabling this writes checkpoints in /var/lib/otelcol/ host directory. + # Note this changes collector's user to root, so that it can write to host directory. + storeCheckpoints: false + # The maximum bytes size of the recombined field. + # Once the size exceeds the limit, all received entries of the source will be combined and flushed. + maxRecombineLogSize: 102400 + # Configures the collector to collect host metrics. + # Adds the hostmetrics receiver to the metrics pipeline + # and adds the necessary volumes and volume mounts. + # Best used with mode = daemonset. + # See https://opentelemetry.io/docs/kubernetes/collector/components/#host-metrics-receiver for details on the receiver. + hostMetrics: + enabled: false + # Configures the Kubernetes Processor to add Kubernetes metadata. + # Adds the k8sattributes processor to all the pipelines + # and adds the necessary rules to ClusteRole. + # Best used with mode = daemonset. + # See https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-attributes-processor for details on the receiver. + kubernetesAttributes: + enabled: false + # When enabled the processor will extra all labels for an associated pod and add them as resource attributes. + # The label's exact name will be the key. + extractAllPodLabels: false + # When enabled the processor will extra all annotations for an associated pod and add them as resource attributes. + # The annotation's exact name will be the key. + extractAllPodAnnotations: false + # Configures the collector to collect node, pod, and container metrics from the API server on a kubelet.. + # Adds the kubeletstats receiver to the metrics pipeline + # and adds the necessary rules to ClusteRole. + # Best used with mode = daemonset. + # See https://opentelemetry.io/docs/kubernetes/collector/components/#kubeletstats-receiver for details on the receiver. + kubeletMetrics: + enabled: false + # Configures the collector to collect kubernetes events. + # Adds the k8sobjects receiver to the logs pipeline + # and collects kubernetes events by default. + # Best used with mode = deployment or statefulset. + # MUST be used by a collector with a single replica. + # See https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-objects-receiver for details on the receiver. + kubernetesEvents: + enabled: false + # Configures the Kubernetes Cluster Receiver to collect cluster-level metrics. + # Adds the k8s_cluster receiver to the metrics pipeline + # and adds the necessary rules to ClusteRole. + # Best used with mode = deployment or statefulset. + # MUST be used by a collector with a single replica. + # See https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-cluster-receiver for details on the receiver. + clusterMetrics: + enabled: false + +# Collectors is a map of collector configurations of the form: +# collectors: +# collectorName: +# enabled: true +# name: "example" +# Each collector configuration is layered on top of the `defaultCRConfig`, overriding a default if set. +# This configuration allows for multiple layers of overrides for different clusters. For example, you could +# create a collector called test with an OTLP exporter in your values.yaml, and then override the endpoint's +# destination in a file called values-staging.yaml. +collectors: + daemon: + suffix: daemon + mode: daemonset + enabled: true + resources: + limits: + cpu: 100m + memory: 250Mi + requests: + cpu: 100m + memory: 128Mi + # A scrape config file to instruct the daemon collector to pull metrics from any matching targets on the same node with + # prometheus.io/scrape=true + # This config also scrapes a running node exporter and the kubelet CAdvisor metrics which aren't currently supported. + scrape_configs_file: "daemon_scrape_configs.yaml" + presets: + logsCollection: + enabled: true + kubeletMetrics: + enabled: true + hostMetrics: + enabled: true + kubernetesAttributes: + enabled: true + config: + receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + processors: + batch: + send_batch_size: 1000 + timeout: 1s + send_batch_max_size: 1500 + resourcedetection/env: + detectors: [env] + timeout: 2s + override: false + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: + - otlp + processors: + - resourcedetection/env + - batch + exporters: + - debug + metrics: + receivers: + - otlp + processors: + - resourcedetection/env + - batch + exporters: + - debug + logs: + receivers: + - otlp + processors: + - resourcedetection/env + - batch + exporters: + - debug + cluster: + suffix: cluster-stats + replicas: 1 + mode: deployment + enabled: true + resources: + limits: + cpu: 100m + memory: 500Mi + requests: + cpu: 100m + memory: 500Mi + presets: + kubernetesAttributes: + enabled: true + kubernetesEvents: + enabled: true + clusterMetrics: + enabled: true + config: + receivers: {} + processors: + batch: + send_batch_size: 1000 + timeout: 1s + send_batch_max_size: 1500 + resourcedetection/env: + detectors: [env] + timeout: 2s + override: false + exporters: + debug: {} + service: + pipelines: + metrics: + receivers: [k8s_cluster] + processors: [resourcedetection/env, batch] + exporters: [debug] + logs: + receivers: [k8sobjects] + processors: [resourcedetection/env, batch] + exporters: [debug] + +# Cluster role configuration +clusterRole: + # Whether the cluster role is enabled or not + enabled: true + + # Annotations for the cluster role + annotations: {} + + # Rules for the cluster role + rules: [] + +# Instrumentation configuration +instrumentation: + # Whether instrumentation is enabled or not + enabled: false + labels: {} + annotations: {} + + # Exporter configuration + exporter: + # This is the default collector's service + # Upon creation of a tracing collector, edit this endpoint. + endpoint: http://collector-collector:4317 + + # Resource configuration + resource: + resourceAttributes: {} + # environment: dev + addK8sUIDAttributes: true + + # Propagators configuration + propagators: + - tracecontext + - baggage + - b3 + - b3multi + - jaeger + - xray + - ottrace + + # Sampler configuration + sampler: {} + # type: parentbased_always_on + # argument: "0.25" + + # Environment variables for instrumentation + env: [] + # - name: ENV_VAR1 + # value: value1 + # - name: ENV_VAR2 + # value: value2 + + # Java agent configuration + java: {} + # image: myregistry/java-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: JAVA_ENV_VAR + # value: java_value + # resources: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # NodeJS agent configuration + nodejs: {} + # image: myregistry/nodejs-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: NODEJS_ENV_VAR + # value: nodejs_value + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # Python agent configuration + python: {} + # image: myregistry/python-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: PYTHON_ENV_VAR + # value: python_value + # # Required if endpoint is set to 4317. + # # Python autoinstrumentation uses http/proto by default + # # so data must be sent to 4318 instead of 4317. + # - name: OTEL_EXPORTER_OTLP_ENDPOINT + # value: http://otel-collector:4318 + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # .NET agent configuration + dotnet: {} + # image: myregistry/dotnet-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: DOTNET_ENV_VAR + # value: dotnet_value + # # Required if endpoint is set to 4317. + # # Dotnet autoinstrumentation uses http/proto by default + # # See https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/888e2cd216c77d12e56b54ee91dafbc4e7452a52/docs/config.md#otlp + # - name: OTEL_EXPORTER_OTLP_ENDPOINT + # value: http://otel-collector:4318 + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # Go agent configuration + go: {} + # image: myregistry/go-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: GO_ENV_VAR + # value: go_value + # # Required if endpoint is set to 4317. + # # Dotnet autoinstrumentation uses http/proto by default + # # See https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/888e2cd216c77d12e56b54ee91dafbc4e7452a52/docs/config.md#otlp + # - name: OTEL_EXPORTER_OTLP_ENDPOINT + # value: http://otel-collector:4318 + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # Apache HTTPd agent configuration + apacheHttpd: {} + # image: myregistry/apache-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: APACHE_ENV_VAR + # value: apache_value + # attrs: + # - name: ATTRIBUTE_VAR + # value: attribute_value + # version: "2.4" + # configPath: "/usr/local/apache2/conf" + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # NGINX agent configuration + nginx: {} + # image: myregistry/nginx-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: NGINX_ENV_VAR + # value: nginx_value + # attrs: + # - name: ATTRIBUTE_VAR + # value: attribute_value + # configFile: "/etc/nginx/nginx.conf" + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + +# OpAMP bridge configuration. The OpAMP Bridge is an OpenTelemetry component +# that enables enhanced configuration and health monitoring for OpenTelemetry collectors +# deployed in Kubernetes. The Bridge pulls collector CRDs from the Kubernetes cluster and +# reports their configuration and status to a remote OpAMP Server. The Bridge will only pull +# collectors labeled with either +# * opentelemetry.io/opamp-reporting: true +# * opentelemetry.io/opamp-managed: true +# You can learn more about the Bridge's design here: +# https://docs.google.com/document/d/1M8VLNe_sv1MIfu5bUR5OV_vrMBnAI7IJN-7-IAr37JY +opAMPBridge: + # Whether OpAMP bridge is enabled or not + enabled: false + + # Adds `opentelemetry.io/opamp-reporting: true` to all collectors + addReportingLabel: true + # Adds `opentelemetry.io/opamp-managed: true` to all collectors + addManagedLabel: false + + # Endpoint for OpAMP server + endpoint: http://opamp-server:8080 + + # Headers configuration for OpAMP bridge + headers: {} + # Authorization: Bearer your_access_token + # Custom-Header: Custom-Value + + # Capabilities of OpAMP bridge + # You can learn more about OpAMP's capabilities here: + # https://github.com/open-telemetry/opamp-spec/blob/main/specification.md#agenttoservercapabilities + capabilities: + AcceptsOpAMPConnectionSettings: true + AcceptsOtherConnectionSettings: true + AcceptsRemoteConfig: true + AcceptsRestartCommand: true + ReportsEffectiveConfig: true + ReportsHealth: true + ReportsOwnLogs: true + ReportsOwnMetrics: true + ReportsOwnTraces: true + ReportsRemoteConfig: true + ReportsStatus: true + + # Components allowed for OpAMP bridge + componentsAllowed: {} + # receiver: + # - otlp + # - prometheus + # processor: + # - batch + # - memory_limiter + # exporter: + # - prometheusremotewrite + + # Resources configuration for OpAMP bridge + resources: + limits: + cpu: "250m" + memory: "256Mi" + requests: + cpu: "250m" + memory: "256Mi" + + # Security context for OpAMP bridge + securityContext: + runAsNonRoot: true + runAsUser: 1000 + + # Pod security context for OpAMP bridge + podSecurityContext: + fsGroup: 1000 + + # Pod annotations for OpAMP bridge + podAnnotations: {} + # prometheus.io/scrape: "true" + # prometheus.io/port: "8080" + + # Service account for OpAMP bridge + serviceAccount: "" + + # Image for OpAMP bridge + image: + repository: ghcr.io/open-telemetry/opentelemetry-operator/operator-opamp-bridge + pullPolicy: IfNotPresent + # By default, the version set for the bridge will match the version of the operator being run. + tag: "" + # When digest is set to a non-empty value, images will be pulled by digest (regardless of tag value). + digest: "" + + # Upgrade strategy for OpAMP bridge + upgradeStrategy: automatic + + # Volume mounts for OpAMP bridge + volumeMounts: [] + # - name: data + # mountPath: /data + + # Ports configuration for OpAMP bridge + ports: [] + # - name: http + # port: 8080 + # protocol: TCP + + # Environment variables for OpAMP bridge + env: [] + # - name: ENVIRONMENT + # value: production + + # Environment variables from config map for OpAMP bridge + envFrom: [] + # - configMapRef: + # name: opamp-config + + # Tolerations for OpAMP bridge + tolerations: [] + # - key: "opamp" + # operator: "Equal" + # value: "true" + # effect: "NoSchedule" + + # Volumes for OpAMP bridge + volumes: [] + # - name: data + # emptyDir: {} + + # Whether to use host network for OpAMP bridge + hostNetwork: false + + # Priority class name for OpAMP bridge + priorityClassName: "" + + # Affinity configuration for OpAMP bridge + affinity: {} + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: opamp + # operator: In + # values: + # - "true" + + # Topology spread constraints for OpAMP bridge + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: "kubernetes.io/hostname" + # whenUnsatisfiable: "DoNotSchedule" + # labelSelector: + # matchLabels: + # opamp: "true" + + # Bridge cluster role configuration + # In order to function the bridge is given its default role to + # list and get pods and opentelemetry collectors + clusterRole: + # Whether the bridge cluster role is enabled or not + enabled: true + + # Annotations for the bridge cluster role + annotations: {} + + # Rules for the bridge cluster role + rules: [] + +############################ +# Prometheus Configuration # +# (optional) # +############################ +# This configuration sections allows for a direct replacement of the kube-prometheus-stack +# chart where the collector scrapes the same metrics as the default prometheus installation. + +## Flag to disable all the kubernetes component scrapers +## +kubernetesServiceMonitors: + enabled: false + ignoreNamespaceSelectors: false + +## Component scraping the kube api server +## +kubeApiServer: + enabled: false + tlsConfig: + serverName: kubernetes + insecureSkipVerify: false + serviceMonitor: + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + jobLabel: component + selector: + matchLabels: + component: apiserver + provider: kubernetes + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + metricRelabelings: + # Drop excessively noisy apiserver buckets. + - action: drop + regex: apiserver_request_duration_seconds_bucket;(0.15|0.2|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2|3|3.5|4|4.5|6|7|8|9|15|25|40|50) + sourceLabels: + - __name__ + - le + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + relabelings: [] + # - sourceLabels: + # - __meta_kubernetes_namespace + # - __meta_kubernetes_service_name + # - __meta_kubernetes_endpoint_port_name + # action: keep + # regex: default;kubernetes;https + # - targetLabel: __address__ + # replacement: kubernetes.default.svc:443 + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping the kubelet and kubelet-hosted cAdvisor +## the configuration for this is currently only in kubelet_scrape_configs.yaml +## This is because kubelet doesn't have a service and can only be scraped manually. +kubelet: + enabled: false + namespace: kube-system + + serviceMonitor: + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## If true, Prometheus use (respect) labels provided by exporter. + ## + honorLabels: true + + ## If true, Prometheus ingests metrics with timestamp provided by exporter. If false, Prometheus ingests metrics with timestamp of scrape. + ## + honorTimestamps: true + + ## Enable scraping the kubelet over https. For requirements to enable this see + ## https://github.com/prometheus-operator/prometheus-operator/issues/926 + ## + https: true + + ## Enable scraping /metrics/cadvisor from kubelet's service + ## + cAdvisor: true + + ## Enable scraping /metrics/probes from kubelet's service + ## + probes: true + +## Component scraping the kube controller manager +## +kubeControllerManager: + enabled: false + + ## If your kube controller manager is not deployed as a pod, specify IPs it can be found on + ## + endpoints: [] + # - 10.141.4.22 + # - 10.141.4.23 + # - 10.141.4.24 + + ## If using kubeControllerManager.endpoints only the port and targetPort are used + ## + service: + enabled: true + ## If null or unset, the value is determined dynamically based on target Kubernetes version due to change + ## of default port in Kubernetes 1.22. + ## + port: null + targetPort: null + # selector: + # component: kube-controller-manager + + serviceMonitor: + enabled: true + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## port: Name of the port the metrics will be scraped from + ## + port: http-metrics + + jobLabel: jobLabel + selector: {} + # matchLabels: + # component: kube-controller-manager + + ## Enable scraping kube-controller-manager over https. + ## Requires proper certs (not self-signed) and delegated authentication/authorization checks. + ## If null or unset, the value is determined dynamically based on target Kubernetes version. + ## + https: null + + # Skip TLS certificate validation when scraping + insecureSkipVerify: null + + # Name of the server to use when validating TLS certificate + serverName: null + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping coreDns. Use either this or kubeDns +## +coreDns: + enabled: false + endpoints: [] + service: + enabled: true + port: 9153 + targetPort: 9153 + # selector: + # k8s-app: kube-dns + serviceMonitor: + enabled: true + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## port: Name of the port the metrics will be scraped from + ## + port: http-metrics + + jobLabel: jobLabel + selector: {} + # matchLabels: + # k8s-app: kube-dns + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping kubeDns. Use either this or coreDns +## +kubeDns: + enabled: false + service: + dnsmasq: + port: 10054 + targetPort: 10054 + skydns: + port: 10055 + targetPort: 10055 + # selector: + # k8s-app: kube-dns + serviceMonitor: + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + jobLabel: jobLabel + selector: {} + # matchLabels: + # k8s-app: kube-dns + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + dnsmasqMetricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + dnsmasqRelabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping etcd +## +kubeEtcd: + enabled: false + + ## If your etcd is not deployed as a pod, specify IPs it can be found on + ## + endpoints: [] + # - 10.141.4.22 + # - 10.141.4.23 + # - 10.141.4.24 + + ## Etcd service. If using kubeEtcd.endpoints only the port and targetPort are used + ## + service: + enabled: true + port: 2381 + targetPort: 2381 + # selector: + # component: etcd + + ## Configure secure access to the etcd cluster by loading a secret into prometheus and + ## specifying security configuration below. For example, with a secret named etcd-client-cert + ## + ## serviceMonitor: + ## scheme: https + ## insecureSkipVerify: false + ## serverName: localhost + ## caFile: /etc/prometheus/secrets/etcd-client-cert/etcd-ca + ## certFile: /etc/prometheus/secrets/etcd-client-cert/etcd-client + ## keyFile: /etc/prometheus/secrets/etcd-client-cert/etcd-client-key + ## + serviceMonitor: + enabled: true + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + scheme: http + insecureSkipVerify: false + serverName: "" + caFile: "" + certFile: "" + keyFile: "" + + ## port: Name of the port the metrics will be scraped from + ## + port: http-metrics + + jobLabel: jobLabel + selector: {} + # matchLabels: + # component: etcd + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping kube scheduler +## +kubeScheduler: + enabled: false + + ## If your kube scheduler is not deployed as a pod, specify IPs it can be found on + ## + endpoints: [] + # - 10.141.4.22 + # - 10.141.4.23 + # - 10.141.4.24 + + ## If using kubeScheduler.endpoints only the port and targetPort are used + ## + service: + enabled: true + ## If null or unset, the value is determined dynamically based on target Kubernetes version due to change + ## of default port in Kubernetes 1.23. + ## + port: null + targetPort: null + # selector: + # component: kube-scheduler + + serviceMonitor: + enabled: true + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + ## Enable scraping kube-scheduler over https. + ## Requires proper certs (not self-signed) and delegated authentication/authorization checks. + ## If null or unset, the value is determined dynamically based on target Kubernetes version. + ## + https: null + + ## port: Name of the port the metrics will be scraped from + ## + port: http-metrics + + jobLabel: jobLabel + selector: {} + # matchLabels: + # component: kube-scheduler + + ## Skip TLS certificate validation when scraping + insecureSkipVerify: null + + ## Name of the server to use when validating TLS certificate + serverName: null + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping kube proxy +## +kubeProxy: + enabled: false + + ## If your kube proxy is not deployed as a pod, specify IPs it can be found on + ## + endpoints: [] + # - 10.141.4.22 + # - 10.141.4.23 + # - 10.141.4.24 + + service: + enabled: true + port: 10249 + targetPort: 10249 + # selector: + # k8s-app: kube-proxy + + serviceMonitor: + enabled: true + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## port: Name of the port the metrics will be scraped from + ## + port: http-metrics + + jobLabel: jobLabel + selector: {} + # matchLabels: + # k8s-app: kube-proxy + + ## Enable scraping kube-proxy over https. + ## Requires proper certs (not self-signed) and delegated authentication/authorization checks + ## + https: false + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + relabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Controls whether the kube-state-metrics chart should be created. +## This block matches the configuration for the kube-prometheus-stack chart for compatibility. +kubeStateMetrics: + enabled: false + +## Configuration for kube-state-metrics subchart +## The Kube-State-Metrics agent collects cluster-level metrics +## Read more here about the chart: +## https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics +kube-state-metrics: + namespaceOverride: "" + rbac: + create: true + releaseLabel: true + prometheus: + monitor: + enabled: true + + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## Scrape Timeout. If not set, the Prometheus default scrape timeout is used. + ## + scrapeTimeout: "" + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + # Keep labels from scraped data, overriding server-side labels + ## + honorLabels: true + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + selfMonitor: + enabled: false + +## Controls whether the prometheus-node-exporter chart should be created. +## This block matches the configuration for the kube-prometheus-stack chart for compatibility. +nodeExporter: + enabled: false + +## Configuration for prometheus-node-exporter subchart +## This will install a daemonset that pulls metric data from each node +## Read more here about the chart: +## https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-node-exporter +prometheus-node-exporter: + namespaceOverride: "" + podLabels: + ## Add the 'node-exporter' label to be used by serviceMonitor to match standard common usage in rules and grafana dashboards + ## + jobLabel: node-exporter + releaseLabel: true + extraArgs: + - --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/.+)($|/) + - --collector.filesystem.fs-types-exclude=^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$ + service: + portName: http-metrics + prometheus: + monitor: + enabled: true + + jobLabel: jobLabel + + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## How long until a scrape request times out. If not set, the Prometheus default scape timeout is used. + ## + scrapeTimeout: "" + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + # - sourceLabels: [__name__] + # separator: ; + # regex: ^node_mountstats_nfs_(event|operations|transport)_.+ + # replacement: $1 + # action: drop + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + rbac: + ## If true, create PSPs for node-exporter + ## + pspEnabled: false From 4c59037b9feeb633aa06fad8b02ead675ab08190 Mon Sep 17 00:00:00 2001 From: Panos Koutsovasilis Date: Fri, 20 Jun 2025 14:08:05 +0300 Subject: [PATCH 8/9] fix: use filepath.Join --- magefile.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/magefile.go b/magefile.go index 63a3c82d3c9..a99e350b9b2 100644 --- a/magefile.go +++ b/magefile.go @@ -3922,9 +3922,10 @@ func (h Helm) BuildDependencies() error { settings.SetNamespace("") actionConfig := &action.Configuration{} - chartFile, err := os.ReadFile(fmt.Sprintf("%s/Chart.yaml", helmChartPath)) + chartFilePath := filepath.Join(helmChartPath, "Chart.yaml") + chartFile, err := os.ReadFile(chartFilePath) if err != nil { - return fmt.Errorf("could not read %s/Chart.yaml: %w", helmChartPath, err) + return fmt.Errorf("could not read %q: %w", chartFilePath, err) } dependencies := struct { From 963742ee38fd304b213e65db6c8db2cf7ab6eff5 Mon Sep 17 00:00:00 2001 From: Panos Koutsovasilis Date: Fri, 20 Jun 2025 14:13:01 +0300 Subject: [PATCH 9/9] doc: update BuildDependencies godoc --- magefile.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/magefile.go b/magefile.go index a99e350b9b2..e8570c33cf0 100644 --- a/magefile.go +++ b/magefile.go @@ -3917,6 +3917,16 @@ func (Helm) ensureRepository(repoName, repoURL string, settings *cli.EnvSettings } // BuildDependencies builds the dependencies for the Elastic-Agent Helm chart. +// +// This is a custom implementation that extends the functionality of `helm dependency update`. +// The standard Helm command assumes that all dependency repositories have been added beforehand +// via `helm repo add`, otherwise it fails. This method improves usability by ensuring all +// required repositories are added automatically before resolving dependencies. +// +// Furthermore, `helm dependency update` downloads dependencies as `.tgz` archives into the `charts/` +// directory but does not untar them. For our integration tests, we require the subcharts to be +// extracted. This method downloads and extracts each `.tgz` archive and removes the archive afterward, +// so that only the extracted subcharts remain in the `charts/` directory. func (h Helm) BuildDependencies() error { settings := cli.New() settings.SetNamespace("")