cluster-status -- part 2

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman committed 2020-07-20 19:00:07 +03:00
1 parent ef3962f8b5
commit 323a4c141e
18 files changed
+319 -379

No files matched your search

+21 -24
View File
@@ -1,5 +1,5 @@
import "./app.scss";
import React, { Fragment } from "react";
import React from "react";
import { observer } from "mobx-react";
import { i18nStore } from "../i18n";
import { configStore } from "../config.store";
@@ -34,11 +34,10 @@ import { LandingPage, landingRoute, landingURL } from "./+landing-page";
import { clusterStore } from "../../common/cluster-store";
import { ClusterSettings, clusterSettingsRoute } from "./+cluster-settings";
import { Workspaces, workspacesRoute } from "./+workspaces";
import { ErrorBoundary } from "./error-boundary";
@observer
export class App extends React.Component {
static rootElem = document.getElementById('app');
static async init() {
await i18nStore.init();
await configStore.init();
@@ -57,27 +56,25 @@ export class App extends React.Component {
render() {
return (
<Fragment>
<ErrorBoundary>
<Switch>
<Switch>
<Route component={LandingPage} {...landingRoute}/>
<Route component={AddCluster} {...addClusterRoute}/>
<Route component={Workspaces} {...workspacesRoute}/>
<Route component={ClusterSettings} {...clusterSettingsRoute}/>
<Route component={Cluster} {...clusterRoute}/>
<Route component={Nodes} {...nodesRoute}/>
<Route component={Workloads} {...workloadsRoute}/>
<Route component={Config} {...configRoute}/>
<Route component={Network} {...networkRoute}/>
<Route component={Storage} {...storageRoute}/>
<Route component={Namespaces} {...namespacesRoute}/>
<Route component={Events} {...eventRoute}/>
<Route component={CustomResources} {...crdRoute}/>
<Route component={UserManagement} {...usersManagementRoute}/>
<Route component={Apps} {...appsRoute}/>
<Redirect exact from="/" to={this.startURL}/>
<Route component={NotFound}/>
</Switch>
<Route component={LandingPage} {...landingRoute}/>
<Route component={AddCluster} {...addClusterRoute}/>
<Route component={Workspaces} {...workspacesRoute}/>
<Route component={ClusterSettings} {...clusterSettingsRoute}/>
<Route component={Cluster} {...clusterRoute}/>
<Route component={Nodes} {...nodesRoute}/>
<Route component={Workloads} {...workloadsRoute}/>
<Route component={Config} {...configRoute}/>
<Route component={Network} {...networkRoute}/>
<Route component={Storage} {...storageRoute}/>
<Route component={Namespaces} {...namespacesRoute}/>
<Route component={Events} {...eventRoute}/>
<Route component={CustomResources} {...crdRoute}/>
<Route component={UserManagement} {...usersManagementRoute}/>
<Route component={Apps} {...appsRoute}/>
<Redirect exact from="/" to={this.startURL}/>
<Route component={NotFound}/>
</Switch>
<KubeObjectDetails/>
<Notifications/>
@@ -86,7 +83,7 @@ export class App extends React.Component {
<AddRoleBindingDialog/>
<PodLogsDialog/>
<DeploymentScaleDialog/>
</Fragment>
</ErrorBoundary>
)
}
}
@@ -1,16 +1,40 @@
import "./cluster-manager.scss"
import React from "react";
import { observer } from "mobx-react";
import { computed } from "mobx";
import { App } from "../app";
import { ClusterStatus } from "./cluster-status";
import { ClustersMenu } from "./clusters-menu";
import { BottomBar } from "./bottom-bar";
import { App } from "../app";
import { cssNames, IClassName } from "../../utils";
import { invokeIpc } from "../../../common/ipc";
import { ClusterIpcChannel } from "../../../main/cluster";
import { clusterStore } from "../../../common/cluster-store";
interface Props {
className?: IClassName;
contentClass?: IClassName;
}
@observer
export class ClusterManager extends React.Component<Props> {
@computed get isReady() {
return clusterStore.activeCluster?.isReady
}
async componentDidMount() {
await invokeIpc(ClusterIpcChannel.INIT)
await App.init();
}
export class ClusterManager extends React.Component {
render() {
const { className, contentClass } = this.props;
return (
<div className="ClusterManager">
<div className={cssNames("ClusterManager", className)}>
<div id="draggable-top"/>
<div id="lens-view">
<App/>
<div id="lens-view" className={cssNames("flex", contentClass)}>
{this.isReady && <App/>}
{!this.isReady && <ClusterStatus/>}
</div>
<ClustersMenu/>
<BottomBar/>
@@ -1,3 +1,19 @@
.ClusterStatus {
--flex-gap: #{$padding * 2};
min-width: 350px;
margin: auto;
text-align: center;
pre {
@include custom-scrollbar;
max-width: 70vw;
max-height: 40vh;
//text-align: left;
}
.Icon {
--size: 70px;
margin: auto;
}
}
@@ -1,29 +1,32 @@
import "./cluster-manager.scss"
import type { KubeAuthProxyResponse } from "../../../main/kube-auth-proxy";
import { Cluster, ClusterIpcEvent } from "../../../main/cluster";
import "./cluster-status.scss"
import React from "react";
import type { KubeAuthProxyResponse } from "../../../main/kube-auth-proxy";
import { ClusterIpcChannel } from "../../../main/cluster";
import { invokeIpc } from "../../../common/ipc";
import { clusterStore } from "../../../common/cluster-store";
import { ipcRenderer } from "electron";
import { computed, observable } from "mobx";
import { 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;
}
import { cssNames } from "../../utils";
@observer
export class ClusterStatus extends React.Component<Props> {
@observable authProxyOutput = "Connecting ...\n"
export class ClusterStatus extends React.Component {
@observable authOutput: string[] = [];
@computed get clusterId() {
return this.props.cluster.id;
get cluster() {
return clusterStore.activeCluster;
}
get clusterId() {
return clusterStore.activeClusterId;
}
componentDidMount() {
ipcRenderer.on(`kube-auth:${this.clusterId}`, (evt, authResponse: KubeAuthProxyResponse) => {
this.authProxyOutput += authResponse.data;
this.authOutput = ["Connecting ...\n"];
ipcRenderer.on(`kube-auth:${this.clusterId}`, (evt, { data, stream }: KubeAuthProxyResponse) => {
this.authOutput.push(`[${stream}]: ${data}`);
})
}
@@ -31,22 +34,32 @@ export class ClusterStatus extends React.Component<Props> {
ipcRenderer.removeAllListeners(`kube-auth:${this.clusterId}`);
}
reconnectCluster = () => {
ipcRenderer.send(ClusterIpcEvent.RECONNECT, this.clusterId);
reconnect = () => {
this.authOutput = ["Reconnecting ...\n"];
invokeIpc(ClusterIpcChannel.RECONNECT, this.clusterId);
}
render() {
const { authProxyOutput } = this;
const { contextName, online } = this.props.cluster;
const { authOutput, cluster } = this;
const isError = cluster?.accessible === false;
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 className="ClusterStatus flex column gaps">
{!isError && <Icon material="cloud_queue"/>}
{isError && <Icon material="cloud_off" className="error"/>}
<h2>{cluster?.contextName}</h2>
<pre className="kube-auth-out">
{authOutput.map((data, index) => {
const error = data.startsWith("[stderr]");
return <p key={index} className={cssNames({ error })}>{data}</p>
})}
</pre>
{isError && (
<Button
primary className="box center"
label="Reconnect"
onClick={this.reconnect}
/>
)}
</div>
)
}
@@ -51,7 +51,7 @@ export class ClustersMenu extends React.Component<Props> {
label: _i18n._(t`Settings`),
click: () => navigate(clusterSettingsURL())
}));
if (cluster.initialized) {
if (cluster.online) {
menu.append(new MenuItem({
label: _i18n._(t`Disconnect`),
click: () => {