finish poc

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton committed 2021-04-19 10:42:53 -04:00
1 parent 0de3bb13ca
commit 3315114ddd
106 files changed
+7158 -892

No files matched your search

+81 -11
View File
@@ -1,23 +1,93 @@
import { LensRendererExtension } from "@k8slens/extensions";
import { PodShellMenu, PodShellMenuProps } from "./src/shell-menu";
import { PodLogsMenu, PodLogsMenuProps } from "./src/logs-menu";
import React from "react";
import { LensRendererExtension, Component, K8sApi } from "@k8slens/extensions";
import { Subject } from "@material-ui/icons";
const { Mui: { SvgIcon }, LensIcons } = Component;
function execShell(pod: K8sApi.Pod, container: K8sApi.IPodContainer) {
let command = `kubectl exec -i -t -n ${pod.getNs()} ${pod.getName()} -c ${container.name} "--"`;
if (window.navigator.platform !== "Win32") {
command = `exec ${command}`;
}
if (pod.getSelectedNodeOs() === "windows") {
command = `${command} powershell`;
} else {
command = `${command} sh -c "clear; (bash || ash || sh)"`;
}
const shell = Component.createTerminalTab({
title: `Pod: ${pod.getName()} (namespace: ${pod.getNs()})`
});
Component.terminalStore.sendCommand(command, {
enter: true,
tabId: shell.id
});
}
export default class PodMenuRendererExtension extends LensRendererExtension {
kubeObjectMenuItems = [
kubeObjectMenuItems: LensRendererExtension["kubeObjectMenuItems"] = [
{
kind: "Pod",
apiVersions: ["v1"],
components: {
MenuItem: (props: PodShellMenuProps) => <PodShellMenu {...props} />
}
text: "Pod Shell",
Icon: () => <SvgIcon component={LensIcons.Ssh} />,
when: (pod: K8sApi.Pod) => pod.getRunningContainers().length === 1,
onClick: (pod: K8sApi.Pod) => execShell(pod, pod.getRunningContainers()[0]),
closeParent: true,
},
{
kind: "Pod",
apiVersions: ["v1"],
components: {
MenuItem: (props: PodLogsMenuProps) => <PodLogsMenu {...props} />
}
}
text: "Pod Shells",
Icon: () => <SvgIcon component={LensIcons.Ssh} />,
when: (pod: K8sApi.Pod) => pod.getRunningContainers().length > 1,
children: (pod: K8sApi.Pod) => (
pod.getRunningContainers()
.map(container => ({
text: container.name,
Icon: () => <SvgIcon component={LensIcons.Ssh} />,
onClick: () => execShell(pod, container),
closeParent: true,
}))
),
},
{
kind: "Pod",
apiVersions: ["v1"],
text: "Logs",
Icon: Subject,
when: (pod: K8sApi.Pod) => pod.getAllContainers().length === 1,
onClick: (pod: K8sApi.Pod) => (
Component.logTabStore.createPodTab({
selectedPod: pod,
selectedContainer: pod.getAllContainers()[0],
})
),
closeParent: true,
},
{
kind: "Pod",
apiVersions: ["v1"],
text: "Logs",
Icon: Subject,
when: (pod: K8sApi.Pod) => pod.getAllContainers().length > 1,
children: (pod: K8sApi.Pod) => (
pod.getAllContainers()
.map(container => ({
text: container.name,
Icon: Subject,
onClick: () => (
Component.logTabStore.createPodTab({
selectedPod: pod,
selectedContainer: container,
})
),
closeParent: true,
}))
),
closeParent: true,
},
];
}
-57
View File
@@ -1,57 +0,0 @@
import React from "react";
import { Component, K8sApi, Util, Navigation } from "@k8slens/extensions";
export interface PodLogsMenuProps extends Component.KubeObjectMenuProps<K8sApi.Pod> {
}
export class PodLogsMenu extends React.Component<PodLogsMenuProps> {
showLogs(container: K8sApi.IPodContainer) {
Navigation.hideDetails();
const pod = this.props.object;
Component.logTabStore.createPodTab({
selectedPod: pod,
selectedContainer: container,
});
}
render() {
const { object: pod, toolbar } = this.props;
const containers = pod.getAllContainers();
const statuses = pod.getContainerStatuses();
if (!containers.length) return null;
return (
<Component.MenuItem onClick={Util.prevDefault(() => this.showLogs(containers[0]))}>
<Component.Icon material="subject" title="Logs" interactive={toolbar}/>
<span className="title">Logs</span>
{containers.length > 1 && (
<>
<Component.Icon className="arrow" material="keyboard_arrow_right"/>
<Component.SubMenu>
{
containers.map(container => {
const { name } = container;
const status = statuses.find(status => status.name === name);
const brick = status ? (
<Component.StatusBrick
className={Util.cssNames(Object.keys(status.state)[0], { ready: status.ready })}
/>
) : null;
return (
<Component.MenuItem key={name} onClick={Util.prevDefault(() => this.showLogs(container))} className="flex align-center">
{brick}
<span>{name}</span>
</Component.MenuItem>
);
})
}
</Component.SubMenu>
</>
)}
</Component.MenuItem>
);
}
}
-68
View File
@@ -1,68 +0,0 @@
import React from "react";
import { Component, K8sApi, Util, Navigation } from "@k8slens/extensions";
export interface PodShellMenuProps extends Component.KubeObjectMenuProps<K8sApi.Pod> {
}
export class PodShellMenu extends React.Component<PodShellMenuProps> {
async execShell(container?: string) {
Navigation.hideDetails();
const { object: pod } = this.props;
const containerParam = container ? `-c ${container}` : "";
let command = `kubectl exec -i -t -n ${pod.getNs()} ${pod.getName()} ${containerParam} "--"`;
if (window.navigator.platform !== "Win32") {
command = `exec ${command}`;
}
if (pod.getSelectedNodeOs() === "windows") {
command = `${command} powershell`;
} else {
command = `${command} sh -c "clear; (bash || ash || sh)"`;
}
const shell = Component.createTerminalTab({
title: `Pod: ${pod.getName()} (namespace: ${pod.getNs()})`
});
Component.terminalStore.sendCommand(command, {
enter: true,
tabId: shell.id
});
}
render() {
const { object, toolbar } = this.props;
const containers = object.getRunningContainers();
if (!containers.length) return null;
return (
<Component.MenuItem onClick={Util.prevDefault(() => this.execShell(containers[0].name))}>
<Component.Icon svg="ssh" interactive={toolbar} title="Pod shell"/>
<span className="title">Shell</span>
{containers.length > 1 && (
<>
<Component.Icon className="arrow" material="keyboard_arrow_right"/>
<Component.SubMenu>
{
containers.map(container => {
const { name } = container;
return (
<Component.MenuItem key={name} onClick={Util.prevDefault(() => this.execShell(name))} className="flex align-center">
<Component.StatusBrick/>
<span>{name}</span>
</Component.MenuItem>
);
})
}
</Component.SubMenu>
</>
)}
</Component.MenuItem>
);
}
}