From eb121e3e171aba93acc7ffbd2f2c208f78806a95 Mon Sep 17 00:00:00 2001 From: cooldragontattoo Date: Wed, 4 Dec 2024 15:16:32 -0700 Subject: [PATCH 01/29] add helm chart for cfgov --- helm/.helmignore | 23 ++++ helm/Chart.lock | 6 ++ helm/Chart.yaml | 30 ++++++ helm/charts/postgresql-16.2.3.tgz | Bin 0 -> 79787 bytes helm/templates/NOTES.txt | 22 ++++ helm/templates/_helpers.tpl | 62 +++++++++++ helm/templates/deployment.yaml | 83 +++++++++++++++ helm/templates/hpa.yaml | 32 ++++++ helm/templates/ingress.yaml | 43 ++++++++ helm/templates/service.yaml | 15 +++ helm/templates/serviceaccount.yaml | 13 +++ helm/templates/tests/test-connection.yaml | 15 +++ helm/values.yaml | 123 ++++++++++++++++++++++ 13 files changed, 467 insertions(+) create mode 100644 helm/.helmignore create mode 100644 helm/Chart.lock create mode 100644 helm/Chart.yaml create mode 100644 helm/charts/postgresql-16.2.3.tgz create mode 100644 helm/templates/NOTES.txt create mode 100644 helm/templates/_helpers.tpl create mode 100644 helm/templates/deployment.yaml create mode 100644 helm/templates/hpa.yaml create mode 100644 helm/templates/ingress.yaml create mode 100644 helm/templates/service.yaml create mode 100644 helm/templates/serviceaccount.yaml create mode 100644 helm/templates/tests/test-connection.yaml create mode 100644 helm/values.yaml diff --git a/helm/.helmignore b/helm/.helmignore new file mode 100644 index 00000000000..0e8a0eb36f4 --- /dev/null +++ b/helm/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/Chart.lock b/helm/Chart.lock new file mode 100644 index 00000000000..675c4db4dcd --- /dev/null +++ b/helm/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: postgresql + repository: https://charts.bitnami.com/bitnami + version: 16.2.3 +digest: sha256:974accf85921cc0b13322a8a2ec90b686c19cbff40fd1d26ea6178025e9121b0 +generated: "2024-12-04T15:11:03.917666-07:00" diff --git a/helm/Chart.yaml b/helm/Chart.yaml new file mode 100644 index 00000000000..137ba2682b0 --- /dev/null +++ b/helm/Chart.yaml @@ -0,0 +1,30 @@ +apiVersion: v2 +name: cfgov +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" + + +dependencies: + - name: postgresql + version: 16.2.3 + repository: https://charts.bitnami.com/bitnami \ No newline at end of file diff --git a/helm/charts/postgresql-16.2.3.tgz b/helm/charts/postgresql-16.2.3.tgz new file mode 100644 index 0000000000000000000000000000000000000000..2fce2524a5143ce4b0d6eab00e485875ef2be771 GIT binary patch literal 79787 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

B_ArsApf zoHdKgdmYEjIXy06`D3lF|8QB=b0te(Jf4q&@q-h~+=ArX))175?j)joJ*Q)Nebz9~ zFL5TO?7Pxb!(4t;Of=cgu6Fv@W$4fCwFU}!8S}on_t#1Uuft&amQ9F;n;RPLTG+be zz^SnRmbIp7;H-2~lC50&kR;Q@%FjnMJ(jdH6dRL7=P`HUjO|s$#z|VQ78Qpq?rdQ9 zYUc1#rtrj1Rb(n9(%Q)o&Fr~i?^8Toh1|uAvk;acjwaoaRob@|!>+OD8w8=M4le3* zq=VS}7y(O-6Bkm~m<*Wr(~ym|#+lP6uGckM{vC4VZMwJN|x64g%?um!yv?D>S zFo>BmaTl{=>)e?I;j`H(OXU8`Idegqk>pqMLD-BMR5W9#d8&n$a14$pR>Xyc9?ElK z1&JHSU)LA>g8p*-`<`dJGbPc82UI4 ztr>+x9HOnx=#-5g{?LIJaLE}TzKC#`)FAkKnmYc8&X1d^#&9;!aD@McKUWj_~yE;N=fNHN!UF7iu#pz???j*+3|I;#{d%NIwTwUEo8D6 za+$bSgUzTQhoKsm%>w;^Vy!iXEOrS@T))MTS&e%yxV62sB>An-6}TDZ{`}MCS^L9# z#4-7|12eo6J&v1G^at8AlB4I!eY896_Tm1%)o!;tM+Y7F7asQSUZ=BXb@q>TcRL4r zyGMIgd$+USIsB8=u5p~&X90&5e`*7aoxE~k5X5=kr9oM>0=c>emfz0zTfJcZ9J=?@ z*!mC#_5?A7AFRGVZdqN=vxe{?vW5?8CxF`(Ot#yzZde z`*hmeZMC<)-$5&Si}F$D*VHHxj;C&nIM^a|AjNJH;RajAB$bOOTQuAB7Oz;9FsHN- zCASzQC);{xAe!4_sTIl&@z+*TCKH<`Pd_2w;1JB8*x@AIX^Dx1(`yb;E1ObS*kkQ8 zo^H?Qt%t>}6Z%NYjaqK7lVmJD#)i`^Q90b=q?zuzH*u=xaeV|hr5)CwMd{Lr$td2mZ_j^7z*!~1*>RH89u5zMv6R?kBO;Dr6b z7Hm1`-^bPkn!PQW5%9@IE!k+zK^kk4`p>aOsAuPH;f()V)aGTHHp?~qUqaUou z1)&ZvaeJiO02Q`ivj~62w)X)4I`()<+eaV=AwnT3iSSFCYr)2nz<3eFa0K?;WxywP ze$Iy=_mcXYISZI9eksIMq6dB5V|Qi&7bfV6Rk12&1r^)2Z95g)wr$(CZQEwWcJe%v z_nn?zJ-vG751e&Ao^$VO-Nfp=-c$omxERxvke3Ktu%Hlkj^yDjdj?+5=M-L);stb*`$UGF%$1k}*S z=%WC!aUiB+kQF%x+)jGvOd$?+0U3uF4Hb06Gw>r+3;}oKY7@AZQb<4=*m7mU@kgkB za;BtwT~rU(S{H{A0qoYF;aq?Yk#V}!sGynLDoT`K6z);=UTm-8mkgAeE*CYr95wF# zje-&L0uT^>G=W0S|MtGCYxa^ya|7J$%#H@M#+dQE>(yVAQb1cQWYKdPOY*3CrD*fmgI$NH}N*+b-g+iI!h0$5lcxe~7Z6e+P zG3widzkf~C*4B4%3QdDjp4>^;bS)3HcXxmNg*OnB?6|vP5g;+qu?ax5L=mUy5A5g? z(An7=8;^FqA>w94D0x75U$ZHzh${78X8!_>p{emj1o2p4O+vR*sKSf864%17B zvXpFENKJ7&WXBG@=8j>PW>#pemS$F!VVUhdrpObfp=%30P;|G@?Enc+KrL0z2CH4S zL041g_;nw9v75g>K*X!xfYOO(uz;b6Ve**Dpa#pctpWVnRehKNZInU%t8z!29qN?I zoihL*9R9=yd?4UI>Iu+?o(ha|UVIkUw*dVpGKt3Ddc%d6!Uw&DuEg`ULg0-<4I1k_3lA8PIcoZS{81&LG3d;Zlz%HM&zV=(y?OiSRFvXN^FWQ zHvMQ#(3e^~Yt|pBNf(8{X-D>!9B)PrM?*fhI7@^R8+MKoP+7F3WMnCpwNFqLOm`;W zgASCBuQ>M_$g&EpSd7RhS92yd6dvL>8B0%!{HKu&>sH;A4Wcgd50Wx+e;mborzbr83greT9o2_~@R}Zwb7Cb43N zt}f-N8`d`XV6U;cSav#5a|&4v)dnH%S)-S%Cj@WO`N3q~fNRc5K=9|7T$T^{BKA(K zSrP|?qGO=RA1xiKW1uW_4|`8}%+4-vx?0RthTP|fD+XL0btRE$r2oayJH$$`zvAP` zO4z_@>5`&54|}=E`me&mg>%ZeJ5{8`w!G2~RI*doQ4^UNI&~Ij2ZI-^4BB+Qb}K07 zI3c|Bq{_#whLGWt2H3DXje?%nW%TK7i;s9 zIw`uOA-GU@z^{Il0kFmktn)@+tf?&e{;J{v{CLp@FS9aaBMI%kYqjLI@uJS;ntDlr z=!XnSydCz^`eZ0h+RIL~0VaWfO3~A!+Ex|Vj?7+Nc;byeZ15(o3g(eqk;dqi63@uE zO?xo4k^D1;Eo$|Qrk)iG;T=~d&ySM06js3BdCY5)f7XO3d$hpj(X5%&gy_gr*G$BJ zkDfnqmJQ9Vk`f6?tRF4q7KOZNakpHp+S4q$U@ zYiBsHA?5UH3wV0{g*r--ZJ>lo+qY4IKDm``X3!%+MHRvR-BJ(RO8~{XfH7L$AVXZ{ z06-A#mF9*5uV#8sRnrO)uo8Li&;hM#fH%_1jspIA-kooYwJvq+8&xlZvF}Y6(TS5Y zKZmW1yI-Ha8kP|bR&yq?r$I(X`s$t6hyC$(LmC76(*#v;KlYyD$=4!IhxXj{{pbRi z-R&Y40SuGGyRv=!o(o&f0e20|bh|UEdRzvVj_GSFh}&*Nd3^ECIZ*V~mrUh5s>NJX zGYzxGgwEFtX9ygnBpqZAIEuJ<{EQ+Qa!}N=DGmiG3#dy8&yyrH{c)Wy_ z#e=_<9oYIhgibM6KhFgvMhFcR9oR1HW%ySrsNvy20f6QjlgHmZ&i^l4k;C=Ap3njcam3ImOwgkPq4 zHb=C#w(Z4VG}IP0)RcLj12Z?Cj--w5w}srmetb`vwSOxP;L3Zz<(RZ}4 z4s6Xa;{oI*fcQfamYj^>l91?iD8HN47e?+zZpSmhN|aH@H@KtgS|#UcG%9HU$i~=v zTDX@2_BLv@X(``;!^g{KW$3=+CT=Hk{=nJ!_)Fj}2e*aoV{bF}W7@jooa|kIJrBB= zJiVy!LicximFzsv!}r^=h^=|B4FbMck1rQN>}wLP=g0Ar{CB!oCh2tQSTncsva1F5 zlcb0s)Ev4lEVl&77mJuVHXnhVVuur{(I#M7%FNIk=q(B^qy4cXCVUe!8yG&ASy!77 zQo`C4v|_su7YUI4qsdejE^>%#lOaaR##z2ES|m_+X*6eEbXPRJHxH95$QCodD`&&a z6JkEx{C&tbL>1{UtD*1sFjQ*$1Ojo?+r~SH`x%-=JpkO56#46_QKW#s0A`2+1nSoQ zQsbqJnRecaY)LHEnY7~TimmdDGHXvZ=eI=Xr?Vw&?VL{n;8f(P3jR-ZjlR87@gR!E2#kmc~0$Dc1TwTUv7Kws%4tm zhRQSmFT@=kz4P6Ihubly@ZYX>hwc2K<0WHte+*elpdhq_4hK7n!eJ@lj%C7U!4Q|+ zP#_f-gh-F_4OM3fv~18?Vk7~j{Nn8Pz6kK(uwKLy_v?zglM9u#-OzZVkD%ZDpi z2bKdI;9mujnza^!fCO&W2E$t^Lhaq~%V^bg)YoaSPmBOr=PqLlWA$e3S%6|aEjo`C zUk3-LG}4tkYqKKQBkm9Ilj{^n4G&qC|*Fi`OQk=2OJVFjn-JT9R-!dNfdd)+J^tS{S^(;{=lKG>Cg|<7o5MKdVp?tr7m_`lB2I;bO%_GD z8y(p*l4Qk_v``1;`Qv8Dw15dzT;m!xvt?4(cv6O&u+-9^3W_a`+F2jLr-Oy5$7wZ( zM`}yrs5?N&+bAw6N;U|_#}B3sspBgSsQY!{`M>XR= z5$bu6G=n4GFmx0;-X1<4Ka=q#l;9v}HZfO4`i+U;^|*Tl{2RaLBTg+NC=a;fdOvI( zae)lzKfaX=$QQhc^FUoBy`CwB7BGx5B>dC;-tsVn=5@gCBQ$*fRt$_G#`z+Pp%|aj z;~<#5HNnjuw=<^u$xvE57v_DIzyWtT4z&per*7V4MZpz`Te*T;tx-ke%SWnyR1A10etjdx#IB;E`Q7@ z+0fh%9tbY_;Jhv?%aZsNd6QSZyKpx|(|I}!BNF`3Sq#IVKGCXYRx&V2c&8ErrR_4; zdPj{?zAOju9h=@Y5j%4)Y*~A_at%chXeeB;tWI zy#=DXp<3Ryi~Z<_ifW0~V?^@pbD0_ow~t|Clhqul=G~8!Qup9;bu|}gtwQztVYU^N zs4|2)w-Z0o*Sv$sE4EowOL2=IE_p3F4;p?)v+pFIf5JON`jTT60HxF)@6KX_ItnfDLQ;9(O!2sRwXhJyIU8#J$bRxk_>pxV3d+LB-6Y4WN6TnlU>#zQnJ9l& zlE>c>7eOhB$itWo+OE3Fqst*WM1X(uz^MeI-g+)6tDgQ$GN=01NMBbgZ|f3CJ(aq( zM=nqf#fovLyJW5p${cM#>=*9AMzhvRtsd)(oCv@ z460)%;2zkZdz}S+QM22w=V`UKA;nCqowL(SyoR4>i?bX^uny|GKnB%^F%zKKnGS>z z5rGF>THP;-CX1_i)D?1)G%aF}3W(46n&|_$sd8LvvTV-V70&0J#>lqZCSZJfJ#reg zDP)?S>!0EQoF;rxDUI;oV}{A#o~!r@a8fAXbjPbJV|w_pKiw^SUC!Qk#w)Tc{vk~r z7h-v&9N%jf%@ONuzwSM(o=Qxh{T`myDmmCl*}d?qee^Rhbe_5eMY+f3t>`~0VMv6%ZtkT|H$hR!7eqQ>HWVmTMCvI1r=%t- zR4_{nhiN75tJBrky-8KHqNkL?2ft8`3kJm3oVWgq1XsAabYJJ5m-QuY!KWSG5yAub zIp>Y(Sfztf5LXD(%!w*l52X$$5%W~?CP^7(Z3{>YcFO2aTa@WvC}MUac)ZeF08zBT(vDS)sTX0YbRJ&hR8);Bt`b?3FCg*>md+nJzf=YA&# zuaf=vyHO6U@^5cFB=Mo?&x^yjiS=CNiRr`sf)GhV=sd?m0GdcNkW9Z0N@T*Zhy%r`D#L ziW;@U|^a)!ui zfObcg*2?)(!skQo@e!|Q#3$coD3rtJ&6n(d#bK2?AT{+G$5uL+tt1{dmCm_FB<9rl zo$R=cm^8#oN;NfKM?<&Er`KAZ2*zIE?m%9zvT{yTav-fu<_NT+N+C-NK2+fk4?gX6 zLJhHRy>}4ZHhh0O*@h`pM8-{f;F3xJctpQmL7(rs{WCY0A_9^xJw6ug*MQOrLD>jV zdFC7ZQ7r$eXhj1?EJOEkPj)H#MdzGgS!Ko2)`PNdA!Lf5-!HyoyEwV0w8eW*Hq*`t z9Wm}4Hl=>L8!ji^v<$7igBhW9=H95NHjdG($r`T4;L(G(TR{Kj=2_g@i}r*f3-NcU z3_bGim1I~*f^wr`?VlXT=o`O=5^91)i^iLCJ43y-9b0m$bK<}gBlW*<9Y6kfI z;4B~}aSbnVO(G~}opilscOONtEpESV=Vk3MciiuGzAid-USRH4&HktBi=C|;FL0Y{ zYsgn?@`3Tr*RO7ATrU#zbBZP28~Ts{JQ0-*7SnN$fdC`Xvs8Oy4LzH2)hjku;LU~Z zx_ert?BoDnZi#92rs4Iph!-gOw^2>aXnW#xdSc@_)shdUGe)##sqn~#LMANv2`R$c zO9qtC)#2mEBhA?DVO$s}c0zwS$J zX3XI{3^ixiM3(IcyIaEJE1K>dZBf3^xrk6yya>eO0OQKhgpbA%Fv5`%3d4ksB&a6N zYln2%9NOBeM3=eR4isAALsTML;2-a|D4aBdtd7CdbAHSqg?%c_PfG~y-`K+!Rf0d* zllUJ7(vAMV1~LSZYv*dfI~u{wyy;~V3SOm*6AT)TqO(Rxw%(ltzaYx2zgxe6*-Uxq z&5BV_WY{I8Sr3jzEo@rgw~s3~0)~$^>1$SH*0@%TSZenp@XL0;4fSDNTcjW+kep^ zIxqAPjcK<~AS4-M^)E~Y$Ep&MZA)alKxWAC-A@hhJUwc!zO1YdHK!3H7Ww@lOd zOwk**+Kjc6slo8L9b*T^IObyX&9I68DCO-(WPfn6{~KnPL9q^bETOOsEt3k%JOv5} zvunkry@CD1l!n!{3)0Vb0<}HUme}|Md2#ags)X3vNtAwjvRs#=;zzfLHmu-eq&e+$SbY(>oK{7Ni}r4$zGExbcF_Rt{Xcw{o3-}*P6o^ zVzXoXXIKuquNsQRz?w0`dpOcoqg?OnL5YipiFHB^`?M^>WUX#DY z^uUxzzlkSW9D$P1og6W>f#D`aXi_xNG~p6NYrvpbMAT9r4V(kTWo1*~Fg0SSDxige75A=oO-e zY%QxTe~DoS5DDg)t)d@6j4%k?Kz&wq5JG}Zsqkf9!9&OeG)gvqn^Bmf=2p{`M3pnV>&X`}Hq7`!w$q!r%@g z5fOZq6LhME1i|&<>@%$E(ZH3BucE**#*SHdd86&`518#pq&)UAXF^f=# zVCJA8K)>rmCAu~mEUo5z3lUdu_8(yfdI+Sulauk4be0&YtSNfuVQc+*Oo~FVp76=9 zIF&brBZ&;>1Wkysr=K17_#&In*yP&nf8kASa?nM4U!*%wXV&4IR}I7d{4j#`i~7Xe z=D-k_0?jl}P<`yl`lFJEy=ZTIK?X+sPj}PLG&}kGPF`vvHQlM1`0&*<;n@D8?J#H_ zR#m%Y_{_CdqGkA!7fsD?RSPJz`>}~ITB8sOTPO7i=1(yuaY^&Ew&(8H+y7=-re922 z{fed8iegREibDCU>C_qGN>78-FLkC}gFX4GMTgPi@V`c{mVQ>uJu`;6e2O*4+~xaz zXKXjSSy?`901A80pFiQ(FyEmOGN9Hiw$`Cx;QKYDUZ;oJb+$04PFph2i|OHM#ncEw zOAC9mw|~-xskKKip)!xSAS|<+mx%yO<%!$uj74yX<3GA|{E(U) z(-b+e=3M^mRMxG4a=V0|UdYvuZw@s!dNcit5#`fEkhAeQ&&{@&9}kfJ_m~~lCVK6a ziRv_vGo_siBIaT)DO}c4ty!mn1SBQ3HA4hJe&TYvZqSRofr@*_8dU(e+vPlH$`kg* z!A8z4@Njj0zMVXJ**(2zPZ>M3(aoDNqOTU>whYn1GTGd2jQ^^6{)#VW=K`Pze=15} zS37pLO4Ca~Si*_d|u?Sle6TRATI~$qd(g`kM zbw7j&@tbZB-l8{cnq{{i;aH}r&JqA`o$OX_oNM1xG1*R2$vwD9Iqi?uWAo5vt)T0w zpiQa!P0OOcFF#3Q`wQ8*b(E;ptNrnDqgWj^YExJl{;Le;E;S_@ncxr^=XkxRX(ciX zaKnc5sSEQkN4zNLwy<+eMEtlLBS>cPBNcXo^@w58BnmFv)he~nLawU&Il&?b1=z!u^xkfy$CC@ zDDm;ULW{9duTr$7x6T&at;QLPe)oJ(24aZ&QRkgu%XidwYi`^XrmruUcx57hIiE?D zQO0$js_F*4lgq+)72(4FP@;??$$yrZw5cs$1uD4RQ9X5w7$lS^mFF$e1kXhNjnip^ zQ4#$-Kk;xY!CPami@#=enRqd+sG+BrO8{EYf3$JoK9|N7*QNNkO>JbK&c$I|@02Qm z$%^dZ%i%T0O|C!gWo*GzjGu&pxH^|08%M{)gGfX!?4QYfqfTLqe_QQ(l7&z2tZMdm{W&N{sfzdMC(s3GJ3++peVI8C9G$I`U)L8;LoTf69;C>1>Texd`G9 zcrI7t*kZy=;aU~CmwGxQzc-;woMB6u3VLKzovgVRp}x^IBr|}=Rb>B%q@H$2BoZuM zo~i45d*-B$rLG@tca5l6bvjeJS8p)W{Ud9KQZdaT8ue|*Il{T%?5wubSFeQRYepvn z!LIepxnKE^iZy_f*@Hh93z3eP14a(ir&56?3T@Ge5y`Z~jt!iHni@=U93IQewD3(61-q9g%jIB&JBd<%{ z+{fA69M0*!HA)HXlvqJ zPyVV>Phk3iD&?-k4fhLExKFZu*~Fh?$X7uf6Ecsfg)E9Ex9UL`pT^@UJ&{2O`f-YOH+K7j#twtz9QS=9$@@s!{*x$O&P1ku-nr6Y`$;aHF5G_b(|R|dzz;v*aODvJ9( z6It7VYnTZ>_Sxa#L>~DGcx+Y2h?9r1Wl`XTIGYW;TBGnfReE6YEevX#Ll*06Wx4ag zQdsh7!wA#M{9U|D(Oxt@uw3?p;#mXC6^&4(aTFV}@FX^eJq!$)K52r*q8X?#jdP9^o+RWm=ctX45%oo7xSntIzV1IlqZ#&{%;Xatrzaee z1#Bf??kI+PpGM`5<~&eB;}dJhX8*G>sp{&mnQ>_>YG@NX;a9~Z zc?_~cicvXnOI3l%S!bEG40|e0twujH(Wo@K6c&d)J=u_`coD@e2tdLfl2Dk4HeBtU zHO85TPln4QG=ZH*Y_@`?{>-&#RGVne#feM?b;{`f_EoC286}srkLcVOY%=T3>*%pHG4l{4o5Hb_D9Y$~ zFo#F=1|h^lGr*$#%Qm=KllMA8zR~Iv{afUY=uv))++V)O%R$8ZzqA--)E_v>d(jgA z#e0!gg#C8+6593(Ic6zGSbBHf51JJZ4?F(XuAEEsPGpIGU!Km`IQM*m_kR$%8{Yqm z$aQ^J(X~7=MYBf3Xmj#p>gd9MmbI-3^_E~RLcqH`H#Uss2Dl_pFag;jy0C}~3CL~0 zN%~vKpW>zeYSLeJBaXNf&f%6|lkySTS^40!&X|;`{ODb|$X&k4pbD4w++}aR%DfF% zX@{lU)SFSE80|LxPf(>A=_huhoq(Kn6r^8rkpASB7B=OMhfnqmbM1NiGUXG0dE?6t|5eoZ$cLPf9IafRD2`QQlBxQ1 zQ&}{U;1aB_r??|@CZAc;72w`4+P8=g8c$FahF7gN{=6OvrY=hdsoh@sYj`64xg}zw z(!_=W<@c^)mH4RCyMdagSjs0Avl|aW84P6nm&HBC2bT{rk3J)?oh3y*%+DqOmln-|jqO z#vC36RoM)$Y&Jf|GmYS<<#EaSPlr;Crwc^E!)2#1aJ!v$Ro>rBs^M_U`vnlgR-L<| zRSi2KlXZ5jx7@kXcP{NFDW11A98Plo1b+2RrME?{*E?TN1<3#WD7s>D03K(x*9|AJ zqK`xM3!2N!7=d0fh0^0nDPa?3k+4P!W14O+(} z9i^mMfZbqhianYo`ax;STs!l`ban7LvsSu@6enJMPYRJW9+Jm0-=Ty(D_B#^XF88J z59?7y?81nPL&?d<+RbGuBQCnb%f*ft6yWRmb4je;_NYp1FU06qjZ^|8WcUJj{;4e$ zTg3@?2#s;uIN){0;Vv08kCjgmjXrv@JlFU<{_dt}-XQg(NYNC>6;%L*U$v%{Rz2K- zv$3Y55%!^C7DLG4v(DKa9@Jyf4{!`s9G87$w~@v3JRq_O$+oI^n!j$^4E^{}?cBb` z#dF%zb6e}}6ce+qZ1ipF+~io>@R|N6`c!Ha4!8CP4)@}M=|hj zQ_4VW>=k7U;Ej4T#tV+oxsk_gRJVg%cJEkXe5a6on8?8~)%xi{7Dn&m^vmHG0Tj(9 z)(>$hE$LlMb1pA$_+@2A7DTu_cv?KRAZOU`NZD>v0Nxhbxh87?!m?bvi~kDW{i#5S zpuMJpaxnWmqyK~PHO42>vF~XU8Otodo6$i!SjjUr=3`g23k4z&P9?F3r$C_$>pkzBQkvA+4qk0je@E-zE9k z-Q6*yz!w*;51hB&7_;H~UWCL3#ZYlsk0niEo|Qwkay4;J-RP!TLsdlr0b?%uA8`?? zthTVeKE&8dynl$p?ZkJjn> zpwa;j=$$<|Ru>^Z^{9wP^2II*BpN5ki4a$~+b`&7v`c0PpBV{|WTdemmsP*)rGudu zRU2{ln>yHw<&s_t!pDj829~i#SB(!Z2s~CEX&aI!Ek5|mWRUJ)OW0dZS$o2-8%7pjlSEd?&)Gh@H%tiWF+3JovOi!^gH69k z!sd-4k@|^qh;?rDNXL%{a|I06A~0HkP9sBT>rFw4q1SFdF&XOEX?hGM)#7oXQ;E`6 ziNumW3HBci7NTYZanpa`HRGUD&)@Elkr4gRF;}0@Cq0Aa{Rt`affSd>_1&3+dzqi zT#J6MD%TvW$OVjsXvfSSx+lA!aMIDeJi@KMFgALr)V1qnR1#UOmQ&N_sLq~*5^0(P zH(@9bol&KL`*RtXUD9Adu<#mkIFz%@g)Gy@s-gua!sO^+ub|tD-Z{E{Of5AMp|@~M zChQG2WMb;5Tyz1X;%CNS2^`m!$Tld={dsasuiV^5wW6YsC6=8ed<~9lM&FC|u?xm}0W&QEl`44bX8aM}!aR52>_51q;L}H^~Mk{IDhab zcAOcxRPMY_Vue!uxh5r6I3auOfr7Chh;BKtNmcRUim#m$_D}F4; z@bp3RxE#syg)qhHXwnLsl0<&%Wf2`M4gpjv=(-HO7qI_CpZXLPtlp4eQ`S}YjhbNF z>A=@+h|hHjpycNft4->HCxR@Mqb3Pc75x7x3{Oh#(xEa*an=2XNHH+c=_A5tvj{gs zQi8^3sFC+bg{DE}9g9QuI&Oqng7(1Ey2}cmk$}xZU7jGcsNx|()@C8_+sGxXC2*W1 z2#sQM>B({haQWh{?gO-rz6EKgE9nQ&1%d63VCB9`6-cL{_y%Xs4>=83IYJHQW-V$EePvC}_r)L2mw5hkS@IM;@r@Q9wLuiPxB=@_%d##kH?E0U Date: Wed, 4 Dec 2024 16:11:00 -0700 Subject: [PATCH 02/29] add configuration for db and pgadmin --- cfgov/cfgov/settings/base.py | 2 +- helm/Chart.lock | 7 +++++-- helm/Chart.yaml | 5 ++++- helm/charts/pgadmin4-1.33.3.tgz | Bin 0 -> 14763 bytes helm/templates/deployment.yaml | 14 ++------------ helm/values.yaml | 15 +++++++++++++++ 6 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 helm/charts/pgadmin4-1.33.3.tgz diff --git a/cfgov/cfgov/settings/base.py b/cfgov/cfgov/settings/base.py index aa3b3124c7e..5c32d34b4f7 100644 --- a/cfgov/cfgov/settings/base.py +++ b/cfgov/cfgov/settings/base.py @@ -221,7 +221,7 @@ # See https://github.com/jazzband/dj-database-url for URL formatting. DATABASES = { "default": dj_database_url.config( - default="postgres://cfpb:cfpb@localhost/cfgov" + default=os.getenv("DATABASE_URL", "postgres://cfpb:cfpb@localhost/cfgov") ), } diff --git a/helm/Chart.lock b/helm/Chart.lock index 675c4db4dcd..b0236c36702 100644 --- a/helm/Chart.lock +++ b/helm/Chart.lock @@ -2,5 +2,8 @@ dependencies: - name: postgresql repository: https://charts.bitnami.com/bitnami version: 16.2.3 -digest: sha256:974accf85921cc0b13322a8a2ec90b686c19cbff40fd1d26ea6178025e9121b0 -generated: "2024-12-04T15:11:03.917666-07:00" +- name: pgadmin4 + repository: https://helm.runix.net + version: 1.33.3 +digest: sha256:cddb1ff2c6977f93a32c08d0089bdff4dc00a80504dad4d728de5f027ce9df30 +generated: "2024-12-04T15:26:35.566385-07:00" diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 137ba2682b0..d748da66363 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -27,4 +27,7 @@ appVersion: "1.16.0" dependencies: - name: postgresql version: 16.2.3 - repository: https://charts.bitnami.com/bitnami \ No newline at end of file + repository: https://charts.bitnami.com/bitnami + - name: pgadmin4 + version: 1.33.3 + repository: https://helm.runix.net \ No newline at end of file diff --git a/helm/charts/pgadmin4-1.33.3.tgz b/helm/charts/pgadmin4-1.33.3.tgz new file mode 100644 index 0000000000000000000000000000000000000000..dc4e3ab388c2ba7d5790ed94b6434d900c0c0d92 GIT binary patch literal 14763 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 F0RTN2*DL@4 literal 0 HcmV?d00001 diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index de16772b4a6..f1ba9ba2519 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -39,18 +39,8 @@ spec: env: - name: SECRET_KEY value: abcdef - - name: PGDATABASE - value: cfgov - - name: PGUSER - value: cfpb - - name: PGPASSWORD - value: cfpb - - name: POSTGRES_USER - value: cfpb - - name: PGHOST - value: "{{ .Values.postgresql.postgresqlDatabase }}" - - name: PGPORT - value: "5432" + - name: DATABASE_URL + value: postgres://cfpb:cfpb@cfgov-postgresql/cfgov ports: - name: http containerPort: {{ .Values.service.port }} diff --git a/helm/values.yaml b/helm/values.yaml index 9748cee7032..b5ab3992d73 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -121,3 +121,18 @@ nodeSelector: {} tolerations: [] affinity: {} + +postgresql: + global: + postgresql: + auth: + database: cfgov + username: cfpb + password: cfpb + +pgadmin4: + env: + email: test@domain.com + password: test + + From 4d282e478ec499bea932b677fdbcd04ab5d4adbd Mon Sep 17 00:00:00 2001 From: Will Barton Date: Thu, 5 Dec 2024 12:07:33 -0500 Subject: [PATCH 03/29] Iterate to working --- Dockerfile | 3 ++- cfgov/cfgov/settings/base.py | 2 +- helm/templates/deployment.yaml | 2 +- helm/values.yaml | 14 +++++++------- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index c34b623afa7..0a9e25fb1dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -170,4 +170,5 @@ RUN chown -R ${USERNAME}:${USERNAME} ${APP_HOME} USER $USERNAME # Run Gunicorn -CMD gunicorn cfgov.wsgi:application -b :8000 +# CMD gunicorn --reload cfgov.wsgi:application -b :8000 +CMD python ./cfgov/manage.py runserver 0.0.0.0:8000 diff --git a/cfgov/cfgov/settings/base.py b/cfgov/cfgov/settings/base.py index 5c32d34b4f7..88168623393 100644 --- a/cfgov/cfgov/settings/base.py +++ b/cfgov/cfgov/settings/base.py @@ -221,7 +221,7 @@ # See https://github.com/jazzband/dj-database-url for URL formatting. DATABASES = { "default": dj_database_url.config( - default=os.getenv("DATABASE_URL", "postgres://cfpb:cfpb@localhost/cfgov") + default=os.getenv("DATABASE_URL", "postgres://cfpb:cfpb@localhost/cfgov") ), } diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index f1ba9ba2519..e06c1a948a4 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -40,7 +40,7 @@ spec: - name: SECRET_KEY value: abcdef - name: DATABASE_URL - value: postgres://cfpb:cfpb@cfgov-postgresql/cfgov + value: sqlite:////src/consumerfinance.gov/cfgov.db ports: - name: http containerPort: {{ .Values.service.port }} diff --git a/helm/values.yaml b/helm/values.yaml index b5ab3992d73..18987c38eac 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -54,7 +54,7 @@ service: # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types type: ClusterIP # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports - port: 80 + port: 8000 # This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ ingress: @@ -90,10 +90,10 @@ livenessProbe: httpGet: path: / port: http -readinessProbe: - httpGet: - path: / - port: http +# readinessProbe: +# httpGet: +# path: / +# port: http # This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ autoscaling: @@ -123,7 +123,7 @@ tolerations: [] affinity: {} postgresql: - global: + global: postgresql: auth: database: cfgov @@ -133,6 +133,6 @@ postgresql: pgadmin4: env: email: test@domain.com - password: test + password: test From 7c578b2f8953979b448a89ffc652f102c640c5f8 Mon Sep 17 00:00:00 2001 From: Will Barton Date: Thu, 5 Dec 2024 13:50:50 -0500 Subject: [PATCH 04/29] Fixes with postgres --- helm/templates/deployment.yaml | 2 +- helm/values.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index e06c1a948a4..f1ba9ba2519 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -40,7 +40,7 @@ spec: - name: SECRET_KEY value: abcdef - name: DATABASE_URL - value: sqlite:////src/consumerfinance.gov/cfgov.db + value: postgres://cfpb:cfpb@cfgov-postgresql/cfgov ports: - name: http containerPort: {{ .Values.service.port }} diff --git a/helm/values.yaml b/helm/values.yaml index 18987c38eac..ffe5147648a 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -86,10 +86,10 @@ resources: {} # memory: 128Mi # This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ -livenessProbe: - httpGet: - path: / - port: http +# livenessProbe: +# httpGet: +# path: / +# port: http # readinessProbe: # httpGet: # path: / From 4978dc70379745b0a4c02d3f7530b4722773d15e Mon Sep 17 00:00:00 2001 From: cooldragontattoo Date: Fri, 6 Dec 2024 08:34:49 -0700 Subject: [PATCH 05/29] update helm chart and scripts --- .dockerignore | 1 + Dockerfile | 5 +- helm/Chart.lock | 2 +- helm/Chart.yaml | 12 +--- helm/templates/_helpers.tpl | 2 +- helm/templates/deployment.yaml | 48 ++++++++------- helm/templates/tests/test-connection.yaml | 2 +- helm/values.yaml | 74 +++++++++++++++++------ refresh-data.sh | 11 ++-- 9 files changed, 95 insertions(+), 62 deletions(-) diff --git a/.dockerignore b/.dockerignore index 97d8388c98d..5cba5b78ee5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -21,6 +21,7 @@ !jest.config.js !package.json !refresh-data.sh +!test.sql.gz !yarn.lock # ...but DO ignore these others diff --git a/Dockerfile b/Dockerfile index 0a9e25fb1dc..fc5e84c8357 100644 --- a/Dockerfile +++ b/Dockerfile @@ -150,6 +150,7 @@ ENV ALLOWED_HOSTS '["*"]' # Copy the application code over COPY cfgov ./cfgov/ COPY static.in ./static.in/ +COPY . . # Copy our static build over from node-builder COPY --from=node-builder ${APP_HOME} ${APP_HOME} @@ -170,5 +171,5 @@ RUN chown -R ${USERNAME}:${USERNAME} ${APP_HOME} USER $USERNAME # Run Gunicorn -# CMD gunicorn --reload cfgov.wsgi:application -b :8000 -CMD python ./cfgov/manage.py runserver 0.0.0.0:8000 +CMD gunicorn --reload cfgov.wsgi:application -b :8000 +# CMD python ./cfgov/manage.py runserver 0.0.0.0:8000 diff --git a/helm/Chart.lock b/helm/Chart.lock index b0236c36702..895ea1faf49 100644 --- a/helm/Chart.lock +++ b/helm/Chart.lock @@ -6,4 +6,4 @@ dependencies: repository: https://helm.runix.net version: 1.33.3 digest: sha256:cddb1ff2c6977f93a32c08d0089bdff4dc00a80504dad4d728de5f027ce9df30 -generated: "2024-12-04T15:26:35.566385-07:00" +generated: "2024-12-06T05:48:28.869178-07:00" diff --git a/helm/Chart.yaml b/helm/Chart.yaml index d748da66363..1a8647bd2e7 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -1,15 +1,6 @@ apiVersion: v2 name: cfgov -description: A Helm chart for Kubernetes - -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. +description: A Helm chart for consumerfinance.gov type: application # This is the chart version. This version number should be incremented each time you make changes @@ -23,7 +14,6 @@ version: 0.1.0 # It is recommended to use it with quotes. appVersion: "1.16.0" - dependencies: - name: postgresql version: 16.2.3 diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl index 4e6d9f9ae75..b815b91e607 100644 --- a/helm/templates/_helpers.tpl +++ b/helm/templates/_helpers.tpl @@ -34,7 +34,7 @@ Create chart name and version as used by the chart label. Common labels */}} {{- define "cfgov.labels" -}} -helm.sh/chart: {{ include "cfgov.chart" . }} +cfgov.sh/chart: {{ include "cfgov.chart" . }} {{ include "cfgov.selectorLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index f1ba9ba2519..b5eb6d8746b 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -30,31 +30,37 @@ spec: serviceAccountName: {{ include "cfgov.serviceAccountName" . }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} - containers: - - name: {{ .Chart.Name }} - securityContext: - {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} + initContainers: + {{- range .Values.initContainers }} + - name: {{ .name }} + image: "{{ .image.repository }}:{{ .image.tag }}" + imagePullPolicy: {{ .image.pullPolicy }} env: - - name: SECRET_KEY - value: abcdef - - name: DATABASE_URL - value: postgres://cfpb:cfpb@cfgov-postgresql/cfgov + {{- range .env }} + - name: {{ .name }} + value: {{ .value | quote }} + {{- end }} + command: + {{- range .command }} + - {{ . }} + {{- end }} + {{- end }} + {{- range .Values.containers }} + containers: + - name: {{ .name }} + image: "{{ .image.repository }}:{{ .image.tag }}" + imagePullPolicy: {{ .image.pullPolicy }} ports: - name: http - containerPort: {{ .Values.service.port }} + containerPort: {{ .port }} protocol: TCP - livenessProbe: - {{- toYaml .Values.livenessProbe | nindent 12 }} - readinessProbe: - {{- toYaml .Values.readinessProbe | nindent 12 }} - resources: - {{- toYaml .Values.resources | nindent 12 }} - {{- with .Values.volumeMounts }} - volumeMounts: - {{- toYaml . | nindent 12 }} - {{- end }} + env: + {{- range .env }} + - name: {{ .name }} + value: {{ .value | quote }} + {{- end }} + readinessProbe: {{ toYaml .readinessProbe | nindent 12 }} + {{- end }} {{- with .Values.volumes }} volumes: {{- toYaml . | nindent 8 }} diff --git a/helm/templates/tests/test-connection.yaml b/helm/templates/tests/test-connection.yaml index 54b79849fea..0962c9f1233 100644 --- a/helm/templates/tests/test-connection.yaml +++ b/helm/templates/tests/test-connection.yaml @@ -5,7 +5,7 @@ metadata: labels: {{- include "cfgov.labels" . | nindent 4 }} annotations: - "helm.sh/hook": test + "cfgov.sh/hook": test spec: containers: - name: wget diff --git a/helm/values.yaml b/helm/values.yaml index ffe5147648a..f3e99e1bd4b 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -1,17 +1,55 @@ -# Default values for helm-cfgov. +# Default values for cfgov. # This is a YAML-formatted file. # Declare variables to be passed into your templates. # This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ replicaCount: 1 -# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ -image: - repository: cfgov - # This sets the pull policy for images. - pullPolicy: Never - # Overrides the image tag whose default is the chart appVersion. - tag: "latest" +initContainers: + - name: wait-for-db + image: + repository: busybox + tag: "latest" + command: + - 'sh' + - '-c' + - 'until nc -z cfgov-postgresql 5432; do echo waiting for database; sleep 2; done;' + - name: cfgov-migrations + image: + repository: cfgov + pullPolicy: Never + tag: "latest" + env: + - name: DATABASE_URL + value: "postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov" + - name: SECRET_KEY + value: "cfgov" + command: + - 'sh' + - '-c' + - './refresh-data.sh --no-index test.sql.gz' + + +containers: + - name: cfgov + image: + repository: cfgov + pullPolicy: Never + tag: "latest" + port: 8000 + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 1 + failedThreshold: 3 + env: + - name: DATABASE_URL + value: "postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov" + - name: SECRET_KEY + value: "cfgov" # This is for the secretes for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ imagePullSecrets: [] @@ -54,7 +92,7 @@ service: # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types type: ClusterIP # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports - port: 8000 + port: 80 # This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ ingress: @@ -86,14 +124,10 @@ resources: {} # memory: 128Mi # This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ -# livenessProbe: -# httpGet: -# path: / -# port: http -# readinessProbe: -# httpGet: -# path: / -# port: http +livenessProbe: + httpGet: + path: / + port: http # This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ autoscaling: @@ -122,6 +156,7 @@ tolerations: [] affinity: {} + postgresql: global: postgresql: @@ -130,9 +165,8 @@ postgresql: username: cfpb password: cfpb + pgadmin4: env: email: test@domain.com - password: test - - + password: test \ No newline at end of file diff --git a/refresh-data.sh b/refresh-data.sh index 5d7d0937176..573ee0b519f 100755 --- a/refresh-data.sh +++ b/refresh-data.sh @@ -8,6 +8,8 @@ set -e +NO_INDEX=0 + usage() { cat << EOF Please download a recent database dump before running this script: @@ -22,7 +24,7 @@ download it for you: Additional options: - --noindex Do not update search indexes after refreshing + --no-index Do not update search indexes after refreshing EOF exit 1; @@ -85,12 +87,11 @@ get_data() { fi } -noindex=false for arg in "$@"; do shift case "$arg" in - "--noindex") - noindex=1 + "--no-index") + NO_INDEX=1 ;; *) refresh_dump_name=$arg @@ -103,6 +104,6 @@ check_data refresh_data initial_data -if [[ $noindex -ne 1 ]]; then +if [[ $NO_INDEX -ne 1 ]]; then update_index fi From aa437f3e8fa25277b707ddab742e54286f8543c7 Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Fri, 6 Dec 2024 11:53:05 -0500 Subject: [PATCH 06/29] Revert refresh-data noindex changes --- helm/values.yaml | 4 ++-- refresh-data.sh | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/helm/values.yaml b/helm/values.yaml index f3e99e1bd4b..0346c4fdb47 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -27,7 +27,7 @@ initContainers: command: - 'sh' - '-c' - - './refresh-data.sh --no-index test.sql.gz' + - './refresh-data.sh --noindex test.sql.gz' containers: @@ -169,4 +169,4 @@ postgresql: pgadmin4: env: email: test@domain.com - password: test \ No newline at end of file + password: test diff --git a/refresh-data.sh b/refresh-data.sh index 573ee0b519f..5d7d0937176 100755 --- a/refresh-data.sh +++ b/refresh-data.sh @@ -8,8 +8,6 @@ set -e -NO_INDEX=0 - usage() { cat << EOF Please download a recent database dump before running this script: @@ -24,7 +22,7 @@ download it for you: Additional options: - --no-index Do not update search indexes after refreshing + --noindex Do not update search indexes after refreshing EOF exit 1; @@ -87,11 +85,12 @@ get_data() { fi } +noindex=false for arg in "$@"; do shift case "$arg" in - "--no-index") - NO_INDEX=1 + "--noindex") + noindex=1 ;; *) refresh_dump_name=$arg @@ -104,6 +103,6 @@ check_data refresh_data initial_data -if [[ $NO_INDEX -ne 1 ]]; then +if [[ $noindex -ne 1 ]]; then update_index fi From 0e8f524cc408fb6c3289b3bf7fa9b8155173629c Mon Sep 17 00:00:00 2001 From: cooldragontattoo Date: Fri, 6 Dec 2024 12:06:38 -0700 Subject: [PATCH 07/29] add apache container --- helm/templates/apache-config.yaml | 565 ++++++++++++++++++++++++++++++ helm/templates/deployment.yaml | 16 +- helm/values.yaml | 20 +- 3 files changed, 594 insertions(+), 7 deletions(-) create mode 100644 helm/templates/apache-config.yaml diff --git a/helm/templates/apache-config.yaml b/helm/templates/apache-config.yaml new file mode 100644 index 00000000000..ac54792bbc2 --- /dev/null +++ b/helm/templates/apache-config.yaml @@ -0,0 +1,565 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: apache-config +data: + httpd.conf: | + # + # This is the main Apache HTTP server configuration file. It contains the + # configuration directives that give the server its instructions. + # See for detailed information. + # In particular, see + # + # for a discussion of each configuration directive. + # + # Do NOT simply read the instructions in here without understanding + # what they do. They're here only as hints or reminders. If you are unsure + # consult the online docs. You have been warned. + # + # Configuration and logfile names: If the filenames you specify for many + # of the server's control files begin with "/" (or "drive:/" for Win32), the + # server will use that explicit path. If the filenames do *not* begin + # with "/", the value of ServerRoot is prepended -- so "logs/access_log" + # with ServerRoot set to "/usr/local/apache2" will be interpreted by the + # server as "/usr/local/apache2/logs/access_log", whereas "/logs/access_log" + # will be interpreted as '/logs/access_log'. + + # + # ServerRoot: The top of the directory tree under which the server's + # configuration, error, and log files are kept. + # + # Do not add a slash at the end of the directory path. If you point + # ServerRoot at a non-local disk, be sure to specify a local disk on the + # Mutex directive, if file-based mutexes are used. If you wish to share the + # same ServerRoot for multiple httpd daemons, you will need to change at + # least PidFile. + # + ServerRoot "/usr/local/apache2" + + # + # Mutex: Allows you to set the mutex mechanism and mutex file directory + # for individual mutexes, or change the global defaults + # + # Uncomment and change the directory if mutexes are file-based and the default + # mutex file directory is not on a local disk or is not appropriate for some + # other reason. + # + # Mutex default:logs + + # + # Listen: Allows you to bind Apache to specific IP addresses and/or + # ports, instead of the default. See also the + # directive. + # + # Change this to Listen on specific IP addresses as shown below to + # prevent Apache from glomming onto all bound IP addresses. + # + #Listen 12.34.56.78:80 + Listen 80 + + # + # Dynamic Shared Object (DSO) Support + # + # To be able to use the functionality of a module which was built as a DSO you + # have to place corresponding `LoadModule' lines at this location so the + # directives contained in it are actually available _before_ they are used. + # Statically compiled modules (those listed by `httpd -l') do not need + # to be loaded here. + # + # Example: + # LoadModule foo_module modules/mod_foo.so + # + LoadModule mpm_event_module modules/mod_mpm_event.so + #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so + #LoadModule mpm_worker_module modules/mod_mpm_worker.so + LoadModule authn_file_module modules/mod_authn_file.so + #LoadModule authn_dbm_module modules/mod_authn_dbm.so + #LoadModule authn_anon_module modules/mod_authn_anon.so + #LoadModule authn_dbd_module modules/mod_authn_dbd.so + #LoadModule authn_socache_module modules/mod_authn_socache.so + LoadModule authn_core_module modules/mod_authn_core.so + LoadModule authz_host_module modules/mod_authz_host.so + LoadModule authz_groupfile_module modules/mod_authz_groupfile.so + LoadModule authz_user_module modules/mod_authz_user.so + #LoadModule authz_dbm_module modules/mod_authz_dbm.so + #LoadModule authz_owner_module modules/mod_authz_owner.so + #LoadModule authz_dbd_module modules/mod_authz_dbd.so + LoadModule authz_core_module modules/mod_authz_core.so + #LoadModule authnz_ldap_module modules/mod_authnz_ldap.so + #LoadModule authnz_fcgi_module modules/mod_authnz_fcgi.so + LoadModule access_compat_module modules/mod_access_compat.so + LoadModule auth_basic_module modules/mod_auth_basic.so + #LoadModule auth_form_module modules/mod_auth_form.so + #LoadModule auth_digest_module modules/mod_auth_digest.so + #LoadModule allowmethods_module modules/mod_allowmethods.so + #LoadModule isapi_module modules/mod_isapi.so + #LoadModule file_cache_module modules/mod_file_cache.so + #LoadModule cache_module modules/mod_cache.so + #LoadModule cache_disk_module modules/mod_cache_disk.so + #LoadModule cache_socache_module modules/mod_cache_socache.so + #LoadModule socache_shmcb_module modules/mod_socache_shmcb.so + #LoadModule socache_dbm_module modules/mod_socache_dbm.so + #LoadModule socache_memcache_module modules/mod_socache_memcache.so + #LoadModule socache_redis_module modules/mod_socache_redis.so + #LoadModule watchdog_module modules/mod_watchdog.so + #LoadModule macro_module modules/mod_macro.so + #LoadModule dbd_module modules/mod_dbd.so + #LoadModule bucketeer_module modules/mod_bucketeer.so + #LoadModule dumpio_module modules/mod_dumpio.so + #LoadModule echo_module modules/mod_echo.so + #LoadModule example_hooks_module modules/mod_example_hooks.so + #LoadModule case_filter_module modules/mod_case_filter.so + #LoadModule case_filter_in_module modules/mod_case_filter_in.so + #LoadModule example_ipc_module modules/mod_example_ipc.so + #LoadModule buffer_module modules/mod_buffer.so + #LoadModule data_module modules/mod_data.so + #LoadModule ratelimit_module modules/mod_ratelimit.so + LoadModule reqtimeout_module modules/mod_reqtimeout.so + #LoadModule ext_filter_module modules/mod_ext_filter.so + #LoadModule request_module modules/mod_request.so + #LoadModule include_module modules/mod_include.so + LoadModule filter_module modules/mod_filter.so + #LoadModule reflector_module modules/mod_reflector.so + #LoadModule substitute_module modules/mod_substitute.so + #LoadModule sed_module modules/mod_sed.so + #LoadModule charset_lite_module modules/mod_charset_lite.so + #LoadModule deflate_module modules/mod_deflate.so + #LoadModule xml2enc_module modules/mod_xml2enc.so + #LoadModule proxy_html_module modules/mod_proxy_html.so + #LoadModule brotli_module modules/mod_brotli.so + LoadModule mime_module modules/mod_mime.so + #LoadModule ldap_module modules/mod_ldap.so + LoadModule log_config_module modules/mod_log_config.so + #LoadModule log_debug_module modules/mod_log_debug.so + #LoadModule log_forensic_module modules/mod_log_forensic.so + #LoadModule logio_module modules/mod_logio.so + #LoadModule lua_module modules/mod_lua.so + LoadModule env_module modules/mod_env.so + #LoadModule mime_magic_module modules/mod_mime_magic.so + #LoadModule cern_meta_module modules/mod_cern_meta.so + #LoadModule expires_module modules/mod_expires.so + LoadModule headers_module modules/mod_headers.so + #LoadModule ident_module modules/mod_ident.so + #LoadModule usertrack_module modules/mod_usertrack.so + #LoadModule unique_id_module modules/mod_unique_id.so + LoadModule setenvif_module modules/mod_setenvif.so + LoadModule version_module modules/mod_version.so + #LoadModule remoteip_module modules/mod_remoteip.so + #LoadModule proxy_module modules/mod_proxy.so + #LoadModule proxy_connect_module modules/mod_proxy_connect.so + #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so + #LoadModule proxy_http_module modules/mod_proxy_http.so + #LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so + #LoadModule proxy_scgi_module modules/mod_proxy_scgi.so + #LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so + #LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so + #LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so + #LoadModule proxy_ajp_module modules/mod_proxy_ajp.so + #LoadModule proxy_balancer_module modules/mod_proxy_balancer.so + #LoadModule proxy_express_module modules/mod_proxy_express.so + #LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so + #LoadModule session_module modules/mod_session.so + #LoadModule session_cookie_module modules/mod_session_cookie.so + #LoadModule session_crypto_module modules/mod_session_crypto.so + #LoadModule session_dbd_module modules/mod_session_dbd.so + #LoadModule slotmem_shm_module modules/mod_slotmem_shm.so + #LoadModule slotmem_plain_module modules/mod_slotmem_plain.so + #LoadModule ssl_module modules/mod_ssl.so + #LoadModule optional_hook_export_module modules/mod_optional_hook_export.so + #LoadModule optional_hook_import_module modules/mod_optional_hook_import.so + #LoadModule optional_fn_import_module modules/mod_optional_fn_import.so + #LoadModule optional_fn_export_module modules/mod_optional_fn_export.so + #LoadModule dialup_module modules/mod_dialup.so + #LoadModule http2_module modules/mod_http2.so + #LoadModule proxy_http2_module modules/mod_proxy_http2.so + #LoadModule md_module modules/mod_md.so + #LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so + #LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so + #LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so + #LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so + LoadModule unixd_module modules/mod_unixd.so + #LoadModule heartbeat_module modules/mod_heartbeat.so + #LoadModule heartmonitor_module modules/mod_heartmonitor.so + #LoadModule dav_module modules/mod_dav.so + LoadModule status_module modules/mod_status.so + LoadModule autoindex_module modules/mod_autoindex.so + #LoadModule asis_module modules/mod_asis.so + #LoadModule info_module modules/mod_info.so + #LoadModule suexec_module modules/mod_suexec.so + + #LoadModule cgid_module modules/mod_cgid.so + + + #LoadModule cgi_module modules/mod_cgi.so + + #LoadModule dav_fs_module modules/mod_dav_fs.so + #LoadModule dav_lock_module modules/mod_dav_lock.so + #LoadModule vhost_alias_module modules/mod_vhost_alias.so + #LoadModule negotiation_module modules/mod_negotiation.so + LoadModule dir_module modules/mod_dir.so + #LoadModule imagemap_module modules/mod_imagemap.so + #LoadModule actions_module modules/mod_actions.so + #LoadModule speling_module modules/mod_speling.so + #LoadModule userdir_module modules/mod_userdir.so + LoadModule alias_module modules/mod_alias.so + #LoadModule rewrite_module modules/mod_rewrite.so + LoadModule mpm_event_module modules/mod_mpm_event.so + LoadModule proxy_module modules/mod_proxy.so + LoadModule proxy_http_module modules/mod_proxy_http.so + + + # + # If you wish httpd to run as a different user or group, you must run + # httpd as root initially and it will switch. + # + # User/Group: The name (or #number) of the user/group to run httpd as. + # It is usually good practice to create a dedicated user and group for + # running httpd, as with most system services. + # + User www-data + Group www-data + + + + # 'Main' server configuration + # + # The directives in this section set up the values used by the 'main' + # server, which responds to any requests that aren't handled by a + # definition. These values also provide defaults for + # any containers you may define later in the file. + # + # All of these directives may appear inside containers, + # in which case these default settings will be overridden for the + # virtual host being defined. + # + + # + # ServerAdmin: Your address, where problems with the server should be + # e-mailed. This address appears on some server-generated pages, such + # as error documents. e.g. admin@your-domain.com + # + ServerAdmin you@example.com + + # + # ServerName gives the name and port that the server uses to identify itself. + # This can often be determined automatically, but we recommend you specify + # it explicitly to prevent problems during startup. + # + # If your host doesn't have a registered DNS name, enter its IP address here. + # + #ServerName www.example.com:80 + + # + # Deny access to the entirety of your server's filesystem. You must + # explicitly permit access to web content directories in other + # blocks below. + # + + AllowOverride none + Require all denied + + + # + # Note that from this point forward you must specifically allow + # particular features to be enabled - so if something's not working as + # you might expect, make sure that you have specifically enabled it + # below. + # + + # + # DocumentRoot: The directory out of which you will serve your + # documents. By default, all requests are taken from this directory, but + # symbolic links and aliases may be used to point to other locations. + # + DocumentRoot "/usr/local/apache2/htdocs" + + # + # Possible values for the Options directive are "None", "All", + # or any combination of: + # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews + # + # Note that "MultiViews" must be named *explicitly* --- "Options All" + # doesn't give it to you. + # + # The Options directive is both complicated and important. Please see + # http://httpd.apache.org/docs/2.4/mod/core.html#options + # for more information. + # + Options Indexes FollowSymLinks + + # + # AllowOverride controls what directives may be placed in .htaccess files. + # It can be "All", "None", or any combination of the keywords: + # AllowOverride FileInfo AuthConfig Limit + # + AllowOverride None + + # + # Controls who can get stuff from this server. + # + Require all granted + + + # + # DirectoryIndex: sets the file that Apache will serve if a directory + # is requested. + # + + DirectoryIndex index.html + + + # + # The following lines prevent .htaccess and .htpasswd files from being + # viewed by Web clients. + # + + Require all denied + + + # + # ErrorLog: The location of the error log file. + # If you do not specify an ErrorLog directive within a + # container, error messages relating to that virtual host will be + # logged here. If you *do* define an error logfile for a + # container, that host's errors will be logged there and not here. + # + ErrorLog /proc/self/fd/2 + + # + # LogLevel: Control the number of messages logged to the error_log. + # Possible values include: debug, info, notice, warn, error, crit, + # alert, emerg. + # + LogLevel warn + + + # + # The following directives define some format nicknames for use with + # a CustomLog directive (see below). + # + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + # You need to enable mod_logio.c to use %I and %O + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + # + # The location and format of the access logfile (Common Logfile Format). + # If you do not define any access logfiles within a + # container, they will be logged here. Contrariwise, if you *do* + # define per- access logfiles, transactions will be + # logged therein and *not* in this file. + # + CustomLog /proc/self/fd/1 common + + # + # If you prefer a logfile with access, agent, and referer information + # (Combined Logfile Format) you can use the following directive. + # + #CustomLog "logs/access_log" combined + + + + # + # Redirect: Allows you to tell clients about documents that used to + # exist in your server's namespace, but do not anymore. The client + # will make a new request for the document at its new location. + # Example: + # Redirect permanent /foo http://www.example.com/bar + + # + # Alias: Maps web paths into filesystem paths and is used to + # access content that does not live under the DocumentRoot. + # Example: + # Alias /webpath /full/filesystem/path + # + # If you include a trailing / on /webpath then the server will + # require it to be present in the URL. You will also likely + # need to provide a section to allow access to + # the filesystem path. + + # + # ScriptAlias: This controls which directories contain server scripts. + # ScriptAliases are essentially the same as Aliases, except that + # documents in the target directory are treated as applications and + # run by the server when requested rather than as documents sent to the + # client. The same rules about trailing "/" apply to ScriptAlias + # directives as to Alias. + # + ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/" + + + + + ProxyPreserveHost On + ProxyPass / http://localhost:8000/ + ProxyPassReverse / http://localhost:8000/ + + + + # + # ScriptSock: On threaded servers, designate the path to the UNIX + # socket used to communicate with the CGI daemon of mod_cgid. + # + #Scriptsock cgisock + + + # + # "/usr/local/apache2/cgi-bin" should be changed to whatever your ScriptAliased + # CGI directory exists, if you have that configured. + # + + AllowOverride None + Options None + Require all granted + + + + # + # Avoid passing HTTP_PROXY environment to CGI's on this or any proxied + # backend servers which have lingering "httpoxy" defects. + # 'Proxy' request header is undefined by the IETF, not listed by IANA + # + RequestHeader unset Proxy early + + + + # + # TypesConfig points to the file containing the list of mappings from + # filename extension to MIME-type. + # + TypesConfig conf/mime.types + + # + # AddType allows you to add to or override the MIME configuration + # file specified in TypesConfig for specific file types. + # + #AddType application/x-gzip .tgz + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # + #AddEncoding x-compress .Z + #AddEncoding x-gzip .gz .tgz + # + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + # + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers": + # actions unrelated to filetype. These can be either built into the server + # or added with the Action directive (see below) + # + # To use CGI scripts outside of ScriptAliased directories: + # (You will also need to add "ExecCGI" to the "Options" directive.) + # + #AddHandler cgi-script .cgi + + # For type maps (negotiated resources): + #AddHandler type-map var + + # + # Filters allow you to process content before it is sent to the client. + # + # To parse .shtml files for server-side includes (SSI): + # (You will also need to add "Includes" to the "Options" directive.) + # + #AddType text/html .shtml + #AddOutputFilter INCLUDES .shtml + + + # + # The mod_mime_magic module allows the server to use various hints from the + # contents of the file itself to determine its type. The MIMEMagicFile + # directive tells the module where the hint definitions are located. + # + #MIMEMagicFile conf/magic + + # + # Customizable error responses come in three flavors: + # 1) plain text 2) local redirects 3) external redirects + # + # Some examples: + #ErrorDocument 500 "The server made a boo boo." + #ErrorDocument 404 /missing.html + #ErrorDocument 404 "/cgi-bin/missing_handler.pl" + #ErrorDocument 402 http://www.example.com/subscription_info.html + # + + # + # MaxRanges: Maximum number of Ranges in a request before + # returning the entire resource, or one of the special + # values 'default', 'none' or 'unlimited'. + # Default setting is to accept 200 Ranges. + #MaxRanges unlimited + + # + # EnableMMAP and EnableSendfile: On systems that support it, + # memory-mapping or the sendfile syscall may be used to deliver + # files. This usually improves server performance, but must + # be turned off when serving from networked-mounted + # filesystems or if support for these functions is otherwise + # broken on your system. + # Defaults: EnableMMAP On, EnableSendfile Off + # + #EnableMMAP off + #EnableSendfile on + + # Supplemental configuration + # + # The configuration files in the conf/extra/ directory can be + # included to add extra features or to modify the default configuration of + # the server, or you may simply copy their contents here and change as + # necessary. + + # Server-pool management (MPM specific) + #Include conf/extra/httpd-mpm.conf + + # Multi-language error messages + #Include conf/extra/httpd-multilang-errordoc.conf + + # Fancy directory listings + #Include conf/extra/httpd-autoindex.conf + + # Language settings + #Include conf/extra/httpd-languages.conf + + # User home directories + #Include conf/extra/httpd-userdir.conf + + # Real-time info on requests and configuration + #Include conf/extra/httpd-info.conf + + # Virtual hosts + #Include conf/extra/httpd-vhosts.conf + + # Local access to the Apache HTTP Server Manual + #Include conf/extra/httpd-manual.conf + + # Distributed authoring and versioning (WebDAV) + #Include conf/extra/httpd-dav.conf + + # Various default settings + #Include conf/extra/httpd-default.conf + + # Configure mod_proxy_html to understand HTML4/XHTML1 + + Include conf/extra/proxy-html.conf + + + # Secure (SSL/TLS) connections + #Include conf/extra/httpd-ssl.conf + # + # Note: The following must must be present to support + # starting without SSL on platforms with no /dev/random equivalent + # but a statically compiled-in mod_ssl. + # + + SSLRandomSeed startup builtin + SSLRandomSeed connect builtin + \ No newline at end of file diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index b5eb6d8746b..7057db6852b 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -45,8 +45,8 @@ spec: - {{ . }} {{- end }} {{- end }} - {{- range .Values.containers }} containers: + {{- range .Values.containers }} - name: {{ .name }} image: "{{ .image.repository }}:{{ .image.tag }}" imagePullPolicy: {{ .image.pullPolicy }} @@ -54,12 +54,26 @@ spec: - name: http containerPort: {{ .port }} protocol: TCP + {{- if .env }} env: {{- range .env }} - name: {{ .name }} value: {{ .value | quote }} {{- end }} + {{- end }} + {{- if .command}} + command: + {{- range .command }} + - {{ . }} + {{- end }} + {{- end }} + {{- if .readinessProbe }} readinessProbe: {{ toYaml .readinessProbe | nindent 12 }} + {{- end }} + {{- if .volumeMounts }} + volumeMounts: + {{- toYaml .volumeMounts | nindent 12 }} + {{- end }} {{- end }} {{- with .Values.volumes }} volumes: diff --git a/helm/values.yaml b/helm/values.yaml index 0346c4fdb47..95e3cd06f7f 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -50,6 +50,16 @@ containers: value: "postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov" - name: SECRET_KEY value: "cfgov" + - name: cfgov-apache + image: + repository: httpd + pullPolicy: IfNotPresent + tag: "latest" + port: 80 + # volumeMounts: + # - name: apache-cfgov-config + # mountPath: /usr/local/apache2/conf/httpd.conf + # subPath: httpd.conf # This is for the secretes for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ imagePullSecrets: [] @@ -138,12 +148,10 @@ autoscaling: # targetMemoryUtilizationPercentage: 80 # Additional volumes on the output Deployment definition. -volumes: [] -# - name: foo -# secret: -# secretName: mysecret -# optional: false - +volumes: +- name: apache-cfgov-config + configMap: + name: apache-config # Additional volumeMounts on the output Deployment definition. volumeMounts: [] # - name: foo From e0dfa9b81132db7ac93fa17bec760ea3179c66ec Mon Sep 17 00:00:00 2001 From: cooldragontattoo Date: Fri, 6 Dec 2024 18:00:15 -0700 Subject: [PATCH 08/29] add apache configuration for helm deployment --- helm-init.sh | 86 +++ helm/templates/apache-conf-config.yaml | 6 + .../templates/apache-conf-modules-config.yaml | 6 + helm/templates/apache-confd-config.yaml | 6 + helm/templates/apache-config.yaml | 565 ------------------ helm/values.yaml | 50 +- 6 files changed, 148 insertions(+), 571 deletions(-) create mode 100755 helm-init.sh create mode 100644 helm/templates/apache-conf-config.yaml create mode 100644 helm/templates/apache-conf-modules-config.yaml create mode 100644 helm/templates/apache-confd-config.yaml delete mode 100644 helm/templates/apache-config.yaml diff --git a/helm-init.sh b/helm-init.sh new file mode 100755 index 00000000000..b9900dac43c --- /dev/null +++ b/helm-init.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# Function to display usage +usage() { + echo "Usage: $0 [--release ]" + exit 1 +} + +# Parse command-line arguments +while [[ "$#" -gt 0 ]]; do + case $1 in + --release) + RELEASE_NAME="$2" + shift + ;; + *) + usage + ;; + esac + shift +done + +if ! command -v helm &> /dev/null; then + echo "helm could not be found. Please install it before running this script." + exit 1 +fi + + +if ! command -v kubectl &> /dev/null; then + echo "kubectl could not be found. Please install it before running this script." + exit 1 +fi + +CLUSTER=$(kubectl config current-context) + +if [ -z "$CLUSTER" ]; then + echo "No Kubernetes cluster is currently configured. Please configure a cluster before running this script." + exit 1 +fi + +echo $CLUSTER + +if [[ "$CLUSTER" != "docker-desktop" && "$CLUSTER" != "colima" ]]; then + echo "" + echo -e "This script is intended to be run on a local Kubernetes cluster (i.e. docker-desktop or colima). The current cluster is $CLUSTER." + echo -e "Your current cluster is $CLUSTER." + echo -e "Please switch to docker-desktop or colima before running this script." + echo "" + echo "" + echo "Exiting helm-init" + exit 1 +fi + +HELM_DIR="./helm" + +if [ -n "$RELEASE_NAME" ]; then + echo "Release name: $RELEASE_NAME" +else + echo "No release name provided." + echo "Using default release name: 'cfgov'" + RELEASE_NAME="cfgov" +fi + +if [ -d "./cfgov/apache" ]; then + echo "Moving ./cfgov/apache to $HELM_DIR" + cp -r ./cfgov/apache $HELM_DIR +else + echo "Directory ./cfgov/apache does not exist." + exit 1 +fi + +if [! -d ./helm/charts]; then + echo "Building Helm charts..." + helm repo update + helm dependency build $HELM_DIR +else + if [ -z $SKIP_DEP_UPDATE ]; then + echo "Updating Helm dependencies..." + helm dependency update $HELM_DIR + fi +fi + +helm upgrade --install $RELEASE_NAME $HELM_DIR -f $HELM_DIR/values.yaml + +rm -r $HELM_DIR/apache + diff --git a/helm/templates/apache-conf-config.yaml b/helm/templates/apache-conf-config.yaml new file mode 100644 index 00000000000..d100a6c3e3a --- /dev/null +++ b/helm/templates/apache-conf-config.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: apache-conf-config +data: + {{ (.Files.Glob "apache/conf/*").AsConfig | nindent 2 }} \ No newline at end of file diff --git a/helm/templates/apache-conf-modules-config.yaml b/helm/templates/apache-conf-modules-config.yaml new file mode 100644 index 00000000000..25936b2c8d1 --- /dev/null +++ b/helm/templates/apache-conf-modules-config.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: apache-conf-modules-config +data: + {{ (.Files.Glob "apache/conf.modules.d/*").AsConfig | nindent 2 }} \ No newline at end of file diff --git a/helm/templates/apache-confd-config.yaml b/helm/templates/apache-confd-config.yaml new file mode 100644 index 00000000000..e00b29cf811 --- /dev/null +++ b/helm/templates/apache-confd-config.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: apache-confd-config +data: + {{ (.Files.Glob "apache/conf.d/*").AsConfig | nindent 2 }} \ No newline at end of file diff --git a/helm/templates/apache-config.yaml b/helm/templates/apache-config.yaml deleted file mode 100644 index ac54792bbc2..00000000000 --- a/helm/templates/apache-config.yaml +++ /dev/null @@ -1,565 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: apache-config -data: - httpd.conf: | - # - # This is the main Apache HTTP server configuration file. It contains the - # configuration directives that give the server its instructions. - # See for detailed information. - # In particular, see - # - # for a discussion of each configuration directive. - # - # Do NOT simply read the instructions in here without understanding - # what they do. They're here only as hints or reminders. If you are unsure - # consult the online docs. You have been warned. - # - # Configuration and logfile names: If the filenames you specify for many - # of the server's control files begin with "/" (or "drive:/" for Win32), the - # server will use that explicit path. If the filenames do *not* begin - # with "/", the value of ServerRoot is prepended -- so "logs/access_log" - # with ServerRoot set to "/usr/local/apache2" will be interpreted by the - # server as "/usr/local/apache2/logs/access_log", whereas "/logs/access_log" - # will be interpreted as '/logs/access_log'. - - # - # ServerRoot: The top of the directory tree under which the server's - # configuration, error, and log files are kept. - # - # Do not add a slash at the end of the directory path. If you point - # ServerRoot at a non-local disk, be sure to specify a local disk on the - # Mutex directive, if file-based mutexes are used. If you wish to share the - # same ServerRoot for multiple httpd daemons, you will need to change at - # least PidFile. - # - ServerRoot "/usr/local/apache2" - - # - # Mutex: Allows you to set the mutex mechanism and mutex file directory - # for individual mutexes, or change the global defaults - # - # Uncomment and change the directory if mutexes are file-based and the default - # mutex file directory is not on a local disk or is not appropriate for some - # other reason. - # - # Mutex default:logs - - # - # Listen: Allows you to bind Apache to specific IP addresses and/or - # ports, instead of the default. See also the - # directive. - # - # Change this to Listen on specific IP addresses as shown below to - # prevent Apache from glomming onto all bound IP addresses. - # - #Listen 12.34.56.78:80 - Listen 80 - - # - # Dynamic Shared Object (DSO) Support - # - # To be able to use the functionality of a module which was built as a DSO you - # have to place corresponding `LoadModule' lines at this location so the - # directives contained in it are actually available _before_ they are used. - # Statically compiled modules (those listed by `httpd -l') do not need - # to be loaded here. - # - # Example: - # LoadModule foo_module modules/mod_foo.so - # - LoadModule mpm_event_module modules/mod_mpm_event.so - #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so - #LoadModule mpm_worker_module modules/mod_mpm_worker.so - LoadModule authn_file_module modules/mod_authn_file.so - #LoadModule authn_dbm_module modules/mod_authn_dbm.so - #LoadModule authn_anon_module modules/mod_authn_anon.so - #LoadModule authn_dbd_module modules/mod_authn_dbd.so - #LoadModule authn_socache_module modules/mod_authn_socache.so - LoadModule authn_core_module modules/mod_authn_core.so - LoadModule authz_host_module modules/mod_authz_host.so - LoadModule authz_groupfile_module modules/mod_authz_groupfile.so - LoadModule authz_user_module modules/mod_authz_user.so - #LoadModule authz_dbm_module modules/mod_authz_dbm.so - #LoadModule authz_owner_module modules/mod_authz_owner.so - #LoadModule authz_dbd_module modules/mod_authz_dbd.so - LoadModule authz_core_module modules/mod_authz_core.so - #LoadModule authnz_ldap_module modules/mod_authnz_ldap.so - #LoadModule authnz_fcgi_module modules/mod_authnz_fcgi.so - LoadModule access_compat_module modules/mod_access_compat.so - LoadModule auth_basic_module modules/mod_auth_basic.so - #LoadModule auth_form_module modules/mod_auth_form.so - #LoadModule auth_digest_module modules/mod_auth_digest.so - #LoadModule allowmethods_module modules/mod_allowmethods.so - #LoadModule isapi_module modules/mod_isapi.so - #LoadModule file_cache_module modules/mod_file_cache.so - #LoadModule cache_module modules/mod_cache.so - #LoadModule cache_disk_module modules/mod_cache_disk.so - #LoadModule cache_socache_module modules/mod_cache_socache.so - #LoadModule socache_shmcb_module modules/mod_socache_shmcb.so - #LoadModule socache_dbm_module modules/mod_socache_dbm.so - #LoadModule socache_memcache_module modules/mod_socache_memcache.so - #LoadModule socache_redis_module modules/mod_socache_redis.so - #LoadModule watchdog_module modules/mod_watchdog.so - #LoadModule macro_module modules/mod_macro.so - #LoadModule dbd_module modules/mod_dbd.so - #LoadModule bucketeer_module modules/mod_bucketeer.so - #LoadModule dumpio_module modules/mod_dumpio.so - #LoadModule echo_module modules/mod_echo.so - #LoadModule example_hooks_module modules/mod_example_hooks.so - #LoadModule case_filter_module modules/mod_case_filter.so - #LoadModule case_filter_in_module modules/mod_case_filter_in.so - #LoadModule example_ipc_module modules/mod_example_ipc.so - #LoadModule buffer_module modules/mod_buffer.so - #LoadModule data_module modules/mod_data.so - #LoadModule ratelimit_module modules/mod_ratelimit.so - LoadModule reqtimeout_module modules/mod_reqtimeout.so - #LoadModule ext_filter_module modules/mod_ext_filter.so - #LoadModule request_module modules/mod_request.so - #LoadModule include_module modules/mod_include.so - LoadModule filter_module modules/mod_filter.so - #LoadModule reflector_module modules/mod_reflector.so - #LoadModule substitute_module modules/mod_substitute.so - #LoadModule sed_module modules/mod_sed.so - #LoadModule charset_lite_module modules/mod_charset_lite.so - #LoadModule deflate_module modules/mod_deflate.so - #LoadModule xml2enc_module modules/mod_xml2enc.so - #LoadModule proxy_html_module modules/mod_proxy_html.so - #LoadModule brotli_module modules/mod_brotli.so - LoadModule mime_module modules/mod_mime.so - #LoadModule ldap_module modules/mod_ldap.so - LoadModule log_config_module modules/mod_log_config.so - #LoadModule log_debug_module modules/mod_log_debug.so - #LoadModule log_forensic_module modules/mod_log_forensic.so - #LoadModule logio_module modules/mod_logio.so - #LoadModule lua_module modules/mod_lua.so - LoadModule env_module modules/mod_env.so - #LoadModule mime_magic_module modules/mod_mime_magic.so - #LoadModule cern_meta_module modules/mod_cern_meta.so - #LoadModule expires_module modules/mod_expires.so - LoadModule headers_module modules/mod_headers.so - #LoadModule ident_module modules/mod_ident.so - #LoadModule usertrack_module modules/mod_usertrack.so - #LoadModule unique_id_module modules/mod_unique_id.so - LoadModule setenvif_module modules/mod_setenvif.so - LoadModule version_module modules/mod_version.so - #LoadModule remoteip_module modules/mod_remoteip.so - #LoadModule proxy_module modules/mod_proxy.so - #LoadModule proxy_connect_module modules/mod_proxy_connect.so - #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so - #LoadModule proxy_http_module modules/mod_proxy_http.so - #LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so - #LoadModule proxy_scgi_module modules/mod_proxy_scgi.so - #LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so - #LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so - #LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so - #LoadModule proxy_ajp_module modules/mod_proxy_ajp.so - #LoadModule proxy_balancer_module modules/mod_proxy_balancer.so - #LoadModule proxy_express_module modules/mod_proxy_express.so - #LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so - #LoadModule session_module modules/mod_session.so - #LoadModule session_cookie_module modules/mod_session_cookie.so - #LoadModule session_crypto_module modules/mod_session_crypto.so - #LoadModule session_dbd_module modules/mod_session_dbd.so - #LoadModule slotmem_shm_module modules/mod_slotmem_shm.so - #LoadModule slotmem_plain_module modules/mod_slotmem_plain.so - #LoadModule ssl_module modules/mod_ssl.so - #LoadModule optional_hook_export_module modules/mod_optional_hook_export.so - #LoadModule optional_hook_import_module modules/mod_optional_hook_import.so - #LoadModule optional_fn_import_module modules/mod_optional_fn_import.so - #LoadModule optional_fn_export_module modules/mod_optional_fn_export.so - #LoadModule dialup_module modules/mod_dialup.so - #LoadModule http2_module modules/mod_http2.so - #LoadModule proxy_http2_module modules/mod_proxy_http2.so - #LoadModule md_module modules/mod_md.so - #LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so - #LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so - #LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so - #LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so - LoadModule unixd_module modules/mod_unixd.so - #LoadModule heartbeat_module modules/mod_heartbeat.so - #LoadModule heartmonitor_module modules/mod_heartmonitor.so - #LoadModule dav_module modules/mod_dav.so - LoadModule status_module modules/mod_status.so - LoadModule autoindex_module modules/mod_autoindex.so - #LoadModule asis_module modules/mod_asis.so - #LoadModule info_module modules/mod_info.so - #LoadModule suexec_module modules/mod_suexec.so - - #LoadModule cgid_module modules/mod_cgid.so - - - #LoadModule cgi_module modules/mod_cgi.so - - #LoadModule dav_fs_module modules/mod_dav_fs.so - #LoadModule dav_lock_module modules/mod_dav_lock.so - #LoadModule vhost_alias_module modules/mod_vhost_alias.so - #LoadModule negotiation_module modules/mod_negotiation.so - LoadModule dir_module modules/mod_dir.so - #LoadModule imagemap_module modules/mod_imagemap.so - #LoadModule actions_module modules/mod_actions.so - #LoadModule speling_module modules/mod_speling.so - #LoadModule userdir_module modules/mod_userdir.so - LoadModule alias_module modules/mod_alias.so - #LoadModule rewrite_module modules/mod_rewrite.so - LoadModule mpm_event_module modules/mod_mpm_event.so - LoadModule proxy_module modules/mod_proxy.so - LoadModule proxy_http_module modules/mod_proxy_http.so - - - # - # If you wish httpd to run as a different user or group, you must run - # httpd as root initially and it will switch. - # - # User/Group: The name (or #number) of the user/group to run httpd as. - # It is usually good practice to create a dedicated user and group for - # running httpd, as with most system services. - # - User www-data - Group www-data - - - - # 'Main' server configuration - # - # The directives in this section set up the values used by the 'main' - # server, which responds to any requests that aren't handled by a - # definition. These values also provide defaults for - # any containers you may define later in the file. - # - # All of these directives may appear inside containers, - # in which case these default settings will be overridden for the - # virtual host being defined. - # - - # - # ServerAdmin: Your address, where problems with the server should be - # e-mailed. This address appears on some server-generated pages, such - # as error documents. e.g. admin@your-domain.com - # - ServerAdmin you@example.com - - # - # ServerName gives the name and port that the server uses to identify itself. - # This can often be determined automatically, but we recommend you specify - # it explicitly to prevent problems during startup. - # - # If your host doesn't have a registered DNS name, enter its IP address here. - # - #ServerName www.example.com:80 - - # - # Deny access to the entirety of your server's filesystem. You must - # explicitly permit access to web content directories in other - # blocks below. - # - - AllowOverride none - Require all denied - - - # - # Note that from this point forward you must specifically allow - # particular features to be enabled - so if something's not working as - # you might expect, make sure that you have specifically enabled it - # below. - # - - # - # DocumentRoot: The directory out of which you will serve your - # documents. By default, all requests are taken from this directory, but - # symbolic links and aliases may be used to point to other locations. - # - DocumentRoot "/usr/local/apache2/htdocs" - - # - # Possible values for the Options directive are "None", "All", - # or any combination of: - # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews - # - # Note that "MultiViews" must be named *explicitly* --- "Options All" - # doesn't give it to you. - # - # The Options directive is both complicated and important. Please see - # http://httpd.apache.org/docs/2.4/mod/core.html#options - # for more information. - # - Options Indexes FollowSymLinks - - # - # AllowOverride controls what directives may be placed in .htaccess files. - # It can be "All", "None", or any combination of the keywords: - # AllowOverride FileInfo AuthConfig Limit - # - AllowOverride None - - # - # Controls who can get stuff from this server. - # - Require all granted - - - # - # DirectoryIndex: sets the file that Apache will serve if a directory - # is requested. - # - - DirectoryIndex index.html - - - # - # The following lines prevent .htaccess and .htpasswd files from being - # viewed by Web clients. - # - - Require all denied - - - # - # ErrorLog: The location of the error log file. - # If you do not specify an ErrorLog directive within a - # container, error messages relating to that virtual host will be - # logged here. If you *do* define an error logfile for a - # container, that host's errors will be logged there and not here. - # - ErrorLog /proc/self/fd/2 - - # - # LogLevel: Control the number of messages logged to the error_log. - # Possible values include: debug, info, notice, warn, error, crit, - # alert, emerg. - # - LogLevel warn - - - # - # The following directives define some format nicknames for use with - # a CustomLog directive (see below). - # - LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined - LogFormat "%h %l %u %t \"%r\" %>s %b" common - - - # You need to enable mod_logio.c to use %I and %O - LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio - - - # - # The location and format of the access logfile (Common Logfile Format). - # If you do not define any access logfiles within a - # container, they will be logged here. Contrariwise, if you *do* - # define per- access logfiles, transactions will be - # logged therein and *not* in this file. - # - CustomLog /proc/self/fd/1 common - - # - # If you prefer a logfile with access, agent, and referer information - # (Combined Logfile Format) you can use the following directive. - # - #CustomLog "logs/access_log" combined - - - - # - # Redirect: Allows you to tell clients about documents that used to - # exist in your server's namespace, but do not anymore. The client - # will make a new request for the document at its new location. - # Example: - # Redirect permanent /foo http://www.example.com/bar - - # - # Alias: Maps web paths into filesystem paths and is used to - # access content that does not live under the DocumentRoot. - # Example: - # Alias /webpath /full/filesystem/path - # - # If you include a trailing / on /webpath then the server will - # require it to be present in the URL. You will also likely - # need to provide a section to allow access to - # the filesystem path. - - # - # ScriptAlias: This controls which directories contain server scripts. - # ScriptAliases are essentially the same as Aliases, except that - # documents in the target directory are treated as applications and - # run by the server when requested rather than as documents sent to the - # client. The same rules about trailing "/" apply to ScriptAlias - # directives as to Alias. - # - ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/" - - - - - ProxyPreserveHost On - ProxyPass / http://localhost:8000/ - ProxyPassReverse / http://localhost:8000/ - - - - # - # ScriptSock: On threaded servers, designate the path to the UNIX - # socket used to communicate with the CGI daemon of mod_cgid. - # - #Scriptsock cgisock - - - # - # "/usr/local/apache2/cgi-bin" should be changed to whatever your ScriptAliased - # CGI directory exists, if you have that configured. - # - - AllowOverride None - Options None - Require all granted - - - - # - # Avoid passing HTTP_PROXY environment to CGI's on this or any proxied - # backend servers which have lingering "httpoxy" defects. - # 'Proxy' request header is undefined by the IETF, not listed by IANA - # - RequestHeader unset Proxy early - - - - # - # TypesConfig points to the file containing the list of mappings from - # filename extension to MIME-type. - # - TypesConfig conf/mime.types - - # - # AddType allows you to add to or override the MIME configuration - # file specified in TypesConfig for specific file types. - # - #AddType application/x-gzip .tgz - # - # AddEncoding allows you to have certain browsers uncompress - # information on the fly. Note: Not all browsers support this. - # - #AddEncoding x-compress .Z - #AddEncoding x-gzip .gz .tgz - # - # If the AddEncoding directives above are commented-out, then you - # probably should define those extensions to indicate media types: - # - AddType application/x-compress .Z - AddType application/x-gzip .gz .tgz - - # - # AddHandler allows you to map certain file extensions to "handlers": - # actions unrelated to filetype. These can be either built into the server - # or added with the Action directive (see below) - # - # To use CGI scripts outside of ScriptAliased directories: - # (You will also need to add "ExecCGI" to the "Options" directive.) - # - #AddHandler cgi-script .cgi - - # For type maps (negotiated resources): - #AddHandler type-map var - - # - # Filters allow you to process content before it is sent to the client. - # - # To parse .shtml files for server-side includes (SSI): - # (You will also need to add "Includes" to the "Options" directive.) - # - #AddType text/html .shtml - #AddOutputFilter INCLUDES .shtml - - - # - # The mod_mime_magic module allows the server to use various hints from the - # contents of the file itself to determine its type. The MIMEMagicFile - # directive tells the module where the hint definitions are located. - # - #MIMEMagicFile conf/magic - - # - # Customizable error responses come in three flavors: - # 1) plain text 2) local redirects 3) external redirects - # - # Some examples: - #ErrorDocument 500 "The server made a boo boo." - #ErrorDocument 404 /missing.html - #ErrorDocument 404 "/cgi-bin/missing_handler.pl" - #ErrorDocument 402 http://www.example.com/subscription_info.html - # - - # - # MaxRanges: Maximum number of Ranges in a request before - # returning the entire resource, or one of the special - # values 'default', 'none' or 'unlimited'. - # Default setting is to accept 200 Ranges. - #MaxRanges unlimited - - # - # EnableMMAP and EnableSendfile: On systems that support it, - # memory-mapping or the sendfile syscall may be used to deliver - # files. This usually improves server performance, but must - # be turned off when serving from networked-mounted - # filesystems or if support for these functions is otherwise - # broken on your system. - # Defaults: EnableMMAP On, EnableSendfile Off - # - #EnableMMAP off - #EnableSendfile on - - # Supplemental configuration - # - # The configuration files in the conf/extra/ directory can be - # included to add extra features or to modify the default configuration of - # the server, or you may simply copy their contents here and change as - # necessary. - - # Server-pool management (MPM specific) - #Include conf/extra/httpd-mpm.conf - - # Multi-language error messages - #Include conf/extra/httpd-multilang-errordoc.conf - - # Fancy directory listings - #Include conf/extra/httpd-autoindex.conf - - # Language settings - #Include conf/extra/httpd-languages.conf - - # User home directories - #Include conf/extra/httpd-userdir.conf - - # Real-time info on requests and configuration - #Include conf/extra/httpd-info.conf - - # Virtual hosts - #Include conf/extra/httpd-vhosts.conf - - # Local access to the Apache HTTP Server Manual - #Include conf/extra/httpd-manual.conf - - # Distributed authoring and versioning (WebDAV) - #Include conf/extra/httpd-dav.conf - - # Various default settings - #Include conf/extra/httpd-default.conf - - # Configure mod_proxy_html to understand HTML4/XHTML1 - - Include conf/extra/proxy-html.conf - - - # Secure (SSL/TLS) connections - #Include conf/extra/httpd-ssl.conf - # - # Note: The following must must be present to support - # starting without SSL on platforms with no /dev/random equivalent - # but a statically compiled-in mod_ssl. - # - - SSLRandomSeed startup builtin - SSLRandomSeed connect builtin - \ No newline at end of file diff --git a/helm/values.yaml b/helm/values.yaml index 95e3cd06f7f..b9560c984c8 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -56,10 +56,42 @@ containers: pullPolicy: IfNotPresent tag: "latest" port: 80 - # volumeMounts: - # - name: apache-cfgov-config - # mountPath: /usr/local/apache2/conf/httpd.conf - # subPath: httpd.conf + env: + - name: APACHE_PORT + value: "80" + - name: APACHE_USER + value: "www-data" + - name: APACHE_GROUP + value: "www-data" + - name: APACHE_SERVER_ROOT + value: "/usr/local/apache2/" + - name: APACHE_UPLOADS_F_ALIAS + value: "/src/consumerfinance.gov/cfgov/f/" + - name: STATIC_PATH + value: "/tmp" + - name: ERROR_LOG + value: "/proc/self/fd/2" + - name: ACCESS_LOG + value: "/proc/self/fd/1" + - name: LIMIT_REQUEST_BODY + value: "0" + - name: APACHE_STATUS_ALLOW_FROM + value: "127.0.0.1" + - name: APACHE_PROCESS_COUNT + value: "4" + - name: CFGOV_APPLICATION_HOST + value: "localhost" + # command: + # - 'sh' + # - '-c' + # - 'sleep 1000' + volumeMounts: + - name: apache-conf + mountPath: /usr/local/apache2/conf + - name: apache-confd + mountPath: /usr/local/apache2/conf.d + - name: apache-conf-modules + mountPath: /usr/local/apache2/conf.modules.d # This is for the secretes for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ imagePullSecrets: [] @@ -149,9 +181,15 @@ autoscaling: # Additional volumes on the output Deployment definition. volumes: -- name: apache-cfgov-config +- name: apache-conf + configMap: + name: apache-conf-config +- name: apache-confd + configMap: + name: apache-confd-config +- name: apache-conf-modules configMap: - name: apache-config + name: apache-conf-modules-config # Additional volumeMounts on the output Deployment definition. volumeMounts: [] # - name: foo From 758c667db14e8a4eb3a03cb2adaa928b67fb932f Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Mon, 9 Dec 2024 11:06:09 -0500 Subject: [PATCH 09/29] Remove unneeded dj-database-url fallback The dj_database_url.config method uses the DATABASE_URL variable by default so it's not necessary to explicitly specify it. --- cfgov/cfgov/settings/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfgov/cfgov/settings/base.py b/cfgov/cfgov/settings/base.py index 88168623393..aa3b3124c7e 100644 --- a/cfgov/cfgov/settings/base.py +++ b/cfgov/cfgov/settings/base.py @@ -221,7 +221,7 @@ # See https://github.com/jazzband/dj-database-url for URL formatting. DATABASES = { "default": dj_database_url.config( - default=os.getenv("DATABASE_URL", "postgres://cfpb:cfpb@localhost/cfgov") + default="postgres://cfpb:cfpb@localhost/cfgov" ), } From c28b40cb4726734aca241d95e05d50fc307a4fce Mon Sep 17 00:00:00 2001 From: cooldragontattoo Date: Tue, 10 Dec 2024 09:17:41 -0700 Subject: [PATCH 10/29] update helm chart to utilize opensearch --- .dockerignore | 1 + cfgov/cfgov/settings/base.py | 1 + helm/Chart.lock | 7 +++++-- helm/Chart.yaml | 5 ++++- helm/charts/opensearch-1.31.3.tgz | Bin 0 -> 26089 bytes helm/values.yaml | 16 ++++++++++++++-- 6 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 helm/charts/opensearch-1.31.3.tgz diff --git a/.dockerignore b/.dockerignore index 5cba5b78ee5..92a82b6670c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -17,6 +17,7 @@ !dump-data.sh !Dockerfile !frontend.sh +!index.sh !initial-data.sh !jest.config.js !package.json diff --git a/cfgov/cfgov/settings/base.py b/cfgov/cfgov/settings/base.py index aa3b3124c7e..59ad683e63e 100644 --- a/cfgov/cfgov/settings/base.py +++ b/cfgov/cfgov/settings/base.py @@ -360,6 +360,7 @@ os.getenv("ES_USER", "admin"), os.getenv("ES_PASS", "admin"), ), + "use_ssl": True, "verify_certs": False, } } diff --git a/helm/Chart.lock b/helm/Chart.lock index 895ea1faf49..64852467f22 100644 --- a/helm/Chart.lock +++ b/helm/Chart.lock @@ -5,5 +5,8 @@ dependencies: - name: pgadmin4 repository: https://helm.runix.net version: 1.33.3 -digest: sha256:cddb1ff2c6977f93a32c08d0089bdff4dc00a80504dad4d728de5f027ce9df30 -generated: "2024-12-06T05:48:28.869178-07:00" +- name: opensearch + repository: https://opensearch-project.github.io/helm-charts/ + version: 1.31.3 +digest: sha256:a9576d12585500d4f1e276d7d35b077f45b734cc2972183d519b60c0283980da +generated: "2024-12-10T07:53:25.026703-07:00" diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 1a8647bd2e7..d7b69fb4190 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -20,4 +20,7 @@ dependencies: repository: https://charts.bitnami.com/bitnami - name: pgadmin4 version: 1.33.3 - repository: https://helm.runix.net \ No newline at end of file + repository: https://helm.runix.net + - name: opensearch + version: 1.31.3 + repository: https://opensearch-project.github.io/helm-charts/ \ No newline at end of file diff --git a/helm/charts/opensearch-1.31.3.tgz b/helm/charts/opensearch-1.31.3.tgz new file mode 100644 index 0000000000000000000000000000000000000000..dc938cf8f58a7de118f8565883d2e4d3c147ccfc GIT binary patch literal 26089 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 Date: Tue, 10 Dec 2024 17:19:12 -0700 Subject: [PATCH 11/29] add docs, helm-uninstall and clean up values.yaml --- .gitignore | 3 + docs/K8s-deplyoment.md | 106 ++++++++++++++++++++++ helm-init.sh | 92 ++++++++++--------- helm-uninstall.sh | 38 ++++++++ helm/Chart.lock | 7 +- helm/Chart.yaml | 3 - helm/charts/pgadmin4-1.33.3.tgz | Bin 14763 -> 0 bytes helm/notes/NOTES-local.txt | 37 ++++++++ helm/notes/NOTES-production.txt | 1 + helm/templates/NOTES.txt | 27 +----- helm/templates/tests/test-connection.yaml | 2 + helm/{values.yaml => values.local.yaml} | 9 +- 12 files changed, 249 insertions(+), 76 deletions(-) create mode 100644 docs/K8s-deplyoment.md create mode 100755 helm-uninstall.sh delete mode 100644 helm/charts/pgadmin4-1.33.3.tgz create mode 100644 helm/notes/NOTES-local.txt create mode 100644 helm/notes/NOTES-production.txt rename helm/{values.yaml => values.local.yaml} (98%) diff --git a/.gitignore b/.gitignore index 9c126cc48c5..f33e4c7941b 100755 --- a/.gitignore +++ b/.gitignore @@ -145,6 +145,9 @@ cfgov/regulations3k/jinja2/regulations3k/regulations3k-service-worker.js.map cfgov/regulations3k/jinja2/regulations3k/workbox-*.js cfgov/regulations3k/jinja2/regulations3k/workbox-*.js.map +# Helm Charts # +helm/charts/ + # Apache # ########## cfgov/apache/logs diff --git a/docs/K8s-deplyoment.md b/docs/K8s-deplyoment.md new file mode 100644 index 00000000000..de6a1d901ba --- /dev/null +++ b/docs/K8s-deplyoment.md @@ -0,0 +1,106 @@ +# Helm Deployment Guide + +This document provides a comprehensive guide to setting up, deploying, and uninstalling your Helm deployment. + +## Table of Contents + +1. [Introduction](#introduction) +2. [Requirements](#requirements) +3. [Helm Chart](#helm-chart) + - [chart.yaml](#chartyaml) + - [values.yaml](#valuesyaml) + - [templates/NOTES.txt](#templatesnotestxt) +4. [Deploying the Helm Chart](#deploying-the-helm-chart) +5. [Uninstalling the Helm Deployment](#uninstalling-the-helm-deployment) + +## Introduction + +This guide explains the setup and deployment process for the CFPB Helm Chart, which includes PostgreSQL, OpenSearch, and the CFGOV application. The Helm chart is configured to support local deployments. + +## Requirements + +1. **Local Kubernetes Cluster**: + - Ensure you have a local Kubernetes cluster running. We only support [Docker Desktop](https://www.docker.com/products/docker-desktop) and [colima](https://github.com/abiosoft/colima). + +2. **kubectl**: + - Install `kubectl`, the Kubernetes command-line tool, by following the [official installation guide](https://kubernetes.io/docs/tasks/tools/install-kubectl/). + +3. **Helm**: + - Install Helm, the package manager for Kubernetes, by following the [official installation guide](https://helm.sh/docs/intro/install/). + + +## Helm Chart + +### chart.yaml + +In our `chart.yaml` we bring two Helm chart dependencies: + +- Opensearch +- Postgresql + +### values.yaml + +The `values.yaml` file contains our local configuration for the deployment of CFGOV. + +#### Init Containers +We have two init containers: + +1. Busybox: +- Starts up once we have our Postgresql and Opensearch Pods running. +- Serves as a pre-cursor to our cfgov-migrations container. + +2. cfgov-migrations +- Runs the django migrations and the `refresh-data.sh` script and populates it with test data `test.sql.gz`. +- Indexes our database to Opensearch. + +#### Containers + +1. cfgov: +- Uses the cfgov image, found in the repo's root `dockerfile` +- Serves up our Django application on Port 8000 of the cfgov pod + +2. cfgov-apache: +- Built from `cfgov-apache` image built from the `apache/dockerfile` +- Serves as a webserver to proxy to our cfgov container + + +### notes.txt + +Our [notes.txt](https://helm.sh/docs/chart_template_guide/notes_files/) is split to work for local deployments and deployments to production. + +```txt +{{- if .Values.localDeployment }} +{{ .Files.Get "notes/NOTES-local.txt" }} +{{- else }} +{{ .Files.Get "notes/NOTES-production.txt" }} +{{- end }} +``` + +## Deploying the CFGOV Helm Chart + +Deploying the CFGOV Helm chart is simple with the `helm-init.sh` script. + +To deploy the CFGOV Helm Chart you must: +1. make sure you have a the cfgov and cfgov-apache image built +2. have a local K8s cluster running (docker desktop, colima) + +If these criteria are not met, the `helm-init.sh` script will not run. + +## Viewing the Helm Chart + +You can either user a K8s IDE ([lens](https://k8slens.dev/), [k9s](https://k9scli.io)) or manually portfward to view the application running. + +Review the output of your deployment for more information on manually portforwarding. + +|Pod|Container|Port| +|-|-|-| +|cfgov|cfgov|8000| +|cfgov|cfogv-apache|80| +|postgresql|postgresql|5432| +|opensearch|opensearch|9200 (http)| +| | | 9300 (transport)| +| | | 9600 (metrics) + +## Uninstall the CFGOV Helm Chart + +Running `helm-uninstall.sh` will uninstall the helm deploymennt of the CFGOV Helm Chart, as well as remove Persistent Volume Claims for the Open Search Pod and the Postgresql Pod. \ No newline at end of file diff --git a/helm-init.sh b/helm-init.sh index b9900dac43c..f3a5252231e 100755 --- a/helm-init.sh +++ b/helm-init.sh @@ -1,86 +1,88 @@ #!/bin/bash -# Function to display usage -usage() { - echo "Usage: $0 [--release ]" - exit 1 -} - -# Parse command-line arguments -while [[ "$#" -gt 0 ]]; do - case $1 in - --release) - RELEASE_NAME="$2" - shift - ;; - *) - usage - ;; - esac - shift -done +# Define color codes for pretty output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +OUTPUT_FILE=$(mktemp) +# Check if helm is installed if ! command -v helm &> /dev/null; then - echo "helm could not be found. Please install it before running this script." + echo -e "${RED}Helm could not be found. Please install it before running this script.${NC}" exit 1 fi - +# Check if kubectl is installed if ! command -v kubectl &> /dev/null; then - echo "kubectl could not be found. Please install it before running this script." + echo -e "${RED}Kubectl could not be found. Please install it before running this script.${NC}" exit 1 fi +if ! docker images | grep -q "cfgov"; then + echo -e "${RED}Docker images 'cfgov' could not be found." + echo -e "Please run:{$NC} docker build . -t cfgov:latest" + exit 1 +fi + +# Get the current Kubernetes cluster context CLUSTER=$(kubectl config current-context) +# Check if a Kubernetes cluster is configured if [ -z "$CLUSTER" ]; then - echo "No Kubernetes cluster is currently configured. Please configure a cluster before running this script." + echo -e "${RED}No Kubernetes cluster is currently configured. Please configure a cluster before running this script.${NC}" exit 1 fi -echo $CLUSTER +echo -e "${GREEN}Current Kubernetes cluster: $CLUSTER${NC}" +# Check if the current cluster is a local cluster (docker-desktop or colima) if [[ "$CLUSTER" != "docker-desktop" && "$CLUSTER" != "colima" ]]; then - echo "" - echo -e "This script is intended to be run on a local Kubernetes cluster (i.e. docker-desktop or colima). The current cluster is $CLUSTER." - echo -e "Your current cluster is $CLUSTER." + echo -e "${YELLOW}" + echo -e "This script is intended to be run on a local Kubernetes cluster (i.e. docker-desktop or colima)." + echo -e "Your current cluster is ${RED}$CLUSTER${YELLOW}." echo -e "Please switch to docker-desktop or colima before running this script." - echo "" - echo "" - echo "Exiting helm-init" + echo -e "${NC}" + echo -e "${RED}Exiting helm-init${NC}" exit 1 fi +# Define the Helm directory HELM_DIR="./helm" -if [ -n "$RELEASE_NAME" ]; then - echo "Release name: $RELEASE_NAME" -else - echo "No release name provided." - echo "Using default release name: 'cfgov'" - RELEASE_NAME="cfgov" -fi +# Check if the ./cfgov/apache directory exists if [ -d "./cfgov/apache" ]; then - echo "Moving ./cfgov/apache to $HELM_DIR" + echo -e "${GREEN}Moving ./cfgov/apache to $HELM_DIR${NC}" cp -r ./cfgov/apache $HELM_DIR else - echo "Directory ./cfgov/apache does not exist." + echo -e "${RED}Directory ./cfgov/apache does not exist.${NC}" exit 1 fi -if [! -d ./helm/charts]; then - echo "Building Helm charts..." - helm repo update +# Check if the ./helm/charts directory exists +if [ ! -d "./helm/charts" ]; then + echo -e "${GREEN}Building Helm charts...${NC}" + helm dependency update $HELM_DIR helm dependency build $HELM_DIR else - if [ -z $SKIP_DEP_UPDATE ]; then - echo "Updating Helm dependencies..." + # Update Helm dependencies if SKIP_DEP_UPDATE is not set + if [ -z "$SKIP_DEP_UPDATE" ]; then + echo -e "${GREEN}Updating Helm dependencies...${NC}" helm dependency update $HELM_DIR fi fi -helm upgrade --install $RELEASE_NAME $HELM_DIR -f $HELM_DIR/values.yaml +# Upgrade or install the Helm release +echo -e "${GREEN}Upgrading/Installing Helm release...${NC}" +helm upgrade --install cfgov $HELM_DIR -f $HELM_DIR/values.local.yaml >> $OUTPUT_FILE 2>&1 +# Remove the copied apache directory +echo -e "${GREEN}Cleaning up...${NC}" rm -r $HELM_DIR/apache +echo -e "${GREEN}Helm initialization script completed successfully.${NC}" + +cat $OUTPUT_FILE +rm $OUTPUT_FILE \ No newline at end of file diff --git a/helm-uninstall.sh b/helm-uninstall.sh new file mode 100755 index 00000000000..9e733fae1a9 --- /dev/null +++ b/helm-uninstall.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Define color codes for pretty output +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' # No Color + +# Check if helm is installed +if ! command -v helm &> /dev/null; then + echo -e "${RED}Helm could not be found. Please install it before running this script.${NC}" + exit 1 +fi + +# Define the release name and namespace +RELEASE_NAME="cfgov" +NAMESPACE="default" + +# Uninstall the Helm release +echo -e "${GREEN}Uninstalling Helm release ${RELEASE_NAME}...${NC}" +helm uninstall $RELEASE_NAME --namespace $NAMESPACE + +# Uninstall the PVCs for the PostgreSQL and OpenSearch pods +kubectl delete pvc data-cfgov-postgresql-0 --namespace $NAMESPACE +kubectl delete pvc opensearch-cluster-master-opensearch-cluster-master-0 --namespace $NAMESPACE + +# Check if the uninstall was successful +if [ $? -eq 0 ]; then + echo -e "${GREEN}Helm release ${RELEASE_NAME} uninstalled successfully.${NC}" +else + echo -e "${RED}Failed to uninstall Helm release ${RELEASE_NAME}.${NC}" + exit 1 +fi + +# Optionally, delete the namespace if it was created specifically for this release +# echo -e "${GREEN}Deleting namespace ${NAMESPACE}...${NC}" +# kubectl delete namespace $NAMESPACE + +echo -e "${GREEN}Helm uninstallation script completed successfully.${NC}" \ No newline at end of file diff --git a/helm/Chart.lock b/helm/Chart.lock index 64852467f22..4a1f9399b9e 100644 --- a/helm/Chart.lock +++ b/helm/Chart.lock @@ -2,11 +2,8 @@ dependencies: - name: postgresql repository: https://charts.bitnami.com/bitnami version: 16.2.3 -- name: pgadmin4 - repository: https://helm.runix.net - version: 1.33.3 - name: opensearch repository: https://opensearch-project.github.io/helm-charts/ version: 1.31.3 -digest: sha256:a9576d12585500d4f1e276d7d35b077f45b734cc2972183d519b60c0283980da -generated: "2024-12-10T07:53:25.026703-07:00" +digest: sha256:9a8a22b89a2f2c3c3d9ab178dc0b751c75d95e37215baf42a27b80982469efe0 +generated: "2024-12-10T15:35:50.786246-07:00" diff --git a/helm/Chart.yaml b/helm/Chart.yaml index d7b69fb4190..043b61a6f09 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -18,9 +18,6 @@ dependencies: - name: postgresql version: 16.2.3 repository: https://charts.bitnami.com/bitnami - - name: pgadmin4 - version: 1.33.3 - repository: https://helm.runix.net - name: opensearch version: 1.31.3 repository: https://opensearch-project.github.io/helm-charts/ \ No newline at end of file diff --git a/helm/charts/pgadmin4-1.33.3.tgz b/helm/charts/pgadmin4-1.33.3.tgz deleted file mode 100644 index dc4e3ab388c2ba7d5790ed94b6434d900c0c0d92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14763 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 F0RTN2*DL@4 diff --git a/helm/notes/NOTES-local.txt b/helm/notes/NOTES-local.txt new file mode 100644 index 00000000000..18ca475f325 --- /dev/null +++ b/helm/notes/NOTES-local.txt @@ -0,0 +1,37 @@ +The following pods have been deployed to your cluster: + +PostgreSQL: + - Service Name: postgres + - Internal Port: 5432 + + To access PostgreSQL, run the following commands: + export POSTGRES_POD=$(kubectl get pods -l "statefulset.kubernetes.io/pod-name=cfgov-postgresql-0" -o jsonpath="{.items[0].metadata.name}") + export POSTGRES_PORT=$(kubectl get pod $POSTGRES_POD -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "PostgreSQL is running on internal port $POSTGRES_PORT" + kubectl port-forward $POSTGRES_POD 5432:$POSTGRES_PORT + Visit PostgreSQL at: http://127.0.0.1:5432 + +OpenSearch: + - Service Name: opensearch + - Http Internal Port: 9200 + - Transport Internal Port: 9300 + - Metrics Internal Port: 9600 + + To access OpenSearch Metrics, run the following commands: + export OPENSEARCH_POD=$(kubectl get pods -l "statefulset.kubernetes.io/pod-name=opensearch-cluster-master-0" -o jsonpath="{.items[0].metadata.name}") + export OPENSEARCH_PORT=$(kubectl get pod $OPENSEARCH_POD -o jsonpath="{.spec.containers[0].ports[2].containerPort}") + echo "OpenSearch Metrics is running on internal port $OPENSEARCH_PORT" + kubectl port-forward $OPENSEARCH_POD 9600:$OPENSEARCH_PORT + Visit OpenSearch at: http://127.0.0.1:9600 + +cfgov: + - Service Name: cfgov + - Applicaiton Port: 8000 + - Apache Port: 80 + + To access cfgov, run the following commands: + export CFGOV_POD=$(kubectl get pods -l "app.kubernetes.io/name=cfgov" -o jsonpath="{.items[0].metadata.name}") + export CFGOV_PORT=$(kubectl get pod $CFGOV_POD -o jsonpath="{.spec.containers[1].ports[0].containerPort}") + echo "cfgov is running on internal port $CFGOV_PORT" + kubectl port-forward $CFGOV_POD 8080:$CFGOV_PORT + Visit cfgov at: http://127.0.0.1:8080 \ No newline at end of file diff --git a/helm/notes/NOTES-production.txt b/helm/notes/NOTES-production.txt new file mode 100644 index 00000000000..1ab4bed12ad --- /dev/null +++ b/helm/notes/NOTES-production.txt @@ -0,0 +1 @@ +Uh-oh, we're not in production yet. :P \ No newline at end of file diff --git a/helm/templates/NOTES.txt b/helm/templates/NOTES.txt index 69274dcb9e4..74fc207e47c 100644 --- a/helm/templates/NOTES.txt +++ b/helm/templates/NOTES.txt @@ -1,22 +1,5 @@ -1. Get the application URL by running these commands: -{{- if .Values.ingress.enabled }} -{{- range $host := .Values.ingress.hosts }} - {{- range .paths }} - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} - {{- end }} -{{- end }} -{{- else if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "cfgov.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.service.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "cfgov.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "cfgov.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.service.port }} -{{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "cfgov.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT -{{- end }} +{{- if .Values.localDeployment }} +{{ .Files.Get "notes/NOTES-local.txt" }} +{{- else }} +{{ .Files.Get "notes/NOTES-production.txt" }} +{{- end }} \ No newline at end of file diff --git a/helm/templates/tests/test-connection.yaml b/helm/templates/tests/test-connection.yaml index 0962c9f1233..75a8c44f928 100644 --- a/helm/templates/tests/test-connection.yaml +++ b/helm/templates/tests/test-connection.yaml @@ -1,3 +1,4 @@ +{{- if .Values.tests.enabled }} apiVersion: v1 kind: Pod metadata: @@ -13,3 +14,4 @@ spec: command: ['wget'] args: ['{{ include "cfgov.fullname" . }}:{{ .Values.service.port }}'] restartPolicy: Never +{{- end }} \ No newline at end of file diff --git a/helm/values.yaml b/helm/values.local.yaml similarity index 98% rename from helm/values.yaml rename to helm/values.local.yaml index 248edd3023b..525e7ca9529 100644 --- a/helm/values.yaml +++ b/helm/values.local.yaml @@ -5,6 +5,11 @@ # This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ replicaCount: 1 +tests: + enabled: false + +localDeployment: true + initContainers: - name: wait-for-db image: @@ -125,7 +130,7 @@ serviceAccount: podAnnotations: {} # This is for setting Kubernetes Labels to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ -podLabels: {} +podLabels: {"app.kubernetes.io/name": "cfgov"} podSecurityContext: {} # fsGroup: 2000 @@ -213,6 +218,8 @@ affinity: {} postgresql: + labels: + app: cfgov-postgresql global: postgresql: auth: From d305d01810948566d59247427d3dc394dd186eab Mon Sep 17 00:00:00 2001 From: cooldragontattoo Date: Wed, 11 Dec 2024 07:50:34 -0700 Subject: [PATCH 12/29] add apache image and remove apache volumes from values-yaml --- cfgov/apache/dockerfile | 24 +++++++++++++++++++ helm-init.sh | 8 +++++-- helm/values.local.yaml | 51 ++--------------------------------------- 3 files changed, 32 insertions(+), 51 deletions(-) create mode 100644 cfgov/apache/dockerfile diff --git a/cfgov/apache/dockerfile b/cfgov/apache/dockerfile new file mode 100644 index 00000000000..587e698969a --- /dev/null +++ b/cfgov/apache/dockerfile @@ -0,0 +1,24 @@ +FROM httpd:latest + +# Copy the Apache configuration file +COPY ./conf /usr/local/apache2/conf +COPY ./conf.d /usr/local/apache2/conf.d +COPY ./conf.modules.d /usr/local/apache2/conf.modules.d + +# Add Apache ENV variables +ENV APACHE_PORT="80" +ENV APACHE_USER="www-data" +ENV APACHE_GROUP="www-data" +ENV APACHE_SERVER_ROOT="/usr/local/apache2/" +ENV APACHE_UPLOADS_F_ALIAS="/src/consumerfinance.gov/cfgov/f/" +ENV STATIC_PATH="/tmp" +ENV ERROR_LOG="/proc/self/fd/2" +ENV ACCESS_LOG="/proc/self/fd/1" +ENV LIMIT_REQUEST_BODY="0" +ENV APACHE_STATUS_ALLOW_FROM="127.0.0.1" +ENV APACHE_PROCESS_COUNT="4" +ENV CFGOV_APPLICATION_HOST="localhost" + +EXPOSE 80 + +CMD ["httpd-foreground"] \ No newline at end of file diff --git a/helm-init.sh b/helm-init.sh index f3a5252231e..1ff9600a5fa 100755 --- a/helm-init.sh +++ b/helm-init.sh @@ -22,8 +22,12 @@ fi if ! docker images | grep -q "cfgov"; then echo -e "${RED}Docker images 'cfgov' could not be found." - echo -e "Please run:{$NC} docker build . -t cfgov:latest" - exit 1 + docker build . -t cfgov +fi + +if ! docker images | grep -q "cfgov-apache"; then + echo -e "${RED}Docker images 'cfgov-apache' could not be found." + docker build ./cfgov/apache/. -t cfgov-apache fi # Get the current Kubernetes cluster context diff --git a/helm/values.local.yaml b/helm/values.local.yaml index 525e7ca9529..3eea3d94f8c 100644 --- a/helm/values.local.yaml +++ b/helm/values.local.yaml @@ -66,46 +66,10 @@ containers: value: "9200" - name: cfgov-apache image: - repository: httpd - pullPolicy: IfNotPresent + repository: cfgov-apache + pullPolicy: Never tag: "latest" port: 80 - env: - - name: APACHE_PORT - value: "80" - - name: APACHE_USER - value: "www-data" - - name: APACHE_GROUP - value: "www-data" - - name: APACHE_SERVER_ROOT - value: "/usr/local/apache2/" - - name: APACHE_UPLOADS_F_ALIAS - value: "/src/consumerfinance.gov/cfgov/f/" - - name: STATIC_PATH - value: "/tmp" - - name: ERROR_LOG - value: "/proc/self/fd/2" - - name: ACCESS_LOG - value: "/proc/self/fd/1" - - name: LIMIT_REQUEST_BODY - value: "0" - - name: APACHE_STATUS_ALLOW_FROM - value: "127.0.0.1" - - name: APACHE_PROCESS_COUNT - value: "4" - - name: CFGOV_APPLICATION_HOST - value: "localhost" - # command: - # - 'sh' - # - '-c' - # - 'sleep 1000' - volumeMounts: - - name: apache-conf - mountPath: /usr/local/apache2/conf - - name: apache-confd - mountPath: /usr/local/apache2/conf.d - - name: apache-conf-modules - mountPath: /usr/local/apache2/conf.modules.d # This is for the secretes for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ imagePullSecrets: [] @@ -193,17 +157,6 @@ autoscaling: targetCPUUtilizationPercentage: 80 # targetMemoryUtilizationPercentage: 80 -# Additional volumes on the output Deployment definition. -volumes: -- name: apache-conf - configMap: - name: apache-conf-config -- name: apache-confd - configMap: - name: apache-confd-config -- name: apache-conf-modules - configMap: - name: apache-conf-modules-config # Additional volumeMounts on the output Deployment definition. volumeMounts: [] # - name: foo From 44b57343a6e54e6caa0060159358f9cd20c42aec Mon Sep 17 00:00:00 2001 From: cooldragontattoo <43133807+cooldragontattoo@users.noreply.github.com> Date: Thu, 19 Dec 2024 06:34:00 -0700 Subject: [PATCH 13/29] remove python command Co-authored-by: Will Barton --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index fc5e84c8357..66a3462d5f8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -172,4 +172,3 @@ USER $USERNAME # Run Gunicorn CMD gunicorn --reload cfgov.wsgi:application -b :8000 -# CMD python ./cfgov/manage.py runserver 0.0.0.0:8000 From 03d7618ef198abff0fe2c4a0ed62b8b32c302107 Mon Sep 17 00:00:00 2001 From: cooldragontattoo <43133807+cooldragontattoo@users.noreply.github.com> Date: Thu, 19 Dec 2024 06:39:35 -0700 Subject: [PATCH 14/29] Update cfgov/apache/dockerfile Co-authored-by: Will Barton --- cfgov/apache/dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfgov/apache/dockerfile b/cfgov/apache/dockerfile index 587e698969a..f387b7306e9 100644 --- a/cfgov/apache/dockerfile +++ b/cfgov/apache/dockerfile @@ -1,4 +1,4 @@ -FROM httpd:latest +FROM httpd:2.4-alpine # Copy the Apache configuration file COPY ./conf /usr/local/apache2/conf From 5048fa7ecafcfc674b0bcc396f0fed2f12a6e731 Mon Sep 17 00:00:00 2001 From: cooldragontattoo Date: Thu, 19 Dec 2024 10:45:43 -0700 Subject: [PATCH 15/29] update docker copy --- .gitignore | 3 +++ Dockerfile | 4 +++- helm/charts/opensearch-1.31.3.tgz | Bin 26089 -> 0 bytes helm/charts/postgresql-16.2.3.tgz | Bin 79787 -> 0 bytes 4 files changed, 6 insertions(+), 1 deletion(-) delete mode 100644 helm/charts/opensearch-1.31.3.tgz delete mode 100644 helm/charts/postgresql-16.2.3.tgz diff --git a/.gitignore b/.gitignore index f33e4c7941b..453b413ae6a 100755 --- a/.gitignore +++ b/.gitignore @@ -156,3 +156,6 @@ cfgov/apache/modules # Local Docker-Compose Files # ############################## docker-compose.pgadmin.yml + +# Helm # +helm/charts/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 66a3462d5f8..19471a494f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -150,7 +150,9 @@ ENV ALLOWED_HOSTS '["*"]' # Copy the application code over COPY cfgov ./cfgov/ COPY static.in ./static.in/ -COPY . . +COPY refresh-data.sh . +COPY index.sh . +COPY test.sql.gz . # Copy our static build over from node-builder COPY --from=node-builder ${APP_HOME} ${APP_HOME} diff --git a/helm/charts/opensearch-1.31.3.tgz b/helm/charts/opensearch-1.31.3.tgz deleted file mode 100644 index dc938cf8f58a7de118f8565883d2e4d3c147ccfc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26089 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

B_ArsApf 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 Date: Thu, 26 Dec 2024 08:22:33 -0700 Subject: [PATCH 16/29] disable use_ssl for opensearch --- cfgov/cfgov/settings/local.py | 2 ++ cfgov/cfgov/settings/test.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/cfgov/cfgov/settings/local.py b/cfgov/cfgov/settings/local.py index df40e7f7c9c..bc94be4a0df 100644 --- a/cfgov/cfgov/settings/local.py +++ b/cfgov/cfgov/settings/local.py @@ -104,3 +104,5 @@ # If DEPLOY_ENVIRONMENT hasn't been set by the environment in base.py, # default it to local. DEPLOY_ENVIRONMENT = DEPLOY_ENVIRONMENT or "local" + +OPENSEARCH_DSL["default"]["use_ssl"] = False \ No newline at end of file diff --git a/cfgov/cfgov/settings/test.py b/cfgov/cfgov/settings/test.py index 3ac5ec358a0..3b882db73aa 100644 --- a/cfgov/cfgov/settings/test.py +++ b/cfgov/cfgov/settings/test.py @@ -65,6 +65,8 @@ OPENSEARCH_DSL_AUTO_REFRESH = False OPENSEARCH_DSL_AUTOSYNC = False +OPENSEARCH_DSL["default"]["use_ssl"] = False + SKIP_DJANGO_MIGRATIONS = os.getenv("SKIP_DJANGO_MIGRATIONS", False) if SKIP_DJANGO_MIGRATIONS: From 6e991e8b94df686b61daefb1172f6e178e4fbe31 Mon Sep 17 00:00:00 2001 From: cooldragontattoo Date: Thu, 26 Dec 2024 08:34:08 -0700 Subject: [PATCH 17/29] add comments --- cfgov/cfgov/settings/local.py | 1 + cfgov/cfgov/settings/test.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/cfgov/cfgov/settings/local.py b/cfgov/cfgov/settings/local.py index bc94be4a0df..f3fa46f4948 100644 --- a/cfgov/cfgov/settings/local.py +++ b/cfgov/cfgov/settings/local.py @@ -105,4 +105,5 @@ # default it to local. DEPLOY_ENVIRONMENT = DEPLOY_ENVIRONMENT or "local" +# Disable use_ssl for functional tests OPENSEARCH_DSL["default"]["use_ssl"] = False \ No newline at end of file diff --git a/cfgov/cfgov/settings/test.py b/cfgov/cfgov/settings/test.py index 3b882db73aa..a50cf13331b 100644 --- a/cfgov/cfgov/settings/test.py +++ b/cfgov/cfgov/settings/test.py @@ -65,6 +65,8 @@ OPENSEARCH_DSL_AUTO_REFRESH = False OPENSEARCH_DSL_AUTOSYNC = False + +# Disable `use_ssl` for unit tests OPENSEARCH_DSL["default"]["use_ssl"] = False From d37c4deae640f350282595108fde3daff73712a1 Mon Sep 17 00:00:00 2001 From: cooldragontattoo Date: Thu, 26 Dec 2024 13:49:04 -0700 Subject: [PATCH 18/29] remove apache config files --- helm/templates/apache-conf-config.yaml | 6 ------ helm/templates/apache-conf-modules-config.yaml | 6 ------ helm/templates/apache-confd-config.yaml | 6 ------ 3 files changed, 18 deletions(-) delete mode 100644 helm/templates/apache-conf-config.yaml delete mode 100644 helm/templates/apache-conf-modules-config.yaml delete mode 100644 helm/templates/apache-confd-config.yaml diff --git a/helm/templates/apache-conf-config.yaml b/helm/templates/apache-conf-config.yaml deleted file mode 100644 index d100a6c3e3a..00000000000 --- a/helm/templates/apache-conf-config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: apache-conf-config -data: - {{ (.Files.Glob "apache/conf/*").AsConfig | nindent 2 }} \ No newline at end of file diff --git a/helm/templates/apache-conf-modules-config.yaml b/helm/templates/apache-conf-modules-config.yaml deleted file mode 100644 index 25936b2c8d1..00000000000 --- a/helm/templates/apache-conf-modules-config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: apache-conf-modules-config -data: - {{ (.Files.Glob "apache/conf.modules.d/*").AsConfig | nindent 2 }} \ No newline at end of file diff --git a/helm/templates/apache-confd-config.yaml b/helm/templates/apache-confd-config.yaml deleted file mode 100644 index e00b29cf811..00000000000 --- a/helm/templates/apache-confd-config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: apache-confd-config -data: - {{ (.Files.Glob "apache/conf.d/*").AsConfig | nindent 2 }} \ No newline at end of file From ac887c8824a83e704c9156c02da95ea28f484918 Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Mon, 6 Jan 2025 15:21:47 -0500 Subject: [PATCH 19/29] Documentation fixups --- docs/{K8s-deplyoment.md => running-k8s.md} | 63 ++++++++++++---------- mkdocs.yml | 1 + 2 files changed, 36 insertions(+), 28 deletions(-) rename docs/{K8s-deplyoment.md => running-k8s.md} (57%) diff --git a/docs/K8s-deplyoment.md b/docs/running-k8s.md similarity index 57% rename from docs/K8s-deplyoment.md rename to docs/running-k8s.md index de6a1d901ba..88ad8836026 100644 --- a/docs/K8s-deplyoment.md +++ b/docs/running-k8s.md @@ -1,6 +1,6 @@ -# Helm Deployment Guide +# Running in Kubernetes -This document provides a comprehensive guide to setting up, deploying, and uninstalling your Helm deployment. +This document provides a comprehensive guide to running in Kubernetes using Helm. ## Table of Contents @@ -20,14 +20,16 @@ This guide explains the setup and deployment process for the CFPB Helm Chart, wh ## Requirements 1. **Local Kubernetes Cluster**: - - Ensure you have a local Kubernetes cluster running. We only support [Docker Desktop](https://www.docker.com/products/docker-desktop) and [colima](https://github.com/abiosoft/colima). + + - Ensure you have a local Kubernetes cluster running. We only support [Docker Desktop](https://www.docker.com/products/docker-desktop) and [colima](https://github.com/abiosoft/colima). 2. **kubectl**: - - Install `kubectl`, the Kubernetes command-line tool, by following the [official installation guide](https://kubernetes.io/docs/tasks/tools/install-kubectl/). + + - Install `kubectl`, the Kubernetes command-line tool, by following the [official installation guide](https://kubernetes.io/docs/tasks/tools/install-kubectl/). 3. **Helm**: - - Install Helm, the package manager for Kubernetes, by following the [official installation guide](https://helm.sh/docs/intro/install/). + - Install Helm, the package manager for Kubernetes, by following the [official installation guide](https://helm.sh/docs/intro/install/). ## Helm Chart @@ -40,33 +42,37 @@ In our `chart.yaml` we bring two Helm chart dependencies: ### values.yaml -The `values.yaml` file contains our local configuration for the deployment of CFGOV. +The `values.yaml` file contains our local configuration for the deployment of CFGOV. #### Init Containers + We have two init containers: 1. Busybox: -- Starts up once we have our Postgresql and Opensearch Pods running. -- Serves as a pre-cursor to our cfgov-migrations container. + + - Starts up once we have our Postgresql and Opensearch Pods running. + - Serves as a pre-cursor to our cfgov-migrations container. 2. cfgov-migrations -- Runs the django migrations and the `refresh-data.sh` script and populates it with test data `test.sql.gz`. -- Indexes our database to Opensearch. + + - Runs the django migrations and the `refresh-data.sh` script and populates it with test data `test.sql.gz`. + - Indexes our database to Opensearch. #### Containers 1. cfgov: -- Uses the cfgov image, found in the repo's root `dockerfile` -- Serves up our Django application on Port 8000 of the cfgov pod + + - Uses the cfgov image, found in the repo's root `dockerfile` + - Serves up our Django application on Port 8000 of the cfgov pod 2. cfgov-apache: -- Built from `cfgov-apache` image built from the `apache/dockerfile` -- Serves as a webserver to proxy to our cfgov container + - Built from `cfgov-apache` image built from the `apache/dockerfile` + - Serves as a webserver to proxy to our cfgov container ### notes.txt -Our [notes.txt](https://helm.sh/docs/chart_template_guide/notes_files/) is split to work for local deployments and deployments to production. +Our [notes.txt](https://helm.sh/docs/chart_template_guide/notes_files/) is split to work for local deployments and deployments to production. ```txt {{- if .Values.localDeployment }} @@ -78,29 +84,30 @@ Our [notes.txt](https://helm.sh/docs/chart_template_guide/notes_files/) is split ## Deploying the CFGOV Helm Chart -Deploying the CFGOV Helm chart is simple with the `helm-init.sh` script. +Deploying the CFGOV Helm chart is simple with the `helm-init.sh` script. To deploy the CFGOV Helm Chart you must: + 1. make sure you have a the cfgov and cfgov-apache image built 2. have a local K8s cluster running (docker desktop, colima) -If these criteria are not met, the `helm-init.sh` script will not run. +If these criteria are not met, the `helm-init.sh` script will not run. ## Viewing the Helm Chart -You can either user a K8s IDE ([lens](https://k8slens.dev/), [k9s](https://k9scli.io)) or manually portfward to view the application running. +You can either user a K8s IDE ([lens](https://k8slens.dev/), [k9s](https://k9scli.io)) or manually portfward to view the application running. -Review the output of your deployment for more information on manually portforwarding. +Review the output of your deployment for more information on manually portforwarding. -|Pod|Container|Port| -|-|-|-| -|cfgov|cfgov|8000| -|cfgov|cfogv-apache|80| -|postgresql|postgresql|5432| -|opensearch|opensearch|9200 (http)| -| | | 9300 (transport)| -| | | 9600 (metrics) +| Pod | Container | Port | +| ---------- | ------------ | ---------------- | +| cfgov | cfgov | 8000 | +| cfgov | cfogv-apache | 80 | +| postgresql | postgresql | 5432 | +| opensearch | opensearch | 9200 (http) | +| | | 9300 (transport) | +| | | 9600 (metrics) | ## Uninstall the CFGOV Helm Chart -Running `helm-uninstall.sh` will uninstall the helm deploymennt of the CFGOV Helm Chart, as well as remove Persistent Volume Claims for the Open Search Pod and the Postgresql Pod. \ No newline at end of file +Running `helm-uninstall.sh` will uninstall the helm deploymennt of the CFGOV Helm Chart, as well as remove Persistent Volume Claims for the Open Search Pod and the Postgresql Pod. diff --git a/mkdocs.yml b/mkdocs.yml index 3edd2ef008a..fc7f67b0933 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -8,6 +8,7 @@ nav: - Running this Project: - Running in a Virtual Environment: running-virtualenv.md - Running in Docker: running-docker.md + - Running in Kubernetes: running-k8s.md - Running documentation site locally: running-docs.md - Debugging and Monitoring: debugging-monitoring.md - Artifacts and Deployment: deployment.md From 078dbe73ba8298ec82a5f142dd843c9c18dd988e Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Mon, 6 Jan 2025 16:03:04 -0500 Subject: [PATCH 20/29] Make "helm lint" pass in strict mode --- helm/Chart.yaml | 5 +++-- helm/values.yaml | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 helm/values.yaml diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 043b61a6f09..a5635190897 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,6 +2,7 @@ apiVersion: v2 name: cfgov description: A Helm chart for consumerfinance.gov type: application +icon: https://www.consumerfinance.gov/static/icon.svg # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. @@ -12,7 +13,7 @@ version: 0.1.0 # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: '1.16.0' dependencies: - name: postgresql @@ -20,4 +21,4 @@ dependencies: repository: https://charts.bitnami.com/bitnami - name: opensearch version: 1.31.3 - repository: https://opensearch-project.github.io/helm-charts/ \ No newline at end of file + repository: https://opensearch-project.github.io/helm-charts/ diff --git a/helm/values.yaml b/helm/values.yaml new file mode 100644 index 00000000000..33447f52ca2 --- /dev/null +++ b/helm/values.yaml @@ -0,0 +1,4 @@ +# This file is deliberately empty. +# In order to pass "helm lint", a values.yaml file must exist. +# Per https://helm.sh/docs/topics/charts/#values-files, +# "The default values file included inside of a chart must be named values.yaml." From 7503f7558e427dee805095b2062e5542fad97367 Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Tue, 7 Jan 2025 08:01:47 -0500 Subject: [PATCH 21/29] Add GitHub Action to test Helm --- .github/workflows/helm.yml | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/helm.yml diff --git a/.github/workflows/helm.yml b/.github/workflows/helm.yml new file mode 100644 index 00000000000..650bc3f7a0c --- /dev/null +++ b/.github/workflows/helm.yml @@ -0,0 +1,39 @@ +name: Helm testing +on: + pull_request: + paths: + - helm/** + push: + +jobs: + helm: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install Helm + uses: azure/setup-helm@v4 + + - name: Install Helm dependencies + run: helm dependency update helm + + - name: Lint Helm chart + run: helm lint --strict -f helm/values.local.yaml helm + + - name: Install Minikube + uses: manusa/actions-setup-minikube@v2.13.0 + with: + minikube version: v1.34.0 + kubernetes version: v1.32.0 + + - name: Setup Kubernetes context + run: kubectl config use-context minikube + + - name: Install and test Helm chart + run: | + helm install cfgov helm \ + -f helm/values.local.yaml \ + --namespace cfgov \ + --create-namespace + helm test cfgov --namespace cfgov From fa887fc997979fbde2f5e38568539a19661d1d5d Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Tue, 7 Jan 2025 08:54:15 -0500 Subject: [PATCH 22/29] Iterating --- .gitignore | 5 +++-- helm-init.sh | 17 ++++++++++------- helm-uninstall.sh | 5 ++++- helm/notes/NOTES-local.txt | 4 ++-- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 453b413ae6a..7034c650246 100755 --- a/.gitignore +++ b/.gitignore @@ -146,6 +146,7 @@ cfgov/regulations3k/jinja2/regulations3k/workbox-*.js cfgov/regulations3k/jinja2/regulations3k/workbox-*.js.map # Helm Charts # +helm/apache/ helm/charts/ # Apache # @@ -157,5 +158,5 @@ cfgov/apache/modules ############################## docker-compose.pgadmin.yml -# Helm # -helm/charts/ \ No newline at end of file +# Helm # +helm/charts/ diff --git a/helm-init.sh b/helm-init.sh index 1ff9600a5fa..f308a569118 100755 --- a/helm-init.sh +++ b/helm-init.sh @@ -1,5 +1,8 @@ #!/bin/bash +# Fail if any command fails. +set -e + # Define color codes for pretty output RED='\033[0;31m' GREEN='\033[0;32m' @@ -20,13 +23,13 @@ if ! command -v kubectl &> /dev/null; then exit 1 fi -if ! docker images | grep -q "cfgov"; then - echo -e "${RED}Docker images 'cfgov' could not be found." - docker build . -t cfgov +if ! docker images -q --filter=reference='cfgov' | grep -q .; then + echo -e "${RED}Docker image 'cfgov' could not be found." + docker build . -t cfgo fi -if ! docker images | grep -q "cfgov-apache"; then - echo -e "${RED}Docker images 'cfgov-apache' could not be found." +if ! docker images -q --filter=reference='cfgov-apache' | grep -q .; then + echo -e "${RED}Docker image 'cfgov-apache' could not be found." docker build ./cfgov/apache/. -t cfgov-apache fi @@ -76,7 +79,7 @@ else echo -e "${GREEN}Updating Helm dependencies...${NC}" helm dependency update $HELM_DIR fi -fi +fi # Upgrade or install the Helm release echo -e "${GREEN}Upgrading/Installing Helm release...${NC}" @@ -89,4 +92,4 @@ rm -r $HELM_DIR/apache echo -e "${GREEN}Helm initialization script completed successfully.${NC}" cat $OUTPUT_FILE -rm $OUTPUT_FILE \ No newline at end of file +rm $OUTPUT_FILE diff --git a/helm-uninstall.sh b/helm-uninstall.sh index 9e733fae1a9..0a4f2075407 100755 --- a/helm-uninstall.sh +++ b/helm-uninstall.sh @@ -1,5 +1,8 @@ #!/bin/bash +# Fail if any command fails. +set -e + # Define color codes for pretty output RED='\033[0;31m' GREEN='\033[0;32m' @@ -35,4 +38,4 @@ fi # echo -e "${GREEN}Deleting namespace ${NAMESPACE}...${NC}" # kubectl delete namespace $NAMESPACE -echo -e "${GREEN}Helm uninstallation script completed successfully.${NC}" \ No newline at end of file +echo -e "${GREEN}Helm uninstallation script completed successfully.${NC}" diff --git a/helm/notes/NOTES-local.txt b/helm/notes/NOTES-local.txt index 18ca475f325..7112ea73a6c 100644 --- a/helm/notes/NOTES-local.txt +++ b/helm/notes/NOTES-local.txt @@ -26,7 +26,7 @@ OpenSearch: cfgov: - Service Name: cfgov - - Applicaiton Port: 8000 + - Application Port: 8000 - Apache Port: 80 To access cfgov, run the following commands: @@ -34,4 +34,4 @@ cfgov: export CFGOV_PORT=$(kubectl get pod $CFGOV_POD -o jsonpath="{.spec.containers[1].ports[0].containerPort}") echo "cfgov is running on internal port $CFGOV_PORT" kubectl port-forward $CFGOV_POD 8080:$CFGOV_PORT - Visit cfgov at: http://127.0.0.1:8080 \ No newline at end of file + Visit cfgov at: http://127.0.0.1:8080 From 81ea3af1550d339a41c7390894b330779996273b Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Tue, 7 Jan 2025 08:55:44 -0500 Subject: [PATCH 23/29] stash --- helm/templates/tests/test-connection.yaml | 4 +- helm/values.local.yaml | 79 ++++++++++++----------- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/helm/templates/tests/test-connection.yaml b/helm/templates/tests/test-connection.yaml index 75a8c44f928..54b79849fea 100644 --- a/helm/templates/tests/test-connection.yaml +++ b/helm/templates/tests/test-connection.yaml @@ -1,4 +1,3 @@ -{{- if .Values.tests.enabled }} apiVersion: v1 kind: Pod metadata: @@ -6,7 +5,7 @@ metadata: labels: {{- include "cfgov.labels" . | nindent 4 }} annotations: - "cfgov.sh/hook": test + "helm.sh/hook": test spec: containers: - name: wget @@ -14,4 +13,3 @@ spec: command: ['wget'] args: ['{{ include "cfgov.fullname" . }}:{{ .Values.service.port }}'] restartPolicy: Never -{{- end }} \ No newline at end of file diff --git a/helm/values.local.yaml b/helm/values.local.yaml index 3eea3d94f8c..dbd8a60c47f 100644 --- a/helm/values.local.yaml +++ b/helm/values.local.yaml @@ -6,46 +6,45 @@ replicaCount: 1 tests: - enabled: false + enabled: true localDeployment: true initContainers: - name: wait-for-db - image: + image: repository: busybox - tag: "latest" - command: - - 'sh' + tag: 'latest' + command: + - 'sh' - '-c' - 'until nc -z cfgov-postgresql 5432; do echo waiting for database; sleep 10; done;' - 'until nc -z opensearch-cluster-master 9200; do echo waiting for opensearch; sleep 10; done;' - name: cfgov-migrations - image: + image: repository: cfgov pullPolicy: Never - tag: "latest" + tag: 'latest' env: - name: DATABASE_URL - value: "postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov" + value: 'postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov' - name: SECRET_KEY - value: "cfgov" + value: 'cfgov' - name: ES_HOST - value: "opensearch-cluster-master" + value: 'opensearch-cluster-master' - name: ES_PORT - value: "9200" - command: + value: '9200' + command: - 'sh' - '-c' - - './refresh-data.sh test.sql.gz' - + - './refresh-data.sh test.sql.gz' containers: - name: cfgov - image: + image: repository: cfgov pullPolicy: Never - tag: "latest" + tag: 'latest' port: 8000 readinessProbe: httpGet: @@ -56,26 +55,26 @@ containers: timeoutSeconds: 1 failedThreshold: 3 env: - - name: DATABASE_URL - value: "postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov" - - name: SECRET_KEY - value: "cfgov" - - name: ES_HOST - value: "opensearch-cluster-master" - - name: ES_PORT - value: "9200" + - name: DATABASE_URL + value: 'postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov' + - name: SECRET_KEY + value: 'cfgov' + - name: ES_HOST + value: 'opensearch-cluster-master' + - name: ES_PORT + value: '9200' - name: cfgov-apache - image: + image: repository: cfgov-apache pullPolicy: Never - tag: "latest" + tag: 'latest' port: 80 # This is for the secretes for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ imagePullSecrets: [] # This is to override the chart name. -nameOverride: "" -fullnameOverride: "" +nameOverride: '' +fullnameOverride: '' # This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ serviceAccount: @@ -87,19 +86,21 @@ serviceAccount: annotations: {} # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template - name: "" + name: '' # This is for setting Kubernetes Annotations to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ podAnnotations: {} # This is for setting Kubernetes Labels to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ -podLabels: {"app.kubernetes.io/name": "cfgov"} +podLabels: { 'app.kubernetes.io/name': 'cfgov' } -podSecurityContext: {} +podSecurityContext: + {} # fsGroup: 2000 -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -117,8 +118,9 @@ service: # This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ ingress: enabled: false - className: "" - annotations: {} + className: '' + annotations: + {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" hosts: @@ -131,7 +133,8 @@ ingress: # hosts: # - chart-example.local -resources: {} +resources: + {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little # resources, such as Minikube. If you do want to specify resources, uncomment the following @@ -169,7 +172,6 @@ tolerations: [] affinity: {} - postgresql: labels: app: cfgov-postgresql @@ -180,11 +182,10 @@ postgresql: username: cfpb password: cfpb - pgadmin4: env: - email: test@domain.com + email: test@domain.com password: test opensearch: - replicas: 1 \ No newline at end of file + replicas: 1 From f5742da0ec121cac3aa9c692b1b1b724d8c9b889 Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Tue, 7 Jan 2025 17:38:50 -0500 Subject: [PATCH 24/29] Working local setup with @cooldragontattoo --- .prettierignore | 1 + Dockerfile | 3 ++- helm-init.sh | 2 +- helm/templates/deployment.yaml | 5 +++-- helm/values.local.yaml | 6 +++++- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.prettierignore b/.prettierignore index 4d66f089cd3..d0a0b33903a 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,6 +6,7 @@ cfgov/retirement_api/data/ cfgov/static_built/ **/fixtures/ collectstatic/ +helm/ # Ignore all HTML files: *.html diff --git a/Dockerfile b/Dockerfile index 19471a494f5..c6ae0fb3735 100644 --- a/Dockerfile +++ b/Dockerfile @@ -151,7 +151,8 @@ ENV ALLOWED_HOSTS '["*"]' COPY cfgov ./cfgov/ COPY static.in ./static.in/ COPY refresh-data.sh . -COPY index.sh . +COPY initial-data.sh . +COPY index.sh . COPY test.sql.gz . # Copy our static build over from node-builder diff --git a/helm-init.sh b/helm-init.sh index f308a569118..c9c771cc6fe 100755 --- a/helm-init.sh +++ b/helm-init.sh @@ -25,7 +25,7 @@ fi if ! docker images -q --filter=reference='cfgov' | grep -q .; then echo -e "${RED}Docker image 'cfgov' could not be found." - docker build . -t cfgo + docker build . -t cfgov fi if ! docker images -q --filter=reference='cfgov-apache' | grep -q .; then diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index 7057db6852b..249e43bf49c 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -4,6 +4,7 @@ metadata: name: {{ include "cfgov.fullname" . }} labels: {{- include "cfgov.labels" . | nindent 4 }} + spec: {{- if not .Values.autoscaling.enabled }} replicas: {{ .Values.replicaCount }} @@ -40,7 +41,7 @@ spec: - name: {{ .name }} value: {{ .value | quote }} {{- end }} - command: + command: {{- range .command }} - {{ . }} {{- end }} @@ -55,7 +56,7 @@ spec: containerPort: {{ .port }} protocol: TCP {{- if .env }} - env: + env: {{- range .env }} - name: {{ .name }} value: {{ .value | quote }} diff --git a/helm/values.local.yaml b/helm/values.local.yaml index dbd8a60c47f..555e798b01c 100644 --- a/helm/values.local.yaml +++ b/helm/values.local.yaml @@ -90,7 +90,11 @@ serviceAccount: # This is for setting Kubernetes Annotations to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ -podAnnotations: {} +podAnnotations: + # Always restart containers, even if the image tag hasn't changed. + # This is currently needed because the crawler image tag is always "main". + # https://v3.helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments + rollme: {{ randAlphaNum 5 | quote }} # This is for setting Kubernetes Labels to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ podLabels: { 'app.kubernetes.io/name': 'cfgov' } From ba645dff8e4594e76765269562d557f18bd79d19 Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Tue, 7 Jan 2025 17:41:48 -0500 Subject: [PATCH 25/29] Don't run against push --- .github/workflows/helm.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/helm.yml b/.github/workflows/helm.yml index 650bc3f7a0c..18f178d9e17 100644 --- a/.github/workflows/helm.yml +++ b/.github/workflows/helm.yml @@ -3,7 +3,6 @@ on: pull_request: paths: - helm/** - push: jobs: helm: From d1dcc2e065a3c4e38e2013d60241a7ccfec56cfd Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Tue, 7 Jan 2025 17:44:43 -0500 Subject: [PATCH 26/29] Rollback unnecessary whitespace changes --- helm/values.local.yaml | 60 +++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/helm/values.local.yaml b/helm/values.local.yaml index 555e798b01c..5e9f3b50547 100644 --- a/helm/values.local.yaml +++ b/helm/values.local.yaml @@ -14,7 +14,7 @@ initContainers: - name: wait-for-db image: repository: busybox - tag: 'latest' + tag: "latest" command: - 'sh' - '-c' @@ -24,27 +24,28 @@ initContainers: image: repository: cfgov pullPolicy: Never - tag: 'latest' + tag: "latest" env: - name: DATABASE_URL - value: 'postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov' + value: "postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov" - name: SECRET_KEY - value: 'cfgov' + value: "cfgov" - name: ES_HOST - value: 'opensearch-cluster-master' + value: "opensearch-cluster-master" - name: ES_PORT - value: '9200' + value: "9200" command: - 'sh' - '-c' - './refresh-data.sh test.sql.gz' + containers: - name: cfgov image: repository: cfgov pullPolicy: Never - tag: 'latest' + tag: "latest" port: 8000 readinessProbe: httpGet: @@ -55,26 +56,26 @@ containers: timeoutSeconds: 1 failedThreshold: 3 env: - - name: DATABASE_URL - value: 'postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov' - - name: SECRET_KEY - value: 'cfgov' - - name: ES_HOST - value: 'opensearch-cluster-master' - - name: ES_PORT - value: '9200' + - name: DATABASE_URL + value: "postgres://cfpb:cfpb@cfgov-postgresql:5432/cfgov" + - name: SECRET_KEY + value: "cfgov" + - name: ES_HOST + value: "opensearch-cluster-master" + - name: ES_PORT + value: "9200" - name: cfgov-apache image: repository: cfgov-apache pullPolicy: Never - tag: 'latest' + tag: "latest" port: 80 # This is for the secretes for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ imagePullSecrets: [] # This is to override the chart name. -nameOverride: '' -fullnameOverride: '' +nameOverride: "" +fullnameOverride: "" # This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ serviceAccount: @@ -86,7 +87,7 @@ serviceAccount: annotations: {} # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template - name: '' + name: "" # This is for setting Kubernetes Annotations to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ @@ -95,16 +96,15 @@ podAnnotations: # This is currently needed because the crawler image tag is always "main". # https://v3.helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments rollme: {{ randAlphaNum 5 | quote }} + # This is for setting Kubernetes Labels to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ -podLabels: { 'app.kubernetes.io/name': 'cfgov' } +podLabels: {"app.kubernetes.io/name": "cfgov"} -podSecurityContext: - {} +podSecurityContext: {} # fsGroup: 2000 -securityContext: - {} +securityContext: {} # capabilities: # drop: # - ALL @@ -122,9 +122,8 @@ service: # This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ ingress: enabled: false - className: '' - annotations: - {} + className: "" + annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" hosts: @@ -137,8 +136,7 @@ ingress: # hosts: # - chart-example.local -resources: - {} +resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little # resources, such as Minikube. If you do want to specify resources, uncomment the following @@ -176,6 +174,7 @@ tolerations: [] affinity: {} + postgresql: labels: app: cfgov-postgresql @@ -186,9 +185,10 @@ postgresql: username: cfpb password: cfpb + pgadmin4: env: - email: test@domain.com + email: test@domain.com password: test opensearch: From d69bcdd89976255ddf39b8d1f34dcf416b5c1a59 Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Tue, 7 Jan 2025 17:46:06 -0500 Subject: [PATCH 27/29] Remove duplicate .gitignore entry for Helm --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7034c650246..c6b8dc59498 100755 --- a/.gitignore +++ b/.gitignore @@ -157,6 +157,3 @@ cfgov/apache/modules # Local Docker-Compose Files # ############################## docker-compose.pgadmin.yml - -# Helm # -helm/charts/ From 4eb70ce7a3a09fe17f8a88526729e8374f6b645b Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Tue, 7 Jan 2025 17:50:43 -0500 Subject: [PATCH 28/29] Fix helm lint --- helm/values.local.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/helm/values.local.yaml b/helm/values.local.yaml index 5e9f3b50547..b9a501ec73c 100644 --- a/helm/values.local.yaml +++ b/helm/values.local.yaml @@ -91,11 +91,11 @@ serviceAccount: # This is for setting Kubernetes Annotations to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ -podAnnotations: - # Always restart containers, even if the image tag hasn't changed. - # This is currently needed because the crawler image tag is always "main". - # https://v3.helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - rollme: {{ randAlphaNum 5 | quote }} +# +# Always restart containers, even if the image tag hasn't changed. +# This is currently needed because the crawler image tag is always "main". +# https://v3.helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments +podAnnotations: {"rollme": "{{ randAlphaNum 5 | quote }}"} # This is for setting Kubernetes Labels to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ From adb6c0bda9a8e4f94d607275ff420b9e820f15db Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Wed, 8 Jan 2025 13:21:11 -0500 Subject: [PATCH 29/29] Don't actually test Helm deployment in GHA --- .github/workflows/helm.yml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/.github/workflows/helm.yml b/.github/workflows/helm.yml index 18f178d9e17..f68c15bcde6 100644 --- a/.github/workflows/helm.yml +++ b/.github/workflows/helm.yml @@ -19,20 +19,3 @@ jobs: - name: Lint Helm chart run: helm lint --strict -f helm/values.local.yaml helm - - - name: Install Minikube - uses: manusa/actions-setup-minikube@v2.13.0 - with: - minikube version: v1.34.0 - kubernetes version: v1.32.0 - - - name: Setup Kubernetes context - run: kubectl config use-context minikube - - - name: Install and test Helm chart - run: | - helm install cfgov helm \ - -f helm/values.local.yaml \ - --namespace cfgov \ - --create-namespace - helm test cfgov --namespace cfgov