Files
pikasTech-unidesk/scripts/native/cicd/compact-native-object.mjs
T
2026-07-03 19:12:08 +00:00

152 lines
6.0 KiB
JavaScript

import { readFileSync } from "node:fs";
const key = process.argv[2] || "";
const input = JSON.parse(readFileSync(0, "utf8"));
function cleanMap(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
const out = {};
for (const [k, v] of Object.entries(value)) {
if (k === "kubectl.kubernetes.io/last-applied-configuration") continue;
out[k] = v;
}
return out;
}
function metadata(obj) {
return {
name: obj?.metadata?.name || null,
namespace: obj?.metadata?.namespace || null,
labels: cleanMap(obj?.metadata?.labels),
annotations: cleanMap(obj?.metadata?.annotations),
};
}
function compactContainer(container) {
return {
name: container?.name || null,
image: container?.image || null,
env: Array.isArray(container?.env)
? container.env.filter((item) => item && typeof item.name === "string" && typeof item.value === "string").map((item) => ({ name: item.name, value: item.value }))
: [],
};
}
function condition(obj, type) {
const conditions = Array.isArray(obj?.status?.conditions) ? obj.status.conditions : [];
return conditions.find((item) => item?.type === type) || conditions[0] || null;
}
function timestampMs(value) {
const parsed = Date.parse(String(value || ""));
return Number.isFinite(parsed) ? parsed : null;
}
function durationSeconds(start, end) {
const s = timestampMs(start);
const e = timestampMs(end);
return s === null || e === null || e < s ? null : Math.round((e - s) / 1000);
}
let output = input;
if (key === "pipelineRun") {
const succeeded = condition(input, "Succeeded");
output = {
apiVersion: input.apiVersion,
kind: input.kind,
metadata: metadata(input),
spec: { params: Array.isArray(input?.spec?.params) ? input.spec.params : [] },
status: {
conditions: Array.isArray(input?.status?.conditions) ? input.status.conditions : [],
startTime: input?.status?.startTime || null,
completionTime: input?.status?.completionTime || null,
durationSeconds: durationSeconds(input?.status?.startTime, input?.status?.completionTime),
succeeded: succeeded?.status || null,
reason: succeeded?.reason || null,
},
};
} else if (key === "taskRuns") {
const items = (Array.isArray(input?.items) ? input.items : []).map((item) => {
const succeeded = condition(item, "Succeeded");
return {
name: item?.metadata?.name || null,
namespace: item?.metadata?.namespace || null,
pipelineTask: item?.metadata?.labels?.["tekton.dev/pipelineTask"] || item?.metadata?.labels?.["tekton.dev/task"] || null,
status: succeeded?.status || null,
reason: succeeded?.reason || null,
startTime: item?.status?.startTime || null,
completionTime: item?.status?.completionTime || null,
durationSeconds: durationSeconds(item?.status?.startTime, item?.status?.completionTime),
};
}).sort((left, right) => String(left.startTime || "").localeCompare(String(right.startTime || "")));
const slow = items.filter((item) => typeof item.durationSeconds === "number" && item.durationSeconds > 60);
output = {
ok: true,
count: items.length,
succeededCount: items.filter((item) => item.status === "True").length,
failedCount: items.filter((item) => item.status === "False").length,
activeCount: items.filter((item) => item.status !== "True" && item.status !== "False").length,
items,
performance: { slowCount: slow.length, slowTaskRuns: slow.slice(0, 8), warning: slow.length > 0 ? "taskrun-over-60s" : null },
statusAuthority: "kubernetes-api-serviceaccount",
};
} else if (key === "argoApplication") {
const resources = Array.isArray(input?.status?.resources) ? input.status.resources : [];
const nonReadyResources = resources
.filter((item) => item?.health?.status && item.health.status !== "Healthy")
.slice(0, 8)
.map((item) => ({
kind: item.kind || null,
namespace: item.namespace || null,
name: item.name || null,
status: item.status || null,
healthStatus: item.health?.status || null,
healthMessage: item.health?.message || null,
}));
output = {
apiVersion: input.apiVersion,
kind: input.kind,
metadata: metadata(input),
status: {
sync: input?.status?.sync || null,
health: input?.status?.health || null,
conditions: Array.isArray(input?.status?.conditions)
? input.status.conditions.slice(0, 8).map((item) => ({ type: item.type || null, message: item.message || null, lastTransitionTime: item.lastTransitionTime || null }))
: [],
nonReadyResources,
operationState: input?.status?.operationState
? {
phase: input.status.operationState.phase || null,
message: input.status.operationState.message || null,
startedAt: input.status.operationState.startedAt || null,
finishedAt: input.status.operationState.finishedAt || null,
durationSeconds: durationSeconds(input.status.operationState.startedAt, input.status.operationState.finishedAt),
}
: null,
},
};
} else if (/^workload\d+$/.test(key)) {
const template = input?.spec?.template || {};
output = {
apiVersion: input.apiVersion,
kind: input.kind,
metadata: metadata(input),
spec: {
replicas: input?.spec?.replicas ?? null,
template: {
metadata: { labels: cleanMap(template?.metadata?.labels), annotations: cleanMap(template?.metadata?.annotations) },
spec: { containers: Array.isArray(template?.spec?.containers) ? template.spec.containers.map(compactContainer) : [] },
},
},
status: {
replicas: input?.status?.replicas ?? null,
readyReplicas: input?.status?.readyReplicas ?? null,
availableReplicas: input?.status?.availableReplicas ?? null,
updatedReplicas: input?.status?.updatedReplicas ?? null,
conditions: Array.isArray(input?.status?.conditions) ? input.status.conditions.map((item) => ({ type: item.type || null, status: item.status || null, reason: item.reason || null })) : [],
},
};
}
console.log(JSON.stringify(output));