From 56843b343080738cba59408a6dfdecba824b8862 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 3 Sep 2024 00:51:12 +0000 Subject: [PATCH] Added chart versions: stackstate/stackstate-k8s-agent: - 1.0.96 --- .../stackstate-k8s-agent-1.0.96.tgz | Bin 0 -> 34916 bytes .../stackstate-k8s-agent/1.0.96/.helmignore | 26 + .../stackstate-k8s-agent/1.0.96/Chart.lock | 6 + .../stackstate-k8s-agent/1.0.96/Chart.yaml | 25 + .../stackstate-k8s-agent/1.0.96/README.md | 263 ++++++++ .../1.0.96/README.md.gotmpl | 45 ++ .../stackstate-k8s-agent/1.0.96/Releasing.md | 15 + .../stackstate-k8s-agent/1.0.96/app-readme.md | 5 + .../charts/http-header-injector/.helmignore | 25 + .../charts/http-header-injector/Chart.yaml | 15 + .../charts/http-header-injector/README.md | 56 ++ .../http-header-injector/Readme.md.gotpl | 26 + .../templates/_defines.tpl | 131 ++++ .../cert-hook-clusterrolbinding.yaml | 24 + .../templates/cert-hook-clusterrole.yaml | 26 + .../templates/cert-hook-config.yaml | 158 +++++ .../templates/cert-hook-job-delete.yaml | 39 ++ .../templates/cert-hook-job-setup.yaml | 39 ++ .../templates/cert-hook-serviceaccount.yaml | 18 + .../templates/pull-secret.yaml | 32 + .../templates/webhook-cert-secret.yaml | 18 + .../templates/webhook-certificate.yaml | 23 + .../templates/webhook-config.yaml | 128 ++++ .../templates/webhook-deployment.yaml | 61 ++ .../webhook-mutatingwebhookconfiguration.yaml | 54 ++ .../templates/webhook-service.yaml | 20 + .../charts/http-header-injector/values.yaml | 110 ++++ .../stackstate-k8s-agent/1.0.96/questions.yml | 184 ++++++ .../_cluster-agent-kube-state-metrics.yaml | 62 ++ .../1.0.96/templates/_container-agent.yaml | 191 ++++++ .../templates/_container-process-agent.yaml | 160 +++++ .../1.0.96/templates/_helpers.tpl | 219 +++++++ .../checks-agent-clusterrolebinding.yaml | 21 + .../templates/checks-agent-configmap.yaml | 17 + .../templates/checks-agent-deployment.yaml | 185 ++++++ .../checks-agent-poddisruptionbudget.yaml | 23 + .../checks-agent-serviceaccount.yaml | 16 + .../templates/cluster-agent-clusterrole.yaml | 152 +++++ .../cluster-agent-clusterrolebinding.yaml | 19 + .../templates/cluster-agent-configmap.yaml | 31 + .../templates/cluster-agent-deployment.yaml | 169 +++++ .../cluster-agent-poddisruptionbudget.yaml | 21 + .../1.0.96/templates/cluster-agent-role.yaml | 21 + .../templates/cluster-agent-rolebinding.yaml | 18 + .../templates/cluster-agent-service.yaml | 21 + .../cluster-agent-serviceaccount.yaml | 14 + .../templates/logs-agent-clusterrole.yaml | 23 + .../logs-agent-clusterrolebinding.yaml | 21 + .../templates/logs-agent-configmap.yaml | 63 ++ .../templates/logs-agent-daemonset.yaml | 91 +++ .../templates/logs-agent-serviceaccount.yaml | 16 + .../templates/node-agent-clusterrole.yaml | 21 + .../node-agent-clusterrolebinding.yaml | 19 + .../templates/node-agent-configmap.yaml | 17 + .../templates/node-agent-daemonset.yaml | 110 ++++ .../templates/node-agent-podautoscaler.yaml | 39 ++ .../1.0.96/templates/node-agent-scc.yaml | 60 ++ .../1.0.96/templates/node-agent-service.yaml | 28 + .../templates/node-agent-serviceaccount.yaml | 14 + .../templates/openshift-logging-secret.yaml | 22 + .../1.0.96/templates/pull-secret.yaml | 39 ++ .../1.0.96/templates/secret.yaml | 27 + .../test/clusteragent_resources_test.go | 145 +++++ .../1.0.96/test/clustername_test.go | 54 ++ .../values/clustercheck_ksm_custom_url.yaml | 7 + .../values/clustercheck_ksm_no_override.yaml | 5 + .../values/clustercheck_ksm_override.yaml | 26 + .../clustercheck_no_ksm_custom_url.yaml | 7 + .../clustercheck_service_port_override.yaml | 4 + .../test/values/disable-all-resource.yaml | 17 + .../test/values/http-header-injector.yaml | 8 + .../1.0.96/test/values/minimal.yaml | 7 + .../1.0.96/values.schema.json | 78 +++ .../stackstate-k8s-agent/1.0.96/values.yaml | 616 ++++++++++++++++++ index.yaml | 31 +- 75 files changed, 4546 insertions(+), 1 deletion(-) create mode 100644 assets/stackstate/stackstate-k8s-agent-1.0.96.tgz create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/.helmignore create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/Chart.lock create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/Chart.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/README.md create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/README.md.gotmpl create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/Releasing.md create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/app-readme.md create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/.helmignore create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/Chart.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/README.md create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/Readme.md.gotpl create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/_defines.tpl create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-clusterrolbinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-clusterrole.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-config.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-job-delete.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-job-setup.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-serviceaccount.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/pull-secret.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-cert-secret.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-certificate.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-config.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-deployment.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-mutatingwebhookconfiguration.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-service.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/values.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/questions.yml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_cluster-agent-kube-state-metrics.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_container-agent.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_container-process-agent.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_helpers.tpl create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-clusterrolebinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-configmap.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-deployment.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-poddisruptionbudget.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-serviceaccount.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-clusterrole.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-clusterrolebinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-configmap.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-deployment.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-poddisruptionbudget.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-role.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-rolebinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-service.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-serviceaccount.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-clusterrole.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-clusterrolebinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-configmap.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-daemonset.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-serviceaccount.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-clusterrole.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-clusterrolebinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-configmap.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-daemonset.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-podautoscaler.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-scc.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-service.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-serviceaccount.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/openshift-logging-secret.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/pull-secret.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/templates/secret.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/test/clusteragent_resources_test.go create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/test/clustername_test.go create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_custom_url.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_no_override.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_override.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_no_ksm_custom_url.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_service_port_override.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/disable-all-resource.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/http-header-injector.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/minimal.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/values.schema.json create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.96/values.yaml diff --git a/assets/stackstate/stackstate-k8s-agent-1.0.96.tgz b/assets/stackstate/stackstate-k8s-agent-1.0.96.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4a6958360df087753f22d8bb1a2ac5fd9328a148 GIT binary patch literal 34916 zcmV*5Ky<$!iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0POvJf7>?FC=6f!R-Xco(tVm_B}(#J65ZQ9x8u02uO_jN#c_{lgmxlAuURvXgYh{cUQIz{~&`3ITsnU6y{Yysdx1_L~ET*z2}93S^wM3_JIkv9Yp zBrHV4TFmol6u@OSgbOqTBhFPL&Q;);bCk8pbv!}c8$_s&!y)+L?>`Ql!851d?f+mc zPEdd#MGAwBZ(A_(-)eX_do376$cYKBPl1XDs>!K@X9$ z@OR`gO#Xo;bBwQB07!JaM0YNVbbVE(1pq-2rar@DIRsNbK*L_o>A8IN&|XQEq``fs z?+gYl4^fx+5fkrzLBRru`e2F)U~^RHN~bl)nj$*v^=3Ys#}miJi=HU@)~5{ijP8+L zqy8gMNsJ0EiaQ4~76o^#4t(^HwBXK1!jk81ke$2TtF4cGUXP^XXfAR>=PV zyVqO6Q6c~P`v(UF`G0VsJghkJ)dLx>Kc z_r%>FJUN;^eKvVAfN+AQPh9WG;q=+F{bvVH4*S!C>2x}I_N;$6d3rRR92~m)2Zx8x z4&A*2w>3i{B9QS#slC_VJLvWgyZimC!TxZ+KRh^e_79Gp96tGLe{b0Dw|6pO#bcfS zH!z41-I@Zpdj3D@4-WS7^Z#IPu$%w)@jS3Stq0&|F~b6I1BnkO0ixhR%U-rM3-AO6 zTzf-4N21<)fG7OBL@i+{@}#5Y+)eGoLcD~0tQEItQI;GwA> zq6}(|Gm3-24`&iS&0sPhspdrle^};5QM_|v5^!u6{D*)Gg8(oBr&HhMJ!gY%KvzW5Y)C<^dWOudH@rqt)-EEkv|2>dYq@Tg^i8G^QW+itaBAf$@m zQ_YMpP*cFslSbg3quf;Dyckm?r>=fE1noa!xO9BXIdTq(heAJ`nXr?W4iYTsaq!0> z@I%jcC0F7pxSb<5M{BE2}l4LAaTh2g`6A;L&C-(_K?`) z4F#ViKOGn|JaQqQzo#ixYR>e4=Tq?)FGgjtWc$d00I{kkQnUz7QvlM&TuM51*QB)M zOE_*!8D5OAdyUuyWOGj1*)-cVfQru`;@>@tCDkhk1Cf-5JUlV z5$6ShKriAIeF_#h4*AG?{&b263R$r1sIM*zId`~o7|xIyf5ei3hf2!6#l;;x| zEs8|KXi-UIQW_jzyaEgC#R1CUU?k=!Ld0${xxOOMHRfoFE&IIzVpWl^TD;~;A|iqr zc5!eP(g?X?(J2s8EYpA(U73%7u5G1+@3%62kuQ*87uy;;LX1mAUL5#SKv6IS)SrdO z1IozfLWU@S1aZ;nIjh#(BEDba2?`LqdO3QFh(BFgP%d!{Zeb|i@hae2){*Nzucc(H zMxBS5S@DheJV)*|y@In7NIXA;fzJf`0N-{1Chi*m#d>fz}6!4{* zav?e9D_uvFlkb#mbDRhRQG!cL3*KP{VS!RH0YSGbW$o0rFt&W}U}KFw27yl*pVU$# zrCKm?{$+E55V%H53f^et>vE$`>U0-gkuz zrQmk%yK^BK_#jOXU$mK24uj<*posEN2x2Ohv_#-ZvKKItih80c{Pr&22@&zJ5J~~0 z^flKughnY}0++uPLdlpVYUwJ}l!^!!nqobZovGJBL|*y}pHcZ1$YoIf0AS&V{vuwa zFY+Q+fOPWE9BCm{wH-H#Ir*>TPjGVaCQP>x8WQ8GU51#g4`6)dM_+gV?lC_gwl0Vn%rS-c>QDJnGB4qt;Iyf}CiLc#= z(&OzgmZpQ*Z~op{*153S@h;SP{SZ!Ho*(EQ^-@o z;4CG9!PyYB-2)dw7fstu&_r<%T;RZWm#eVxQXmq=Qmkp!Avl}9#_WP1nzqs|BUX}> zVV^3U5^8-iU>MQ9%;f>HnJkRG^8VpJ-YkKo3iAcb-G~S!U zgjazuz_XV^H&eP~fM+wVb=)8_;Y_ydNOKYYAhkH5z7B049^IaHpgp!1(Q%%kTzV+j~Q;JxJcTE5$(7hIF>|9wcxFVJ%P;-I)J>(5L zd;QaStEFd!GX11OA7qr1%DzY-II^OaYZiHCkzP;ArB^j3Lt{)iD> ztG&9awZ+NDCTdk3WaW*vp|q<{fq#QSMCk>=le)q;Q^zvvV=DMBQ%vqeoZ{40d&9

T!*d*5g&UdMVU9%v}B5}O9hQxF7mTum48`HOTNYs4A!BB`3r<&W_C*U zRW&8q@YFIWa;sbp?0XFpQux{w9BxwdS)6N*f@Yfzcn7)2||v~80hdIAro zuyUJZ!JXYLt?r?9_DuD7u-T@hq=TAlPBQraJbRQnt>r)7;vin2O9Z|1Fc2fJ&y`Se zGTNJC%92AdE{_1_g>$1&vPCRnQ8Ho+yQxfbHriATR#?+&BV2E9)n9jSRYJ_VTdYkw zVB?+E-c#8L8B-i0H@=IsQ^2qB1d$LiM1lU2F;29Aes4K*l^-0oj3hk%Up%$I9D| z4!(rp3{l-#XBP+HWT6kD}Z!klEs**EGdSXl|l4pz7Y1GPV#S~AOlu*LFuZhfv zw_F)#hF_tD_*3Wyc*?p$t_yNzIDp{{%n^*loRf#&9r2CAQ0NYem@+Uy01_OB9(a2A z7e2GrTiN6sOi3Do{e%81|9PE;%o&SD3^MvWo=y=N`Ts^rE9h;qn@x2>78s@t7cXi%=+c+knI&?I_1BaL~UN;@>C2B|$X)|B7{Q!of-avOyNo zhTx#z@AvCA>|EYx5o5nj`>;{}PMc{bRJT^UB%FnemkOwrMYBax1}ZoMYOkzBpUiqh z$=3J^5N|G(+e+n$r3((h-qU(?gwg?q)}|z>P)&<2It2Sxw#ZSV_0w9E=)x6LsA5B~ zzt?KHQVU3gi;IIG>tSS;aMI7tb)tWq-k?yr99wta3V@P$NES8#2|Rgd#%8<@39k?% zzFU`ug(_W6go4+QiYsZ>F!#aA(g7Z(qwt9DPC|eu+H;2QxyZusHD+0r@%Z8_PoKiX z*X#P!;Rpv<>KQdUiRt3yy`&);-NZkNYl6B5lTF#|lb9jCHw7LN9=^x} zx0qb>^;FSo5|KYFt=$r-UmepcI4e4)GpxH#vSI2c&Nu#iS09s5-cm5GgBrG+2M@p* z19M2F6F27iJ7;jpNbIthBwFW#2f(Dncn!ecG}^)6hv|+^Iju(6>lnV=9if4A0Aj9V z!T{iJ0zL=vHwI^ezjGLJjPw`aOEOb-mNbdRs!FOzwzW1ydkWFs->psA`}@#VYhTsc zPiv*c{sD>b3YTXTf-<3mrS8g%z>ub*!^0s0lci-wbW*5Xb3h;9A__!XsBvemr>@I^ z33BlQQSp78ejlsvi2=tPLDN{pM=726T&0boA^#_R$A>LbMnRcMPi)*=4Z<+NIy573Te&8^C7KTe^MBPeqA%8ILLZ> zq}_a(w;k45!Y{MCDU#St3JYagook0;iy=)M$?Q!5G*}k%WXv(~|IIb*Ai`eicUFg{ zUy`a9*gHzG6`jNkYy-Oioe}mtpORRFW0=I= z43((YSt>8E_adqGTvpRG+CXkVA!V4r84^y?wK#AjE1bv*nyM_A4d}TMR(i-7bmxoG z-AI-sY1s$IX(b1|p~~aj4?SV%66?bSpWc*lbyHSK8c@KyK^ufGd<5NE{rNg6tVv0$ zZ$LxhJzs|gdED{}MyZaPRNsIG6nYW%>y6>5F6)4^DM)KVf^-d!uLz;JaNXkY2WiX_ zTMDfAI@ps_frNmx`X)3adS)#m($WbP>8s6G?3#U{mT9vy3;-J~caWiJ z9Mq&^q>7t_m>@Qw#1Cf#)m(GWbXiS9QhAdVg5dCXJgK!l5FGwDo}{aTs=5L8nwU+j z8)DR3mOo<5U_B<375=BF;N)BdB$(8Vpg@fMVxF{`mTncqO+8u0aUnx9Onk{AC-Q>w z0!ERzbH{hMhJ{Mh0R%ycLy+C!%1;W~(g7zaTy-!z1jhj)jCR1W%lsRk`G|JFiMUrx zJK&tn5utkQliJB%NE;Yew@Q~X#z~vU#RX~oH{ZUIIFwfri>AwtVFpi>l{~;9c-C*F zddw>rt)?w0<}Bcc7mz`HT%&K)KyfRPbA>yH1iHdhs1I*E$RLOaju2r>;U|-7RGPRn zHiNN2Pn$PK?sa;Qt0^e4-2Vx$bLN~TG7Z*#0TCv`A}{$;^rdorkdf??6WU1oNAN#} z;IQ96Tm@G~i@2x@JuNPoKl!OJ6=gvqJ2;m!Su1xDp!GWT*;Ewo0Dl%@f@pGRjfi<4 z8%&TeX~~P)lO=#5h{Nj;--ZCjY%cD@uDq(9522AEZSAXG^_&|OF2lLeiofpVF5AT} zE5J3cah19wwybwKa;P`GxlueUS&3i^cQneJ$yegt+HH(gPU9;n*y!Gc-8pNJi?WZRkll;)qYkP1a&X_+fh~B`?p;Q$q}&m1(3>lc?VZLYR=3% zyVTKOZf^DZMy=U-2NyMJ&d)7h$*40!)kgY6D74)!c%8T&=`D8R5R-EwP^JKk2{;jwFRfUENSH~cSRC%KAJ`6%rw4O>YYhz`DH$^d1gMa`DRK{lQ}oa`kNQV ztg&0Ubf`Wsq6}2Qtm`?RI7~lHy~gt%I<*GRGbZe>`6fk5<+fIa6yi3Qg%s-D-J~!C>eiIHI(H~!h&*GhFkY-&El3@$=NA#~nCpMY<1`f3l1wyB6Z02~rvSxClwRdbK&sfI` zXg4&D7vSBSZQQ_oC#LaI_;+g=FGYJ_hVfDY?#3=&itcXB;-zTs$SQ8)TWJ(m3W?H3 z>e|FJD_y-^q!rPc7I6dp9T~*SG2F2|yd3epnZwITxFc(LIl?&mbT=Z~Wn}YPz!1*R z`E8g9vui zNF8Hjwwqk)xX8aj1RP(S@tr3}n1_@krz&7Oj{INIQkMJ`33lcG@x!$+=AaEhn=;yk zk>9;W%MuEdJKJ&0=2!R{h0SP5PF!O)2aMNGsVRl5=t{h{Vm9xJx&;!UXb`95A!Wo5 zXOF<+#}}99Z_i$wf`6XBxfFfy>*+tiFQ=EMk00wUQ5*J{rVf?{za}1a61<3uAZgL^ z(Cj7oMO@!0A>`LL&rdI3pI)7gz{$%uqpQEIQHXlTh_Cg}E zF}2FuX6d8R)$z%%qpRbqQ}E{UrS2O3r?z>f+;iX4y5imwofA zepcoG7dK zq!P7!lS)g1YSCbao_)_#}yUP7e!CW`0Z z7D?^ozekWUL_%KV|NI8K|L%96y?dzs_}9O>|N58n?y-LV==*l2`sXaPcCz%JrI4u~nti4YE~5 zo|&ISB7U3CsG_X3O)YW4}CV)ZVY1k8Y-KAS399%oiD8`%%W8NotTBY z+K?=ND#CRal!a~h{8_`XeosItI_p4Q0kjr8BhE0x=UljM2I7}7B_!qR>G*qoM3kjYPg;eWzK06qaf^!VQSsm5p=bZrA| zG2UMZZryOcjC|>ZZ}*6&QvcI#Ve(TQb+7QO*8c`adxL&X{~PS@4|e+BeLNZcFFV#! z-IFT9P^d=AQ86bfVGuZTNIVo8j>AII1pXAcOE*x*BN0I(hLg}9=mT=oj3q8!EMVvj z!Ed15oA_am&f6W(?z;S623&%{}T<2XP3 zKY#`ZMPRVkZ-aNOjL?;io}m5lBk)5vh&^N){nD8rJti+z4yiV9z~|3BLqs;oq5Jvs zut`k@XW;YawkGz%@V;y}fn#`kN^mH=8LDNdqVduMc^cmEhJON~66FV3?QsZ3SEF%y z(kA|Vd3rVe<$QFdhF6$se*H6a>tl(KE4uKt^q0=I$p(H1+TTC4knpH$3`)r%rR@I{$MMgnudl{$PcKJj=dZI! znsUk~z!fZ%9~n;F_~P>XB-eyAJ5#$@e)P|gwK!eUcF9QO%5zPpUFgo^i&x{**T>Ia zp1!EjSo7{fN$WJwHjG$XVmy|^R7JTpf=rI^RXV1wQb~xxe52FL zw`V7(<06xC!Y)yOAVrQi<^KHH5{sp>pG*o9Z-H`wP|*I1ZLpKNdfu!W|Ix2!7vs0b zFV9{aU!7_!mPu=8$&+7BPktSZua18npB!JlID38k^6cuLb*7^2LPy1DTP{9X8g%-< zt}c(qC+Dw!I{SI7&gd`m6D-+uOQ7wl-v8zF_~q3vesOv^ zK7Dz5a#fH`ZQ-Mnt@QHz=kd$ax2MI4SVN2@?$)1@^cuxlMxjz>_&TU~eR}ne^UGhy zSC_{pXRm*5AoEJ@V6DJ)ae01qescbDeD->DAqT4gzKCFkT^yW+d?6H@yLvcJPDi7f zaK(Z5^3s4vLX z9?dN+rFJnr8okt_+NSVelC)_S;0X*Y_wg9+lUuQqn5%?UI76g6<)75C3dP#0Au}rGVIOH24?JJ4hYs9#cYh~-pv+?Ns>Vp@gD>1+S_gFDHkE>&zpS(l z?A(Q^gum8cwvsD-0*dWI;C-`O)rG*#`K`vyzfBl!<*mLAIj-sg-$pFA`jTFe=lD=3 z$Kwi?43_(Juy@o-g}%sMo<{CfJBcB5(|>xx~lfABPvTgHE7n;=C%LNkQY!8VIhXrfr2A_>-Rby%b0|rKJG$x6;ZUZy2d) zo-9a(JofYd%vfjr05YFieCuDaL&?}D^{Kc#P%j+D zZvd$BSl(K_$?3cWfIg)E_|XuAcj{blx2?##NHp>~us|+2A0*og%NF6Nf3&~zPxy2A zCzNnm#o67}`S|4g_2~R%_37>1dNzpCr&o61h`Ag2LG1hr{?vX2YaT*pX3Up95x*N^ zb_e6lI(~N~e*Z_}KcBxkef9F})!9`&=oC+x40k0`eLFM!3N6H+tJ?F+)z!s#bai|+ z8b5#Y(@&?DNBZ;68Q3FRFuMzS6u zcj9i*d4P?9uUAW1GjU?0H(laz^6$LWGn*h zX~GaIKUzbq;$*GP!Q2Dz4+Q4$1_2l<(y_P+E0%{BXCuB&kDp)sH2&|itMM<#moH9V z1I8)8B|Z}urvxZRMsD;efIyCy3d#v4G2=7v7O4P_7{n?>qt810wZP8iNF!z#EZ{Yg za0ME^>N~l%HrfjDA8&yCckvjxh7lCBFR=%&POh zISL{^8(Gx&+Hdky-v8ato&OD<93CF+&j0S?`S`K-7~J@aAs6=|=?Ys$=*I=`7I%(@ z;BimzdGB%S^h2bhkA_CzR1u8NX{mDQX`)qEmU?nGEh^24Cjy2rC?_HjF3`D_f}i-z z3te!uFaGowqj);?KY(^O1*YerB=$tc9EJ%FuB9)*A2AI4sgFDWqewKvY5fC9=%PI1 zICzsNm>?I%6ak7Cneecp@#2t1CIb=yD`YAfv4lQUacy6`9`Uk57mASk$Z4HT0g=XY z2}G@SR0T8?@BB2*tO$||`GU-eSJc+)=X6ifEsACRG3j1irnEq<{^w#e2@oXOGW@ar z5F2zR-6El64;&I&GjAIc7!f~YQ_%hk?f!+fbI`sIYr|AbSN3;?8I4iq6X^yK%GD)E zGvSbBDG|z}?r4iD?b5cHT`&KBt56$@|6j%8zs^jblwvkQKPErFj2RNUx$gZ9(N^^N%rJ%6zR^i!cv1QK^3YPyKqCRC_<5O z(!K6vnWbr@G91_kCX;hn-V}`&X7HEV>?NyqrT$6V9G`yKqbfD5(diEb2ZHaNE2T&{ z&ml!(!`xQog#%Ihk+28QIovxu;EvRG`kr*1RSxF@>=YFLq>B@UKfzGHyR$*vQW9(Qf1}3dw=ng)Vdds$ zD}9j0F1f=FNHc6!cEDB|#qq7vsJiogy}?|SBXDahEr4t~pi;VAA{G-FU|(nOlm1vW zPU{U7=@KhfTNVWZltTpQHh2g;-({dJ-nP?2M#$z4!w#Dx`AWJZq7SSMzJJ8~ zuilsx@O882HGGG2Mw5WNz>y6#Z1=)o&6f!I#ZhErtmTQ-AY0|3qYdoR;{C{8yJ$bC zZdVisL02uGrgGote4=YWv5tN+A7lV#@IqKk!I_vH36rX9@~=gPPQ;rGg|ScuW#>9= zVnnE>Fm)DGd0e$`_>{4qEF zI-H_W#lXzz)d3h366g&De3Zek|A%KLyCEuz`W~UwC;zb0RKM9aL;PgfZ`4y zQfU9cNQ{1vE0cN^Vm9Yu`Jqgi>{Ds?e&kdOWlOB@6m=VXUtf+^Kw4vGlo=vl9-FU- zMQy2{FbE7i@DTkWK%|p)sdTp`V*aN@X)zW4f zLArHn-p92MscaowQF&GG!kFRlSJcH>r3Xe_?IAv72w*C$T17UO);UZw9ZS*T29XoK zyb=W3|7YL~4!Zp|a88VqD(BaDf|U8k`PpaM62#$TZ9bT0t(FtSpkptxLYL%DN8S;Gos`r8=UHq$Q1xQvvP*8QJ&gVY-uTMHT)98Gdw8pg+!bjyOxNUos6 zxUynis*;fm&&I!={GGOUX(a~bM?#k>ipN!*I)Hm6_YsL|FD&(u&f@y zFMTrlpYc?j|7T5Yax@7J(8LctKb+OO23(QMm@X6k~F{oo62X%g`??@dzCd-eS73K+J+hX$=dhUJ-$ zTe_(goV;>QF6pQr0sC$B^2=HLVTdgJPz?Rg1iI)V8#Q_Fpl`d*4ANVv21}S{<%TbM z=C1U%f~FOEsysYev1poeEkjmW6tp6MLcBABA?o(Lm{i%sdHTsE(9=&gk)D3;I-#D~ zxC{#jl5`L^U1q&dZi9XnY;}w^`B*Ob%f}XP&G=FlbuEkC5_`=+yNw8JS$wuQY#D@= zOkFs+0V@Jl)d5`=?y1;O#jJ1HzA}#v+?cPj)|M}BKS=Bf~D4ZxI#h03?PNpPslE~F|vl!d5F z=%zd&YX)$VkM%-AF;J1UzjNV=${3?6%FrseO&2N)dnBJtgCEJq76NHShgdQr=_i-6MnAUHHOV(y3LE{bOl6aia8C1% zO*!NhDQl7jm8PyK2Ww4Lld!<5lr`lr%Tmln&U(}E}Y9uZ)hm#I760t1%kbXj27NP`RE*p`28gJsQ(PUB_mRL9X zDUErfA6x7j{a9k)Byd;8!Z90~zunfLH5Oo5F~8D!n+qhDQl1GYXM$Q0Sgw?WVwgGo zn4y-uuDCa1hFQ{2KFCywzk2II5=BczKa*jUL?0yqMsAUaHYWYg#jq{`!zw*POtv_W!ZQR;|N}I}hEl%Kz`6f0+0GK0G+s`G4HUQ_ufHm&)8^JH9wmP9fC!1yazC#K~9hX3)F9 z-iw4&o(oQC=lw{M(wS>1))EuM;J`efm%b+!EISv&t+|&h;D=|8loLcJ6=oBcE40zh$Q= z%-+0SvAxK?E|aN?~=K9PCuNfWxyhZ5}51JX7Z6saQHi(7`!2VS!tbc zaFtAvK-8i{{jM4mvyQENlZJBX9O@PK&E-qo0_ETEZ`Id2+<3bPKG%9toH9({43&*b zzClvZK*pduH~5@`DtxNuSb^FNpk^frDEq#&%hFCWx-IQETVtg)v9ggCBey}G?dvv) ztRznf1&-duAtQYCBnE-@@7p91#tc&z27WlJq*kbaIAk!0u%|0#=q)R8ubnC~c!*PM zgEHggy2N~G<-W$V?*6Yy0HEslKgIK(qh0==dwK3Cvd?b+_SHoCX*3iYg#Kwb|9Sy{D&+s({@$Pv|6#wslmGYeY$sw*PA=}mc`;@WFhYEfVdRgcYNt2mwoSN#@i$`^GBm@)M|4;YPk4bz zv`$(fNpxYkZ?mZXZG$X|0-i$k5yprv5N`H^kF98KvrZIUt!1{mT1lHTaijqpQ=`o5I~fNT{zUBGetl_sM9g z%>(?LoWFc|dXfni_UiQN^6aE4woZMAxpio`I(v0`{>B<}su2xWGDO3AG@M_YzdZlB zGH6#d5z6dWO+}rMS*v*L4n$UYe7TcXFG>T0mEls;T;0XKz@)~|++PeTo0TxRDeNrZ zhZm5+k^k?Ne8dIotK*CDtK}lm^YowWtPY&;=Yvj?SiwUaNF=c0&^*hEY=o=-EHY+wgyWFf-zxwD! z_Z9ZX?B_d=`(q-zm%u+J!uyN-Q!4x|@qQXGur+>9{e!?SeZskWRy~c*|JMuvROSD@ zUx@#3@Z@Nh|Mgy;Z#=Tk&d>bojP&zWxg31yIrcR_jpTpRzz^!FjQ?|#zyC8h+TX>0 zxR>Y4#DCZYe)!^nA2Ij2tX5@dxk;gxNX{OyhTYDPI|0Wkd)l((^ z2Z#ClKl_8DUH;d5dDalzyNjP+*~QOq;>PEfX7t@-eHzJs?NQKh3s7nQIV|M=-rwo} z_w%fZ?78N>k3UyT&-*pSB&lq2Zpx`4MdmL0_|XqbT+Q_)QVr%@VpS9$F z!!v*?`Mh0V7Cl>k$8}+x_yJgfYqZ}XZyEXX}-YIK>n{6 z{IOd8?;kzM+kf^3dprIAUY@4%f9)8NJK?@MI%Guff7ofsc$kVqFju89k9jfh|}=Oad9qgtxwT{gnO>82RIC zwEXe=kE5&6`1s;%{OjpIjS!L_7$PAI#`(BHya9}kmEt%K^Fe582MTC#!B)H+>n7H} z<7&Ab!vdNKOer5f6gLUcm|pwQ_y!Swx@;UtAf0B#GM_)UTI!^S`k5OdQ$Ikm6MJkC z^^))DjVpOflcSn0Lw6jBkU2vz=*x>C)Fm)Ns$>$&{&zf4!xUk!Yuq9+FMN5~TCyhB zQA92EF7hK3_@TJ&HOpR6@vwW1@^?{O;u~)W61-$X1ce{sP~V6$Z+MDruZ;^q7mUYT zOpT3pMA#E;H43Wk6A(mWvIVw`JodenxXtfdMx6vkTHOOB#U6mGIRfKx1lfE%20jG@ z{So^Fd0?^xY>pCPri72lCzAYykgv%-)ChaD_xSrk?=hbmnOnONB#>b;1ifwc_QqYK zTW@sA3xXp6g8&e;fPUzQGquijz%2qE1|eo3M92edj;W2UJc6Ulo#7e!Fw}HDbRIw2 zzK&d9|4T9?b|VN11S-*>``sprC2vzoGD;1#a5K2CWerG#%;<0)wuKZfO~o?S;0?QC}X{ zGGDM5)Dn_eE_z8dN$AWw z3ni&Xt*rwow!s6TDIyQt&QSorwzB&ZyyQ2hS;y?_WAh&Wb=e z)=)XQ5~Wc#Y*SFN>k1?$3pdAf14-ad*y_ufbWpe+9 zp9b>(uKa&3_Mg4}lb!s(mnUcc;p1Hz{Cq2Zz`KQDl^<|1BK^t{*`?CnJ)1rC<^P@e z|2-+j|K1zy?e72G%hT<4x9H#3STEcy0bBR)%TQ`B{l)zI(#7mQ(7!Lgl7AEaeFbjX z`S;cE@5>Ceay4+^W)6Q}EMs=2dy)dOXR_>iRG1JYI}6<<5y38^tFrQzAXgP@5s_)2 z7gFs3sB9=d`Gm56_-y_QrtCG+d_I@IZZWyexIYO$ld~7AT%yvZuI&<43&h$kQH4o; zPg$SRR^4^VrxeqDxL2jv?#sQZdU9RHA@di=abwExVuammB>baNfL*K4RFtG1+XS{& z5@iXO_*4|Kw`>(5iR;$2JQ&Nt&%Uh%D4fz9kn~M00LqDsFWmuL?&W~Vuepya;gUGi zFhj(`JazJu`K6Ld4$&oiAtyd|c-QBLB{Lv(A?o4xj6bc=ldtuW&?W7OW(GYEP2yP& zBwf<3{Mf?pp8)Zr8bfECWWX^uv?rAe9`iJQipcL++1bE8r1DYkkVT(kKcS* zIT};ib7us{QGRsAOIo$`l_pQDnRm|WY*};X39?e=OYgD2=BK{>C&C_#8Ky1_5NTus zs<8j;4+{4`_xt^w{r_H`ZnxViox^;*M=lKfaCT~U2W@MX;G2--u(++vM{f~fz6*m3 z>>Vep)7X^My@}xV%}MpFLU(NGk(zUIFDKix(h?`H;pEM64TPcg8B*Jx7BIJY;-#N; z+D|^p4a5&Av>yynyzs;0Ai%fC%X-7RQCzZ8YBouw$V-3WGrcih_@Tdu7mgdn`5nOm zEihSb23EqzLSDcRTW$mVa3^h0U~O&SqeXBKATLSCH3Yx4-6(E%KwH*mzq3}5WDLP2 z`Xfe^(c{pQXjd>pX5)QF{E)E*UGT%>A7oMFnK_n+;J0`B{hN@&DH<)Q%L3t^C+ZlwpuT?X;0T3u?oXL=%Jk3_ z#sNF_a$wR;$>^5{Lg=Tmt5}3-1k1gA!P&# z$MG+J5d1|ocWsVWeXMUtUt-LD@&iPL5nSJc*I}_<5FA+sC^s&I|M7;(cz?Mex`g43 z^VA!PM1ZaLG;+u6J)kJ?!}x$XL2?cH0;BhRsDKZM2eo5p@39cnjye|bq(m09&5ibk|X-?A|iJTZQb5#Flufq+?xUTRa$GWCS5%z5z2t8-{6C-c z3;CZ9clm$r=h;I3x1H0^RxkA$Dwvva>)+;0>`X#j+IN*Y!y8{gRBe9>&>vN0+b=Qn zp2Gl!E+TC;uEwj8*kFo?k3S&#r#h;oZSG= zW_~#9N(FVB=YNC!g8gT|zw`gTpGPhCA!fF)>uQqwz+;2$wcatrY7anieO82Q&|*#@7$ z3?Mdu2w}5nsXZ$NY@WM1<87?0beIQ8sx& zREgu5&0j(BQMk!}{@gOIHYUY7;Cq)KF1&mg&@!|aaS)ss#nipW9J&|SjTc-DYMkA) z+?c>^~ z=LAb4C+ic=$!TY)N-9fpKvEI36~DAi{nIw~1$_Md!$z@(IgdRmAzEL6P1lizq@+z+ ziNLn1G&s{mho)BOBpST)Z)-^+spUX1E;G~or&fPBYs znt1gsYt-fMl=sfZk0t&52{8QM6o*!wQYz6|dq5ucpG2>$ z(Em17{lrsw{xj%j^}oTBgMNRf|J}#aeE)x^+xc(Kba;Q;`1)IO%4ioxe)k$Jx3W7g zgSXZO-DrX({~urVuJAPqQ_Sj9mw)Oq{;evBU<#yO+e$DH7<$J+G>5O_1=!!K(>S%i zxkh|zBa$&#HZ@}OPs1CBCMGhW#`0?VYNe`N-{7(C{I|+~XO4n}KMOHI+mJC;=RZgN z-1*PoaQ|p`|Knbs2jBuShDb;O!$6L?%sDcN{lN3X8Hk{J4QGfttq0(0?o&YHNcz{& zISK;6*;+=a@WWY0oW-`s?!-$}%{{eaO*yI2A$N>PnKtsRh zVXy=^6g4?XAVLHLeu$iw^I|j}F-%bF0XV^n1rEX6lM(QILR-$vXFc(+B){cM{!Mz~ zU;Sb}>+yf|PkIyfQa}^vUdNHhu1Q;u9eNwJ9y=3w-Fob>Mbvuye_Id0TS$ByQ*id; zl(w9R;NOwUT8{4_*puZ5{=MbgP#1fs*9!cQAu_&^^IoK)as6IPnZ`v2^jZO)VTaz# zzNjW?o&T4o$1h%;Ity<*I9AX9qy52AUjI8d9PIpm@8x*_Y#h*P{epr8aOaRP;q=Dl z2#k2a5ibbj!DOp-5);C87FqB{s)fL(;QheqJI{{Zw_1-M|AH4Nf-^LH{22Ug&R9f; zz23}c^LXO8c+nGZ-};ono}& zSkphT%Fi<6pKKjbf0SC2`M z)G~NECV{AzzUo7IF#8E_uOfgv?&yn1w2cLs{{Ft}t@ne&n1Rp@rB%zLjTO0=-n4oWj4GR5TfFYW7 zFTAAr=M#_{w5w&r<>d=$!WVy0m-xc9JCUA6vDwW?)z&9qjX%UUEEosi6L>E?;NOE! z;FwDa&v&KTho@Y4usI@14Cq)u3CAJMR|&@@C;()D$Pf!aZnHYb7eoQ%7alw}yi6gdKvjJ=f$7xM{V5igko`}kQjM1P`)F+ZHi`y~I!9is20h^URQ$y|MGPP~zIX)|*oy-TmGbW^I6HyF^FtU&ijC%D z;?5CeB6qgvgCY!J%FMR2t)nrthrhl1yrNnf*Wr`M8o+D+_D=MY{EepyF4bc!*9n3U zxJF9~-it-01K#s(!h3No;k^eLeBTkVx%}ypSI{Z%DIb3M-gm{$f`Z$*@6J_1ZOl36 zVT74HaSN7@fTGY#(kDWh0}pv1iN988U4xM#aTtn5sX49S06!F>OXMv_!4h~V3h)wn zf>ZMN3i&28gLpQ5joAf36opI-qMo(Mv{7u$0f0zAC^AbSNoNK}g&YxRpF@fYI8%US zC>fk(ak&RBgf5z{Yzu?4BEZ1EK_Q~_g5U|N9;KKf&ViX)5?&SPDfEMwpsP7SbdCd0 z*yRL!@4uH~E&Kg_q8@8Fd@-F^=4=)Zmn1$6UZ4OjRamwZ)!Xh*TutE035SITVzwRUmM`SvzO=w1-S|M`loZjtjf7f-dqwu)vQ;O zUW#mWBM8wV{7_zZydu!Gua`Ae1O-F5xN~C4R){f~E5ClEHxfID(D-$C*;Oong1W*~P<}ht6Ntz;D zOO`Z6vc5EFifKK0QUgmA_%5V5!e7UW2_l@W%I1eK6u5K5dDsF~#cgl`8T-MF;_P%h z==T?5N}gQ2Nn*bMRk|9U3LB9DdDQQ}@&(LS@@oUIM8%6J61r!jGbvsNq>a|Y!Cnci z<)F>0?v@RVRqmLkTt1q@KvuXlJ@sd?jQpt6d2{~B)(yeAcA+j(R_^+5*`F9+HJd5` zKtV{}=X6%VcLn6vel()NTNwDBq}9?nBe6#pSKfg?1r!BSz?TxPWh274x(*pv--(c? zo~8G74Cw4mge@b~9=0#BFbTX70Y%!M^=>Yyq#N`?XxYNoMnWkfGGlY*cP&@Rx5|}K z_S`miizY-D2Z4-nAnv0GbL%U4!Pp%BW4`&bF~R8vMxc2r%|}N81yh0-X%0ED=i*}* z6TU@f*tGDbT6kURRKXM8<2FwD2@?=NGE10`@8A%T)9Kg5*9J)Z3M!D`PB1}Y22r)u z^Y|{_pTvAOheO~YVPHTW;0h8Vv?1*cl@2|7q|oNjx^mm3u7U#tS2IE+^Hq$l;?NBS z_5nC!U=C@{*h(3RT^18G1P_2o3jYnj-!z87--kLv&;#JYkdH`&y^h-Ja@OvMTT>l? znCpnj0Q^lrzi!vDY6o$ROXQ}4z&2syy z+&(Y&0Q>_IzMUV+?SeqNh$)jNnBpZPFr-sV7E(}nI7DEww2XfTJP@-TeSnK75EPn@ z3O#*LGC?k0AS%9()9+*Ty_$DqC!O9Xm$o&S7s&z30HVIsn2GOrY zLkf(q)=AQ$8iJyLm*DVsJXr@T!Qp@7$r?D5+$(EfO@aolgEyJa>mW`mH^-c0Ds7JU zR96*;94R2Kf~XoE=gH6%BDXmFfpIw|ITq^#tN`lUu>9qP(9h?PNyRFh0iQK)n#k&h zLk5FPNYyo3`bz>S6Jc|W?)JkO5tfVQM4aiW&9SaGjn4My&G=V&RWCu9urtuOzwX>+&G(seo=d!A28EY8y=u{T>wW?x|MMFQoygwmWA zZGu>fgiBd@y>&xj=HHVLlIsY#%M{K@3TGX9;ZFo>EnyD z+SK3(2UwV4)==n~u3e$gTaKKQNNMfi$Myn#cmWw4`Ts`kVHgL&=T2L0QTSKB#h+o~ zBmV32=T7Fhy3^J~h@uG{XCXu61_tfnv;Jq}OuI;!laS&VbY$#{p&tm_q71SNpg2($ z*4#NH&=pnQCQc9?m{o>w7avWRsQz%EYMMs4UlBS*t zHn*OFtAdGP8~y_(yfqyN>~yCd1SX2@AMLMzzU{O96{zm$aDN5HEuQYLz_RV*{S~OT zdA^@TBle~zLIW&20b%Zc6|P{-ci3DZuwdNlNx9J6)-nC z>^EWSXrmD(#<(5!`+^~)`f9n*pik0ewKAY-IMFpgo0Urt+?^+Y;eb*^UdI#QY%06} zI_eT3O|T+jx&nX+5=V{FM_{rPR|UfB5Z{IX#%wND0o$SI^u#R@$Tw}q39(BMG&Y~}^tM+X;c0jyV*Hh26CY7{ z;}a~JpWaXsH%i4tDR~N=uH7X!q03OH&$W?&8y^A)-b?G*`^-=muk}}*vv1Oc)&N#T zd_RlQ!dZOkhX|Nau>^y~@?wn4Htkq3j1n7TmSy$(UIwb+j#S(>$vYAmG!elcmQG9p ztL}zB$SEdnc@a3}du)ac4bB8rOPVM>jRh3kqy>fj!VP@R0s1DN^|D?Ke=a^~x3aYI z%KBZ||2R}2FZvm8sqY~d5+Hg)U=Q$Yo3}<%a1HkI*H4A_7O!lYFthOPYBQh5P-7<_ z5xii~59;sQ^GFI?_C4pB^R#<789aFg5vsRwPl0Y>vy%c_bElI4Fhpbuv|1A!>{qIS zE5O+_tHHA}&8iCMMh>4V0b1!S)mO^^-e9HWNc0PlmjhX(J*p3H@|Ke;M)!`-vUg)+@H-IaBjYpW-91;Vi_Crq3MWn z@}1|?D1ggxBFIIFJbCqRGM4A3{`QX{nk4Ek&XBWd_Cl^s8zrK+co@lx;;A#FiUBHE z=;ZROd)@&_3N()o_6rd(uOp(x1WN#cB*KJS;Iq

KS^u65+P(W2$ZwtHh}&ys^z; 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 literal 0 HcmV?d00001 diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/.helmignore b/charts/stackstate/stackstate-k8s-agent/1.0.96/.helmignore new file mode 100644 index 0000000000..15a5c12775 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/.helmignore @@ -0,0 +1,26 @@ +# 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 +.vscode/ +linter_values.yaml +ci/ +installation/ +logo.svg diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/Chart.lock b/charts/stackstate/stackstate-k8s-agent/1.0.96/Chart.lock new file mode 100644 index 0000000000..a8df83f136 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: http-header-injector + repository: https://helm.stackstate.io + version: 0.0.11 +digest: sha256:ae5ad7c3176f89b71aabef7cd75f99394750f4fffb9905b86fb45c345595c24c +generated: "2024-05-30T13:30:45.346757+02:00" diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/Chart.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/Chart.yaml new file mode 100644 index 0000000000..d573c8bba4 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/Chart.yaml @@ -0,0 +1,25 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: StackState Agent + catalog.cattle.io/kube-version: '>=1.19.0-0' + catalog.cattle.io/release-name: stackstate-k8s-agent +apiVersion: v2 +appVersion: 3.0.0 +dependencies: +- alias: httpHeaderInjectorWebhook + name: http-header-injector + repository: file://./charts/http-header-injector + version: 0.0.11 +description: Helm chart for the StackState Agent. +home: https://github.com/StackVista/stackstate-agent +icon: file://assets/icons/stackstate-k8s-agent.svg +keywords: +- monitoring +- observability +- stackstate +kubeVersion: '>=1.19.0-0' +maintainers: +- email: ops@stackstate.com + name: Stackstate +name: stackstate-k8s-agent +version: 1.0.96 diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/README.md b/charts/stackstate/stackstate-k8s-agent/1.0.96/README.md new file mode 100644 index 0000000000..a026f5b1a4 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/README.md @@ -0,0 +1,263 @@ +# stackstate-k8s-agent + +Helm chart for the StackState Agent. + +Current chart version is `1.0.96` + +**Homepage:** + +## Requirements + +| Repository | Name | Version | +|------------|------|---------| +| https://helm.stackstate.io | httpHeaderInjectorWebhook(http-header-injector) | 0.0.11 | + +## Required Values + +In order to successfully install this chart, you **must** provide the following variables: + +* `stackstate.apiKey` +* `stackstate.cluster.name` +* `stackstate.url` + +The parameter `stackstate.cluster.name` is entered when installing the Cluster Agent StackPack. + +Install them on the command line on Helm with the following command: + +```shell +helm install \ +--set-string 'stackstate.apiKey'='' \ +--set-string 'stackstate.cluster.name'='' \ +--set-string 'stackstate.url'='' \ +stackstate/stackstate-k8s-agent +``` + +## Recommended Values + +It is also recommended that you set a value for `stackstate.cluster.authToken`. If it is not provided, a value will be generated for you, but the value will change each time an upgrade is performed. + +The command for **also** installing with a set token would be: + +```shell +helm install \ +--set-string 'stackstate.apiKey'='' \ +--set-string 'stackstate.cluster.name'='' \ +--set-string 'stackstate.cluster.authToken'='' \ +--set-string 'stackstate.url'='' \ +stackstate/stackstate-k8s-agent +``` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| all.hardening.enabled | bool | `false` | An indication of whether the containers will be evaluated for hardening at runtime | +| all.image.registry | string | `"quay.io"` | The image registry to use. | +| checksAgent.affinity | object | `{}` | Affinity settings for pod assignment. | +| checksAgent.apm.enabled | bool | `true` | Enable / disable the agent APM module. | +| checksAgent.checksTagCardinality | string | `"orchestrator"` | | +| checksAgent.config | object | `{"override":[]}` | | +| checksAgent.config.override | list | `[]` | A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap | +| checksAgent.enabled | bool | `true` | Enable / disable runnning cluster checks in a separately deployed pod | +| checksAgent.image.pullPolicy | string | `"IfNotPresent"` | Default container image pull policy. | +| checksAgent.image.repository | string | `"stackstate/stackstate-k8s-agent"` | Base container image repository. | +| checksAgent.image.tag | string | `"c4caacef"` | Default container image tag. | +| checksAgent.livenessProbe.enabled | bool | `true` | Enable use of livenessProbe check. | +| checksAgent.livenessProbe.failureThreshold | int | `3` | `failureThreshold` for the liveness probe. | +| checksAgent.livenessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the liveness probe. | +| checksAgent.livenessProbe.periodSeconds | int | `15` | `periodSeconds` for the liveness probe. | +| checksAgent.livenessProbe.successThreshold | int | `1` | `successThreshold` for the liveness probe. | +| checksAgent.livenessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the liveness probe. | +| checksAgent.logLevel | string | `"INFO"` | Logging level for clusterchecks agent processes. | +| checksAgent.networkTracing.enabled | bool | `true` | Enable / disable the agent network tracing module. | +| checksAgent.nodeSelector | object | `{}` | Node labels for pod assignment. | +| checksAgent.priorityClassName | string | `""` | Priority class for clusterchecks agent pods. | +| checksAgent.processAgent.enabled | bool | `true` | Enable / disable the agent process agent module. | +| checksAgent.readinessProbe.enabled | bool | `true` | Enable use of readinessProbe check. | +| checksAgent.readinessProbe.failureThreshold | int | `3` | `failureThreshold` for the readiness probe. | +| checksAgent.readinessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the readiness probe. | +| checksAgent.readinessProbe.periodSeconds | int | `15` | `periodSeconds` for the readiness probe. | +| checksAgent.readinessProbe.successThreshold | int | `1` | `successThreshold` for the readiness probe. | +| checksAgent.readinessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the readiness probe. | +| checksAgent.replicas | int | `1` | Number of clusterchecks agent pods to schedule | +| checksAgent.resources.limits.cpu | string | `"400m"` | CPU resource limits. | +| checksAgent.resources.limits.memory | string | `"600Mi"` | Memory resource limits. | +| checksAgent.resources.requests.cpu | string | `"20m"` | CPU resource requests. | +| checksAgent.resources.requests.memory | string | `"512Mi"` | Memory resource requests. | +| checksAgent.scc.enabled | bool | `false` | Enable / disable the installation of the SecurityContextConfiguration needed for installation on OpenShift | +| checksAgent.serviceaccount.annotations | object | `{}` | Annotations for the service account for the cluster checks pods | +| checksAgent.skipSslValidation | bool | `false` | Set to true if self signed certificates are used. | +| checksAgent.strategy | object | `{"type":"RollingUpdate"}` | The strategy for the Deployment object. | +| checksAgent.tolerations | list | `[]` | Toleration labels for pod assignment. | +| clusterAgent.affinity | object | `{}` | Affinity settings for pod assignment. | +| clusterAgent.collection.kubeStateMetrics.annotationsAsTags | object | `{}` | Extra annotations to collect from resources and to turn into StackState tag. | +| clusterAgent.collection.kubeStateMetrics.clusterCheck | bool | `false` | For large clusters where the Kubernetes State Metrics Check Core needs to be distributed on dedicated workers. | +| clusterAgent.collection.kubeStateMetrics.enabled | bool | `true` | Enable / disable the cluster agent kube-state-metrics collection. | +| clusterAgent.collection.kubeStateMetrics.labelsAsTags | object | `{}` | Extra labels to collect from resources and to turn into StackState tag. # It has the following structure: # labelsAsTags: # : # can be pod, deployment, node, etc. # : # where is the kubernetes label and is the StackState tag # : # : # : # # Warning: the label must match the transformation done by kube-state-metrics, # for example tags.stackstate/version becomes tags_stackstate_version. | +| clusterAgent.collection.kubernetesEvents | bool | `true` | Enable / disable the cluster agent events collection. | +| clusterAgent.collection.kubernetesMetrics | bool | `true` | Enable / disable the cluster agent metrics collection. | +| clusterAgent.collection.kubernetesResources.configmaps | bool | `true` | Enable / disable collection of ConfigMaps. | +| clusterAgent.collection.kubernetesResources.cronjobs | bool | `true` | Enable / disable collection of CronJobs. | +| clusterAgent.collection.kubernetesResources.daemonsets | bool | `true` | Enable / disable collection of DaemonSets. | +| clusterAgent.collection.kubernetesResources.deployments | bool | `true` | Enable / disable collection of Deployments. | +| clusterAgent.collection.kubernetesResources.endpoints | bool | `true` | Enable / disable collection of Endpoints. If endpoints are disabled then StackState won't be able to connect a Service to Pods that serving it | +| clusterAgent.collection.kubernetesResources.horizontalpodautoscalers | bool | `true` | Enable / disable collection of HorizontalPodAutoscalers. | +| clusterAgent.collection.kubernetesResources.ingresses | bool | `true` | Enable / disable collection of Ingresses. | +| clusterAgent.collection.kubernetesResources.jobs | bool | `true` | Enable / disable collection of Jobs. | +| clusterAgent.collection.kubernetesResources.limitranges | bool | `true` | Enable / disable collection of LimitRanges. | +| clusterAgent.collection.kubernetesResources.namespaces | bool | `true` | Enable / disable collection of Namespaces. | +| clusterAgent.collection.kubernetesResources.persistentvolumeclaims | bool | `true` | Enable / disable collection of PersistentVolumeClaims. Disabling these will not let StackState connect PersistentVolumes to pods they are attached to | +| clusterAgent.collection.kubernetesResources.persistentvolumes | bool | `true` | Enable / disable collection of PersistentVolumes. | +| clusterAgent.collection.kubernetesResources.poddisruptionbudgets | bool | `true` | Enable / disable collection of PodDisruptionBudgets. | +| clusterAgent.collection.kubernetesResources.replicasets | bool | `true` | Enable / disable collection of ReplicaSets. | +| clusterAgent.collection.kubernetesResources.replicationcontrollers | bool | `true` | Enable / disable collection of ReplicationControllers. | +| clusterAgent.collection.kubernetesResources.resourcequotas | bool | `true` | Enable / disable collection of ResourceQuotas. | +| clusterAgent.collection.kubernetesResources.secrets | bool | `true` | Enable / disable collection of Secrets. | +| clusterAgent.collection.kubernetesResources.statefulsets | bool | `true` | Enable / disable collection of StatefulSets. | +| clusterAgent.collection.kubernetesResources.storageclasses | bool | `true` | Enable / disable collection of StorageClasses. | +| clusterAgent.collection.kubernetesResources.volumeattachments | bool | `true` | Enable / disable collection of Volume Attachments. Used to bind Nodes to Persistent Volumes. | +| clusterAgent.collection.kubernetesTimeout | int | `10` | Default timeout (in seconds) when obtaining information from the Kubernetes API. | +| clusterAgent.collection.kubernetesTopology | bool | `true` | Enable / disable the cluster agent topology collection. | +| clusterAgent.config | object | `{"configMap":{"maxDataSize":null},"events":{"categories":{}},"override":[],"topology":{"collectionInterval":90}}` | | +| clusterAgent.config.configMap.maxDataSize | string | `nil` | Maximum amount of characters for the data property of a ConfigMap collected by the kubernetes topology check | +| clusterAgent.config.events.categories | object | `{}` | Custom mapping from Kubernetes event reason to StackState event category. Categories allowed: Alerts, Activities, Changes, Others | +| clusterAgent.config.override | list | `[]` | A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap | +| clusterAgent.config.topology.collectionInterval | int | `90` | Interval for running topology collection, in seconds | +| clusterAgent.enabled | bool | `true` | Enable / disable the cluster agent. | +| clusterAgent.image.pullPolicy | string | `"IfNotPresent"` | Default container image pull policy. | +| clusterAgent.image.repository | string | `"stackstate/stackstate-k8s-cluster-agent"` | Base container image repository. | +| clusterAgent.image.tag | string | `"c4caacef"` | Default container image tag. | +| clusterAgent.livenessProbe.enabled | bool | `true` | Enable use of livenessProbe check. | +| clusterAgent.livenessProbe.failureThreshold | int | `3` | `failureThreshold` for the liveness probe. | +| clusterAgent.livenessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the liveness probe. | +| clusterAgent.livenessProbe.periodSeconds | int | `15` | `periodSeconds` for the liveness probe. | +| clusterAgent.livenessProbe.successThreshold | int | `1` | `successThreshold` for the liveness probe. | +| clusterAgent.livenessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the liveness probe. | +| clusterAgent.logLevel | string | `"INFO"` | Logging level for stackstate-k8s-agent processes. | +| clusterAgent.nodeSelector | object | `{}` | Node labels for pod assignment. | +| clusterAgent.priorityClassName | string | `""` | Priority class for stackstate-k8s-agent pods. | +| clusterAgent.readinessProbe.enabled | bool | `true` | Enable use of readinessProbe check. | +| clusterAgent.readinessProbe.failureThreshold | int | `3` | `failureThreshold` for the readiness probe. | +| clusterAgent.readinessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the readiness probe. | +| clusterAgent.readinessProbe.periodSeconds | int | `15` | `periodSeconds` for the readiness probe. | +| clusterAgent.readinessProbe.successThreshold | int | `1` | `successThreshold` for the readiness probe. | +| clusterAgent.readinessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the readiness probe. | +| clusterAgent.replicaCount | int | `1` | Number of replicas of the cluster agent to deploy. | +| clusterAgent.resources.limits.cpu | string | `"400m"` | CPU resource limits. | +| clusterAgent.resources.limits.memory | string | `"800Mi"` | Memory resource limits. | +| clusterAgent.resources.requests.cpu | string | `"70m"` | CPU resource requests. | +| clusterAgent.resources.requests.memory | string | `"512Mi"` | Memory resource requests. | +| clusterAgent.service.port | int | `5005` | Change the Cluster Agent service port | +| clusterAgent.service.targetPort | int | `5005` | Change the Cluster Agent service targetPort | +| clusterAgent.serviceaccount.annotations | object | `{}` | Annotations for the service account for the cluster agent pods | +| clusterAgent.skipSslValidation | bool | `false` | If true, ignores the server certificate being signed by an unknown authority. | +| clusterAgent.strategy | object | `{"type":"RollingUpdate"}` | The strategy for the Deployment object. | +| clusterAgent.tolerations | list | `[]` | Toleration labels for pod assignment. | +| fullnameOverride | string | `""` | Override the fullname of the chart. | +| global.extraAnnotations | object | `{}` | Extra annotations added ta all resources created by the helm chart | +| global.extraEnv.open | object | `{}` | Extra open environment variables to inject into pods. | +| global.extraEnv.secret | object | `{}` | Extra secret environment variables to inject into pods via a `Secret` object. | +| global.extraLabels | object | `{}` | Extra labels added ta all resources created by the helm chart | +| global.imagePullCredentials | object | `{}` | Globally define credentials for pulling images. | +| global.imagePullSecrets | list | `[]` | Secrets / credentials needed for container image registry. | +| global.proxy.url | string | `""` | Proxy for all traffic to stackstate | +| global.skipSslValidation | bool | `false` | Enable tls validation from client | +| httpHeaderInjectorWebhook.enabled | bool | `false` | Enable the webhook for injection http header injection sidecar proxy | +| logsAgent.affinity | object | `{}` | Affinity settings for pod assignment. | +| logsAgent.enabled | bool | `true` | Enable / disable k8s pod log collection | +| logsAgent.image.pullPolicy | string | `"IfNotPresent"` | Default container image pull policy. | +| logsAgent.image.repository | string | `"stackstate/promtail"` | Base container image repository. | +| logsAgent.image.tag | string | `"2.9.8-5b179aee"` | Default container image tag. | +| logsAgent.nodeSelector | object | `{}` | Node labels for pod assignment. | +| logsAgent.priorityClassName | string | `""` | Priority class for logsAgent pods. | +| logsAgent.resources.limits.cpu | string | `"1300m"` | CPU resource limits. | +| logsAgent.resources.limits.memory | string | `"192Mi"` | Memory resource limits. | +| logsAgent.resources.requests.cpu | string | `"20m"` | CPU resource requests. | +| logsAgent.resources.requests.memory | string | `"100Mi"` | Memory resource requests. | +| logsAgent.serviceaccount.annotations | object | `{}` | Annotations for the service account for the daemonset pods | +| logsAgent.skipSslValidation | bool | `false` | If true, ignores the server certificate being signed by an unknown authority. | +| logsAgent.tolerations | list | `[]` | Toleration labels for pod assignment. | +| logsAgent.updateStrategy | object | `{"rollingUpdate":{"maxUnavailable":100},"type":"RollingUpdate"}` | The update strategy for the DaemonSet object. | +| nameOverride | string | `""` | Override the name of the chart. | +| nodeAgent.affinity | object | `{}` | Affinity settings for pod assignment. | +| nodeAgent.apm.enabled | bool | `true` | Enable / disable the nodeAgent APM module. | +| nodeAgent.autoScalingEnabled | bool | `false` | Enable / disable autoscaling for the node agent pods. | +| nodeAgent.checksTagCardinality | string | `"orchestrator"` | low, orchestrator or high. Orchestrator level adds pod_name, high adds display_container_name | +| nodeAgent.config | object | `{"override":[]}` | | +| nodeAgent.config.override | list | `[]` | A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap | +| nodeAgent.containerRuntime.customSocketPath | string | `""` | If the container socket path does not match the default for CRI-O, Containerd or Docker, supply a custom socket path. | +| nodeAgent.containerRuntime.hostProc | string | `"/proc"` | | +| nodeAgent.containers.agent.env | object | `{}` | Additional environment variables for the agent container | +| nodeAgent.containers.agent.image.pullPolicy | string | `"IfNotPresent"` | Default container image pull policy. | +| nodeAgent.containers.agent.image.repository | string | `"stackstate/stackstate-k8s-agent"` | Base container image repository. | +| nodeAgent.containers.agent.image.tag | string | `"c4caacef"` | Default container image tag. | +| nodeAgent.containers.agent.livenessProbe.enabled | bool | `true` | Enable use of livenessProbe check. | +| nodeAgent.containers.agent.livenessProbe.failureThreshold | int | `3` | `failureThreshold` for the liveness probe. | +| nodeAgent.containers.agent.livenessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the liveness probe. | +| nodeAgent.containers.agent.livenessProbe.periodSeconds | int | `15` | `periodSeconds` for the liveness probe. | +| nodeAgent.containers.agent.livenessProbe.successThreshold | int | `1` | `successThreshold` for the liveness probe. | +| nodeAgent.containers.agent.livenessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the liveness probe. | +| nodeAgent.containers.agent.logLevel | string | `nil` | Set logging verbosity, valid log levels are: trace, debug, info, warn, error, critical, and off # If not set, fall back to the value of agent.logLevel. | +| nodeAgent.containers.agent.processAgent.enabled | bool | `false` | Enable / disable the agent process agent module. - deprecated | +| nodeAgent.containers.agent.readinessProbe.enabled | bool | `true` | Enable use of readinessProbe check. | +| nodeAgent.containers.agent.readinessProbe.failureThreshold | int | `3` | `failureThreshold` for the readiness probe. | +| nodeAgent.containers.agent.readinessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the readiness probe. | +| nodeAgent.containers.agent.readinessProbe.periodSeconds | int | `15` | `periodSeconds` for the readiness probe. | +| nodeAgent.containers.agent.readinessProbe.successThreshold | int | `1` | `successThreshold` for the readiness probe. | +| nodeAgent.containers.agent.readinessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the readiness probe. | +| nodeAgent.containers.agent.resources.limits.cpu | string | `"270m"` | CPU resource limits. | +| nodeAgent.containers.agent.resources.limits.memory | string | `"420Mi"` | Memory resource limits. | +| nodeAgent.containers.agent.resources.requests.cpu | string | `"20m"` | CPU resource requests. | +| nodeAgent.containers.agent.resources.requests.memory | string | `"180Mi"` | Memory resource requests. | +| nodeAgent.containers.processAgent.enabled | bool | `true` | Enable / disable the process agent container. | +| nodeAgent.containers.processAgent.env | object | `{}` | Additional environment variables for the process-agent container | +| nodeAgent.containers.processAgent.image.pullPolicy | string | `"IfNotPresent"` | Process-agent container image pull policy. | +| nodeAgent.containers.processAgent.image.registry | string | `nil` | | +| nodeAgent.containers.processAgent.image.repository | string | `"stackstate/stackstate-k8s-process-agent"` | Process-agent container image repository. | +| nodeAgent.containers.processAgent.image.tag | string | `"cae7a4fa"` | Default process-agent container image tag. | +| nodeAgent.containers.processAgent.logLevel | string | `nil` | Set logging verbosity, valid log levels are: trace, debug, info, warn, error, critical, and off # If not set, fall back to the value of agent.logLevel. | +| nodeAgent.containers.processAgent.procVolumeReadOnly | bool | `true` | Configure whether /host/proc is read only for the process agent container | +| nodeAgent.containers.processAgent.resources.limits.cpu | string | `"125m"` | CPU resource limits. | +| nodeAgent.containers.processAgent.resources.limits.memory | string | `"400Mi"` | Memory resource limits. | +| nodeAgent.containers.processAgent.resources.requests.cpu | string | `"25m"` | CPU resource requests. | +| nodeAgent.containers.processAgent.resources.requests.memory | string | `"128Mi"` | Memory resource requests. | +| nodeAgent.httpTracing.enabled | bool | `true` | | +| nodeAgent.logLevel | string | `"INFO"` | Logging level for agent processes. | +| nodeAgent.networkTracing.enabled | bool | `true` | Enable / disable the nodeAgent network tracing module. | +| nodeAgent.nodeSelector | object | `{}` | Node labels for pod assignment. | +| nodeAgent.priorityClassName | string | `""` | Priority class for nodeAgent pods. | +| nodeAgent.protocolInspection.enabled | bool | `true` | Enable / disable the nodeAgent protocol inspection. | +| nodeAgent.scaling.autoscalerLimits.agent.maximum.cpu | string | `"200m"` | Maximum CPU resource limits for main agent. | +| nodeAgent.scaling.autoscalerLimits.agent.maximum.memory | string | `"450Mi"` | Maximum memory resource limits for main agent. | +| nodeAgent.scaling.autoscalerLimits.agent.minimum.cpu | string | `"20m"` | Minimum CPU resource limits for main agent. | +| nodeAgent.scaling.autoscalerLimits.agent.minimum.memory | string | `"180Mi"` | Minimum memory resource limits for main agent. | +| nodeAgent.scaling.autoscalerLimits.processAgent.maximum.cpu | string | `"200m"` | Maximum CPU resource limits for process agent. | +| nodeAgent.scaling.autoscalerLimits.processAgent.maximum.memory | string | `"500Mi"` | Maximum memory resource limits for process agent. | +| nodeAgent.scaling.autoscalerLimits.processAgent.minimum.cpu | string | `"25m"` | Minimum CPU resource limits for process agent. | +| nodeAgent.scaling.autoscalerLimits.processAgent.minimum.memory | string | `"100Mi"` | Minimum memory resource limits for process agent. | +| nodeAgent.scc.enabled | bool | `false` | Enable / disable the installation of the SecurityContextConfiguration needed for installation on OpenShift. | +| nodeAgent.service | object | `{"annotations":{},"loadBalancerSourceRanges":["10.0.0.0/8"],"type":"ClusterIP"}` | The Kubernetes service for the agent | +| nodeAgent.service.annotations | object | `{}` | Annotations for the service | +| nodeAgent.service.loadBalancerSourceRanges | list | `["10.0.0.0/8"]` | The IP4 CIDR allowed to reach LoadBalancer for the service. For LoadBalancer type of service only. | +| nodeAgent.service.type | string | `"ClusterIP"` | Type of Kubernetes service: ClusterIP, LoadBalancer, NodePort | +| nodeAgent.serviceaccount.annotations | object | `{}` | Annotations for the service account for the agent daemonset pods | +| nodeAgent.skipKubeletTLSVerify | bool | `false` | Set to true if you want to skip kubelet tls verification. | +| nodeAgent.skipSslValidation | bool | `false` | Set to true if self signed certificates are used. | +| nodeAgent.tolerations | list | `[]` | Toleration labels for pod assignment. | +| nodeAgent.updateStrategy | object | `{"rollingUpdate":{"maxUnavailable":100},"type":"RollingUpdate"}` | The update strategy for the DaemonSet object. | +| openShiftLogging.installSecret | bool | `false` | Install a secret for logging on openshift | +| processAgent.checkIntervals.connections | int | `30` | Override the default value of the connections check interval in seconds. | +| processAgent.checkIntervals.container | int | `28` | Override the default value of the container check interval in seconds. | +| processAgent.checkIntervals.process | int | `32` | Override the default value of the process check interval in seconds. | +| processAgent.softMemoryLimit.goMemLimit | string | `"340MiB"` | Soft-limit for golang heap allocation, for sanity, must be around 85% of nodeAgent.containers.processAgent.resources.limits.cpu. | +| processAgent.softMemoryLimit.httpObservationsBufferSize | int | `40000` | Sets a maximum for the number of http observations to keep in memory between check runs, to use 40k requires around ~400Mib of memory. | +| processAgent.softMemoryLimit.httpStatsBufferSize | int | `40000` | Sets a maximum for the number of http stats to keep in memory between check runs, to use 40k requires around ~400Mib of memory. | +| stackstate.apiKey | string | `nil` | **PROVIDE YOUR API KEY HERE** API key to be used by the StackState agent. | +| stackstate.cluster.authToken | string | `""` | Provide a token to enable secure communication between the agent and the cluster agent. | +| stackstate.cluster.name | string | `nil` | **PROVIDE KUBERNETES CLUSTER NAME HERE** Name of the Kubernetes cluster where the agent will be installed. | +| stackstate.customApiKeySecretKey | string | `"sts-api-key"` | Key in the secret containing the receiver API key. | +| stackstate.customClusterAuthTokenSecretKey | string | `"sts-cluster-auth-token"` | Key in the secret containing the cluster auth token. | +| stackstate.customSecretName | string | `""` | Name of the secret containing the receiver API key. | +| stackstate.manageOwnSecrets | bool | `false` | Set to true if you don't want this helm chart to create secrets for you. | +| stackstate.url | string | `nil` | **PROVIDE STACKSTATE URL HERE** URL of the StackState installation to receive data from the agent. | +| targetSystem | string | `"linux"` | Target OS for this deployment (possible values: linux) | diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/README.md.gotmpl b/charts/stackstate/stackstate-k8s-agent/1.0.96/README.md.gotmpl new file mode 100644 index 0000000000..7909e6f0d7 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/README.md.gotmpl @@ -0,0 +1,45 @@ +{{ template "chart.header" . }} +{{ template "chart.description" . }} + +Current chart version is `{{ template "chart.version" . }}` + +{{ template "chart.homepageLine" . }} + +{{ template "chart.requirementsSection" . }} + +## Required Values + +In order to successfully install this chart, you **must** provide the following variables: + +* `stackstate.apiKey` +* `stackstate.cluster.name` +* `stackstate.url` + +The parameter `stackstate.cluster.name` is entered when installing the Cluster Agent StackPack. + +Install them on the command line on Helm with the following command: + +```shell +helm install \ +--set-string 'stackstate.apiKey'='' \ +--set-string 'stackstate.cluster.name'='' \ +--set-string 'stackstate.url'='' \ +stackstate/stackstate-k8s-agent +``` + +## Recommended Values + +It is also recommended that you set a value for `stackstate.cluster.authToken`. If it is not provided, a value will be generated for you, but the value will change each time an upgrade is performed. + +The command for **also** installing with a set token would be: + +```shell +helm install \ +--set-string 'stackstate.apiKey'='' \ +--set-string 'stackstate.cluster.name'='' \ +--set-string 'stackstate.cluster.authToken'='' \ +--set-string 'stackstate.url'='' \ +stackstate/stackstate-k8s-agent +``` + +{{ template "chart.valuesSection" . }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/Releasing.md b/charts/stackstate/stackstate-k8s-agent/1.0.96/Releasing.md new file mode 100644 index 0000000000..bab6c2b944 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/Releasing.md @@ -0,0 +1,15 @@ +To make a new release of this helm chart, follow the following steps: + + +- Create a branch from master +- Set the latest tags for the docker images, based on the dev settings (while we do not promote to prod, the moment we promote to prod we should take those tags) from https://gitlab.com/stackvista/devops/agent-promoter/-/blob/master/config.yml. Set the value to the folowing keys: + * stackstate-k8s-cluster-agent: + * [clusterAgent.image.tag] + * stackstate-k8s-agent: + * [nodeAgent.containers.agent.image.tag] + * [checksAgent.image.tag] + * stackstate-k8s-process-agent: + * [nodeAgent.containers.processAgent.image.tag] +- Bump the version of the chart +- Merge the mr and hit the public release button on the ci pipeline +- Manually smoke-test (deploy) the newly released stackstate/stackstate-k8s-agent chart to make sure it runs diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/app-readme.md b/charts/stackstate/stackstate-k8s-agent/1.0.96/app-readme.md new file mode 100644 index 0000000000..8025fe1d36 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/app-readme.md @@ -0,0 +1,5 @@ +## Introduction + +StackState is a modern Application Troubleshooting and Observability solution designed for the rapid evolving engineering landscape. With specific enhancements for Kubernetes environments it empowers engineers, allowing them to remediate application issues independently in production. + +The StackState Agent auto-discovers your entire environment in minutes, assimilating topology, logs, metrics, and events and sends this of to the StackState server. By using StackState you're able to tracke all activity in your environment in real-time and over time. StackState provides instant understanding of the business impact of an issue, offering end-to-end chain observability and ensuring that you can quickly correlate any product or environmental changes to the overall health of your cloud-native implementation. diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/.helmignore b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/.helmignore new file mode 100644 index 0000000000..69790771c9 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/.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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +linter_values.yaml +ci/ +installation/ diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/Chart.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/Chart.yaml new file mode 100644 index 0000000000..ff28ae8dab --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/Chart.yaml @@ -0,0 +1,15 @@ +apiVersion: v2 +appVersion: 0.0.1 +description: 'Helm chart for deploying the http-header-injector sidecar, which automatically + injects x-request-id into http traffic going through the cluster for pods which + have the annotation `http-header-injector.stackstate.io/inject: enabled` is set. ' +home: https://github.com/StackVista/http-header-injector +icon: https://www.stackstate.com/wp-content/uploads/2019/02/152x152-favicon.png +keywords: +- monitoring +- stackstate +maintainers: +- email: ops@stackstate.com + name: Stackstate Lupulus Team +name: http-header-injector +version: 0.0.11 diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/README.md b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/README.md new file mode 100644 index 0000000000..840ff52404 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/README.md @@ -0,0 +1,56 @@ +# http-header-injector + +![Version: 0.0.11](https://img.shields.io/badge/Version-0.0.11-informational?style=flat-square) ![AppVersion: 0.0.1](https://img.shields.io/badge/AppVersion-0.0.1-informational?style=flat-square) + +Helm chart for deploying the http-header-injector sidecar, which automatically injects x-request-id into http traffic +going through the cluster for pods which have the annotation `http-header-injector.stackstate.io/inject: enabled` is set. + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| Stackstate Lupulus Team | | | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| certificatePrehook | object | `{"image":{"pullPolicy":"IfNotPresent","registry":null,"repository":"stackstate/container-tools","tag":"1.4.0"},"resources":{"limits":{"cpu":"100m","memory":"200Mi"},"requests":{"cpu":"100m","memory":"200Mi"}}}` | Helm prehook to setup/remove a certificate for the sidecarInjector mutationwebhook | +| certificatePrehook.image.pullPolicy | string | `"IfNotPresent"` | Policy when pulling an image | +| certificatePrehook.image.registry | string | `nil` | Registry for the docker image. | +| certificatePrehook.image.tag | string | `"1.4.0"` | The tag for the docker image | +| debug | bool | `false` | Enable debugging. This will leave leave artifacts around like the prehook jobs for further inspection | +| enabled | bool | `true` | Enable/disable the mutationwebhook | +| global.extraAnnotations | object | `{}` | Extra annotations added ta all resources created by the helm chart | +| global.extraLabels | object | `{}` | Extra labels added ta all resources created by the helm chart | +| global.imagePullCredentials | object | `{}` | Globally define credentials for pulling images. | +| global.imagePullSecrets | list | `[]` | Globally add image pull secrets that are used. | +| global.imageRegistry | string | `nil` | Globally override the image registry that is used. Can be overridden by specific containers. Defaults to quay.io | +| images.pullSecretName | string | `nil` | | +| proxy | object | `{"image":{"pullPolicy":"IfNotPresent","registry":null,"repository":"stackstate/http-header-injector-proxy","tag":"sha-5ff79451"},"resources":{"limits":{"memory":"40Mi"},"requests":{"memory":"25Mi"}}}` | Proxy being injected into pods for rewriting http headers | +| proxy.image.pullPolicy | string | `"IfNotPresent"` | Policy when pulling an image | +| proxy.image.registry | string | `nil` | Registry for the docker image. | +| proxy.image.tag | string | `"sha-5ff79451"` | The tag for the docker image | +| proxy.resources.limits.memory | string | `"40Mi"` | Memory resource limits. | +| proxy.resources.requests.memory | string | `"25Mi"` | Memory resource requests. | +| proxyInit | object | `{"image":{"pullPolicy":"IfNotPresent","registry":null,"repository":"stackstate/http-header-injector-proxy-init","tag":"sha-5ff79451"}}` | InitContainer within pod which redirects traffic to the proxy container. | +| proxyInit.image.pullPolicy | string | `"IfNotPresent"` | Policy when pulling an image | +| proxyInit.image.registry | string | `nil` | Registry for the docker image | +| proxyInit.image.tag | string | `"sha-5ff79451"` | The tag for the docker image | +| sidecarInjector | object | `{"image":{"pullPolicy":"IfNotPresent","registry":null,"repository":"stackstate/generic-sidecar-injector","tag":"sha-9c852245"}}` | Service for injecting the proxy sidecar into pods | +| sidecarInjector.image.pullPolicy | string | `"IfNotPresent"` | Policy when pulling an image | +| sidecarInjector.image.registry | string | `nil` | Registry for the docker image. | +| sidecarInjector.image.tag | string | `"sha-9c852245"` | The tag for the docker image | +| webhook | object | `{"failurePolicy":"Ignore","tls":{"certManager":{"issuer":"","issuerKind":"ClusterIssuer","issuerNamespace":""},"mode":"generated","provided":{"caBundle":"","crt":"","key":""},"secret":{"name":""}}}` | MutationWebhook that will be installed to inject a sidecar into pods | +| webhook.failurePolicy | string | `"Ignore"` | How should the webhook fail? Best is to use Ignore, because there is a brief moment at initialization when the hook s there but the service not. Also, putting this to fail can cause the control plane be unresponsive. | +| webhook.tls.certManager.issuer | string | `""` | The issuer that is used for the webhook. Only used if you set webhook.tls.mode to "cert-manager". | +| webhook.tls.certManager.issuerKind | string | `"ClusterIssuer"` | The issuer kind that is used for the webhook, valid values are "Issuer" or "ClusterIssuer". Only used if you set webhook.tls.mode to "cert-manager". | +| webhook.tls.certManager.issuerNamespace | string | `""` | The namespace the cert-manager issuer is located in. If left empty defaults to the release's namespace that is used for the webhook. Only used if you set webhook.tls.mode to "cert-manager". | +| webhook.tls.mode | string | `"generated"` | The mode for the webhook. Can be "provided", "generated", "secret" or "cert-manager". If you want to use cert-manager, you need to install it first. NOTE: If you choose "generated", additional privileges are required to create the certificate and webhook at runtime. | +| webhook.tls.provided.caBundle | string | `""` | The caBundle that is used for the webhook. This is the certificate that is used to sign the webhook. Only used if you set webhook.tls.mode to "provided". | +| webhook.tls.provided.crt | string | `""` | The certificate that is used for the webhook. Only used if you set webhook.tls.mode to "provided". | +| webhook.tls.provided.key | string | `""` | The key that is used for the webhook. Only used if you set webhook.tls.mode to "provided". | +| webhook.tls.secret.name | string | `""` | The name of the secret containing the pre-provisioned certificate data that is used for the webhook. Only used if you set webhook.tls.mode to "secret". | + diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/Readme.md.gotpl b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/Readme.md.gotpl new file mode 100644 index 0000000000..225032aa2a --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/Readme.md.gotpl @@ -0,0 +1,26 @@ +{{ template "chart.header" . }} +{{ template "chart.description" . }} + +Current chart version is `{{ template "chart.version" . }}` + +{{ template "chart.homepageLine" . }} + +{{ template "chart.requirementsSection" . }} + +## Required Values + +No values have to be included to install this chart. After installing this chart, it becomes possible to annotate pods with +the `http-header-injector.stackstate.io/inject: enabled` annotation to make sure the sidecar provided by this chart is +activated on a pod. + +## Recommended Values + +{{ template "chart.valuesSection" . -}} + +## Install + +Install from the command line on Helm with the following command: + +```shell +helm install stackstate/http-header-injector +``` diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/_defines.tpl b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/_defines.tpl new file mode 100644 index 0000000000..ee6b7320ef --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/_defines.tpl @@ -0,0 +1,131 @@ +{{- define "http-header-injector.app.name" -}} +{{ .Release.Name }}-http-header-injector +{{- end -}} + +{{- define "http-header-injector.webhook-service.name" -}} +{{ .Release.Name }}-http-header-injector +{{- end -}} + +{{- define "http-header-injector.webhook-service.fqname" -}} +{{ .Release.Name }}-http-header-injector.{{ .Release.Namespace }}.svc +{{- end -}} + +{{- define "http-header-injector.cert-secret.name" -}} +{{- if eq .Values.webhook.tls.mode "secret" -}} +{{ .Values.webhook.tls.secret.name }} +{{- else -}} +{{ .Release.Name }}-http-injector-cert +{{- end -}} +{{- end -}} + +{{- define "http-header-injector.cert-clusterrole.name" -}} +{{ .Release.Name }}-http-injector-cert-cluster-role +{{- end -}} + +{{- define "http-header-injector.cert-serviceaccount.name" -}} +{{ .Release.Name }}-http-injector-cert-sa +{{- end -}} + +{{- define "http-header-injector.cert-config.name" -}} +{{ .Release.Name }}-cert-config +{{- end -}} + +{{- define "http-header-injector.mutatingwebhookconfiguration.name" -}} +{{ .Release.Name }}-http-header-injector-webhook.stackstate.io +{{- end -}} + +{{- define "http-header-injector.webhook-config.name" -}} +{{ .Release.Name }}-http-header-injector-config +{{- end -}} + +{{- define "http-header-injector.mutating-webhook.name" -}} +{{ .Release.Name }}-http-header-injector-webhook +{{- end -}} + +{{- define "http-header-injector.pull-secret.name" -}} +{{ include "http-header-injector.app.name" . }}-pull-secret +{{- end -}} + +{{/* If the issuer is located in a different namespace, it is possible to set that, else default to the release namespace */}} +{{- define "cert-manager.certificate.namespace" -}} +{{ .Values.webhook.tls.certManager.issuerNamespace | default .Release.Namespace }} +{{- end -}} + +{{- define "http-header-injector.image.registry.global" -}} + {{- if .Values.global }} + {{- .Values.global.imageRegistry | default "quay.io" -}} + {{- else -}} + quay.io + {{- end -}} +{{- end -}} + +{{- define "http-header-injector.image.registry" -}} + {{- if ((.ContainerConfig).image).registry -}} + {{- tpl .ContainerConfig.image.registry . -}} + {{- else -}} + {{- include "http-header-injector.image.registry.global" . }} + {{- end -}} +{{- end -}} + +{{- define "http-header-injector.image.pullSecrets" -}} + {{- $pullSecrets := list }} + {{- $pullSecrets = append $pullSecrets (include "http-header-injector.pull-secret.name" .) }} + {{- range .Values.global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- if (not (empty $pullSecrets)) -}} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end -}} +{{- end -}} + +{{- define "http-header-injector.cert-setup.container.main" }} +{{- $containerConfig := dict "ContainerConfig" .Values.certificatePrehook -}} +name: webhook-cert-setup +image: "{{ include "http-header-injector.image.registry" (merge $containerConfig .) }}/{{ .Values.certificatePrehook.image.repository }}:{{ .Values.certificatePrehook.image.tag }}" +imagePullPolicy: {{ .Values.certificatePrehook.image.pullPolicy }} +{{- with .Values.certificatePrehook.resources }} +resources: + {{- toYaml . | nindent 2 }} +{{- end }} +volumeMounts: + - name: "{{ include "http-header-injector.cert-config.name" . }}" + mountPath: /scripts + readOnly: true +command: ["/scripts/generate-cert.sh"] +{{- end }} + +{{- define "http-header-injector.cert-delete.container.main" }} +{{- $containerConfig := dict "ContainerConfig" .Values.certificatePrehook -}} +name: webhook-cert-delete +image: "{{ include "http-header-injector.image.registry" (merge $containerConfig .) }}/{{ .Values.certificatePrehook.image.repository }}:{{ .Values.certificatePrehook.image.tag }}" +imagePullPolicy: {{ .Values.certificatePrehook.image.pullPolicy }} +{{- with .Values.certificatePrehook.resources }} +resources: + {{- toYaml . | nindent 2 }} +{{- end }} +volumeMounts: + - name: "{{ include "http-header-injector.cert-config.name" . }}" + mountPath: /scripts +command: [ "/scripts/delete-cert.sh" ] +{{- end }} + +{{/* +Returns a YAML with extra annotations. +*/}} +{{- define "http-header-injector.global.extraAnnotations" -}} +{{- with .Values.global.extraAnnotations }} +{{- toYaml . }} +{{- end }} +{{- end -}} + +{{/* +Returns a YAML with extra labels. +*/}} +{{- define "http-header-injector.global.extraLabels" -}} +{{- with .Values.global.extraLabels }} +{{- toYaml . }} +{{- end }} +{{- end -}} \ No newline at end of file diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-clusterrolbinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-clusterrolbinding.yaml new file mode 100644 index 0000000000..fc0c012585 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-clusterrolbinding.yaml @@ -0,0 +1,24 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: "{{ include "http-header-injector.cert-serviceaccount.name" . }}" + labels: + app.kubernetes.io/component: http-header-injector-cert-hook + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-delete,post-upgrade + "helm.sh/hook-weight": "-3" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "{{ include "http-header-injector.cert-clusterrole.name" . }}" +subjects: + - kind: ServiceAccount + name: "{{ include "http-header-injector.cert-serviceaccount.name" . }}" + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-clusterrole.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-clusterrole.yaml new file mode 100644 index 0000000000..afab838b3c --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-clusterrole.yaml @@ -0,0 +1,26 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "{{ include "http-header-injector.cert-clusterrole.name" . }}" + labels: + app.kubernetes.io/component: http-header-injector-cert-hook + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-delete,post-upgrade + "helm.sh/hook-weight": "-4" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +rules: + - apiGroups: [ "admissionregistration.k8s.io" ] + resources: [ "mutatingwebhookconfigurations" ] + verbs: [ "get", "create", "patch","update","delete" ] + - apiGroups: [ "" ] + resources: [ "secrets" ] + verbs: [ "create", "get", "patch","update","delete" ] + - apiGroups: [ "apps" ] + resources: [ "deployments" ] + verbs: [ "get" ] +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-config.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-config.yaml new file mode 100644 index 0000000000..a22bdf4fb9 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-config.yaml @@ -0,0 +1,158 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ include "http-header-injector.cert-config.name" . }}" + labels: + app.kubernetes.io/component: http-header-injector-cert-hook + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-delete,post-upgrade + "helm.sh/hook-weight": "-3" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +data: + generate-cert.sh: | + #!/bin/bash + + # We are going for a self-signed certificate here. We would like to use k8s CertificateSigningRequest, however, + # currently there are no out of the box signers that can sign a 'server auth' certificate, which is required for mutation webhooks. + set -ex + + SCRIPTDIR="${BASH_SOURCE%/*}" + + DIR=`mktemp -d` + + cd "$DIR" + + {{ if .Values.enabled }} + echo "Chart enabled, creating secret and webhook" + + openssl genrsa -out ca.key 2048 + + openssl req -x509 -new -nodes -key ca.key -subj "/CN={{ include "http-header-injector.webhook-service.fqname" . }}" -days 10000 -out ca.crt + + openssl genrsa -out tls.key 2048 + + openssl req -new -key tls.key -out tls.csr -config "$SCRIPTDIR/csr.conf" + + openssl x509 -req -in tls.csr -CA ca.crt -CAkey ca.key \ + -CAcreateserial -out tls.crt -days 10000 \ + -extensions v3_ext -extfile "$SCRIPTDIR/csr.conf" -sha256 + + # Create or update the secret + echo "Applying secret" + kubectl create secret tls "{{ include "http-header-injector.cert-secret.name" . }}" \ + -n "{{ .Release.Namespace }}" \ + --cert=./tls.crt \ + --key=./tls.key \ + --dry-run=client \ + -o yaml | kubectl apply -f - + + echo "Applying mutationwebhook" + caBundle=`base64 -w 0 ca.crt` + cat "$SCRIPTDIR/mutatingwebhookconfiguration.yaml" | sed "s/\\\$CA_BUNDLE/$caBundle/g" | kubectl apply -f - + {{ else }} + echo "Chart disabled, not creating secret and webhook" + {{ end }} + delete-cert.sh: | + #!/bin/bash + + set -x + + DIR="${BASH_SOURCE%/*}" + if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi + if [[ "$DIR" = "." ]]; then DIR="$PWD"; fi + + cd "$DIR" + + # Using detection of deployment hee to also make this work in post-delete. + if kubectl get deployments "{{ include "http-header-injector.app.name" . }}" -n "{{ .Release.Namespace }}"; then + echo "Chart enabled, not removing secret and mutationwebhook" + exit 0 + else + echo "Chart disabled, removing secret and mutationwebhook" + fi + + # Create or update the secret + echo "Deleting secret" + kubectl delete secret "{{ include "http-header-injector.cert-secret.name" . }}" -n "{{ .Release.Namespace }}" + + echo "Applying mutationwebhook" + kubectl delete MutatingWebhookConfiguration "{{ include "http-header-injector.mutating-webhook.name" . }}" -n "{{ .Release.Namespace }}" + + exit 0 + + csr.conf: | + [ req ] + default_bits = 2048 + prompt = no + default_md = sha256 + req_extensions = req_ext + distinguished_name = dn + + [ dn ] + C = NL + ST = Utrecht + L = Hilversum + O = StackState + OU = Dev + CN = {{ include "http-header-injector.webhook-service.fqname" . }} + + [ req_ext ] + subjectAltName = @alt_names + + [ alt_names ] + DNS.1 = {{ include "http-header-injector.webhook-service.fqname" . }} + + [ v3_ext ] + authorityKeyIdentifier=keyid,issuer:always + basicConstraints=CA:FALSE + keyUsage=keyEncipherment,dataEncipherment + extendedKeyUsage=serverAuth + subjectAltName=@alt_names + + mutatingwebhookconfiguration.yaml: | + apiVersion: admissionregistration.k8s.io/v1 + kind: MutatingWebhookConfiguration + metadata: + name: "{{ include "http-header-injector.mutating-webhook.name" . }}" + namespace: "{{ .Release.Namespace }}" + labels: +{{ include "http-header-injector.global.extraLabels" . | indent 8 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 8 }} + webhooks: + - clientConfig: + caBundle: "$CA_BUNDLE" + service: + name: "{{ include "http-header-injector.webhook-service.name" . }}" + path: /mutate + namespace: {{ .Release.Namespace }} + port: 8443 + # Putting failure on ignore, not doing so can crash the entire control plane if something goes wrong with the service. + failurePolicy: "{{ .Values.webhook.failurePolicy }}" + name: "{{ include "http-header-injector.mutatingwebhookconfiguration.name" . }}" + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: NotIn + values: + - kube-system + - cert-manager + - {{ .Release.Namespace }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None + admissionReviewVersions: + - v1 +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-job-delete.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-job-delete.yaml new file mode 100644 index 0000000000..6f72ce2478 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-job-delete.yaml @@ -0,0 +1,39 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Release.Name }}-header-injector-cert-delete + labels: + app.kubernetes.io/component: http-header-injector-cert-hook-delete + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + "helm.sh/hook": post-delete,post-upgrade + "helm.sh/hook-weight": "-2" + "helm.sh/hook-delete-policy": before-hook-creation{{- if not .Values.debug -}},hook-succeeded{{- end }} +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +spec: + template: + metadata: + labels: + app.kubernetes.io/component: http-header-injector-delete + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 8 }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/cert-hook-config.yaml") . | sha256sum }} +{{ include "http-header-injector.global.extraAnnotations" . | indent 8 }} + spec: + serviceAccountName: "{{ include "http-header-injector.cert-serviceaccount.name" . }}" + {{- include "http-header-injector.image.pullSecrets" . | nindent 6 }} + volumes: + - name: "{{ include "http-header-injector.cert-config.name" . }}" + configMap: + name: "{{ include "http-header-injector.cert-config.name" . }}" + defaultMode: 0777 + containers: + - {{ include "http-header-injector.cert-delete.container.main" . | nindent 8 }} + restartPolicy: Never + backoffLimit: 0 +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-job-setup.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-job-setup.yaml new file mode 100644 index 0000000000..cc1c89631f --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-job-setup.yaml @@ -0,0 +1,39 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Release.Name }}-header-injector-cert-setup + labels: + app.kubernetes.io/component: http-header-injector-cert-hook-setup + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-2" + "helm.sh/hook-delete-policy": before-hook-creation{{- if not .Values.debug -}},hook-succeeded{{- end }} +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +spec: + template: + metadata: + labels: + app.kubernetes.io/component: http-header-injector-setup + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 8 }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/cert-hook-config.yaml") . | sha256sum }} +{{ include "http-header-injector.global.extraAnnotations" . | indent 8 }} + spec: + serviceAccountName: "{{ include "http-header-injector.cert-serviceaccount.name" . }}" + {{- include "http-header-injector.image.pullSecrets" . | nindent 6 }} + volumes: + - name: "{{ include "http-header-injector.cert-config.name" . }}" + configMap: + name: "{{ include "http-header-injector.cert-config.name" . }}" + defaultMode: 0777 + containers: + - {{ include "http-header-injector.cert-setup.container.main" . | nindent 8 }} + restartPolicy: Never + backoffLimit: 0 +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-serviceaccount.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-serviceaccount.yaml new file mode 100644 index 0000000000..29b26df95b --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/cert-hook-serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "{{ include "http-header-injector.cert-serviceaccount.name" . }}" + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-delete,post-upgrade + "helm.sh/hook-weight": "-4" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} + labels: + app.kubernetes.io/component: http-header-injector-cert-hook + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} + app: "{{ include "http-header-injector.app.name" . }}" +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/pull-secret.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/pull-secret.yaml new file mode 100644 index 0000000000..80b4ee404b --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/pull-secret.yaml @@ -0,0 +1,32 @@ +{{- $defaultRegistry := .Values.global.imageRegistry }} +{{- $top := . }} +{{- $registryAuthMap := dict }} + +{{- range $registry, $credentials := .Values.global.imagePullCredentials }} + {{- $registryAuthDocument := dict -}} + {{- $_ := set $registryAuthDocument "username" $credentials.username }} + {{- $_ := set $registryAuthDocument "password" $credentials.password }} + {{- $authMessage := printf "%s:%s" $registryAuthDocument.username $registryAuthDocument.password | b64enc }} + {{- $_ := set $registryAuthDocument "auth" $authMessage }} + {{- if eq $registry "default" }} + {{- $registryAuthMap := set $registryAuthMap (include "http-header-injector.image.registry.global" $top) $registryAuthDocument }} + {{ else }} + {{- $registryAuthMap := set $registryAuthMap $registry $registryAuthDocument }} + {{- end }} +{{- end }} +{{- $dockerAuthsDocuments := dict "auths" $registryAuthMap }} + +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} + name: {{ include "http-header-injector.pull-secret.name" . }} +data: + .dockerconfigjson: {{ $dockerAuthsDocuments | toJson | b64enc | quote }} +type: kubernetes.io/dockerconfigjson \ No newline at end of file diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-cert-secret.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-cert-secret.yaml new file mode 100644 index 0000000000..f571ca86bb --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-cert-secret.yaml @@ -0,0 +1,18 @@ +{{- if eq .Values.webhook.tls.mode "provided" }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "http-header-injector.cert-secret.name" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +type: kubernetes.io/tls +data: + tls.crt: {{ .Values.webhook.tls.provided.crt | b64enc }} + tls.key: {{ .Values.webhook.tls.provided.key | b64enc }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-certificate.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-certificate.yaml new file mode 100644 index 0000000000..a68c7c5f62 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-certificate.yaml @@ -0,0 +1,23 @@ +{{- if eq .Values.webhook.tls.mode "cert-manager" }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "http-header-injector.webhook-service.name" . }} + namespace: {{ include "cert-manager.certificate.namespace" . }} + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +spec: + secretName: {{ include "http-header-injector.cert-secret.name" . }} + issuerRef: + name: {{ .Values.webhook.tls.certManager.issuer }} + kind: {{ .Values.webhook.tls.certManager.issuerKind }} + dnsNames: + - "{{ include "http-header-injector.webhook-service.name" . }}" + - "{{ include "http-header-injector.webhook-service.name" . }}.{{ .Release.Namespace }}" + - "{{ include "http-header-injector.webhook-service.name" . }}.{{ .Release.Namespace }}.svc" +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-config.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-config.yaml new file mode 100644 index 0000000000..20b38ce963 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-config.yaml @@ -0,0 +1,128 @@ +{{- if .Values.enabled -}} +{{- $proxyContainerConfig := dict "ContainerConfig" .Values.proxy -}} +{{- $proxyInitContainerConfig := dict "ContainerConfig" .Values.proxyInit -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} + name: {{ .Release.Name }}-http-header-injector-config +data: + sidecarconfig.yaml: | + initContainers: + - name: http-header-proxy-init + image: "{{ include "http-header-injector.image.registry" (merge $proxyInitContainerConfig .) }}/{{ .Values.proxyInit.image.repository }}:{{ .Values.proxyInit.image.tag }}" + imagePullPolicy: {{ .Values.proxyInit.image.pullPolicy }} + command: ["/init-iptables.sh"] + env: + - name: CHART_VERSION + value: "{{ .Chart.Version }}" + - name: PROXY_PORT + value: {% if index .Annotations "config.http-header-injector.stackstate.io/proxy-port" %}"{% index .Annotations "config.http-header-injector.stackstate.io/proxy-port" %}"{% else %}"7060"{% end %} + - name: PROXY_UID + value: {% if index .Annotations "config.http-header-injector.stackstate.io/proxy-uid" %}"{% index .Annotations "config.http-header-injector.stackstate.io/proxy-uid" %}"{% else %}"2103"{% end %} + - name: POD_HOST_NETWORK + value: {% .Spec.HostNetwork %} + {% if eq (index .Annotations "linkerd.io/inject") "enabled" %} + - name: LINKERD + value: true + # Reference: https://linkerd.io/2.13/reference/proxy-configuration/ + - name: LINKERD_PROXY_UID + value: {% if index .Annotations "config.linkerd.io/proxy-uid" %}"{% index .Annotations "config.linkerd.io/proxy-uid" %}"{% else %}"2102"{% end %} + # Due to https://github.com/linkerd/linkerd2/issues/10981 this is now not realy possible, still bringing in the code for future reference + - name: LINKERD_ADMIN_PORT + value: {% if index .Annotations "config.linkerd.io/admin-port" %}"{% index .Annotations "config.linkerd.io/admin-port" %}"{% else %}"4191"{% end %} + {% end %} + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_ADMIN + - NET_RAW + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + volumeMounts: + # This is required for iptables to be able to run + - mountPath: /run + name: http-header-proxy-init-xtables-lock + + containers: + - name: http-header-proxy + image: "{{ include "http-header-injector.image.registry" (merge $proxyContainerConfig .) }}/{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }}" + imagePullPolicy: {{ .Values.proxy.image.pullPolicy }} + env: + - name: CHART_VERSION + value: "{{ .Chart.Version }}" + - name: PORT + value: {% if index .Annotations "config.http-header-injector.stackstate.io/proxy-port" %}"{% index .Annotations "config.http-header-injector.stackstate.io/proxy-port" %}"{% else %}"7060"{% end %} + - name: DEBUG + value: {% if index .Annotations "config.http-header-injector.stackstate.io/debug" %}"{% index .Annotations "config.http-header-injector.stackstate.io/debug" %}"{% else %}"disabled"{% end %} + securityContext: + runAsUser: {% if index .Annotations "config.http-header-injector.stackstate.io/proxy-uid" %}{% index .Annotations "config.http-header-injector.stackstate.io/proxy-uid" %}{% else %}2103{% end %} + seccompProfile: + type: RuntimeDefault + {{- with .Values.proxy.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + - name: http-header-inject-debug + image: "{{ include "http-header-injector.image.registry" (merge $proxyContainerConfig .) }}/{{ .Values.proxyInit.image.repository }}:{{ .Values.proxyInit.image.tag }}" + imagePullPolicy: {{ .Values.proxyInit.image.pullPolicy }} + command: ["/bin/sh", "-c", "while echo \"Running\"; do sleep 1; done"] + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_ADMIN + - NET_RAW + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + volumeMounts: + # This is required for iptables to be able to run + - mountPath: /run + name: http-header-proxy-init-xtables-lock + + volumes: + - emptyDir: {} + name: http-header-proxy-init-xtables-lock + + mutationconfig.yaml: | + mutationConfigs: + - name: "http-header-injector" + annotationNamespace: "http-header-injector.stackstate.io" + annotationTrigger: "inject" + annotationConfig: + volumeMounts: [] + initContainersBeforePodInitContainers: [ "http-header-proxy-init" ] + initContainers: [ "http-header-proxy-init" ] + containers: [ "http-header-proxy" ] + volumes: [ "http-header-proxy-init-xtables-lock" ] + volumeMounts: [ ] + # Namespaces are ignored by the mutatingwebhook + ignoreNamespaces: [ ] + - name: "http-header-injector-debug" + annotationNamespace: "http-header-injector-debug.stackstate.io" + annotationTrigger: "inject" + annotationConfig: + volumeMounts: [] + initContainersBeforePodInitContainers: [ ] + initContainers: [ ] + containers: [ "http-header-inject-debug" ] + volumes: [ "http-header-proxy-init-xtables-lock" ] + volumeMounts: [ ] + # Namespaces are ignored by the mutatingwebhook + ignoreNamespaces: [ ] + {{- end -}} \ No newline at end of file diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-deployment.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-deployment.yaml new file mode 100644 index 0000000000..8af6ff51a2 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-deployment.yaml @@ -0,0 +1,61 @@ +{{- if .Values.enabled -}} +{{- $containerConfig := dict "ContainerConfig" .Values.sidecarInjector -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} + app: "{{ include "http-header-injector.app.name" . }}" +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} + name: "{{ include "http-header-injector.app.name" . }}" +spec: + replicas: 1 + selector: + matchLabels: + app: "{{ include "http-header-injector.app.name" . }}" + template: + metadata: + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} + app: "{{ include "http-header-injector.app.name" . }}" +{{ include "http-header-injector.global.extraLabels" . | indent 8 }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/webhook-config.yaml") . | sha256sum }} + # This is here to make sure the generic injector gets restarted and picks up a new secret that may have been generated upon upgrade. + revision: "{{ .Release.Revision }}" +{{ include "http-header-injector.global.extraAnnotations" . | indent 8 }} + name: "{{ include "http-header-injector.app.name" . }}" + spec: + {{- include "http-header-injector.image.pullSecrets" . | nindent 6 }} + volumes: + - name: "{{ include "http-header-injector.webhook-config.name" . }}" + configMap: + name: "{{ include "http-header-injector.webhook-config.name" . }}" + - name: "{{ include "http-header-injector.cert-secret.name" . }}" + secret: + secretName: "{{ include "http-header-injector.cert-secret.name" . }}" + containers: + - image: "{{ include "http-header-injector.image.registry" (merge $containerConfig .) }}/{{ .Values.sidecarInjector.image.repository }}:{{ .Values.sidecarInjector.image.tag }}" + imagePullPolicy: {{ .Values.sidecarInjector.image.pullPolicy }} + name: http-header-injector + volumeMounts: + - name: "{{ include "http-header-injector.webhook-config.name" . }}" + mountPath: /etc/webhook/config + readOnly: true + - name: "{{ include "http-header-injector.cert-secret.name" . }}" + mountPath: /etc/webhook/certs + readOnly: true + command: [ "/sidecarinjector" ] + args: + - --port=8443 + - --sidecar-config-file=/etc/webhook/config/sidecarconfig.yaml + - --mutation-config-file=/etc/webhook/config/mutationconfig.yaml + - --cert-file-path=/etc/webhook/certs/tls.crt + - --key-file-path=/etc/webhook/certs/tls.key +{{- end -}} \ No newline at end of file diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-mutatingwebhookconfiguration.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-mutatingwebhookconfiguration.yaml new file mode 100644 index 0000000000..de0acc1dff --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-mutatingwebhookconfiguration.yaml @@ -0,0 +1,54 @@ +{{- if not (eq .Values.webhook.tls.mode "generated") }} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: "{{ include "http-header-injector.mutating-webhook.name" . }}" + namespace: "{{ .Release.Namespace }}" + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + {{- if eq .Values.webhook.tls.mode "cert-manager" }} + cert-manager.io/inject-ca-from: {{ include "cert-manager.certificate.namespace" . }}/{{ include "http-header-injector.webhook-service.name" . }} + {{- else if eq .Values.webhook.tls.mode "secret" }} + cert-manager.io/inject-ca-from-secret: {{ .Release.Namespace }}/{{ .Values.webhook.tls.secret.name | required "'webhook.tls.secret.name' is required when webhook.tls.mode is 'secret'" }} + {{- end }} +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +webhooks: + - clientConfig: + {{- if eq .Values.webhook.tls.mode "provided" }} + caBundle: "{{ .Values.webhook.tls.provided.caBundle | b64enc }}" + {{- else if or (eq .Values.webhook.tls.mode "cert-manager") (eq .Values.webhook.tls.mode "secret") }} + caBundle: "" + {{- end }} + service: + name: "{{ include "http-header-injector.webhook-service.name" . }}" + path: /mutate + namespace: {{ .Release.Namespace }} + port: 8443 + # Putting failure on ignore, not doing so can crash the entire control plane if something goes wrong with the service. + failurePolicy: "{{ .Values.webhook.failurePolicy }}" + name: "{{ include "http-header-injector.mutatingwebhookconfiguration.name" . }}" + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: NotIn + values: + - kube-system + - cert-manager + - {{ .Release.Namespace }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None + admissionReviewVersions: + - v1 +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-service.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-service.yaml new file mode 100644 index 0000000000..55abdb022c --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/templates/webhook-service.yaml @@ -0,0 +1,20 @@ +{{- if .Values.enabled -}} +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} + name: "{{ include "http-header-injector.webhook-service.name" . }}" +spec: + ports: + - port: 8443 + protocol: TCP + targetPort: 8443 + selector: + app: "{{ include "http-header-injector.app.name" . }}" +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/values.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/values.yaml new file mode 100644 index 0000000000..a1b4be2fcc --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/charts/http-header-injector/values.yaml @@ -0,0 +1,110 @@ +# enabled -- Enable/disable the mutationwebhook +enabled: true + +# debug -- Enable debugging. This will leave leave artifacts around like the prehook jobs for further inspection +debug: false + +global: + # global.imageRegistry -- Globally override the image registry that is used. Can be overridden by specific containers. Defaults to quay.io + imageRegistry: null + # global.imagePullSecrets -- Globally add image pull secrets that are used. + imagePullSecrets: [] + # global.imagePullCredentials -- Globally define credentials for pulling images. + imagePullCredentials: {} + + # global.extraLabels -- Extra labels added ta all resources created by the helm chart + extraLabels: {} + # global.extraAnnotations -- Extra annotations added ta all resources created by the helm chart + extraAnnotations: {} + +images: + pullSecretName: + +# proxy -- Proxy being injected into pods for rewriting http headers +proxy: + image: + # proxy.image.registry -- Registry for the docker image. + registry: + # proxy.image.repository - Repository for the docker image + repository: "stackstate/http-header-injector-proxy" + # proxy.image.pullPolicy -- Policy when pulling an image + pullPolicy: IfNotPresent + # proxy.image.tag -- The tag for the docker image + tag: sha-5ff79451 + + # proxy.resource -- Resources for the proxy container + resources: + requests: + # proxy.resources.requests.memory -- Memory resource requests. + memory: "25Mi" + limits: + # proxy.resources.limits.memory -- Memory resource limits. + memory: "40Mi" + +# proxyInit -- InitContainer within pod which redirects traffic to the proxy container. +proxyInit: + image: + # proxyInit.image.registry -- Registry for the docker image + registry: + # proxyInit.image.repository - Repository for the docker image + repository: "stackstate/http-header-injector-proxy-init" + # proxyInit.image.pullPolicy -- Policy when pulling an image + pullPolicy: IfNotPresent + # proxyInit.image.tag -- The tag for the docker image + tag: sha-5ff79451 + +# sidecarInjector -- Service for injecting the proxy sidecar into pods +sidecarInjector: + image: + # sidecarInjector.image.registry -- Registry for the docker image. + registry: + # sidecarInjector.image.repository - Repository for the docker image + repository: "stackstate/generic-sidecar-injector" + # sidecarInjector.image.pullPolicy -- Policy when pulling an image + pullPolicy: IfNotPresent + # sidecarInjector.image.tag -- The tag for the docker image + tag: sha-9c852245 + +# certificatePrehook -- Helm prehook to setup/remove a certificate for the sidecarInjector mutationwebhook +certificatePrehook: + image: + # certificatePrehook.image.registry -- Registry for the docker image. + registry: + # certificatePrehook.image.repository - Repository for the docker image. + repository: stackstate/container-tools + # certificatePrehook.image.pullPolicy -- Policy when pulling an image + pullPolicy: IfNotPresent + # certificatePrehook.image.tag -- The tag for the docker image + tag: 1.4.0 + resources: + limits: + cpu: "100m" + memory: "200Mi" + requests: + cpu: "100m" + memory: "200Mi" + +# webhook -- MutationWebhook that will be installed to inject a sidecar into pods +webhook: + # webhook.failurePolicy -- How should the webhook fail? Best is to use Ignore, because there is a brief moment at initialization when the hook s there but the service not. Also, putting this to fail can cause the control plane be unresponsive. + failurePolicy: Ignore + tls: + # webhook.tls.mode -- The mode for the webhook. Can be "provided", "generated", "secret" or "cert-manager". If you want to use cert-manager, you need to install it first. NOTE: If you choose "generated", additional privileges are required to create the certificate and webhook at runtime. + mode: "generated" + provided: + # webhook.tls.provided.caBundle -- The caBundle that is used for the webhook. This is the certificate that is used to sign the webhook. Only used if you set webhook.tls.mode to "provided". + caBundle: "" + # webhook.tls.provided.crt -- The certificate that is used for the webhook. Only used if you set webhook.tls.mode to "provided". + crt: "" + # webhook.tls.provided.key -- The key that is used for the webhook. Only used if you set webhook.tls.mode to "provided". + key: "" + certManager: + # webhook.tls.certManager.issuer -- The issuer that is used for the webhook. Only used if you set webhook.tls.mode to "cert-manager". + issuer: "" + # webhook.tls.certManager.issuerKind -- The issuer kind that is used for the webhook, valid values are "Issuer" or "ClusterIssuer". Only used if you set webhook.tls.mode to "cert-manager". + issuerKind: "ClusterIssuer" + # webhook.tls.certManager.issuerNamespace -- The namespace the cert-manager issuer is located in. If left empty defaults to the release's namespace that is used for the webhook. Only used if you set webhook.tls.mode to "cert-manager". + issuerNamespace: "" + secret: + # webhook.tls.secret.name -- The name of the secret containing the pre-provisioned certificate data that is used for the webhook. Only used if you set webhook.tls.mode to "secret". + name: "" diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/questions.yml b/charts/stackstate/stackstate-k8s-agent/1.0.96/questions.yml new file mode 100644 index 0000000000..5d6e6a0112 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/questions.yml @@ -0,0 +1,184 @@ +questions: + - variable: stackstate.apiKey + label: "StackState API Key" + type: string + description: "The API key for StackState." + required: true + group: General + - variable: stackstate.url + label: "StackState URL" + type: string + description: "The URL where StackState is running." + required: true + group: General + - variable: stackstate.cluster.name + label: "StackState Cluster Name" + type: string + description: "The StackState Cluster Name given when installing the instance of the Kubernetes StackPack in StackState. This is used to identify the cluster in StackState." + required: true + group: General + - variable: all.registry.override + label: "Override Default Image Registry" + type: boolean + description: "Whether or not to override the default image registry." + default: false + group: "General" + show_subquestions_if: true + subquestions: + - variable: all.image.registry + label: "Docker Image Registry" + type: string + description: "The registry to pull the StackState Agent images from." + default: "quay.io" + - variable: global.imagePullCredentials.username + label: "Docker Image Pull Username" + type: string + description: "The username to use when pulling the StackState Agent images." + - variable: global.imagePullCredentials.password + label: "Docker Image Pull Password" + type: secret + description: "The password to use when pulling the StackState Agent images." + - variable: nodeAgent.containers.agent.resources.override + label: "Override Node Agent Resource Allocation" + type: boolean + description: "Whether or not to override the default resources." + default: "false" + group: "Node Agent" + show_subquestions_if: true + subquestions: + - variable: nodeAgent.containers.agent.resources.requests.cpu + label: "CPU Requests" + type: string + description: "The requested CPU for the Node Agent." + default: "20m" + - variable: nodeAgent.containers.agent.resources.requests.memory + label: "Memory Requests" + type: string + description: "The requested memory for the Node Agent." + default: "180Mi" + - variable: nodeAgent.containers.agent.resources.limits.cpu + label: "CPU Limit" + type: string + description: "The CPU limit for the Node Agent." + default: "270m" + - variable: nodeAgent.containers.agent.resources.limits.memory + label: "Memory Limit" + type: string + description: "The memory limit for the Node Agent." + default: "420Mi" + - variable: nodeAgent.containers.processAgent.enabled + label: "Enable Process Agent" + type: boolean + description: "Whether or not to enable the Process Agent." + default: "true" + group: "Process Agent" + - variable: nodeAgent.skipKubeletTLSVerify + label: "Skip Kubelet TLS Verify" + type: boolean + description: "Whether or not to skip TLS verification when connecting to the kubelet API." + default: "true" + group: "Process Agent" + - variable: nodeAgent.containers.processAgent.resources.override + label: "Override Process Agent Resource Allocation" + type: boolean + description: "Whether or not to override the default resources." + default: "false" + group: "Process Agent" + show_subquestions_if: true + subquestions: + - variable: nodeAgent.containers.processAgent.resources.requests.cpu + label: "CPU Requests" + type: string + description: "The requested CPU for the Process Agent." + default: "25m" + - variable: nodeAgent.containers.processAgent.resources.requests.memory + label: "Memory Requests" + type: string + description: "The requested memory for the Process Agent." + default: "128Mi" + - variable: nodeAgent.containers.processAgent.resources.limits.cpu + label: "CPU Limit" + type: string + description: "The CPU limit for the Process Agent." + default: "125m" + - variable: nodeAgent.containers.processAgent.resources.limits.memory + label: "Memory Limit" + type: string + description: "The memory limit for the Process Agent." + default: "400Mi" + - variable: clusterAgent.enabled + label: "Enable Cluster Agent" + type: boolean + description: "Whether or not to enable the Cluster Agent." + default: "true" + group: "Cluster Agent" + - variable: clusterAgent.collection.kubernetesResources.secrets + label: "Collect Secret Resources" + type: boolean + description: | + Whether or not to collect Kubernetes Secrets. + NOTE: StackState will not send the actual data of the secrets, only the metadata and a secure hash of the data. + default: "true" + group: "Cluster Agent" + - variable: clusterAgent.resources.override + label: "Override Cluster Agent Resource Allocation" + type: boolean + description: "Whether or not to override the default resources." + default: "false" + group: "Cluster Agent" + show_subquestions_if: true + subquestions: + - variable: clusterAgent.resources.requests.cpu + label: "CPU Requests" + type: string + description: "The requested CPU for the Cluster Agent." + default: "70m" + - variable: clusterAgent.resources.requests.memory + label: "Memory Requests" + type: string + description: "The requested memory for the Cluster Agent." + default: "512Mi" + - variable: clusterAgent.resources.limits.cpu + label: "CPU Limit" + type: string + description: "The CPU limit for the Cluster Agent." + default: "400m" + - variable: clusterAgent.resources.limits.memory + label: "Memory Limit" + type: string + description: "The memory limit for the Cluster Agent." + default: "800Mi" + - variable: logsAgent.enabled + label: "Enable Logs Agent" + type: boolean + description: "Whether or not to enable the Logs Agent." + default: "true" + group: "Logs Agent" + - variable: logsAgent.resources.override + label: "Override Logs Agent Resource Allocation" + type: boolean + description: "Whether or not to override the default resources." + default: "false" + group: "Logs Agent" + show_subquestions_if: true + subquestions: + - variable: logsAgent.resources.requests.cpu + label: "CPU Requests" + type: string + description: "The requested CPU for the Logs Agent." + default: "20m" + - variable: logsAgent.resources.requests.memory + label: "Memory Requests" + type: string + description: "The requested memory for the Logs Agent." + default: "100Mi" + - variable: logsAgent.resources.limits.cpu + label: "CPU Limit" + type: string + description: "The CPU limit for the Logs Agent." + default: "1300m" + - variable: logsAgent.resources.limits.memory + label: "Memory Limit" + type: string + description: "The memory limit for the Logs Agent." + default: "192Mi" diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_cluster-agent-kube-state-metrics.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_cluster-agent-kube-state-metrics.yaml new file mode 100644 index 0000000000..f99fbf6187 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_cluster-agent-kube-state-metrics.yaml @@ -0,0 +1,62 @@ +{{- define "cluster-agent-kube-state-metrics" -}} +{{- $kubeRes := .Values.clusterAgent.collection.kubernetesResources }} +{{- if .Values.clusterAgent.collection.kubeStateMetrics.clusterCheck }} +cluster_check: true +{{- end }} +init_config: +instances: + - collectors: + - nodes + - pods + - services + {{- if $kubeRes.persistentvolumeclaims }} + - persistentvolumeclaims + {{- end }} + {{- if $kubeRes.persistentvolumes }} + - persistentvolumes + {{- end }} + {{- if $kubeRes.namespaces }} + - namespaces + {{- end }} + {{- if $kubeRes.endpoints }} + - endpoints + {{- end }} + {{- if $kubeRes.daemonsets }} + - daemonsets + {{- end }} + {{- if $kubeRes.deployments }} + - deployments + {{- end }} + {{- if $kubeRes.replicasets }} + - replicasets + {{- end }} + {{- if $kubeRes.statefulsets }} + - statefulsets + {{- end }} + {{- if $kubeRes.cronjobs }} + - cronjobs + {{- end }} + {{- if $kubeRes.jobs }} + - jobs + {{- end }} + {{- if $kubeRes.ingresses }} + - ingresses + {{- end }} + {{- if $kubeRes.secrets }} + - secrets + {{- end }} + - resourcequotas + - replicationcontrollers + - limitranges + - horizontalpodautoscalers + - poddisruptionbudgets + - storageclasses + - volumeattachments + {{- if .Values.clusterAgent.collection.kubeStateMetrics.clusterCheck }} + skip_leader_election: true + {{- end }} + labels_as_tags: + {{ .Values.clusterAgent.collection.kubeStateMetrics.labelsAsTags | toYaml | indent 8 }} + annotations_as_tags: + {{ .Values.clusterAgent.collection.kubeStateMetrics.annotationsAsTags | toYaml | indent 8 }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_container-agent.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_container-agent.yaml new file mode 100644 index 0000000000..09f9591c63 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_container-agent.yaml @@ -0,0 +1,191 @@ +{{- define "container-agent" -}} +- name: node-agent +{{- if .Values.all.hardening.enabled}} + lifecycle: + preStop: + exec: + command: [ "/bin/sh", "-c", "echo 'Giving slim.ai monitor time to submit data...'; sleep 120" ] +{{- end }} + image: "{{ include "stackstate-k8s-agent.imageRegistry" . }}/{{ .Values.nodeAgent.containers.agent.image.repository }}:{{ .Values.nodeAgent.containers.agent.image.tag }}" + imagePullPolicy: "{{ .Values.nodeAgent.containers.agent.image.pullPolicy }}" + env: + {{ include "stackstate-k8s-agent.apiKeyEnv" . | nindent 4 }} + - name: STS_KUBERNETES_KUBELET_HOST + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: KUBERNETES_HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: STS_HOSTNAME + value: "$(KUBERNETES_HOSTNAME)-{{ .Values.stackstate.cluster.name}}" + - name: AGENT_VERSION + value: {{ .Values.nodeAgent.containers.agent.image.tag | quote }} + - name: HOST_PROC + value: "/host/proc" + - name: HOST_SYS + value: "/host/sys" + - name: KUBERNETES + value: "true" + - name: STS_APM_ENABLED + value: {{ .Values.nodeAgent.apm.enabled | quote }} + - name: STS_APM_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + - name: STS_CLUSTER_AGENT_ENABLED + value: {{ .Values.clusterAgent.enabled | quote }} + {{- if .Values.clusterAgent.enabled }} + - name: STS_CLUSTER_AGENT_KUBERNETES_SERVICE_NAME + value: {{ .Release.Name }}-cluster-agent + {{ include "stackstate-k8s-agent.clusterAgentAuthTokenEnv" . | nindent 4 }} + {{- end }} + - name: STS_CLUSTER_NAME + value: {{ .Values.stackstate.cluster.name | quote }} + - name: STS_SKIP_VALIDATE_CLUSTERNAME + value: "true" + - name: STS_CHECKS_TAG_CARDINALITY + value: {{ .Values.nodeAgent.checksTagCardinality | quote }} + {{- if .Values.checksAgent.enabled }} + - name: STS_EXTRA_CONFIG_PROVIDERS + value: "endpointschecks" + {{- end }} + - name: STS_HEALTH_PORT + value: "5555" + - name: STS_LEADER_ELECTION + value: "false" + - name: LOG_LEVEL + value: {{ .Values.nodeAgent.containers.agent.logLevel | default .Values.nodeAgent.logLevel | quote }} + - name: STS_LOG_LEVEL + value: {{ .Values.nodeAgent.containers.agent.logLevel | default .Values.nodeAgent.logLevel | quote }} + - name: STS_NETWORK_TRACING_ENABLED + value: {{ .Values.nodeAgent.networkTracing.enabled | quote }} + - name: STS_PROTOCOL_INSPECTION_ENABLED + value: {{ .Values.nodeAgent.protocolInspection.enabled | quote }} + - name: STS_PROCESS_AGENT_ENABLED + value: {{ .Values.nodeAgent.containers.agent.processAgent.enabled | quote }} + - name: STS_CONTAINER_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.container | quote }} + - name: STS_CONNECTION_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.connections | quote }} + - name: STS_PROCESS_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.process | quote }} + - name: STS_PROCESS_AGENT_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + + - name: STS_SKIP_SSL_VALIDATION + value: {{ or .Values.global.skipSslValidation .Values.nodeAgent.skipSslValidation | quote }} + - name: STS_SKIP_KUBELET_TLS_VERIFY + value: {{ .Values.nodeAgent.skipKubeletTLSVerify | quote }} + - name: STS_STS_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + {{- if .Values.nodeAgent.containerRuntime.customSocketPath }} + - name: STS_CRI_SOCKET_PATH + value: {{ .Values.nodeAgent.containerRuntime.customSocketPath }} + {{- end }} + {{- if .Values.global.proxy.url }} + - name: STS_PROXY_HTTPS + value: {{ .Values.global.proxy.url | quote }} + - name: STS_PROXY_HTTP + value: {{ .Values.global.proxy.url | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.open }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.secret }} + - name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: {{ $key }} + {{- end }} + {{- range $key, $value := .Values.nodeAgent.containers.agent.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- if .Values.nodeAgent.containers.agent.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /health + port: healthport + failureThreshold: {{ .Values.nodeAgent.containers.agent.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.nodeAgent.containers.agent.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.nodeAgent.containers.agent.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.nodeAgent.containers.agent.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.nodeAgent.containers.agent.livenessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.nodeAgent.containers.agent.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: /health + port: healthport + failureThreshold: {{ .Values.nodeAgent.containers.agent.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.nodeAgent.containers.agent.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.nodeAgent.containers.agent.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.nodeAgent.containers.agent.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.nodeAgent.containers.agent.readinessProbe.timeoutSeconds }} + {{- end }} + ports: + - containerPort: 8126 + name: traceport + protocol: TCP + - containerPort: 5555 + name: healthport + protocol: TCP + {{- with .Values.nodeAgent.containers.agent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.nodeAgent.containerRuntime.customSocketPath }} + - name: customcrisocket + mountPath: {{ .Values.nodeAgent.containerRuntime.customSocketPath }} + readOnly: true + {{- end }} + - name: crisocket + mountPath: /var/run/crio/crio.sock + readOnly: true + - name: containerdsocket + mountPath: /var/run/containerd/containerd.sock + readOnly: true + - name: kubelet + mountPath: /var/lib/kubelet + readOnly: true + - name: nfs + mountPath: /var/lib/nfs + readOnly: true + - name: dockersocket + mountPath: /var/run/docker.sock + readOnly: true + - name: dockernetns + mountPath: /run/docker/netns + readOnly: true + - name: dockeroverlay2 + mountPath: /var/lib/docker/overlay2 + readOnly: true + - name: procdir + mountPath: /host/proc + readOnly: true + - name: cgroups + mountPath: /host/sys/fs/cgroup + readOnly: true + {{- if .Values.nodeAgent.config.override }} + {{- range .Values.nodeAgent.config.override }} + - name: config-override-volume + mountPath: {{ .path }}/{{ .name }} + subPath: {{ .path | replace "/" "_"}}_{{ .name }} + readOnly: true + {{- end }} + {{- end }} +{{- if .Values.all.hardening.enabled}} + securityContext: + privileged: true + runAsUser: 0 # root + capabilities: + add: [ "ALL" ] + readOnlyRootFilesystem: false +{{- else }} + securityContext: + privileged: false +{{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_container-process-agent.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_container-process-agent.yaml new file mode 100644 index 0000000000..893f11581a --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_container-process-agent.yaml @@ -0,0 +1,160 @@ +{{- define "container-process-agent" -}} +- name: process-agent +{{ if .Values.nodeAgent.containers.processAgent.image.registry }} + image: "{{ .Values.nodeAgent.containers.processAgent.image.registry }}/{{ .Values.nodeAgent.containers.processAgent.image.repository }}:{{ .Values.nodeAgent.containers.processAgent.image.tag }}" +{{ else }} + image: "{{ include "stackstate-k8s-agent.imageRegistry" . }}/{{ .Values.nodeAgent.containers.processAgent.image.repository }}:{{ .Values.nodeAgent.containers.processAgent.image.tag }}" +{{- end }} + imagePullPolicy: "{{ .Values.nodeAgent.containers.processAgent.image.pullPolicy }}" + ports: + - containerPort: 6063 + env: + {{ include "stackstate-k8s-agent.apiKeyEnv" . | nindent 4 }} + - name: STS_KUBERNETES_KUBELET_HOST + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: KUBERNETES_HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: STS_HOSTNAME + value: "$(KUBERNETES_HOSTNAME)-{{ .Values.stackstate.cluster.name}}" + - name: AGENT_VERSION + value: {{ .Values.nodeAgent.containers.processAgent.image.tag | quote }} + - name: STS_LOG_TO_CONSOLE + value: "true" + - name: HOST_PROC + value: "/host/proc" + - name: HOST_SYS + value: "/host/sys" + - name: HOST_ETC + value: "/host/etc" + - name: KUBERNETES + value: "true" + - name: STS_CLUSTER_AGENT_ENABLED + value: {{ .Values.clusterAgent.enabled | quote }} + {{- if .Values.clusterAgent.enabled }} + - name: STS_CLUSTER_AGENT_KUBERNETES_SERVICE_NAME + value: {{ .Release.Name }}-cluster-agent + {{ include "stackstate-k8s-agent.clusterAgentAuthTokenEnv" . | nindent 4 }} + {{- end }} + - name: STS_CLUSTER_NAME + value: {{ .Values.stackstate.cluster.name | quote }} + - name: STS_SKIP_VALIDATE_CLUSTERNAME + value: "true" + - name: LOG_LEVEL + value: {{ .Values.nodeAgent.containers.processAgent.logLevel | default .Values.nodeAgent.logLevel | quote }} + - name: STS_LOG_LEVEL + value: {{ .Values.nodeAgent.containers.processAgent.logLevel | default .Values.nodeAgent.logLevel | quote }} + - name: STS_NETWORK_TRACING_ENABLED + value: {{ .Values.nodeAgent.networkTracing.enabled | quote }} + - name: STS_PROTOCOL_INSPECTION_ENABLED + value: {{ .Values.nodeAgent.protocolInspection.enabled | quote }} + - name: STS_PROCESS_AGENT_ENABLED + value: {{ .Values.nodeAgent.containers.processAgent.enabled | quote }} + - name: STS_CONTAINER_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.container | quote }} + - name: STS_CONNECTION_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.connections | quote }} + - name: STS_PROCESS_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.process | quote }} + - name: GOMEMLIMIT + value: {{ .Values.processAgent.softMemoryLimit.goMemLimit | quote }} + - name: STS_HTTP_STATS_BUFFER_SIZE + value: {{ .Values.processAgent.softMemoryLimit.httpStatsBufferSize | quote }} + - name: STS_HTTP_OBSERVATIONS_BUFFER_SIZE + value: {{ .Values.processAgent.softMemoryLimit.httpObservationsBufferSize | quote }} + - name: STS_PROCESS_AGENT_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + - name: STS_SKIP_SSL_VALIDATION + value: {{ or .Values.global.skipSslValidation .Values.nodeAgent.skipSslValidation | quote }} + - name: STS_SKIP_KUBELET_TLS_VERIFY + value: {{ .Values.nodeAgent.skipKubeletTLSVerify | quote }} + - name: STS_STS_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + - name: STS_HTTP_TRACING_ENABLED + value: {{ .Values.nodeAgent.httpTracing.enabled | quote }} + {{- if .Values.nodeAgent.containerRuntime.customSocketPath }} + - name: STS_CRI_SOCKET_PATH + value: {{ .Values.nodeAgent.containerRuntime.customSocketPath }} + {{- end }} + {{- if .Values.global.proxy.url }} + - name: STS_PROXY_HTTPS + value: {{ .Values.global.proxy.url | quote }} + - name: STS_PROXY_HTTP + value: {{ .Values.global.proxy.url | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.open }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.secret }} + - name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: {{ $key }} + {{- end }} + {{- range $key, $value := .Values.nodeAgent.containers.processAgent.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- with .Values.nodeAgent.containers.processAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.nodeAgent.containerRuntime.customSocketPath }} + - name: customcrisocket + mountPath: {{ .Values.nodeAgent.containerRuntime.customSocketPath }} + readOnly: true + {{- end }} + - name: crisocket + mountPath: /var/run/crio/crio.sock + readOnly: true + - name: containerdsocket + mountPath: /var/run/containerd/containerd.sock + readOnly: true + - name: sys-kernel-debug + mountPath: /sys/kernel/debug + # Having sys-kernel-debug as read only breaks specific monitors from receiving metrics + # readOnly: true + - name: dockersocket + mountPath: /var/run/docker.sock + readOnly: true + # The agent needs access to /etc to figure out what os it is running on. + - name: etcdir + mountPath: /host/etc + readOnly: true + - name: procdir + mountPath: /host/proc + # We have an agent option STS_DISABLE_BPF_JIT_HARDEN that write to /proc. this is a debug setting but if we want to use + # it, we have the option to make /proc writable. + readOnly: {{ .Values.nodeAgent.containers.processAgent.procVolumeReadOnly }} + - name: passwd + mountPath: /etc/passwd + readOnly: true + - name: cgroups + mountPath: /host/sys/fs/cgroup + readOnly: true + {{- if .Values.nodeAgent.config.override }} + {{- range .Values.nodeAgent.config.override }} + - name: config-override-volume + mountPath: {{ .path }}/{{ .name }} + subPath: {{ .path | replace "/" "_"}}_{{ .name }} + readOnly: true + {{- end }} + {{- end }} +{{- if .Values.all.hardening.enabled}} + securityContext: + privileged: true + runAsUser: 0 # root + capabilities: + add: [ "ALL" ] + readOnlyRootFilesystem: false +{{- else }} + securityContext: + privileged: true +{{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_helpers.tpl b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_helpers.tpl new file mode 100644 index 0000000000..3c51bc3087 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/_helpers.tpl @@ -0,0 +1,219 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "stackstate-k8s-agent.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 "stackstate-k8s-agent.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 "stackstate-k8s-agent.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "stackstate-k8s-agent.labels" -}} +app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +helm.sh/chart: {{ include "stackstate-k8s-agent.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Cluster agent checksum annotations +*/}} +{{- define "stackstate-k8s-agent.checksum-configs" }} +checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- end }} + +{{/* +StackState URL function +*/}} +{{- define "stackstate-k8s-agent.stackstate.url" -}} +{{ tpl .Values.stackstate.url . | quote }} +{{- end }} + +{{- define "stackstate-k8s-agent.configmap.override.checksum" -}} +{{- if .Values.clusterAgent.config.override }} +checksum/override-configmap: {{ include (print $.Template.BasePath "/cluster-agent-configmap.yaml") . | sha256sum }} +{{- end }} +{{- end }} + +{{- define "stackstate-k8s-agent.nodeAgent.configmap.override.checksum" -}} +{{- if .Values.nodeAgent.config.override }} +checksum/override-configmap: {{ include (print $.Template.BasePath "/node-agent-configmap.yaml") . | sha256sum }} +{{- end }} +{{- end }} + +{{- define "stackstate-k8s-agent.logsAgent.configmap.override.checksum" -}} +checksum/override-configmap: {{ include (print $.Template.BasePath "/logs-agent-configmap.yaml") . | sha256sum }} +{{- end }} + +{{- define "stackstate-k8s-agent.checksAgent.configmap.override.checksum" -}} +{{- if .Values.checksAgent.config.override }} +checksum/override-configmap: {{ include (print $.Template.BasePath "/checks-agent-configmap.yaml") . | sha256sum }} +{{- end }} +{{- end }} + + +{{/* +Return the image registry +*/}} +{{- define "stackstate-k8s-agent.imageRegistry" -}} + {{- if .Values.global }} + {{- .Values.global.imageRegistry | default .Values.all.image.registry -}} + {{- else -}} + {{- .Values.all.image.registry -}} + {{- end -}} +{{- end -}} + +{{/* +Renders a value that contains a template. +Usage: +{{ include "stackstate-k8s-agent.tplvalue.render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "stackstate-k8s-agent.tplvalue.render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} + +{{- define "stackstate-k8s-agent.pull-secret.name" -}} +{{ include "stackstate-k8s-agent.fullname" . }}-pull-secret +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names evaluating values as templates +{{ include "stackstate-k8s-agent.image.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} +*/}} +{{- define "stackstate-k8s-agent.image.pullSecrets" -}} + {{- $pullSecrets := list }} + {{- $context := .context }} + {{- if $context.Values.global }} + {{- range $context.Values.global.imagePullSecrets -}} + {{/* Is plain array of strings, compatible with all bitnami charts */}} + {{- $pullSecrets = append $pullSecrets (include "stackstate-k8s-agent.tplvalue.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + {{- range $context.Values.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "stackstate-k8s-agent.tplvalue.render" (dict "value" .name "context" $context)) -}} + {{- end -}} + {{- range .images -}} + {{- if .pullSecretName -}} + {{- $pullSecrets = append $pullSecrets (include "stackstate-k8s-agent.tplvalue.render" (dict "value" .pullSecretName "context" $context)) -}} + {{- end -}} + {{- end -}} + {{- $pullSecrets = append $pullSecrets (include "stackstate-k8s-agent.pull-secret.name" $context) -}} + {{- if (not (empty $pullSecrets)) -}} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Check whether the kubernetes-state-metrics configuration is overridden. If so, return 'true' else return nothing (which is false). +{{ include "stackstate-k8s-agent.kube-state-metrics.overridden" $ }} +*/}} +{{- define "stackstate-k8s-agent.kube-state-metrics.overridden" -}} +{{- if .Values.clusterAgent.config.override }} + {{- range $i, $val := .Values.clusterAgent.config.override }} + {{- if and (eq $val.name "conf.yaml") (eq $val.path "/etc/stackstate-agent/conf.d/kubernetes_state.d") }} +true + {{- end }} + {{- end }} +{{- end }} +{{- end -}} + +{{- define "stackstate-k8s-agent.nodeAgent.kube-state-metrics.overridden" -}} +{{- if .Values.nodeAgent.config.override }} + {{- range $i, $val := .Values.nodeAgent.config.override }} + {{- if and (eq $val.name "auto_conf.yaml") (eq $val.path "/etc/stackstate-agent/conf.d/kubernetes_state.d") }} +true + {{- end }} + {{- end }} +{{- end }} +{{- end -}} + +{{/* +Return the appropriate os label +*/}} +{{- define "label.os" -}} +{{- if semverCompare "^1.14-0" .Capabilities.KubeVersion.GitVersion -}} +kubernetes.io/os +{{- else -}} +beta.kubernetes.io/os +{{- end -}} +{{- end -}} + +{{/* +Returns a YAML with extra annotations +*/}} +{{- define "stackstate-k8s-agent.global.extraAnnotations" -}} +{{- with .Values.global.extraAnnotations }} +{{- toYaml . }} +{{- end }} +{{- end -}} + +{{/* +Returns a YAML with extra labels +*/}} +{{- define "stackstate-k8s-agent.global.extraLabels" -}} +{{- with .Values.global.extraLabels }} +{{- toYaml . }} +{{- end }} +{{- end -}} + +{{- define "stackstate-k8s-agent.apiKeyEnv" -}} +- name: STS_API_KEY + valueFrom: + secretKeyRef: +{{- if not .Values.stackstate.manageOwnSecrets }} + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: sts-api-key +{{- else }} + name: {{ .Values.stackstate.customSecretName | quote }} + key: {{ .Values.stackstate.customApiKeySecretKey | quote }} +{{- end }} +{{- end -}} + +{{- define "stackstate-k8s-agent.clusterAgentAuthTokenEnv" -}} +- name: STS_CLUSTER_AGENT_AUTH_TOKEN + valueFrom: + secretKeyRef: +{{- if not .Values.stackstate.manageOwnSecrets }} + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: sts-cluster-auth-token +{{- else }} + name: {{ .Values.stackstate.customSecretName | quote }} + key: {{ .Values.stackstate.customClusterAuthTokenSecretKey | quote }} +{{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-clusterrolebinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-clusterrolebinding.yaml new file mode 100644 index 0000000000..4fd0eadbcd --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-clusterrolebinding.yaml @@ -0,0 +1,21 @@ +{{- if .Values.checksAgent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }}-checks-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: checks-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-node-agent +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ .Release.Name }}-checks-agent + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-configmap.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-configmap.yaml new file mode 100644 index 0000000000..54a1abf2fe --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-configmap.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.checksAgent.enabled .Values.checksAgent.config.override }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-checks-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: checks-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +data: +{{- range .Values.checksAgent.config.override }} + {{ .path | replace "/" "_"}}_{{ .name }}: | +{{ .data | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-deployment.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-deployment.yaml new file mode 100644 index 0000000000..37a0b1a1db --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-deployment.yaml @@ -0,0 +1,185 @@ +{{- if .Values.checksAgent.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-checks-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: checks-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/component: checks-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} + replicas: {{ .Values.checksAgent.replicas }} +{{- with .Values.checksAgent.strategy }} + strategy: + {{- toYaml . | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "stackstate-k8s-agent.checksum-configs" . | nindent 8 }} + {{- include "stackstate-k8s-agent.nodeAgent.configmap.override.checksum" . | nindent 8 }} +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 8 }} + labels: + app.kubernetes.io/component: checks-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 8 }} + spec: + {{- include "stackstate-k8s-agent.image.pullSecrets" (dict "images" (list .Values.checksAgent.image .Values.all.image) "context" $) | nindent 6 }} + {{- if .Values.all.hardening.enabled}} + terminationGracePeriodSeconds: 240 + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ include "stackstate-k8s-agent.imageRegistry" . }}/{{ .Values.checksAgent.image.repository }}:{{ .Values.checksAgent.image.tag }}" + imagePullPolicy: "{{ .Values.checksAgent.image.pullPolicy }}" + {{- if .Values.all.hardening.enabled}} + lifecycle: + preStop: + exec: + command: [ "/bin/sh", "-c", "echo 'Giving slim.ai monitor time to submit data...'; sleep 120" ] + {{- end }} + env: + {{ include "stackstate-k8s-agent.apiKeyEnv" . | nindent 10 }} + - name: KUBERNETES_HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: STS_HOSTNAME + value: "$(KUBERNETES_HOSTNAME)-{{ .Values.stackstate.cluster.name}}" + - name: AGENT_VERSION + value: {{ .Values.checksAgent.image.tag | quote }} + - name: LOG_LEVEL + value: {{ .Values.checksAgent.logLevel | quote }} + - name: STS_APM_ENABLED + value: "false" + - name: STS_CLUSTER_AGENT_ENABLED + value: {{ .Values.clusterAgent.enabled | quote }} + {{- if .Values.clusterAgent.enabled }} + - name: STS_CLUSTER_AGENT_KUBERNETES_SERVICE_NAME + value: {{ .Release.Name }}-cluster-agent + {{ include "stackstate-k8s-agent.clusterAgentAuthTokenEnv" . | nindent 10 }} + {{- end }} + - name: STS_CLUSTER_NAME + value: {{ .Values.stackstate.cluster.name | quote }} + - name: STS_SKIP_VALIDATE_CLUSTERNAME + value: "true" + - name: STS_CHECKS_TAG_CARDINALITY + value: {{ .Values.checksAgent.checksTagCardinality | quote }} + - name: STS_EXTRA_CONFIG_PROVIDERS + value: "clusterchecks" + - name: STS_HEALTH_PORT + value: "5555" + - name: STS_LEADER_ELECTION + value: "false" + - name: STS_LOG_LEVEL + value: {{ .Values.checksAgent.logLevel | quote }} + - name: STS_NETWORK_TRACING_ENABLED + value: "false" + - name: STS_PROCESS_AGENT_ENABLED + value: "false" + - name: STS_SKIP_SSL_VALIDATION + value: {{ or .Values.global.skipSslValidation .Values.checksAgent.skipSslValidation | quote }} + - name: STS_STS_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + {{- if .Values.global.proxy.url }} + - name: STS_PROXY_HTTPS + value: {{ .Values.global.proxy.url | quote }} + - name: STS_PROXY_HTTP + value: {{ .Values.global.proxy.url | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.open }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.secret }} + - name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: {{ $key }} + {{- end }} + livenessProbe: + httpGet: + path: /health + port: healthport + failureThreshold: {{ .Values.checksAgent.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.checksAgent.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.checksAgent.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.checksAgent.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.checksAgent.livenessProbe.timeoutSeconds }} + readinessProbe: + httpGet: + path: /health + port: healthport + failureThreshold: {{ .Values.checksAgent.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.checksAgent.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.checksAgent.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.checksAgent.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.checksAgent.readinessProbe.timeoutSeconds }} + ports: + - containerPort: 5555 + name: healthport + protocol: TCP + {{- if .Values.all.hardening.enabled}} + securityContext: + privileged: true + runAsUser: 0 # root + capabilities: + add: [ "ALL" ] + readOnlyRootFilesystem: false + {{- else }} + securityContext: + privileged: false + {{- end }} + {{- with .Values.checksAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: confd-empty-volume + mountPath: /etc/stackstate-agent/conf.d +# setting as readOnly: false because we need the ability to write data on /etc/stackstate-agent/conf.d as we enable checks to run. + readOnly: false + {{- if .Values.checksAgent.config.override }} + {{- range .Values.checksAgent.config.override }} + - name: config-override-volume + mountPath: {{ .path }}/{{ .name }} + subPath: {{ .path | replace "/" "_"}}_{{ .name }} + readOnly: true + {{- end }} + {{- end }} + {{- if .Values.checksAgent.priorityClassName }} + priorityClassName: {{ .Values.checksAgent.priorityClassName }} + {{- end }} + serviceAccountName: {{ .Release.Name }}-checks-agent + nodeSelector: + {{ template "label.os" . }}: {{ .Values.targetSystem }} + {{- with .Values.checksAgent.nodeSelector }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.checksAgent.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.checksAgent.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: confd-empty-volume + emptyDir: {} + {{- if .Values.checksAgent.config.override }} + - name: config-override-volume + configMap: + name: {{ .Release.Name }}-checks-agent + {{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-poddisruptionbudget.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-poddisruptionbudget.yaml new file mode 100644 index 0000000000..19d3924ea3 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-poddisruptionbudget.yaml @@ -0,0 +1,23 @@ +{{- if .Values.checksAgent.enabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ .Release.Name }}-checks-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: checks-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + maxUnavailable: 1 + selector: + matchLabels: + app.kubernetes.io/component: checks-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-serviceaccount.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-serviceaccount.yaml new file mode 100644 index 0000000000..a90a43589d --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/checks-agent-serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.checksAgent.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-checks-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: checks-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +{{- with .Values.checksAgent.serviceaccount.annotations }} + {{- toYaml . | nindent 4 }} +{{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-clusterrole.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-clusterrole.yaml new file mode 100644 index 0000000000..021a43ebdf --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-clusterrole.yaml @@ -0,0 +1,152 @@ +{{- $kubeRes := .Values.clusterAgent.collection.kubernetesResources }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +rules: +- apiGroups: + - "" + resources: + - events + - nodes + - pods + - services + {{- if $kubeRes.namespaces }} + - namespaces + {{- end }} + {{- if .Values.clusterAgent.collection.kubernetesMetrics }} + - componentstatuses + {{- end }} + {{- if $kubeRes.configmaps }} + - configmaps + {{- end }} + {{- if $kubeRes.endpoints }} + - endpoints + {{- end }} + {{- if $kubeRes.persistentvolumeclaims }} + - persistentvolumeclaims + {{- end }} + {{- if $kubeRes.persistentvolumes }} + - persistentvolumes + {{- end }} + {{- if $kubeRes.secrets }} + - secrets + {{- end }} + {{- if $kubeRes.resourcequotas }} + - resourcequotas + {{- end }} + verbs: + - get + - list + - watch +{{- if or $kubeRes.daemonsets $kubeRes.deployments $kubeRes.replicasets $kubeRes.statefulsets }} +- apiGroups: + - "apps" + resources: + {{- if $kubeRes.daemonsets }} + - daemonsets + {{- end }} + {{- if $kubeRes.deployments }} + - deployments + {{- end }} + {{- if $kubeRes.replicasets }} + - replicasets + {{- end }} + {{- if $kubeRes.statefulsets }} + - statefulsets + {{- end }} + verbs: + - get + - list + - watch +{{- end}} +{{- if $kubeRes.ingresses }} +- apiGroups: + - "extensions" + - "networking.k8s.io" + resources: + - ingresses + verbs: + - get + - list + - watch +{{- end}} +{{- if or $kubeRes.cronjobs $kubeRes.jobs }} +- apiGroups: + - "batch" + resources: + {{- if $kubeRes.cronjobs }} + - cronjobs + {{- end }} + {{- if $kubeRes.jobs }} + - jobs + {{- end }} + verbs: + - get + - list + - watch +{{- end}} +- nonResourceURLs: + - "/healthz" + - "/version" + verbs: + - get +- apiGroups: + - "storage.k8s.io" + resources: + {{- if $kubeRes.volumeattachments }} + - volumeattachments + {{- end }} + {{- if $kubeRes.storageclasses }} + - storageclasses + {{- end }} + verbs: + - get + - list + - watch +- apiGroups: + - "policy" + resources: + {{- if $kubeRes.poddisruptionbudgets }} + - poddisruptionbudgets + {{- end }} + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + {{- if $kubeRes.replicationcontrollers }} + - replicationcontrollers + {{- end }} + verbs: + - get + - list + - watch +- apiGroups: + - "autoscaling" + resources: + {{- if $kubeRes.horizontalpodautoscalers }} + - horizontalpodautoscalers + {{- end }} + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + {{- if $kubeRes.limitranges }} + - limitranges + {{- end }} + verbs: + - get + - list + - watch diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-clusterrolebinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-clusterrolebinding.yaml new file mode 100644 index 0000000000..207613dd9e --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-clusterrolebinding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "stackstate-k8s-agent.fullname" . }} +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ include "stackstate-k8s-agent.fullname" . }} + namespace: {{ .Release.Namespace }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-configmap.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-configmap.yaml new file mode 100644 index 0000000000..37d10217f8 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-configmap.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cluster-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +data: + kubernetes_api_events_conf: | + init_config: + instances: + - collect_events: {{ .Values.clusterAgent.collection.kubernetesEvents }} + event_categories:{{ .Values.clusterAgent.config.events.categories | toYaml | nindent 10 }} + kubernetes_api_topology_conf: | + init_config: + instances: + - collection_interval: {{ .Values.clusterAgent.config.topology.collectionInterval }} + resources:{{ .Values.clusterAgent.collection.kubernetesResources | toYaml | nindent 10 }} + {{- if .Values.clusterAgent.collection.kubeStateMetrics.enabled }} + kube_state_metrics_core_conf: | + {{- include "cluster-agent-kube-state-metrics" . | nindent 6 }} + {{- end }} +{{- if .Values.clusterAgent.config.override }} +{{- range .Values.clusterAgent.config.override }} + {{ .path | replace "/" "_"}}_{{ .name }}: | +{{ .data | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-deployment.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-deployment.yaml new file mode 100644 index 0000000000..51025a6703 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-deployment.yaml @@ -0,0 +1,169 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-cluster-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + replicas: {{ .Values.clusterAgent.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/component: cluster-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{- with .Values.clusterAgent.strategy }} + strategy: + {{- toYaml . | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "stackstate-k8s-agent.checksum-configs" . | nindent 8 }} + {{- include "stackstate-k8s-agent.configmap.override.checksum" . | nindent 8 }} +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 8 }} + labels: + app.kubernetes.io/component: cluster-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 8 }} + spec: + {{- include "stackstate-k8s-agent.image.pullSecrets" (dict "images" (list .Values.clusterAgent.image .Values.all.image) "context" $) | nindent 6 }} + {{- if .Values.clusterAgent.priorityClassName }} + priorityClassName: {{ .Values.clusterAgent.priorityClassName }} + {{- end }} + serviceAccountName: {{ include "stackstate-k8s-agent.fullname" . }} + {{- if .Values.all.hardening.enabled}} + terminationGracePeriodSeconds: 240 + {{- end }} + containers: + - name: cluster-agent + image: "{{ include "stackstate-k8s-agent.imageRegistry" . }}/{{ .Values.clusterAgent.image.repository }}:{{ .Values.clusterAgent.image.tag }}" + imagePullPolicy: "{{ .Values.clusterAgent.image.pullPolicy }}" + {{- if .Values.all.hardening.enabled}} + lifecycle: + preStop: + exec: + command: [ "/bin/sh", "-c", "echo 'Giving slim.ai monitor time to submit data...'; sleep 120" ] + {{- end }} + env: + {{ include "stackstate-k8s-agent.apiKeyEnv" . | nindent 10 }} + {{ include "stackstate-k8s-agent.clusterAgentAuthTokenEnv" . | nindent 10 }} + - name: KUBERNETES_HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: STS_HOSTNAME + value: "$(KUBERNETES_HOSTNAME)-{{ .Values.stackstate.cluster.name}}" + - name: LOG_LEVEL + value: {{ .Values.clusterAgent.logLevel | quote }} + {{- if .Values.checksAgent.enabled }} + - name: STS_CLUSTER_CHECKS_ENABLED + value: "true" + - name: STS_EXTRA_CONFIG_PROVIDERS + value: "kube_endpoints kube_services" + - name: STS_EXTRA_LISTENERS + value: "kube_endpoints kube_services" + {{- end }} + - name: STS_CLUSTER_NAME + value: {{.Values.stackstate.cluster.name | quote }} + - name: STS_SKIP_VALIDATE_CLUSTERNAME + value: "true" + - name: STS_SKIP_SSL_VALIDATION + value: {{ or .Values.global.skipSslValidation .Values.clusterAgent.skipSslValidation | quote }} + - name: STS_COLLECT_KUBERNETES_METRICS + value: {{ .Values.clusterAgent.collection.kubernetesMetrics | quote }} + - name: STS_COLLECT_KUBERNETES_TIMEOUT + value: {{ .Values.clusterAgent.collection.kubernetesTimeout | quote }} + - name: STS_COLLECT_KUBERNETES_TOPOLOGY + value: {{ .Values.clusterAgent.collection.kubernetesTopology | quote }} + - name: STS_LEADER_ELECTION + value: "true" + - name: STS_LOG_LEVEL + value: {{ .Values.clusterAgent.logLevel | quote }} + - name: STS_CLUSTER_AGENT_CMD_PORT + value: {{ .Values.clusterAgent.service.targetPort | quote }} + - name: STS_STS_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + {{- if .Values.clusterAgent.config.configMap.maxDataSize }} + - name: STS_CONFIGMAP_MAX_DATASIZE + value: {{ .Values.clusterAgent.config.configMap.maxDataSize | quote }} + {{- end}} + {{- if .Values.global.proxy.url }} + - name: STS_PROXY_HTTPS + value: {{ .Values.global.proxy.url | quote }} + - name: STS_PROXY_HTTP + value: {{ .Values.global.proxy.url | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.open }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.secret }} + - name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: {{ $key }} + {{- end }} + {{- if .Values.all.hardening.enabled}} + securityContext: + privileged: true + runAsUser: 0 # root + capabilities: + add: [ "ALL" ] + readOnlyRootFilesystem: false + {{- else }} + securityContext: + privileged: false + {{- end }} + {{- with .Values.clusterAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: logs + mountPath: /var/log/stackstate-agent + - name: config-override-volume + mountPath: /etc/stackstate-agent/conf.d/kubernetes_api_events.d/conf.yaml + subPath: kubernetes_api_events_conf + - name: config-override-volume + mountPath: /etc/stackstate-agent/conf.d/kubernetes_api_topology.d/conf.yaml + subPath: kubernetes_api_topology_conf + readOnly: true + {{- if .Values.clusterAgent.collection.kubeStateMetrics.enabled }} + - name: config-override-volume + mountPath: /etc/stackstate-agent/conf.d/kubernetes_state_core.d/conf.yaml + subPath: kube_state_metrics_core_conf + readOnly: true + {{- end }} + {{- if .Values.clusterAgent.config.override }} + {{- range .Values.clusterAgent.config.override }} + - name: config-override-volume + mountPath: {{ .path }}/{{ .name }} + subPath: {{ .path | replace "/" "_"}}_{{ .name }} + readOnly: true + {{- end }} + {{- end }} + nodeSelector: + {{ template "label.os" . }}: {{ .Values.targetSystem }} + {{- with .Values.clusterAgent.nodeSelector }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.clusterAgent.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.clusterAgent.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: logs + emptyDir: {} + - name: config-override-volume + configMap: + name: {{ .Release.Name }}-cluster-agent diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-poddisruptionbudget.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-poddisruptionbudget.yaml new file mode 100644 index 0000000000..64a265b7db --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-poddisruptionbudget.yaml @@ -0,0 +1,21 @@ +{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + maxUnavailable: 1 + selector: + matchLabels: + app.kubernetes.io/component: cluster-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-role.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-role.yaml new file mode 100644 index 0000000000..eabc5bde36 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-role.yaml @@ -0,0 +1,21 @@ +{{- $kubeRes := .Values.clusterAgent.collection.kubernetesResources }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - get + - patch + - update diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-rolebinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-rolebinding.yaml new file mode 100644 index 0000000000..adabad45e0 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-rolebinding.yaml @@ -0,0 +1,18 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "stackstate-k8s-agent.fullname" . }} +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ include "stackstate-k8s-agent.fullname" . }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-service.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-service.yaml new file mode 100644 index 0000000000..8b687e8f76 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-service.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-cluster-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + ports: + - name: clusteragent + port: {{int .Values.clusterAgent.service.port }} + protocol: TCP + targetPort: {{int .Values.clusterAgent.service.targetPort }} + selector: + app.kubernetes.io/component: cluster-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-serviceaccount.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-serviceaccount.yaml new file mode 100644 index 0000000000..6cbc89699e --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/cluster-agent-serviceaccount.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +{{- with .Values.clusterAgent.serviceaccount.annotations }} + {{- toYaml . | nindent 4 }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-clusterrole.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-clusterrole.yaml new file mode 100644 index 0000000000..da6cd59dd5 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-clusterrole.yaml @@ -0,0 +1,23 @@ +{{- if .Values.logsAgent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Release.Name }}-logs-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: logs-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +rules: +- apiGroups: # Kubelet connectivity + - "" + resources: + - nodes + - services + - pods + verbs: + - get + - watch + - list +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-clusterrolebinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-clusterrolebinding.yaml new file mode 100644 index 0000000000..1f6e7cfcff --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-clusterrolebinding.yaml @@ -0,0 +1,21 @@ +{{- if .Values.logsAgent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }}-logs-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: logs-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-logs-agent +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ .Release.Name }}-logs-agent + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-configmap.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-configmap.yaml new file mode 100644 index 0000000000..ff9440a4b7 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-configmap.yaml @@ -0,0 +1,63 @@ +{{- if .Values.logsAgent.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-logs-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: logs-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +data: + promtail.yaml: | + server: + http_listen_port: 9080 + grpc_listen_port: 0 + + clients: + - url: {{ tpl .Values.stackstate.url . }}/logs/k8s?api_key=${STS_API_KEY} + external_labels: + sts_cluster_name: {{ .Values.stackstate.cluster.name | quote }} + {{- if .Values.global.proxy.url }} + proxy_url: {{ .Values.global.proxy.url | quote }} + {{- end }} + tls_config: + insecure_skip_verify: {{ or .Values.global.skipSslValidation .Values.logsAgent.skipSslValidation }} + + + positions: + filename: /tmp/positions.yaml + target_config: + sync_period: 10s + scrape_configs: + - job_name: pod-logs + kubernetes_sd_configs: + - role: pod + pipeline_stages: + - docker: {} + - cri: {} + relabel_configs: + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod_name + - action: replace + source_labels: + - __meta_kubernetes_pod_uid + target_label: pod_uid + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container_name + # The __path__ is required by the promtail client + - replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + target_label: __path__ + # Drop all remaining labels, we do not need those + - action: drop + regex: __meta_(.*) +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-daemonset.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-daemonset.yaml new file mode 100644 index 0000000000..23cfce31f0 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-daemonset.yaml @@ -0,0 +1,91 @@ +{{- if .Values.logsAgent.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-logs-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: logs-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/component: logs-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{- with .Values.logsAgent.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "stackstate-k8s-agent.checksum-configs" . | nindent 8 }} + {{- include "stackstate-k8s-agent.logsAgent.configmap.override.checksum" . | nindent 8 }} +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 8 }} + labels: + app.kubernetes.io/component: logs-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 8 }} + spec: + {{- include "stackstate-k8s-agent.image.pullSecrets" (dict "images" (list .Values.logsAgent.image .Values.all.image) "context" $) | nindent 6 }} + containers: + - name: logs-agent + image: "{{ include "stackstate-k8s-agent.imageRegistry" . }}/{{ .Values.logsAgent.image.repository }}:{{ .Values.logsAgent.image.tag }}" + args: + - -config.expand-env=true + - -config.file=/etc/promtail/promtail.yaml + imagePullPolicy: "{{ .Values.logsAgent.image.pullPolicy }}" + env: + {{ include "stackstate-k8s-agent.apiKeyEnv" . | nindent 10 }} + - name: "HOSTNAME" # needed when using kubernetes_sd_configs + valueFrom: + fieldRef: + fieldPath: "spec.nodeName" + securityContext: + privileged: false + {{- with .Values.logsAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: logs + mountPath: /var/log + readOnly: true + - name: logs-agent-config + mountPath: /etc/promtail + readOnly: true + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + {{- if .Values.logsAgent.priorityClassName }} + priorityClassName: {{ .Values.logsAgent.priorityClassName }} + {{- end }} + serviceAccountName: {{ .Release.Name }}-logs-agent + {{- with .Values.logsAgent.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.logsAgent.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.logsAgent.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: logs + hostPath: + path: /var/log + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + - name: logs-agent-config + configMap: + name: {{ .Release.Name }}-logs-agent +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-serviceaccount.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-serviceaccount.yaml new file mode 100644 index 0000000000..91cfdb137d --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/logs-agent-serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.logsAgent.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-logs-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: logs-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +{{- with .Values.logsAgent.serviceaccount.annotations }} + {{- toYaml . | nindent 4 }} +{{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-clusterrole.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-clusterrole.yaml new file mode 100644 index 0000000000..1ded16cc29 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-clusterrole.yaml @@ -0,0 +1,21 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Release.Name }}-node-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +rules: +- apiGroups: # Kubelet connectivity + - "" + resources: + - nodes/metrics + - nodes/proxy + - nodes/spec + - endpoints + verbs: + - get + - list diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-clusterrolebinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-clusterrolebinding.yaml new file mode 100644 index 0000000000..b3f033ebbf --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-clusterrolebinding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }}-node-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-node-agent +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ .Release.Name }}-node-agent + namespace: {{ .Release.Namespace }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-configmap.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-configmap.yaml new file mode 100644 index 0000000000..8f6b2ed3ac --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-configmap.yaml @@ -0,0 +1,17 @@ +{{- if .Values.nodeAgent.config.override }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-node-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +data: +{{- range .Values.nodeAgent.config.override }} + {{ .path | replace "/" "_"}}_{{ .name }}: | +{{ .data | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-daemonset.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-daemonset.yaml new file mode 100644 index 0000000000..4c8dbdd5a9 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-daemonset.yaml @@ -0,0 +1,110 @@ +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-node-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/component: node-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{- with .Values.nodeAgent.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "stackstate-k8s-agent.checksum-configs" . | nindent 8 }} + {{- include "stackstate-k8s-agent.nodeAgent.configmap.override.checksum" . | nindent 8 }} +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 8 }} + labels: + app.kubernetes.io/component: node-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 8 }} + spec: + {{- include "stackstate-k8s-agent.image.pullSecrets" (dict "images" (list .Values.nodeAgent.containers.agent.image .Values.all.image) "context" $) | nindent 6 }} + {{- if .Values.all.hardening.enabled}} + terminationGracePeriodSeconds: 240 + {{- end }} + containers: + {{- include "container-agent" . | nindent 6 }} + {{- if .Values.nodeAgent.containers.processAgent.enabled }} + {{- include "container-process-agent" . | nindent 6 }} + {{- end }} + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + hostPID: true + {{- if .Values.nodeAgent.priorityClassName }} + priorityClassName: {{ .Values.nodeAgent.priorityClassName }} + {{- end }} + serviceAccountName: {{ .Release.Name }}-node-agent + nodeSelector: + {{ template "label.os" . }}: {{ .Values.targetSystem }} + {{- with .Values.nodeAgent.nodeSelector }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeAgent.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeAgent.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- if .Values.nodeAgent.containerRuntime.customSocketPath }} + - hostPath: + path: {{ .Values.nodeAgent.containerRuntime.customSocketPath }} + name: customcrisocket + {{- end }} + - hostPath: + path: /var/lib/kubelet + name: kubelet + - hostPath: + path: /var/lib/nfs + name: nfs + - hostPath: + path: /var/lib/docker/overlay2 + name: dockeroverlay2 + - hostPath: + path: /run/docker/netns + name: dockernetns + - hostPath: + path: /var/run/crio/crio.sock + name: crisocket + - hostPath: + path: /var/run/containerd/containerd.sock + name: containerdsocket + - hostPath: + path: /sys/kernel/debug + name: sys-kernel-debug + - hostPath: + path: /var/run/docker.sock + name: dockersocket + - hostPath: + path: {{ .Values.nodeAgent.containerRuntime.hostProc }} + name: procdir + - hostPath: + path: /etc + name: etcdir + - hostPath: + path: /etc/passwd + name: passwd + - hostPath: + path: /sys/fs/cgroup + name: cgroups + {{- if .Values.nodeAgent.config.override }} + - name: config-override-volume + configMap: + name: {{ .Release.Name }}-node-agent + {{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-podautoscaler.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-podautoscaler.yaml new file mode 100644 index 0000000000..38298d4147 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-podautoscaler.yaml @@ -0,0 +1,39 @@ +--- +{{- if .Values.nodeAgent.autoScalingEnabled }} +apiVersion: "autoscaling.k8s.io/v1" +kind: VerticalPodAutoscaler +metadata: + name: {{ .Release.Name }}-node-agent-vpa + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + targetRef: + apiVersion: "apps/v1" + kind: DaemonSet + name: {{ .Release.Name }}-node-agent + resourcePolicy: + containerPolicies: + - containerName: 'node-agent' + minAllowed: + cpu: {{ .Values.nodeAgent.scaling.autoscalerLimits.agent.minimum.cpu }} + memory: {{ .Values.nodeAgent.scaling.autoscalerLimits.agent.minimum.memory }} + maxAllowed: + cpu: {{ .Values.nodeAgent.scaling.autoscalerLimits.agent.maximum.cpu }} + memory: {{ .Values.nodeAgent.scaling.autoscalerLimits.agent.maximum.memory }} + controlledResources: ["cpu", "memory"] + controlledValues: RequestsAndLimits + - containerName: 'process-agent' + minAllowed: + cpu: {{ .Values.nodeAgent.scaling.autoscalerLimits.processAgent.minimum.cpu }} + memory: {{ .Values.nodeAgent.scaling.autoscalerLimits.processAgent.minimum.memory }} + maxAllowed: + cpu: {{ .Values.nodeAgent.scaling.autoscalerLimits.processAgent.maximum.cpu }} + memory: {{ .Values.nodeAgent.scaling.autoscalerLimits.processAgent.maximum.memory }} + controlledResources: ["cpu", "memory"] + controlledValues: RequestsAndLimits + updatePolicy: + updateMode: "Auto" +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-scc.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-scc.yaml new file mode 100644 index 0000000000..a09da78c17 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-scc.yaml @@ -0,0 +1,60 @@ +{{- if .Values.nodeAgent.scc.enabled }} +allowHostDirVolumePlugin: true +# was true +allowHostIPC: true +# was true +allowHostNetwork: true +# Allow host PID for dogstatsd origin detection +allowHostPID: true +# Allow host ports for dsd / trace / logs intake +allowHostPorts: true +allowPrivilegeEscalation: true +# was true +allowPrivilegedContainer: true +# was - '*' +allowedCapabilities: [] +allowedUnsafeSysctls: +- '*' +apiVersion: security.openshift.io/v1 +defaultAddCapabilities: null +fsGroup: +# was RunAsAny + type: MustRunAs +groups: [] +kind: SecurityContextConstraints +metadata: + name: {{ .Release.Name }}-node-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +priority: null +readOnlyRootFilesystem: false +requiredDropCapabilities: null +# was RunAsAny +runAsUser: + type: MustRunAsRange +# Use the `spc_t` selinux type to access the +# docker socket + proc and cgroup stats +seLinuxContext: + type: RunAsAny + seLinuxOptions: + user: "system_u" + role: "system_r" + type: "spc_t" + level: "s0" +# was - '*' +seccompProfiles: [] +supplementalGroups: + type: RunAsAny +users: +- system:serviceaccount:{{ .Release.Namespace }}:{{ .Release.Name }}-node-agent +# Allow hostPath for docker / process metrics +volumes: + - configMap + - downwardAPI + - emptyDir + - hostPath + - secret +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-service.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-service.yaml new file mode 100644 index 0000000000..0b6cd6ec03 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-node-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +{{- with .Values.nodeAgent.service.annotations }} + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.nodeAgent.service.type }} +{{- if eq .Values.nodeAgent.service.type "LoadBalancer" }} + loadBalancerSourceRanges: {{ toYaml .Values.nodeAgent.service.loadBalancerSourceRanges | nindent 4}} +{{- end }} + ports: + - name: traceport + port: 8126 + protocol: TCP + targetPort: 8126 + selector: + app.kubernetes.io/component: node-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-serviceaccount.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-serviceaccount.yaml new file mode 100644 index 0000000000..803d184ef7 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/node-agent-serviceaccount.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-node-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +{{- with .Values.nodeAgent.serviceaccount.annotations }} + {{- toYaml . | nindent 4 }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/openshift-logging-secret.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/openshift-logging-secret.yaml new file mode 100644 index 0000000000..ed0707f1fa --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/openshift-logging-secret.yaml @@ -0,0 +1,22 @@ +{{- if not .Values.stackstate.manageOwnSecrets }} +{{- if .Values.openShiftLogging.installSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }}-logging-secret + namespace: openshift-logging + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +type: Opaque +data: + username: {{ "apikey" | b64enc | quote }} +{{- if .Values.global.receiverApiKey }} + password: {{ .Values.global.receiverApiKey | b64enc | quote }} +{{- else }} + password: {{ .Values.stackstate.apiKey | b64enc | quote }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/pull-secret.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/pull-secret.yaml new file mode 100644 index 0000000000..9169416657 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/pull-secret.yaml @@ -0,0 +1,39 @@ +{{- $defaultRegistry := .Values.global.imageRegistry }} +{{- $top := . }} +{{- $registryAuthMap := dict }} + +{{- range $registry, $credentials := .Values.global.imagePullCredentials }} + {{- $registryAuthDocument := dict -}} + {{- $_ := set $registryAuthDocument "username" $credentials.username }} + {{- $_ := set $registryAuthDocument "password" $credentials.password }} + {{- $authMessage := printf "%s:%s" $registryAuthDocument.username $registryAuthDocument.password | b64enc }} + {{- $_ := set $registryAuthDocument "auth" $authMessage }} + {{- if eq $registry "default" }} + {{- $registryAuthMap := set $registryAuthMap (include "stackstate-k8s-agent.imageRegistry" $top) $registryAuthDocument }} + {{ else }} + {{- $registryAuthMap := set $registryAuthMap $registry $registryAuthDocument }} + {{- end }} +{{- end }} + +{{- if .Values.all.image.pullSecretUsername }} + {{- $registryAuthDocument := dict -}} + {{- $_ := set $registryAuthDocument "username" .Values.all.image.pullSecretUsername }} + {{- $_ := set $registryAuthDocument "password" .Values.all.image.pullSecretPassword }} + {{- $authMessage := printf "%s:%s" $registryAuthDocument.username $registryAuthDocument.password | b64enc }} + {{- $_ := set $registryAuthDocument "auth" $authMessage }} + {{- $registryAuthMap := set $registryAuthMap (include "stackstate-k8s-agent.imageRegistry" $top) $registryAuthDocument }} +{{- end }} + +{{- $dockerAuthsDocuments := dict "auths" $registryAuthMap }} + +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "stackstate-k8s-agent.pull-secret.name" . }} + labels: +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +data: + .dockerconfigjson: {{ $dockerAuthsDocuments | toJson | b64enc | quote }} +type: kubernetes.io/dockerconfigjson diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/secret.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/secret.yaml new file mode 100644 index 0000000000..5e0f5f74cd --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/templates/secret.yaml @@ -0,0 +1,27 @@ +{{- if not .Values.stackstate.manageOwnSecrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +type: Opaque +data: +{{- if .Values.global.receiverApiKey }} + sts-api-key: {{ .Values.global.receiverApiKey | b64enc | quote }} +{{- else }} + sts-api-key: {{ .Values.stackstate.apiKey | b64enc | quote }} +{{- end }} +{{- if .Values.stackstate.cluster.authToken }} + sts-cluster-auth-token: {{ .Values.stackstate.cluster.authToken | b64enc | quote }} +{{- else }} + sts-cluster-auth-token: {{ randAlphaNum 32 | b64enc | quote }} +{{- end }} +{{- range $key, $value := .Values.global.extraEnv.secret }} + {{ $key }}: {{ $value | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/test/clusteragent_resources_test.go b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/clusteragent_resources_test.go new file mode 100644 index 0000000000..25875e871a --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/clusteragent_resources_test.go @@ -0,0 +1,145 @@ +package test + +import ( + "regexp" + "strings" + "testing" + + v1 "k8s.io/api/rbac/v1" + + "github.com/stretchr/testify/assert" + "gitlab.com/StackVista/DevOps/helm-charts/helmtestutil" +) + +var requiredRules = []string{ + "events+get,list,watch", + "nodes+get,list,watch", + "pods+get,list,watch", + "services+get,list,watch", + "configmaps+create,get,patch,update", +} + +var optionalRules = []string{ + "namespaces+get,list,watch", + "componentstatuses+get,list,watch", + "configmaps+list,watch", // get is already required + "endpoints+get,list,watch", + "persistentvolumeclaims+get,list,watch", + "persistentvolumes+get,list,watch", + "secrets+get,list,watch", + "apps/daemonsets+get,list,watch", + "apps/deployments+get,list,watch", + "apps/replicasets+get,list,watch", + "apps/statefulsets+get,list,watch", + "extensions/ingresses+get,list,watch", + "batch/cronjobs+get,list,watch", + "batch/jobs+get,list,watch", +} + +var roleDescriptionRegexp = regexp.MustCompile(`^((?P\w+)/)?(?P\w+)\+(?P[\w,]+)`) + +type Rule struct { + Group string + ResourceName string + Verb string +} + +func assertRuleExistence(t *testing.T, rules []v1.PolicyRule, roleDescription string, shouldBePresent bool) { + match := roleDescriptionRegexp.FindStringSubmatch(roleDescription) + assert.NotNil(t, match) + + var roleRules []Rule + for _, rule := range rules { + for _, group := range rule.APIGroups { + for _, resource := range rule.Resources { + for _, verb := range rule.Verbs { + roleRules = append(roleRules, Rule{group, resource, verb}) + } + } + } + } + + resGroup := match[roleDescriptionRegexp.SubexpIndex("group")] + resName := match[roleDescriptionRegexp.SubexpIndex("name")] + verbs := strings.Split(match[roleDescriptionRegexp.SubexpIndex("verbs")], ",") + + for _, verb := range verbs { + requiredRule := Rule{resGroup, resName, verb} + found := false + for _, rule := range roleRules { + if rule == requiredRule { + found = true + break + } + } + if shouldBePresent { + assert.Truef(t, found, "Rule %v has not been found", requiredRule) + } else { + assert.Falsef(t, found, "Rule %v should not be present", requiredRule) + } + } +} + +func TestAllResourcesAreEnabled(t *testing.T) { + output := helmtestutil.RenderHelmTemplate(t, "stackstate-k8s-agent", "values/minimal.yaml") + resources := helmtestutil.NewKubernetesResources(t, output) + + assert.Contains(t, resources.ClusterRoles, "stackstate-k8s-agent") + assert.Contains(t, resources.Roles, "stackstate-k8s-agent") + rules := resources.ClusterRoles["stackstate-k8s-agent"].Rules + rules = append(rules, resources.Roles["stackstate-k8s-agent"].Rules...) + + for _, requiredRole := range requiredRules { + assertRuleExistence(t, rules, requiredRole, true) + } + // be default, everything is enabled, so all the optional roles should be present as well + for _, optionalRule := range optionalRules { + assertRuleExistence(t, rules, optionalRule, true) + } +} + +func TestMostOfResourcesAreDisabled(t *testing.T) { + output := helmtestutil.RenderHelmTemplate(t, "stackstate-k8s-agent", "values/minimal.yaml", "values/disable-all-resource.yaml") + resources := helmtestutil.NewKubernetesResources(t, output) + + assert.Contains(t, resources.ClusterRoles, "stackstate-k8s-agent") + assert.Contains(t, resources.Roles, "stackstate-k8s-agent") + rules := resources.ClusterRoles["stackstate-k8s-agent"].Rules + rules = append(rules, resources.Roles["stackstate-k8s-agent"].Rules...) + + for _, requiredRole := range requiredRules { + assertRuleExistence(t, rules, requiredRole, true) + } + + // we expect all optional resources to be removed from ClusterRole with the given values + for _, optionalRule := range optionalRules { + assertRuleExistence(t, rules, optionalRule, false) + } +} + +func TestNoClusterWideModificationRights(t *testing.T) { + output := helmtestutil.RenderHelmTemplate(t, "stackstate-k8s-agent", "values/minimal.yaml", "values/http-header-injector.yaml") + resources := helmtestutil.NewKubernetesResources(t, output) + assert.Contains(t, resources.ClusterRoles, "stackstate-k8s-agent") + illegalVerbs := []string{"create", "patch", "update", "delete"} + + for _, clusterRole := range resources.ClusterRoles { + for _, rule := range clusterRole.Rules { + for _, verb := range rule.Verbs { + assert.NotContains(t, illegalVerbs, verb, "ClusterRole %s should not have %s verb for %s resource", clusterRole.Name, verb, rule.Resources) + } + } + } +} + +func TestServicePortChange(t *testing.T) { + output := helmtestutil.RenderHelmTemplate(t, "stackstate-k8s-agent", "values/minimal.yaml", "values/clustercheck_service_port_override.yaml") + resources := helmtestutil.NewKubernetesResources(t, output) + + cluster_agent_service := resources.Services["stackstate-k8s-agent-cluster-agent"] + + port := cluster_agent_service.Spec.Ports[0] + assert.Equal(t, port.Name, "clusteragent") + assert.Equal(t, port.Port, int32(8008)) + assert.Equal(t, port.TargetPort.IntVal, int32(9009)) +} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/test/clustername_test.go b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/clustername_test.go new file mode 100644 index 0000000000..55090b9956 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/clustername_test.go @@ -0,0 +1,54 @@ +package test + +import ( + "testing" + + "github.com/gruntwork-io/terratest/modules/helm" + "github.com/stretchr/testify/assert" + + "gitlab.com/StackVista/DevOps/helm-charts/helmtestutil" +) + +func TestHelmBasicRender(t *testing.T) { + output := helmtestutil.RenderHelmTemplate(t, "stackstate-k8s-agent", "values/minimal.yaml") + + // Parse all resources into their corresponding types for validation and further inspection + helmtestutil.NewKubernetesResources(t, output) +} + +func TestClusterNameValidation(t *testing.T) { + testCases := []struct { + Name string + ClusterName string + IsValid bool + }{ + {"not allowed end with special character [.]", "name.", false}, + {"not allowed end with special character [-]", "name.", false}, + {"not allowed start with special character [-]", "-name", false}, + {"not allowed start with special character [.]", ".name", false}, + {"upper case is not allowed", "Euwest1-prod.cool-company.com", false}, + {"upper case is not allowed", "euwest1-PROD.cool-company.com", false}, + {"upper case is not allowed", "euwest1-prod.cool-company.coM", false}, + {"dots and dashes are allowed in the middle", "euwest1-prod.cool-company.com", true}, + {"underscore is not allowed", "why_7", false}, + } + + for _, testCase := range testCases { + t.Run(testCase.Name, func(t *testing.T) { + output, err := helmtestutil.RenderHelmTemplateOpts( + t, "cluster-agent", + &helm.Options{ + ValuesFiles: []string{"values/minimal.yaml"}, + SetStrValues: map[string]string{ + "stackstate.cluster.name": testCase.ClusterName, + }, + }) + if testCase.IsValid { + assert.Nil(t, err) + } else { + assert.NotNil(t, err) + assert.Contains(t, output, "stackstate.cluster.name: Does not match pattern") + } + }) + } +} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_custom_url.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_custom_url.yaml new file mode 100644 index 0000000000..57b973eed9 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_custom_url.yaml @@ -0,0 +1,7 @@ +checksAgent: + enabled: true + kubeStateMetrics: + url: http://my-custom-ksm-url.monitoring.svc.local:8080/metrics +dependencies: + kubeStateMetrics: + enabled: true diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_no_override.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_no_override.yaml new file mode 100644 index 0000000000..b6c817d473 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_no_override.yaml @@ -0,0 +1,5 @@ +checksAgent: + enabled: true +dependencies: + kubeStateMetrics: + enabled: true diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_override.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_override.yaml new file mode 100644 index 0000000000..9ca201345a --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_ksm_override.yaml @@ -0,0 +1,26 @@ +checksAgent: + enabled: true +dependencies: + kubeStateMetrics: + enabled: true +agent: + config: + override: +# agent.config.override -- Disables kubernetes_state check on regular agent pods. + - name: auto_conf.yaml + path: /etc/stackstate-agent/conf.d/kubernetes_state.d + data: | +clusterAgent: + config: + override: +# clusterAgent.config.override -- Defines kubernetes_state check for clusterchecks agents. Auto-discovery +# with ad_identifiers does not work here. Use a specific URL instead. + - name: conf.yaml + path: /etc/stackstate-agent/conf.d/kubernetes_state.d + data: | + cluster_check: true + + init_config: + + instances: + - kube_state_url: http://YOUR_KUBE_STATE_METRICS_SERVICE_NAME:8080/metrics diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_no_ksm_custom_url.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_no_ksm_custom_url.yaml new file mode 100644 index 0000000000..a62691878c --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_no_ksm_custom_url.yaml @@ -0,0 +1,7 @@ +checksAgent: + enabled: true + kubeStateMetrics: + url: http://my-custom-ksm-url.monitoring.svc.local:8080/metrics +dependencies: + kubeStateMetrics: + enabled: false diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_service_port_override.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_service_port_override.yaml new file mode 100644 index 0000000000..c01a98fcb4 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/clustercheck_service_port_override.yaml @@ -0,0 +1,4 @@ +clusterAgent: + service: + port: 8008 + targetPort: 9009 diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/disable-all-resource.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/disable-all-resource.yaml new file mode 100644 index 0000000000..cd33e843ea --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/disable-all-resource.yaml @@ -0,0 +1,17 @@ +clusterAgent: + collection: + kubernetesMetrics: false + kubernetesResources: + namespaces: false + configmaps: false + endpoints: false + persistentvolumes: false + persistentvolumeclaims: false + secrets: false + daemonsets: false + deployments: false + replicasets: false + statefulsets: false + ingresses: false + cronjobs: false + jobs: false diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/http-header-injector.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/http-header-injector.yaml new file mode 100644 index 0000000000..c9392ce2dd --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/http-header-injector.yaml @@ -0,0 +1,8 @@ +httpHeaderInjectorWebhook: + webhook: + tls: + mode: "provided" + provided: + caBundle: insert-ca-here + crt: insert-cert-here + key: insert-key-here diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/minimal.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/minimal.yaml new file mode 100644 index 0000000000..b310c9a093 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/test/values/minimal.yaml @@ -0,0 +1,7 @@ +stackstate: + apiKey: foobar + cluster: + name: some-k8s-cluster + token: some-token + + url: https://stackstate:7000/receiver diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/values.schema.json b/charts/stackstate/stackstate-k8s-agent/1.0.96/values.schema.json new file mode 100644 index 0000000000..57d36a9f34 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/values.schema.json @@ -0,0 +1,78 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://stackstate.io/example.json", + "type": "object", + "default": {}, + "title": "StackState Agent Helm chart values", + "required": [ + "stackstate", + "clusterAgent" + ], + "properties": { + "stackstate": { + "type": "object", + "required": [ + "cluster", + "url" + ], + "properties": { + "apiKey": { + "type": "string" + }, + "cluster": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z0-9]([a-z0-9\\-\\.]*[a-z0-9])$" + }, + "authToken": { + "type": "string" + } + } + }, + "url": { + "type": "string" + } + } + }, + "clusterAgent": { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "required": [ + "events" + ], + "properties": { + "events": { + "type": "object", + "properties": { + "categories": { + "type": "object", + "patternProperties": { + ".*": { + "type": [ + "string" + ], + "enum": [ + "Alerts", + "Activities", + "Changes", + "Others" + ] + } + } + } + } + } + } + } + } + } + } +} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.96/values.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.96/values.yaml new file mode 100644 index 0000000000..c58846a7c0 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.96/values.yaml @@ -0,0 +1,616 @@ +##################### +# General variables # +##################### + +global: + extraEnv: + # global.extraEnv.open -- Extra open environment variables to inject into pods. + open: {} + # global.extraEnv.secret -- Extra secret environment variables to inject into pods via a `Secret` object. + secret: {} + # global.imagePullSecrets -- Secrets / credentials needed for container image registry. + imagePullSecrets: [] + # global.imagePullCredentials -- Globally define credentials for pulling images. + imagePullCredentials: {} + proxy: + # global.proxy.url -- Proxy for all traffic to stackstate + url: "" + # global.skipSslValidation -- Enable tls validation from client + skipSslValidation: false + + # global.extraLabels -- Extra labels added ta all resources created by the helm chart + extraLabels: {} + # global.extraAnnotations -- Extra annotations added ta all resources created by the helm chart + extraAnnotations: {} + +# nameOverride -- Override the name of the chart. +nameOverride: "" +# fullnameOverride -- Override the fullname of the chart. +fullnameOverride: "" + +# targetSystem -- Target OS for this deployment (possible values: linux) +targetSystem: "linux" + +all: + image: + # all.image.registry -- The image registry to use. + registry: "quay.io" + hardening: + # all.hardening.enabled -- An indication of whether the containers will be evaluated for hardening at runtime + enabled: false + +nodeAgent: + # nodeAgent.autoScalingEnabled -- Enable / disable autoscaling for the node agent pods. + autoScalingEnabled: false + containerRuntime: + # nodeAgent.containerRuntime.customSocketPath -- If the container socket path does not match the default for CRI-O, Containerd or Docker, supply a custom socket path. + customSocketPath: "" + # nodeAgent.containerRuntime.customHostProc -- If the container is launched from a place where /proc is mounted differently, /proc can be changed + hostProc: /proc + + scc: + # nodeAgent.scc.enabled -- Enable / disable the installation of the SecurityContextConfiguration needed for installation on OpenShift. + enabled: false + apm: + # nodeAgent.apm.enabled -- Enable / disable the nodeAgent APM module. + enabled: true + networkTracing: + # nodeAgent.networkTracing.enabled -- Enable / disable the nodeAgent network tracing module. + enabled: true + protocolInspection: + # nodeAgent.protocolInspection.enabled -- Enable / disable the nodeAgent protocol inspection. + enabled: true + httpTracing: + enabled: true + # nodeAgent.skipSslValidation -- Set to true if self signed certificates are used. + skipSslValidation: false + # nodeAgent.skipKubeletTLSVerify -- Set to true if you want to skip kubelet tls verification. + skipKubeletTLSVerify: false + + # nodeAgent.checksTagCardinality -- low, orchestrator or high. Orchestrator level adds pod_name, high adds display_container_name + checksTagCardinality: orchestrator + + # nodeAgent.config -- + config: + # nodeAgent.config.override -- A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap + override: [] + + # nodeAgent.priorityClassName -- Priority class for nodeAgent pods. + priorityClassName: "" + + scaling: + autoscalerLimits: + agent: + minimum: + # nodeAgent.scaling.autoscalerLimits.agent.minimum.cpu -- Minimum CPU resource limits for main agent. + cpu: "20m" + # nodeAgent.scaling.autoscalerLimits.agent.minimum.memory -- Minimum memory resource limits for main agent. + memory: "180Mi" + maximum: + # nodeAgent.scaling.autoscalerLimits.agent.maximum.cpu -- Maximum CPU resource limits for main agent. + cpu: "200m" + # nodeAgent.scaling.autoscalerLimits.agent.maximum.memory -- Maximum memory resource limits for main agent. + memory: "450Mi" + processAgent: + minimum: + # nodeAgent.scaling.autoscalerLimits.processAgent.minimum.cpu -- Minimum CPU resource limits for process agent. + cpu: "25m" + # nodeAgent.scaling.autoscalerLimits.processAgent.minimum.memory -- Minimum memory resource limits for process agent. + memory: "100Mi" + maximum: + # nodeAgent.scaling.autoscalerLimits.processAgent.maximum.cpu -- Maximum CPU resource limits for process agent. + cpu: "200m" + # nodeAgent.scaling.autoscalerLimits.processAgent.maximum.memory -- Maximum memory resource limits for process agent. + memory: "500Mi" + + containers: + agent: + image: + # nodeAgent.containers.agent.image.repository -- Base container image repository. + repository: stackstate/stackstate-k8s-agent + # nodeAgent.containers.agent.image.tag -- Default container image tag. + tag: "c4caacef" + # nodeAgent.containers.agent.image.pullPolicy -- Default container image pull policy. + pullPolicy: IfNotPresent + processAgent: + # nodeAgent.containers.agent.processAgent.enabled -- Enable / disable the agent process agent module. - deprecated + enabled: false + # nodeAgent.containers.agent.env -- Additional environment variables for the agent container + env: {} + # nodeAgent.containers.agent.logLevel -- Set logging verbosity, valid log levels are: trace, debug, info, warn, error, critical, and off + ## If not set, fall back to the value of agent.logLevel. + logLevel: # INFO + + resources: + limits: + # nodeAgent.containers.agent.resources.limits.cpu -- CPU resource limits. + cpu: "270m" + # nodeAgent.containers.agent.resources.limits.memory -- Memory resource limits. + memory: "420Mi" + requests: + # nodeAgent.containers.agent.resources.requests.cpu -- CPU resource requests. + cpu: "20m" + # nodeAgent.containers.agent.resources.requests.memory -- Memory resource requests. + memory: "180Mi" + livenessProbe: + # nodeAgent.containers.agent.livenessProbe.enabled -- Enable use of livenessProbe check. + enabled: true + # nodeAgent.containers.agent.livenessProbe.failureThreshold -- `failureThreshold` for the liveness probe. + failureThreshold: 3 + # nodeAgent.containers.agent.livenessProbe.initialDelaySeconds -- `initialDelaySeconds` for the liveness probe. + initialDelaySeconds: 15 + # nodeAgent.containers.agent.livenessProbe.periodSeconds -- `periodSeconds` for the liveness probe. + periodSeconds: 15 + # nodeAgent.containers.agent.livenessProbe.successThreshold -- `successThreshold` for the liveness probe. + successThreshold: 1 + # nodeAgent.containers.agent.livenessProbe.timeoutSeconds -- `timeoutSeconds` for the liveness probe. + timeoutSeconds: 5 + readinessProbe: + # nodeAgent.containers.agent.readinessProbe.enabled -- Enable use of readinessProbe check. + enabled: true + # nodeAgent.containers.agent.readinessProbe.failureThreshold -- `failureThreshold` for the readiness probe. + failureThreshold: 3 + # nodeAgent.containers.agent.readinessProbe.initialDelaySeconds -- `initialDelaySeconds` for the readiness probe. + initialDelaySeconds: 15 + # nodeAgent.containers.agent.readinessProbe.periodSeconds -- `periodSeconds` for the readiness probe. + periodSeconds: 15 + # nodeAgent.containers.agent.readinessProbe.successThreshold -- `successThreshold` for the readiness probe. + successThreshold: 1 + # nodeAgent.containers.agent.readinessProbe.timeoutSeconds -- `timeoutSeconds` for the readiness probe. + timeoutSeconds: 5 + + processAgent: + # nodeAgent.containers.processAgent.enabled -- Enable / disable the process agent container. + enabled: true + image: + # Override to pull the image from an alternate registry + registry: + # nodeAgent.containers.processAgent.image.repository -- Process-agent container image repository. + repository: stackstate/stackstate-k8s-process-agent + # nodeAgent.containers.processAgent.image.tag -- Default process-agent container image tag. + tag: "cae7a4fa" + # nodeAgent.containers.processAgent.image.pullPolicy -- Process-agent container image pull policy. + pullPolicy: IfNotPresent + # nodeAgent.containers.processAgent.env -- Additional environment variables for the process-agent container + env: {} + # nodeAgent.containers.processAgent.logLevel -- Set logging verbosity, valid log levels are: trace, debug, info, warn, error, critical, and off + ## If not set, fall back to the value of agent.logLevel. + logLevel: # INFO + + # nodeAgent.containers.processAgent.procVolumeReadOnly -- Configure whether /host/proc is read only for the process agent container + procVolumeReadOnly: true + + resources: + limits: + # nodeAgent.containers.processAgent.resources.limits.cpu -- CPU resource limits. + cpu: "125m" + # nodeAgent.containers.processAgent.resources.limits.memory -- Memory resource limits. + memory: "400Mi" + requests: + # nodeAgent.containers.processAgent.resources.requests.cpu -- CPU resource requests. + cpu: "25m" + # nodeAgent.containers.processAgent.resources.requests.memory -- Memory resource requests. + memory: "128Mi" + # nodeAgent.service -- The Kubernetes service for the agent + service: + # nodeAgent.service.type -- Type of Kubernetes service: ClusterIP, LoadBalancer, NodePort + type: ClusterIP + # nodeAgent.service.annotations -- Annotations for the service + annotations: {} + # nodeAgent.service.loadBalancerSourceRanges -- The IP4 CIDR allowed to reach LoadBalancer for the service. For LoadBalancer type of service only. + loadBalancerSourceRanges: ["10.0.0.0/8"] + + # nodeAgent.logLevel -- Logging level for agent processes. + logLevel: INFO + + # nodeAgent.updateStrategy -- The update strategy for the DaemonSet object. + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 100 + + # nodeAgent.nodeSelector -- Node labels for pod assignment. + nodeSelector: {} + + # nodeAgent.tolerations -- Toleration labels for pod assignment. + tolerations: [] + + # nodeAgent.affinity -- Affinity settings for pod assignment. + affinity: {} + + serviceaccount: + # nodeAgent.serviceaccount.annotations -- Annotations for the service account for the agent daemonset pods + annotations: {} + +processAgent: + softMemoryLimit: + # processAgent.softMemoryLimit.goMemLimit -- Soft-limit for golang heap allocation, for sanity, must be around 85% of nodeAgent.containers.processAgent.resources.limits.cpu. + goMemLimit: 340MiB + # processAgent.softMemoryLimit.httpStatsBufferSize -- Sets a maximum for the number of http stats to keep in memory between check runs, to use 40k requires around ~400Mib of memory. + httpStatsBufferSize: 40000 + # processAgent.softMemoryLimit.httpObservationsBufferSize -- Sets a maximum for the number of http observations to keep in memory between check runs, to use 40k requires around ~400Mib of memory. + httpObservationsBufferSize: 40000 + + checkIntervals: + # processAgent.checkIntervals.container -- Override the default value of the container check interval in seconds. + container: 28 + # processAgent.checkIntervals.connections -- Override the default value of the connections check interval in seconds. + connections: 30 + # processAgent.checkIntervals.process -- Override the default value of the process check interval in seconds. + process: 32 + +clusterAgent: + collection: + # clusterAgent.collection.kubernetesEvents -- Enable / disable the cluster agent events collection. + kubernetesEvents: true + # clusterAgent.collection.kubernetesMetrics -- Enable / disable the cluster agent metrics collection. + kubernetesMetrics: true + # clusterAgent.collection.kubernetesTimeout -- Default timeout (in seconds) when obtaining information from the Kubernetes API. + kubernetesTimeout: 10 + # clusterAgent.collection.kubernetesTopology -- Enable / disable the cluster agent topology collection. + kubernetesTopology: true + kubeStateMetrics: + # clusterAgent.collection.kubeStateMetrics.enabled -- Enable / disable the cluster agent kube-state-metrics collection. + enabled: true + # clusterAgent.collection.kubeStateMetrics.clusterCheck -- For large clusters where the Kubernetes State Metrics Check Core needs to be distributed on dedicated workers. + clusterCheck: false + # clusterAgent.collection.kubeStateMetrics.labelsAsTags -- Extra labels to collect from resources and to turn into StackState tag. + ## It has the following structure: + ## labelsAsTags: + ## : # can be pod, deployment, node, etc. + ## : # where is the kubernetes label and is the StackState tag + ## : + ## : + ## : + ## + ## Warning: the label must match the transformation done by kube-state-metrics, + ## for example tags.stackstate/version becomes tags_stackstate_version. + labelsAsTags: {} + # pod: + # app: app + # node: + # zone: zone + # team: team + + # clusterAgent.collection.kubeStateMetrics.annotationsAsTags -- Extra annotations to collect from resources and to turn into StackState tag. + + ## It has the following structure: + ## annotationsAsTags: + ## : # can be pod, deployment, node, etc. + ## : # where is the kubernetes annotation and is the StackState tag + ## : + ## : + ## : + ## + ## Warning: the annotation must match the transformation done by kube-state-metrics, + ## for example tags.stackstate/version becomes tags_stackstate_version. + annotationsAsTags: {} + kubernetesResources: + # clusterAgent.collection.kubernetesResources.limitranges -- Enable / disable collection of LimitRanges. + limitranges: true + # clusterAgent.collection.kubernetesResources.horizontalpodautoscalers -- Enable / disable collection of HorizontalPodAutoscalers. + horizontalpodautoscalers: true + # clusterAgent.collection.kubernetesResources.replicationcontrollers -- Enable / disable collection of ReplicationControllers. + replicationcontrollers: true + # clusterAgent.collection.kubernetesResources.poddisruptionbudgets -- Enable / disable collection of PodDisruptionBudgets. + poddisruptionbudgets: true + # clusterAgent.collection.kubernetesResources.storageclasses -- Enable / disable collection of StorageClasses. + storageclasses: true + # clusterAgent.collection.kubernetesResources.volumeattachments -- Enable / disable collection of Volume Attachments. Used to bind Nodes to Persistent Volumes. + volumeattachments: true + # clusterAgent.collection.kubernetesResources.namespaces -- Enable / disable collection of Namespaces. + namespaces: true + # clusterAgent.collection.kubernetesResources.configmaps -- Enable / disable collection of ConfigMaps. + configmaps: true + # clusterAgent.collection.kubernetesResources.endpoints -- Enable / disable collection of Endpoints. If endpoints are disabled then StackState won't be able to connect a Service to Pods that serving it + endpoints: true + # clusterAgent.collection.kubernetesResources.persistentvolumes -- Enable / disable collection of PersistentVolumes. + persistentvolumes: true + # clusterAgent.collection.kubernetesResources.persistentvolumeclaims -- Enable / disable collection of PersistentVolumeClaims. Disabling these will not let StackState connect PersistentVolumes to pods they are attached to + persistentvolumeclaims: true + # clusterAgent.collection.kubernetesResources.secrets -- Enable / disable collection of Secrets. + secrets: true + # clusterAgent.collection.kubernetesResources.daemonsets -- Enable / disable collection of DaemonSets. + daemonsets: true + # clusterAgent.collection.kubernetesResources.deployments -- Enable / disable collection of Deployments. + deployments: true + # clusterAgent.collection.kubernetesResources.replicasets -- Enable / disable collection of ReplicaSets. + replicasets: true + # clusterAgent.collection.kubernetesResources.statefulsets -- Enable / disable collection of StatefulSets. + statefulsets: true + # clusterAgent.collection.kubernetesResources.ingresses -- Enable / disable collection of Ingresses. + ingresses: true + # clusterAgent.collection.kubernetesResources.cronjobs -- Enable / disable collection of CronJobs. + cronjobs: true + # clusterAgent.collection.kubernetesResources.jobs -- Enable / disable collection of Jobs. + jobs: true + # clusterAgent.collection.kubernetesResources.resourcequotas -- Enable / disable collection of ResourceQuotas. + resourcequotas: true + + # clusterAgent.config -- + config: + events: + # clusterAgent.config.events.categories -- Custom mapping from Kubernetes event reason to StackState event category. Categories allowed: Alerts, Activities, Changes, Others + categories: {} + topology: + # clusterAgent.config.topology.collectionInterval -- Interval for running topology collection, in seconds + collectionInterval: 90 + configMap: + # clusterAgent.config.configMap.maxDataSize -- Maximum amount of characters for the data property of a ConfigMap collected by the kubernetes topology check + maxDataSize: + # clusterAgent.config.override -- A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap + override: [] + + service: + # clusterAgent.service.port -- Change the Cluster Agent service port + port: 5005 + # clusterAgent.service.targetPort -- Change the Cluster Agent service targetPort + targetPort: 5005 + + # clusterAgent.enabled -- Enable / disable the cluster agent. + enabled: true + + # clusterAgent.skipSslValidation -- If true, ignores the server certificate being signed by an unknown authority. + skipSslValidation: false + + image: + # clusterAgent.image.repository -- Base container image repository. + repository: stackstate/stackstate-k8s-cluster-agent + # clusterAgent.image.tag -- Default container image tag. + tag: "c4caacef" + # clusterAgent.image.pullPolicy -- Default container image pull policy. + pullPolicy: IfNotPresent + + livenessProbe: + # clusterAgent.livenessProbe.enabled -- Enable use of livenessProbe check. + enabled: true + # clusterAgent.livenessProbe.failureThreshold -- `failureThreshold` for the liveness probe. + failureThreshold: 3 + # clusterAgent.livenessProbe.initialDelaySeconds -- `initialDelaySeconds` for the liveness probe. + initialDelaySeconds: 15 + # clusterAgent.livenessProbe.periodSeconds -- `periodSeconds` for the liveness probe. + periodSeconds: 15 + # clusterAgent.livenessProbe.successThreshold -- `successThreshold` for the liveness probe. + successThreshold: 1 + # clusterAgent.livenessProbe.timeoutSeconds -- `timeoutSeconds` for the liveness probe. + timeoutSeconds: 5 + + # clusterAgent.logLevel -- Logging level for stackstate-k8s-agent processes. + logLevel: INFO + + # clusterAgent.priorityClassName -- Priority class for stackstate-k8s-agent pods. + priorityClassName: "" + + readinessProbe: + # clusterAgent.readinessProbe.enabled -- Enable use of readinessProbe check. + enabled: true + # clusterAgent.readinessProbe.failureThreshold -- `failureThreshold` for the readiness probe. + failureThreshold: 3 + # clusterAgent.readinessProbe.initialDelaySeconds -- `initialDelaySeconds` for the readiness probe. + initialDelaySeconds: 15 + # clusterAgent.readinessProbe.periodSeconds -- `periodSeconds` for the readiness probe. + periodSeconds: 15 + # clusterAgent.readinessProbe.successThreshold -- `successThreshold` for the readiness probe. + successThreshold: 1 + # clusterAgent.readinessProbe.timeoutSeconds -- `timeoutSeconds` for the readiness probe. + timeoutSeconds: 5 + + # clusterAgent.replicaCount -- Number of replicas of the cluster agent to deploy. + replicaCount: 1 + + serviceaccount: + # clusterAgent.serviceaccount.annotations -- Annotations for the service account for the cluster agent pods + annotations: {} + + # clusterAgent.strategy -- The strategy for the Deployment object. + strategy: + type: RollingUpdate + # rollingUpdate: + # maxUnavailable: 1 + + resources: + limits: + # clusterAgent.resources.limits.cpu -- CPU resource limits. + cpu: "400m" + # clusterAgent.resources.limits.memory -- Memory resource limits. + memory: "800Mi" + requests: + # clusterAgent.resources.requests.cpu -- CPU resource requests. + cpu: "70m" + # clusterAgent.resources.requests.memory -- Memory resource requests. + memory: "512Mi" + + # clusterAgent.nodeSelector -- Node labels for pod assignment. + nodeSelector: {} + + # clusterAgent.tolerations -- Toleration labels for pod assignment. + tolerations: [] + + # clusterAgent.affinity -- Affinity settings for pod assignment. + affinity: {} + +openShiftLogging: + # openShiftLogging.installSecret -- Install a secret for logging on openshift + installSecret: false + +logsAgent: + # logsAgent.enabled -- Enable / disable k8s pod log collection + enabled: true + + # logsAgent.skipSslValidation -- If true, ignores the server certificate being signed by an unknown authority. + skipSslValidation: false + + # logsAgent.priorityClassName -- Priority class for logsAgent pods. + priorityClassName: "" + + image: + # logsAgent.image.repository -- Base container image repository. + repository: stackstate/promtail + # logsAgent.image.tag -- Default container image tag. + tag: 2.9.8-5b179aee + # logsAgent.image.pullPolicy -- Default container image pull policy. + pullPolicy: IfNotPresent + + resources: + limits: + # logsAgent.resources.limits.cpu -- CPU resource limits. + cpu: "1300m" + # logsAgent.resources.limits.memory -- Memory resource limits. + memory: "192Mi" + requests: + # logsAgent.resources.requests.cpu -- CPU resource requests. + cpu: "20m" + # logsAgent.resources.requests.memory -- Memory resource requests. + memory: "100Mi" + + # logsAgent.updateStrategy -- The update strategy for the DaemonSet object. + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 100 + + # logsAgent.nodeSelector -- Node labels for pod assignment. + nodeSelector: {} + + # logsAgent.tolerations -- Toleration labels for pod assignment. + tolerations: [] + + # logsAgent.affinity -- Affinity settings for pod assignment. + affinity: {} + + serviceaccount: + # logsAgent.serviceaccount.annotations -- Annotations for the service account for the daemonset pods + annotations: {} + +checksAgent: + # checksAgent.enabled -- Enable / disable runnning cluster checks in a separately deployed pod + enabled: true + scc: + # checksAgent.scc.enabled -- Enable / disable the installation of the SecurityContextConfiguration needed for installation on OpenShift + enabled: false + apm: + # checksAgent.apm.enabled -- Enable / disable the agent APM module. + enabled: true + networkTracing: + # checksAgent.networkTracing.enabled -- Enable / disable the agent network tracing module. + enabled: true + processAgent: + # checksAgent.processAgent.enabled -- Enable / disable the agent process agent module. + enabled: true + # checksAgent.skipSslValidation -- Set to true if self signed certificates are used. + skipSslValidation: false + + # nodeAgent.checksTagCardinality -- low, orchestrator or high. Orchestrator level adds pod_name, high adds display_container_name + checksTagCardinality: orchestrator + + # checksAgent.config -- + config: + # checksAgent.config.override -- A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap + override: [] + + image: + # checksAgent.image.repository -- Base container image repository. + repository: stackstate/stackstate-k8s-agent + # checksAgent.image.tag -- Default container image tag. + tag: "c4caacef" + # checksAgent.image.pullPolicy -- Default container image pull policy. + pullPolicy: IfNotPresent + + livenessProbe: + # checksAgent.livenessProbe.enabled -- Enable use of livenessProbe check. + enabled: true + # checksAgent.livenessProbe.failureThreshold -- `failureThreshold` for the liveness probe. + failureThreshold: 3 + # checksAgent.livenessProbe.initialDelaySeconds -- `initialDelaySeconds` for the liveness probe. + initialDelaySeconds: 15 + # checksAgent.livenessProbe.periodSeconds -- `periodSeconds` for the liveness probe. + periodSeconds: 15 + # checksAgent.livenessProbe.successThreshold -- `successThreshold` for the liveness probe. + successThreshold: 1 + # checksAgent.livenessProbe.timeoutSeconds -- `timeoutSeconds` for the liveness probe. + timeoutSeconds: 5 + + # checksAgent.logLevel -- Logging level for clusterchecks agent processes. + logLevel: INFO + + # checksAgent.priorityClassName -- Priority class for clusterchecks agent pods. + priorityClassName: "" + + readinessProbe: + # checksAgent.readinessProbe.enabled -- Enable use of readinessProbe check. + enabled: true + # checksAgent.readinessProbe.failureThreshold -- `failureThreshold` for the readiness probe. + failureThreshold: 3 + # checksAgent.readinessProbe.initialDelaySeconds -- `initialDelaySeconds` for the readiness probe. + initialDelaySeconds: 15 + # checksAgent.readinessProbe.periodSeconds -- `periodSeconds` for the readiness probe. + periodSeconds: 15 + # checksAgent.readinessProbe.successThreshold -- `successThreshold` for the readiness probe. + successThreshold: 1 + # checksAgent.readinessProbe.timeoutSeconds -- `timeoutSeconds` for the readiness probe. + timeoutSeconds: 5 + + # checksAgent.replicas -- Number of clusterchecks agent pods to schedule + replicas: 1 + + resources: + limits: + # checksAgent.resources.limits.cpu -- CPU resource limits. + cpu: "400m" + # checksAgent.resources.limits.memory -- Memory resource limits. + memory: "600Mi" + requests: + # checksAgent.resources.requests.cpu -- CPU resource requests. + cpu: "20m" + # checksAgent.resources.requests.memory -- Memory resource requests. + memory: "512Mi" + + serviceaccount: + # checksAgent.serviceaccount.annotations -- Annotations for the service account for the cluster checks pods + annotations: {} + + # checksAgent.strategy -- The strategy for the Deployment object. + strategy: + type: RollingUpdate + # rollingUpdate: + # maxUnavailable: 1 + + # checksAgent.nodeSelector -- Node labels for pod assignment. + nodeSelector: {} + + # checksAgent.tolerations -- Toleration labels for pod assignment. + tolerations: [] + + # checksAgent.affinity -- Affinity settings for pod assignment. + affinity: {} + +################################## +# http-header-injector variables # +################################## + +httpHeaderInjectorWebhook: + # httpHeaderInjectorWebhook.enabled -- Enable the webhook for injection http header injection sidecar proxy + enabled: false + +######################## +# StackState variables # +######################## + +stackstate: + # stackstate.manageOwnSecrets -- Set to true if you don't want this helm chart to create secrets for you. + manageOwnSecrets: false + # stackstate.customSecretName -- Name of the secret containing the receiver API key. + customSecretName: "" + # stackstate.customApiKeySecretKey -- Key in the secret containing the receiver API key. + customApiKeySecretKey: "sts-api-key" + # stackstate.customClusterAuthTokenSecretKey -- Key in the secret containing the cluster auth token. + customClusterAuthTokenSecretKey: "sts-cluster-auth-token" + # stackstate.apiKey -- (string) **PROVIDE YOUR API KEY HERE** API key to be used by the StackState agent. + apiKey: + cluster: + # stackstate.cluster.name -- (string) **PROVIDE KUBERNETES CLUSTER NAME HERE** Name of the Kubernetes cluster where the agent will be installed. + name: + # stackstate.cluster.authToken -- Provide a token to enable secure communication between the agent and the cluster agent. + authToken: "" + # stackstate.url -- (string) **PROVIDE STACKSTATE URL HERE** URL of the StackState installation to receive data from the agent. + url: diff --git a/index.yaml b/index.yaml index d83774652e..019cd5db6e 100644 --- a/index.yaml +++ b/index.yaml @@ -37579,6 +37579,35 @@ entries: - assets/speedscale/speedscale-operator-1.3.10.tgz version: 1.3.10 stackstate-k8s-agent: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: StackState Agent + catalog.cattle.io/kube-version: '>=1.19.0-0' + catalog.cattle.io/release-name: stackstate-k8s-agent + apiVersion: v2 + appVersion: 3.0.0 + created: "2024-09-03T00:50:19.243556428Z" + dependencies: + - alias: httpHeaderInjectorWebhook + name: http-header-injector + repository: file://./charts/http-header-injector + version: 0.0.11 + description: Helm chart for the StackState Agent. + digest: 5756b15ec4111ccfa0c0bb595453cfe888aed2a2a268942f0d32e71db9fb3461 + home: https://github.com/StackVista/stackstate-agent + icon: file://assets/icons/stackstate-k8s-agent.svg + keywords: + - monitoring + - observability + - stackstate + kubeVersion: '>=1.19.0-0' + maintainers: + - email: ops@stackstate.com + name: Stackstate + name: stackstate-k8s-agent + urls: + - assets/stackstate/stackstate-k8s-agent-1.0.96.tgz + version: 1.0.96 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: StackState Agent @@ -41313,4 +41342,4 @@ entries: urls: - assets/netfoundry/ziti-host-1.5.1.tgz version: 1.5.1 -generated: "2024-08-31T00:50:26.097603637Z" +generated: "2024-09-03T00:50:14.380046656Z"