kui-shell
Version:
This is the monorepo for Kui, the hybrid command-line/GUI electron-based Kubernetes tool
173 lines • 7.46 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const debug_1 = require("debug");
const path_1 = require("path");
const capabilities_1 = require("@kui-shell/core/api/capabilities");
const i18n_1 = require("@kui-shell/core/api/i18n");
const tables_1 = require("@kui-shell/core/api/tables");
const util_1 = require("@kui-shell/core/api/util");
const inject_1 = require("@kui-shell/core/api/inject");
const repl_util_1 = require("@kui-shell/core/api/repl-util");
const states_1 = require("../model/states");
const status_1 = require("../view/modes/status");
const formatEntity_1 = require("../view/formatEntity");
const strings = i18n_1.i18n('plugin-k8s');
const debug = debug_1.default('k8s/controller/kedit');
const usage = {
kedit: {
command: 'kedit',
strict: 'kedit',
docs: strings('keditUsageDocs'),
example: 'kedit @seed/cloud-functions/function/echo.yaml',
required: [{ name: 'file', file: true, docs: strings('keditUsageRequiredDocs') }],
optional: [
{
name: 'resource',
positional: true,
docs: strings('keditUsageOptionalDocs')
}
]
}
};
const showResource = (yaml, filepath, tab) => __awaiter(void 0, void 0, void 0, function* () {
debug('showing one resource', yaml);
if (capabilities_1.default.inBrowser()) {
inject_1.injectCSS({
css: require('@kui-shell/plugin-k8s/web/css/main.css').toString(),
key: 'kedit'
});
}
else {
const ourRoot = path_1.dirname(require.resolve('@kui-shell/plugin-k8s/package.json'));
inject_1.injectCSS(path_1.join(ourRoot, 'web/css/main.css'));
}
const typeOverride = yaml.kind;
const nameOverride = (resource) => (resource.metadata && resource.metadata.name) || path_1.basename(filepath);
const resource = {
kind: yaml.kind,
filepathForDrilldown: filepath,
resource: yaml
};
const addModeButtons = (defaultMode) => (response) => {
response.modes = (response.modes || []).concat([
{ mode: 'edit', direct: openAsForm },
status_1.statusButton('kubectl', resource, states_1.FinalState.NotPendingLike),
{ mode: 'raw', label: 'YAML', direct: openInEditor }
]);
response.modes.forEach(spec => {
if (spec.mode === defaultMode) {
spec.defaultMode = true;
}
else {
spec.defaultMode = false;
}
});
return response;
};
const { safeLoad, safeDump } = yield Promise.resolve().then(() => require('js-yaml'));
const extract = (rawText, entity) => {
try {
const resource = (editorEntity.resource = safeLoad(rawText));
editorEntity.source = rawText;
editorEntity.name = resource.metadata.name;
editorEntity.kind = resource.kind;
if (entity) {
entity.source = editorEntity.source;
entity.name = editorEntity.name;
entity.kind = editorEntity.kind;
}
return entity;
}
catch (err) {
console.error('error parsing as yaml', err);
}
};
const editorEntity = {
name: yaml.metadata.name,
kind: yaml.kind,
lock: false,
extract,
filepath,
source: safeDump(yaml),
resource: yaml
};
const openInEditor = () => {
debug('openInEditor', yaml.metadata.name);
return tab.REPL.qexec(`edit !source --type "${typeOverride}" --name "${nameOverride(editorEntity.resource)}" --language yaml`, undefined, undefined, {
parameters: editorEntity
}).then(addModeButtons('raw'));
};
const openAsForm = () => __awaiter(void 0, void 0, void 0, function* () {
const generateForm = (yield Promise.resolve().then(() => require('../view/form'))).default;
return Promise.resolve(generateForm(tab)(editorEntity.resource, filepath, nameOverride(editorEntity.resource), typeOverride, extract)).then(addModeButtons('edit'));
});
return openAsForm();
});
const showAsTable = (yamls, filepathAsGiven, { parsedOptions, REPL }) => __awaiter(void 0, void 0, void 0, function* () {
debug('showing as table', yamls);
const ourOptions = {
'no-status': true,
onclickFn: (kubeEntity) => {
return evt => {
evt.stopPropagation();
return REPL.pexec(`kedit ${repl_util_1.encodeComponent(filepathAsGiven)} ${repl_util_1.encodeComponent(kubeEntity.metadata.name)}`);
};
}
};
return Promise.all(yamls.map(formatEntity_1.formatEntity(Object.assign({}, parsedOptions, ourOptions)))).then(formattedEntities => {
return new tables_1.default.Table({ body: formattedEntities });
});
});
const kedit = (args) => __awaiter(void 0, void 0, void 0, function* () {
const { tab, argvNoOptions, REPL } = args;
const idx = argvNoOptions.indexOf('kedit') + 1;
const filepathAsGiven = argvNoOptions[idx];
const resource = argvNoOptions[idx + 1];
const filepath = util_1.default.findFile(util_1.default.expandHomeDir(filepathAsGiven));
debug('filepath', filepath);
const { safeLoadAll: parseYAML } = yield Promise.resolve().then(() => require('js-yaml'));
const { readFile } = yield Promise.resolve().then(() => require('fs-extra'));
try {
const yamls = parseYAML((yield readFile(filepath)).toString()).filter(x => x);
debug('yamls', yamls);
if (yamls.length === 0) {
throw new Error('The specified file is empty');
}
else if (yamls.filter(({ apiVersion, kind }) => apiVersion && kind).length === 0) {
debug('The specified file does not contain any Kubernetes resource definitions');
return REPL.qexec(`edit "${filepathAsGiven}"`);
}
else if (yamls.length > 1 && !resource) {
return showAsTable(yamls, filepathAsGiven, args);
}
else {
const yamlIdx = !resource ? 0 : yamls.findIndex(({ metadata }) => metadata && metadata.name === resource);
if (yamlIdx < 0) {
throw new Error('Cannot find the specified resource');
}
else {
return showResource(yamls[yamlIdx], filepath, tab);
}
}
}
catch (err) {
console.error('error parsing yaml');
return REPL.qexec(`edit "${filepathAsGiven}"`);
}
});
const registration = (commandTree) => {
commandTree.listen('/kedit', kedit, {
usage: usage.kedit
});
};
exports.default = registration;
//# sourceMappingURL=kedit.js.map