@blogic-cz/agent-tools 0.8.11 → 0.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/k8s-tool/transformers.ts +96 -14
package/package.json
CHANGED
|
@@ -184,30 +184,65 @@ function parseDescribeSections(
|
|
|
184
184
|
return sections;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
|
|
187
|
+
type KubectlTableResult = {
|
|
188
|
+
headers: string[];
|
|
189
|
+
rows: Record<string, string>[];
|
|
190
|
+
uniform?: Record<string, string>;
|
|
191
|
+
stripped?: string[];
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const PLACEHOLDER_VALUES = new Set(["<none>", "<pending>", "<unknown>", "<unset>", ""]);
|
|
195
|
+
const ALWAYS_STRIP_COLUMNS = new Set(["SELECTOR", "LABELS", "NODE-SELECTORS", "NODE_SELECTORS"]);
|
|
196
|
+
|
|
197
|
+
function isSelectorLikeValue(value: string): boolean {
|
|
198
|
+
if (!value.includes("=")) return false;
|
|
199
|
+
return value.includes("kubernetes.io/") || value.includes("k8s.io/") || value.includes(",");
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function stripLowValueColumns(rows: Record<string, string>[]): {
|
|
203
|
+
rows: Record<string, string>[];
|
|
204
|
+
stripped: string[];
|
|
205
|
+
} {
|
|
188
206
|
if (rows.length === 0) {
|
|
189
|
-
return rows;
|
|
207
|
+
return { rows, stripped: [] };
|
|
190
208
|
}
|
|
191
209
|
|
|
192
210
|
const keys = Object.keys(rows[0] ?? {});
|
|
193
211
|
const keysToRemove = new Set<string>();
|
|
194
212
|
|
|
195
213
|
for (const key of keys) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
214
|
+
if (ALWAYS_STRIP_COLUMNS.has(key.toUpperCase())) {
|
|
215
|
+
keysToRemove.add(key);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const values = rows.map((row) => (row[key] ?? "").trim());
|
|
200
220
|
|
|
201
|
-
|
|
221
|
+
const allPlaceholder = values.every((v) => PLACEHOLDER_VALUES.has(v.toLowerCase()));
|
|
222
|
+
if (allPlaceholder) {
|
|
202
223
|
keysToRemove.add(key);
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const nonEmptyValues = values.filter(
|
|
228
|
+
(v) => v.length > 0 && !PLACEHOLDER_VALUES.has(v.toLowerCase()),
|
|
229
|
+
);
|
|
230
|
+
if (nonEmptyValues.length > 0) {
|
|
231
|
+
const avgLength =
|
|
232
|
+
nonEmptyValues.reduce((sum, v) => sum + v.length, 0) / nonEmptyValues.length;
|
|
233
|
+
const labelCount = nonEmptyValues.filter(isSelectorLikeValue).length;
|
|
234
|
+
if (avgLength > 50 && labelCount / nonEmptyValues.length > 0.5) {
|
|
235
|
+
keysToRemove.add(key);
|
|
236
|
+
}
|
|
203
237
|
}
|
|
204
238
|
}
|
|
205
239
|
|
|
206
240
|
if (keysToRemove.size === 0) {
|
|
207
|
-
return rows;
|
|
241
|
+
return { rows, stripped: [] };
|
|
208
242
|
}
|
|
209
243
|
|
|
210
|
-
|
|
244
|
+
const stripped = keys.filter((k) => keysToRemove.has(k));
|
|
245
|
+
const filteredRows = rows.map((row) => {
|
|
211
246
|
const filtered: Record<string, string> = {};
|
|
212
247
|
for (const [key, value] of Object.entries(row)) {
|
|
213
248
|
if (!keysToRemove.has(key)) {
|
|
@@ -216,6 +251,47 @@ function stripLowValueColumns(rows: Record<string, string>[]): Record<string, st
|
|
|
216
251
|
}
|
|
217
252
|
return filtered;
|
|
218
253
|
});
|
|
254
|
+
|
|
255
|
+
return { rows: filteredRows, stripped };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function collapseUniformColumns(rows: Record<string, string>[]): {
|
|
259
|
+
rows: Record<string, string>[];
|
|
260
|
+
uniform: Record<string, string>;
|
|
261
|
+
} {
|
|
262
|
+
if (rows.length <= 1) {
|
|
263
|
+
return { rows, uniform: {} };
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const keys = Object.keys(rows[0] ?? {});
|
|
267
|
+
const uniform: Record<string, string> = {};
|
|
268
|
+
const keysToCollapse = new Set<string>();
|
|
269
|
+
|
|
270
|
+
for (const key of keys) {
|
|
271
|
+
const values = rows.map((row) => (row[key] ?? "").trim());
|
|
272
|
+
const firstValue = values[0] ?? "";
|
|
273
|
+
|
|
274
|
+
if (firstValue.length > 0 && values.every((v) => v === firstValue)) {
|
|
275
|
+
uniform[key] = firstValue;
|
|
276
|
+
keysToCollapse.add(key);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (keysToCollapse.size === 0) {
|
|
281
|
+
return { rows, uniform: {} };
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const cleanedRows = rows.map((row) => {
|
|
285
|
+
const filtered: Record<string, string> = {};
|
|
286
|
+
for (const [key, value] of Object.entries(row)) {
|
|
287
|
+
if (!keysToCollapse.has(key)) {
|
|
288
|
+
filtered[key] = value;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return filtered;
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
return { rows: cleanedRows, uniform };
|
|
219
295
|
}
|
|
220
296
|
|
|
221
297
|
export function transformPods(jsonOutput: string): PodSummary | string {
|
|
@@ -487,11 +563,17 @@ export function transformGenericKubectl(
|
|
|
487
563
|
parsedTable.headers.every((header) => /^[A-Z0-9_()\-/]+$/.test(header));
|
|
488
564
|
|
|
489
565
|
if (looksLikeTable) {
|
|
490
|
-
const rows = stripLowValueColumns(parsedTable.rows);
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
566
|
+
const { rows: strippedRows, stripped } = stripLowValueColumns(parsedTable.rows);
|
|
567
|
+
const { rows: finalRows, uniform } = collapseUniformColumns(strippedRows);
|
|
568
|
+
|
|
569
|
+
const remainingKeys =
|
|
570
|
+
finalRows.length > 0 ? new Set(Object.keys(finalRows[0] ?? {})) : new Set<string>();
|
|
571
|
+
const headers = parsedTable.headers.filter((h) => remainingKeys.has(h));
|
|
572
|
+
|
|
573
|
+
const result: KubectlTableResult = { headers, rows: finalRows };
|
|
574
|
+
if (Object.keys(uniform).length > 0) result.uniform = uniform;
|
|
575
|
+
if (stripped.length > 0) result.stripped = stripped;
|
|
576
|
+
return result;
|
|
495
577
|
}
|
|
496
578
|
|
|
497
579
|
if (lines.length > 50) {
|