mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
cluster-status -- part 1 (ex. ClusterPage.vue)
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
a3edb75fea
commit
d7d9c99005
@ -118,7 +118,7 @@ export class BaseStore<T = any> extends Singleton {
|
|||||||
protected async onModelChange(model: T) {
|
protected async onModelChange(model: T) {
|
||||||
if (ipcMain) {
|
if (ipcMain) {
|
||||||
this.save(model); // save config file
|
this.save(model); // save config file
|
||||||
sendMessage({ channel: this.syncChannel, args: model }); // broadcast to renderer views
|
sendMessage({ channel: this.syncChannel, args: [model] }); // broadcast to renderer views
|
||||||
}
|
}
|
||||||
// send "update-request" to main-process
|
// send "update-request" to main-process
|
||||||
if (ipcRenderer) {
|
if (ipcRenderer) {
|
||||||
|
|||||||
@ -48,6 +48,14 @@ export class ClusterManager {
|
|||||||
this.getCluster(clusterId)?.destroy();
|
this.getCluster(clusterId)?.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo
|
||||||
|
protected reconnectCluster(clusterId: ClusterId) {
|
||||||
|
tracker.event("cluster", "reconnect");
|
||||||
|
logger.info(`[CLUSTER-MANAGER]: reconnect cluster`, {
|
||||||
|
meta: this.getCluster(clusterId)?.getMeta()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getClusterForRequest(req: http.IncomingMessage): Cluster {
|
getClusterForRequest(req: http.IncomingMessage): Cluster {
|
||||||
let cluster: Cluster = null
|
let cluster: Cluster = null
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import logger from "./logger"
|
|||||||
|
|
||||||
export enum ClusterIpcEvent {
|
export enum ClusterIpcEvent {
|
||||||
STOP = "cluster:stop",
|
STOP = "cluster:stop",
|
||||||
|
RECONNECT = "cluster:reconnect",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ClusterStatus {
|
export enum ClusterStatus {
|
||||||
@ -111,7 +112,7 @@ export class Cluster implements ClusterModel {
|
|||||||
sendMessage({
|
sendMessage({
|
||||||
channel: "cluster:state",
|
channel: "cluster:state",
|
||||||
webContentId: viewId,
|
webContentId: viewId,
|
||||||
args: clusterState,
|
args: [clusterState],
|
||||||
})
|
})
|
||||||
}, {
|
}, {
|
||||||
fireImmediately: true
|
fireImmediately: true
|
||||||
|
|||||||
@ -5,6 +5,11 @@ import type { Cluster } from "./cluster"
|
|||||||
import { bundledKubectl, Kubectl } from "./kubectl"
|
import { bundledKubectl, Kubectl } from "./kubectl"
|
||||||
import logger from "./logger"
|
import logger from "./logger"
|
||||||
|
|
||||||
|
export interface KubeAuthProxyResponse {
|
||||||
|
data: string;
|
||||||
|
stream: "stderr" | "stdout";
|
||||||
|
}
|
||||||
|
|
||||||
export class KubeAuthProxy {
|
export class KubeAuthProxy {
|
||||||
public lastError: string
|
public lastError: string
|
||||||
|
|
||||||
@ -43,13 +48,9 @@ export class KubeAuthProxy {
|
|||||||
})
|
})
|
||||||
this.proxyProcess.on("exit", (code) => {
|
this.proxyProcess.on("exit", (code) => {
|
||||||
if (code) {
|
if (code) {
|
||||||
logger.error(`proxy ${this.cluster.contextName} exited with code ${code}`)
|
logger.error(`[KUBE-AUTH]: proxying ${this.cluster.contextName} exited with code ${code}`, this.cluster.getMeta());
|
||||||
} else {
|
|
||||||
logger.info(`proxy ${this.cluster.contextName} exited successfully`)
|
|
||||||
}
|
}
|
||||||
this.sendIpcLogMessage(`proxy exited with code ${code}`, "stderr").catch((err: Error) => {
|
this.sendIpcLogMessage({ data: `proxy exited with code ${code}`, stream: "stderr" })
|
||||||
logger.debug("failed to send IPC log message: " + err.message)
|
|
||||||
})
|
|
||||||
this.proxyProcess = null
|
this.proxyProcess = null
|
||||||
})
|
})
|
||||||
this.proxyProcess.stdout.on('data', (data) => {
|
this.proxyProcess.stdout.on('data', (data) => {
|
||||||
@ -57,13 +58,11 @@ export class KubeAuthProxy {
|
|||||||
if (logItem.startsWith("Starting to serve on")) {
|
if (logItem.startsWith("Starting to serve on")) {
|
||||||
logItem = "Authentication proxy started\n"
|
logItem = "Authentication proxy started\n"
|
||||||
}
|
}
|
||||||
logger.debug(`proxy ${this.cluster.contextName} stdout: ${logItem}`)
|
this.sendIpcLogMessage({ data: logItem, stream: "stdout" })
|
||||||
this.sendIpcLogMessage(logItem, "stdout")
|
|
||||||
})
|
})
|
||||||
this.proxyProcess.stderr.on('data', (data) => {
|
this.proxyProcess.stderr.on('data', (data) => {
|
||||||
this.lastError = this.parseError(data.toString())
|
this.lastError = this.parseError(data.toString())
|
||||||
logger.debug(`proxy ${this.cluster.contextName} stderr: ${data}`)
|
this.sendIpcLogMessage({ data: data.toString(), stream: "stderr" })
|
||||||
this.sendIpcLogMessage(data.toString(), "stderr")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return waitUntilUsed(this.port, 500, 10000)
|
return waitUntilUsed(this.port, 500, 10000)
|
||||||
@ -84,11 +83,14 @@ export class KubeAuthProxy {
|
|||||||
return errorMsg
|
return errorMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async sendIpcLogMessage(data: string, stream: string) {
|
protected async sendIpcLogMessage(res: KubeAuthProxyResponse) {
|
||||||
const channel = `kube-auth:${this.cluster.id}`
|
const channel = `kube-auth:${this.cluster.id}`
|
||||||
const message = { data, stream };
|
logger.debug(`[KUBE-AUTH]: output for ${channel}`, { ...res, meta: this.cluster.getMeta() });
|
||||||
logger.debug(channel, message);
|
sendMessage({
|
||||||
sendMessage({ channel, args: message }); // todo: send message only to cluster's window
|
// webContentId: null, // todo: send a message only to single cluster's window
|
||||||
|
channel: channel,
|
||||||
|
args: [res],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public exit() {
|
public exit() {
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
.ClusterStatus {
|
||||||
|
|
||||||
|
}
|
||||||
53
src/renderer/components/cluster-manager/cluster-status.tsx
Normal file
53
src/renderer/components/cluster-manager/cluster-status.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import "./cluster-manager.scss"
|
||||||
|
import type { KubeAuthProxyResponse } from "../../../main/kube-auth-proxy";
|
||||||
|
import { Cluster, ClusterIpcEvent } from "../../../main/cluster";
|
||||||
|
import React from "react";
|
||||||
|
import { ipcRenderer } from "electron";
|
||||||
|
import { computed, observable } from "mobx";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import { Icon } from "../icon";
|
||||||
|
import { Button } from "../button";
|
||||||
|
import { Trans } from "@lingui/macro";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
cluster: Cluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export class ClusterStatus extends React.Component<Props> {
|
||||||
|
@observable authProxyOutput = "Connecting ...\n"
|
||||||
|
|
||||||
|
@computed get clusterId() {
|
||||||
|
return this.props.cluster.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
ipcRenderer.on(`kube-auth:${this.clusterId}`, (evt, authResponse: KubeAuthProxyResponse) => {
|
||||||
|
this.authProxyOutput += authResponse.data;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
ipcRenderer.removeAllListeners(`kube-auth:${this.clusterId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
reconnectCluster = () => {
|
||||||
|
ipcRenderer.send(ClusterIpcEvent.RECONNECT, this.clusterId);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { authProxyOutput } = this;
|
||||||
|
const { contextName, online } = this.props.cluster;
|
||||||
|
return (
|
||||||
|
<div className="ClusterStatus flex column">
|
||||||
|
<Icon sticker className="status-icon" material={online ? "https" : "cloud_off"}/>
|
||||||
|
<h2>{contextName}</h2>
|
||||||
|
<pre className="kube-auth-stdout">{authProxyOutput}</pre>
|
||||||
|
<Button
|
||||||
|
primary label={<Trans>Reconnect</Trans>}
|
||||||
|
onClick={this.reconnectCluster}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,6 +10,8 @@ import { Button } from "../button";
|
|||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { _i18n } from "../../i18n";
|
import { _i18n } from "../../i18n";
|
||||||
|
|
||||||
|
// todo: make as external BrowserWindow (?)
|
||||||
|
|
||||||
interface Props extends DialogProps {
|
interface Props extends DialogProps {
|
||||||
title: string;
|
title: string;
|
||||||
logs: string;
|
logs: string;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user