UNPKG

kui-shell

Version:

This is the monorepo for Kui, the hybrid command-line/GUI electron-based Kubernetes tool

224 lines 9.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const repl_util_1 = require("@kui-shell/core/api/repl-util"); const fillTo = (length, maxColumns) => { if (length >= maxColumns) { return []; } else { return new Array(maxColumns - length).fill(''); } }; const outerCSSForKey = { NAME: 'entity-name-group', READY: 'a-few-numbers-wide', KIND: 'max-width-id-like entity-kind', NAMESPACE: 'entity-name-group hide-with-sidecar not-a-name', MESSAGE: 'not-too-compact', TYPE: 'hide-with-sidecar', CLUSTER: 'entity-name-group entity-name-group-narrow hide-with-sidecar', AUTHINFO: 'entity-name-group entity-name-group-narrow hide-with-sidecar', REFERENCE: 'entity-name-group entity-name-group-narrow hide-with-sidecar', 'CREATED AT': 'hide-with-sidecar', CURRENT: 'entity-name-group entity-name-group-extra-narrow text-center', DESIRED: 'entity-name-group entity-name-group-extra-narrow text-center', RESTARTS: 'very-narrow', 'LAST SEEN': 'hide-with-sidecar entity-name-group-extra-narrow', 'FIRST SEEN': 'hide-with-sidecar entity-name-group-extra-narrow', UPDATED: 'min-width-date-like', REVISION: 'hide-with-sidecar', AGE: 'hide-with-sidecar very-narrow', 'PORT(S)': 'entity-name-group entity-name-group-narrow hide-with-sidecar', SUBOBJECT: 'entity-name-group entity-name-group-extra-narrow' }; const cssForKey = { NAME: 'entity-name', SOURCE: 'lighter-text smaller-text', SUBOBJECT: 'lighter-text smaller-text', MESSAGE: 'somewhat-smaller-text pre-wrap slightly-deemphasize', 'CREATED AT': 'lighter-text smaller-text', AGE: 'slightly-deemphasize', 'APP VERSION': 'pre-wrap slightly-deemphasize', UPDATED: 'slightly-deemphasize somewhat-smaller-text' }; const tagForKey = { REASON: 'badge', STATUS: 'badge' }; const cssForKeyValue = {}; const cssForValue = { UNKNOWN: '', DEPLOYED: 'green-background', DELETED: '', SUPERSEDED: 'yellow-background', FAILED: 'red-background', DELETING: 'yellow-background', 'Init:0/1': 'yellow-background', PodScheduled: 'yellow-background', PodInitializing: 'yellow-background', Initialized: 'yellow-background', Terminating: 'yellow-background', CrashLoopBackOff: 'red-background', Failed: 'red-background', Running: 'green-background', Pending: 'yellow-background', Succeeded: 'gray-background', Completed: 'gray-background', Unknown: '', Ready: 'green-background', ProvisionedSuccessfully: 'green-background', Active: 'green-background', Online: 'green-background', NodeReady: 'green-background', Pulled: 'green-background', Rebooted: 'green-background', Started: 'green-background', Created: 'green-background', Scheduled: 'green-background', SuccessfulCreate: 'green-background', SuccessfulMountVol: 'green-background', ContainerCreating: 'yellow-background', Starting: 'yellow-background', NodeNotReady: 'yellow-background', Killing: 'yellow-background', Deleting: 'yellow-background', Pulling: 'yellow-background', BackOff: 'yellow-background', Unhealthy: 'red-background', FailedScheduling: 'red-background', FailedKillPod: 'red-background' }; const split = (str, splits, headerCells) => { return splits.map((splitIndex, idx) => { return { key: headerCells && headerCells[idx], value: str.substring(splitIndex, splits[idx + 1] || str.length).trim() }; }); }; const detabbify = (str) => str.replace(/\t/g, ' '); exports.preprocessTable = (raw) => { return raw.map(table => { const header = detabbify(table.substring(0, table.indexOf('\n'))); const headerCells = header .split(/(\s\s)+\s?/) .map(x => x && x.trim()) .filter(x => x); const columnStarts = []; for (let idx = 0, jdx = 0; idx < headerCells.length; idx++) { const { offset, prefix } = idx === 0 ? { offset: 0, prefix: '' } : { offset: 1, prefix: ' ' }; const newJdx = header.indexOf(prefix + headerCells[idx] + ' ', jdx); if (newJdx < 0) { jdx = header.indexOf(' ' + headerCells[idx], jdx); } else { jdx = newJdx; } columnStarts.push(jdx + offset); } return table .split(/\n/) .filter(x => x) .map(detabbify) .map(line => split(line, columnStarts, headerCells)); }); }; const capitalize = (str) => { return !str ? 'Unknown' : str[0].toUpperCase() + str.slice(1).toLowerCase(); }; exports.formatTable = (command, verb, entityTypeFromCommandLine, options, preTable) => { const isHelmStatus = command === 'helm' && verb === 'status'; const drilldownCommand = isHelmStatus ? 'kubectl' : command; const drilldownVerb = (verb === 'get' ? 'get' : command === 'helm' && (verb === 'list' || verb === 'ls') ? 'get' : isHelmStatus ? 'get' : undefined) || undefined; const drilldownFormat = drilldownCommand === 'kubectl' && drilldownVerb === 'get' ? '-o yaml' : ''; const drilldownNamespace = options.n || options.namespace ? `-n ${repl_util_1.encodeComponent(options.n || options.namespace)}` : ''; const kindColumnIdx = preTable[0].findIndex(({ key }) => key === 'KIND'); const drilldownKind = (nameSplit, row) => { if (drilldownVerb === 'get') { const kind = kindColumnIdx >= 0 ? row[kindColumnIdx].value : nameSplit.length > 1 ? nameSplit[0] : entityTypeFromCommandLine; return kind ? ' ' + kind : ''; } else { return ''; } }; const nameColumnIdx = preTable[0].findIndex(({ key }) => key === 'NAME'); const namespaceColumnIdx = preTable[0].findIndex(({ key }) => key === 'NAMESPACE'); const maxColumns = preTable.reduce((max, columns) => Math.max(max, columns.length), 0); let entityTypeFromRows; const rows = preTable.map((rows, idx) => { const name = nameColumnIdx >= 0 ? rows[nameColumnIdx].value : ''; const nameSplit = name.split(/\//); const nameForDisplay = nameSplit[1] || rows[0].value; const nameForDrilldown = nameSplit[1] || name; const css = ''; const firstColumnCSS = idx === 0 || rows[0].key !== 'CURRENT' ? css : 'selected-entity'; if (nameSplit[1]) { if (!entityTypeFromRows) { entityTypeFromRows = nameSplit[0]; } else if (entityTypeFromRows !== nameSplit[0]) { entityTypeFromRows = undefined; } } const rowIsSelected = rows[0].key === 'CURRENT' && rows[0].value === '*'; const rowKey = rows[0].key; const rowValue = rows[0].value; const rowCSS = [ (cssForKeyValue[rowKey] && cssForKeyValue[rowKey][rowValue]) || '', rowIsSelected ? 'selected-row' : '' ]; const ns = (namespaceColumnIdx >= 0 && command !== 'helm' && `-n ${repl_util_1.encodeComponent(rows[namespaceColumnIdx].value)}`) || drilldownNamespace || ''; const onclick = idx === 0 ? false : drilldownVerb ? `${drilldownCommand} ${drilldownVerb}${drilldownKind(nameSplit, rows)} ${repl_util_1.encodeComponent(nameForDrilldown)} ${drilldownFormat} ${ns}` : false; const header = idx === 0 ? 'header-cell' : ''; const columnVisibleWithSidecar = new RegExp(/STATUS|REASON|MESSAGE/i); const maybeRed = (reason) => { return /failed/i.test(reason) ? 'red-background' : ''; }; return { key: rows[0].key, name: nameForDisplay, fontawesome: idx !== 0 && rows[0].key === 'CURRENT' && 'fas fa-check', onclick: nameColumnIdx === 0 && onclick, onclickSilence: true, css: firstColumnCSS, rowCSS, outerCSS: `${header} ${outerCSSForKey[rows[0].key] || ''}`, attributes: rows .slice(1) .map(({ key, value: column }, colIdx) => ({ key, tag: idx > 0 && tagForKey[key], onclick: colIdx + 1 === nameColumnIdx && onclick, outerCSS: header + ' ' + outerCSSForKey[key] + (colIdx <= 1 || colIdx === nameColumnIdx - 1 || columnVisibleWithSidecar.test(key) ? '' : ' hide-with-sidecar'), css: css + ' ' + ((idx > 0 && cssForKey[key]) || '') + ' ' + (cssForValue[column] || maybeRed(column)), value: key === 'STATUS' && idx > 0 ? capitalize(column) : column })) .concat(fillTo(rows.length, maxColumns)) }; }); return { header: rows[0], body: rows.slice(1), noSort: true, title: entityTypeFromRows || entityTypeFromCommandLine }; }; //# sourceMappingURL=formatTable.js.map