mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
cleanup Lens repo with tighter linting
Signed-off-by: Sebastian Malton <smalton@mirantis.com>
This commit is contained in:
1 parent
e468105143
commit
b1ff34879a
470 files changed
+8447
-7443
No files matched your search
@@ -1,4 +1,4 @@
|
||||
export * from "./nodes"
|
||||
export * from "./nodes.route"
|
||||
export * from "./node-menu"
|
||||
export * from "./node-details"
|
||||
export * from "./nodes";
|
||||
export * from "./nodes.route";
|
||||
export * from "./node-menu";
|
||||
export * from "./node-details";
|
||||
@@ -1,24 +1,28 @@
|
||||
import React, { useContext } from "react";
|
||||
import { t } from "@lingui/macro";
|
||||
import { IClusterMetrics, Node } from "../../api/endpoints";
|
||||
import { ClusterMetrics, Node } from "../../api/endpoints";
|
||||
import { BarChart, cpuOptions, memoryOptions } from "../chart";
|
||||
import { isMetricsEmpty, normalizeMetrics } from "../../api/endpoints/metrics.api";
|
||||
import { NoMetrics } from "../resource-metrics/no-metrics";
|
||||
import { IResourceMetricsValue, ResourceMetricsContext } from "../resource-metrics";
|
||||
import { ResourceMetricsValue, ResourceMetricsContext } from "../resource-metrics";
|
||||
import { observer } from "mobx-react";
|
||||
import { ChartOptions, ChartPoint } from "chart.js";
|
||||
import { themeStore } from "../../theme.store";
|
||||
import { _i18n } from "../../i18n";
|
||||
|
||||
type IContext = IResourceMetricsValue<Node, { metrics: IClusterMetrics }>;
|
||||
type IContext = ResourceMetricsValue<Node, { metrics: ClusterMetrics }>;
|
||||
|
||||
export const NodeCharts = observer(() => {
|
||||
const { params: { metrics }, tabId, object } = useContext<IContext>(ResourceMetricsContext);
|
||||
const id = object.getId();
|
||||
const { chartCapacityColor } = themeStore.activeTheme.colors;
|
||||
|
||||
if (!metrics) return null;
|
||||
if (isMetricsEmpty(metrics)) return <NoMetrics/>;
|
||||
if (!metrics) {
|
||||
return null;
|
||||
}
|
||||
if (isMetricsEmpty(metrics)) {
|
||||
return <NoMetrics/>;
|
||||
}
|
||||
|
||||
const values = Object.values(metrics).map(metric =>
|
||||
normalizeMetrics(metric).data.result[0].values
|
||||
@@ -26,11 +30,11 @@ export const NodeCharts = observer(() => {
|
||||
const [
|
||||
memoryUsage,
|
||||
memoryRequests,
|
||||
memoryLimits,
|
||||
_memoryLimits,
|
||||
memoryCapacity,
|
||||
cpuUsage,
|
||||
cpuRequests,
|
||||
cpuLimits,
|
||||
_cpuLimits,
|
||||
cpuCapacity,
|
||||
podUsage,
|
||||
podCapacity,
|
||||
@@ -127,20 +131,20 @@ export const NodeCharts = observer(() => {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
callback: value => value
|
||||
callback: (value): any => value
|
||||
}
|
||||
}]
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: ({ datasetIndex, index }, { datasets }) => {
|
||||
label: ({ datasetIndex, index }, { datasets }): string => {
|
||||
const { label, data } = datasets[datasetIndex];
|
||||
const value = data[index] as ChartPoint;
|
||||
return `${label}: ${value.y}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const options = [cpuOptions, memoryOptions, memoryOptions, podOptions];
|
||||
|
||||
@@ -151,4 +155,4 @@ export const NodeCharts = observer(() => {
|
||||
data={{ datasets: datasets[tabId] }}
|
||||
/>
|
||||
);
|
||||
})
|
||||
});
|
||||
@@ -30,36 +30,38 @@ export class NodeDetails extends React.Component<Props> {
|
||||
nodesStore.nodeMetrics = null;
|
||||
});
|
||||
|
||||
async componentDidMount() {
|
||||
async componentDidMount(): Promise<void> {
|
||||
if (!podsStore.isLoaded) {
|
||||
podsStore.loadAll();
|
||||
await podsStore.loadAll();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
nodesStore.nodeMetrics = null;
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
const { object: node } = this.props;
|
||||
if (!node) return;
|
||||
const { status } = node
|
||||
const { nodeInfo, addresses, capacity, allocatable } = status
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
const { status } = node;
|
||||
const { nodeInfo, addresses, capacity, allocatable } = status;
|
||||
const conditions = node.getActiveConditions();
|
||||
const taints = node.getTaints()
|
||||
const childPods = podsStore.getPodsByNode(node.getName())
|
||||
const metrics = nodesStore.nodeMetrics
|
||||
const taints = node.getTaints();
|
||||
const childPods = podsStore.getPodsByNode(node.getName());
|
||||
const metrics = nodesStore.nodeMetrics;
|
||||
const metricTabs = [
|
||||
<Trans>CPU</Trans>,
|
||||
<Trans>Memory</Trans>,
|
||||
<Trans>Disk</Trans>,
|
||||
<Trans>Pods</Trans>,
|
||||
<Trans key="cpu">CPU</Trans>,
|
||||
<Trans key="memory">Memory</Trans>,
|
||||
<Trans key="disk">Disk</Trans>,
|
||||
<Trans key="pods">Pods</Trans>,
|
||||
];
|
||||
return (
|
||||
<div className="NodeDetails">
|
||||
{podsStore.isLoaded && (
|
||||
<ResourceMetrics
|
||||
loader={() => nodesStore.loadMetrics(node.getName())}
|
||||
loader={(): Promise<void> => nodesStore.loadMetrics(node.getName())}
|
||||
tabs={metricTabs} object={node} params={{ metrics }}
|
||||
>
|
||||
<NodeCharts/>
|
||||
@@ -121,7 +123,7 @@ export class NodeDetails extends React.Component<Props> {
|
||||
<DrawerItem name={<Trans>Conditions</Trans>} className="conditions" labelsOnly>
|
||||
{
|
||||
conditions.map(condition => {
|
||||
const { type } = condition
|
||||
const { type } = condition;
|
||||
return (
|
||||
<Badge
|
||||
key={type}
|
||||
@@ -138,7 +140,7 @@ export class NodeDetails extends React.Component<Props> {
|
||||
</TooltipContent>
|
||||
}
|
||||
/>
|
||||
)
|
||||
);
|
||||
})
|
||||
}
|
||||
</DrawerItem>
|
||||
@@ -151,7 +153,7 @@ export class NodeDetails extends React.Component<Props> {
|
||||
/>
|
||||
<KubeEventDetails object={node}/>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,36 +9,38 @@ import { Icon } from "../icon";
|
||||
import { _i18n } from "../../i18n";
|
||||
import { hideDetails } from "../../navigation";
|
||||
|
||||
export function NodeMenu(props: KubeObjectMenuProps<Node>) {
|
||||
export function NodeMenu(props: KubeObjectMenuProps<Node>): JSX.Element {
|
||||
const { object: node, toolbar } = props;
|
||||
if (!node) return null;
|
||||
if (!node) {
|
||||
return null;
|
||||
}
|
||||
const nodeName = node.getName();
|
||||
|
||||
const sendToTerminal = (command: string) => {
|
||||
const sendToTerminal = (command: string): void => {
|
||||
terminalStore.sendCommand(command, {
|
||||
enter: true,
|
||||
newTab: true,
|
||||
});
|
||||
hideDetails();
|
||||
}
|
||||
};
|
||||
|
||||
const shell = () => {
|
||||
const shell = (): void => {
|
||||
createTerminalTab({
|
||||
title: _i18n._(t`Node`) + `: ${nodeName}`,
|
||||
node: nodeName,
|
||||
});
|
||||
hideDetails();
|
||||
}
|
||||
};
|
||||
|
||||
const cordon = () => {
|
||||
const cordon = (): void => {
|
||||
sendToTerminal(`kubectl cordon ${nodeName}`);
|
||||
}
|
||||
};
|
||||
|
||||
const unCordon = () => {
|
||||
sendToTerminal(`kubectl uncordon ${nodeName}`)
|
||||
}
|
||||
const unCordon = (): void => {
|
||||
sendToTerminal(`kubectl uncordon ${nodeName}`);
|
||||
};
|
||||
|
||||
const drain = () => {
|
||||
const drain = (): void => {
|
||||
const command = `kubectl drain ${nodeName} --delete-local-data --ignore-daemonsets --force`;
|
||||
ConfirmDialog.open({
|
||||
ok: () => sendToTerminal(command),
|
||||
@@ -48,8 +50,8 @@ export function NodeMenu(props: KubeObjectMenuProps<Node>) {
|
||||
<Trans>Are you sure you want to drain <b>{nodeName}</b>?</Trans>
|
||||
</p>
|
||||
),
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<KubeObjectMenu {...props}>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { RouteProps } from "react-router"
|
||||
import { RouteProps } from "react-router";
|
||||
import { buildURL } from "../../navigation";
|
||||
|
||||
export const nodesRoute: RouteProps = {
|
||||
path: "/nodes"
|
||||
};
|
||||
|
||||
export interface NodesRouteParams {
|
||||
}
|
||||
|
||||
export interface INodesRouteParams {
|
||||
}
|
||||
|
||||
export const nodesURL = buildURL<INodesRouteParams>(nodesRoute.path)
|
||||
export const nodesURL = buildURL<NodesRouteParams>(nodesRoute.path);
|
||||
@@ -1,5 +1,5 @@
|
||||
import { action, computed, observable } from "mobx"
|
||||
import { clusterApi, IClusterMetrics, INodeMetrics, Node, nodesApi } from "../../api/endpoints";
|
||||
import { action, computed, observable } from "mobx";
|
||||
import { clusterApi, ClusterMetrics, NodeMetrics, Node, nodesApi } from "../../api/endpoints";
|
||||
import { autobind } from "../../utils";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
@@ -8,13 +8,13 @@ import { apiManager } from "../../api/api-manager";
|
||||
export class NodesStore extends KubeObjectStore<Node> {
|
||||
api = nodesApi
|
||||
|
||||
@observable metrics: Partial<INodeMetrics> = {};
|
||||
@observable nodeMetrics: Partial<IClusterMetrics> = null;
|
||||
@observable metrics: Partial<NodeMetrics> = {};
|
||||
@observable nodeMetrics: Partial<ClusterMetrics> = null;
|
||||
@observable metricsLoading = false;
|
||||
@observable metricsLoaded = false;
|
||||
|
||||
@action
|
||||
async loadUsageMetrics() {
|
||||
async loadUsageMetrics(): Promise<void> {
|
||||
this.metricsLoading = true;
|
||||
try {
|
||||
this.metrics = await nodesApi.getMetrics();
|
||||
@@ -25,16 +25,16 @@ export class NodesStore extends KubeObjectStore<Node> {
|
||||
}
|
||||
|
||||
@action
|
||||
async loadMetrics(nodeName: string) {
|
||||
async loadMetrics(nodeName: string): Promise<void> {
|
||||
this.nodeMetrics = await clusterApi.getMetrics([nodeName]);
|
||||
}
|
||||
|
||||
@computed get masterNodes() {
|
||||
return this.items.filter(node => node.getRoleLabels().includes("master"))
|
||||
@computed get masterNodes(): Node[] {
|
||||
return this.items.filter(node => node.getRoleLabels().includes("master"));
|
||||
}
|
||||
|
||||
@computed get workerNodes() {
|
||||
return this.items.filter(node => !node.getRoleLabels().includes("master"))
|
||||
@computed get workerNodes(): Node[] {
|
||||
return this.items.filter(node => !node.getRoleLabels().includes("master"));
|
||||
}
|
||||
|
||||
getLastMetricValues(node: Node, metricNames: string[]): number[] {
|
||||
@@ -50,7 +50,7 @@ export class NodesStore extends KubeObjectStore<Node> {
|
||||
result.metric.node,
|
||||
result.metric.instance,
|
||||
result.metric.kubernetes_node,
|
||||
].includes(nodeName)
|
||||
].includes(nodeName);
|
||||
});
|
||||
return result ? parseFloat(result.values.slice(-1)[0][1]) : 0;
|
||||
} catch (e) {
|
||||
@@ -59,7 +59,7 @@ export class NodesStore extends KubeObjectStore<Node> {
|
||||
});
|
||||
}
|
||||
|
||||
reset() {
|
||||
reset(): void {
|
||||
super.reset();
|
||||
this.metrics = {};
|
||||
this.nodeMetrics = null;
|
||||
@@ -68,5 +68,5 @@ export class NodesStore extends KubeObjectStore<Node> {
|
||||
}
|
||||
}
|
||||
|
||||
export const nodesStore = new NodesStore()
|
||||
export const nodesStore = new NodesStore();
|
||||
apiManager.registerStore(nodesApi, nodesStore);
|
||||
@@ -4,12 +4,12 @@ import * as React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { t, Trans } from "@lingui/macro";
|
||||
import { cssNames, interval } from "../../utils";
|
||||
import { cssNames, IntervalManager } from "../../utils";
|
||||
import { MainLayout } from "../layout/main-layout";
|
||||
import { nodesStore } from "./nodes.store";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { INodesRouteParams } from "./nodes.route";
|
||||
import { NodesRouteParams } from "./nodes.route";
|
||||
import { Node, nodesApi } from "../../api/endpoints/nodes.api";
|
||||
import { NodeMenu } from "./node-menu";
|
||||
import { LineProgress } from "../line-progress";
|
||||
@@ -33,24 +33,26 @@ enum sortBy {
|
||||
status = "status",
|
||||
}
|
||||
|
||||
interface Props extends RouteComponentProps<INodesRouteParams> {
|
||||
interface Props extends RouteComponentProps<NodesRouteParams> {
|
||||
}
|
||||
|
||||
@observer
|
||||
export class Nodes extends React.Component<Props> {
|
||||
private metricsWatcher = interval(30, () => nodesStore.loadUsageMetrics());
|
||||
private metricsWatcher = new IntervalManager(30, () => nodesStore.loadUsageMetrics());
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount(): void {
|
||||
this.metricsWatcher.start(true);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
this.metricsWatcher.stop();
|
||||
}
|
||||
|
||||
renderCpuUsage(node: Node) {
|
||||
renderCpuUsage(node: Node): JSX.Element {
|
||||
const metrics = nodesStore.getLastMetricValues(node, ["cpuUsage", "cpuCapacity"]);
|
||||
if (!metrics || !metrics[1]) return <LineProgress value={0}/>;
|
||||
if (!metrics || !metrics[1]) {
|
||||
return <LineProgress value={0}/>;
|
||||
}
|
||||
const usage = metrics[0];
|
||||
const cores = metrics[1];
|
||||
return (
|
||||
@@ -59,12 +61,14 @@ export class Nodes extends React.Component<Props> {
|
||||
value={usage}
|
||||
tooltip={_i18n._(t`CPU:`) + ` ${Math.ceil(usage * 100) / cores}\%, ` + _i18n._(t`cores:`) + ` ${cores}`}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
renderMemoryUsage(node: Node) {
|
||||
renderMemoryUsage(node: Node): JSX.Element {
|
||||
const metrics = nodesStore.getLastMetricValues(node, ["memoryUsage", "memoryCapacity"]);
|
||||
if (!metrics || !metrics[1]) return <LineProgress value={0}/>;
|
||||
if (!metrics || !metrics[1]) {
|
||||
return <LineProgress value={0}/>;
|
||||
}
|
||||
const usage = metrics[0];
|
||||
const capacity = metrics[1];
|
||||
return (
|
||||
@@ -73,12 +77,14 @@ export class Nodes extends React.Component<Props> {
|
||||
value={usage}
|
||||
tooltip={_i18n._(t`Memory:`) + ` ${Math.ceil(usage * 100 / capacity)}%, ${bytesToUnits(usage, 3)}`}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
renderDiskUsage(node: Node): any {
|
||||
renderDiskUsage(node: Node): JSX.Element {
|
||||
const metrics = nodesStore.getLastMetricValues(node, ["fsUsage", "fsSize"]);
|
||||
if (!metrics || !metrics[1]) return <LineProgress value={0}/>;
|
||||
if (!metrics || !metrics[1]) {
|
||||
return <LineProgress value={0}/>;
|
||||
}
|
||||
const usage = metrics[0];
|
||||
const capacity = metrics[1];
|
||||
return (
|
||||
@@ -87,17 +93,17 @@ export class Nodes extends React.Component<Props> {
|
||||
value={usage}
|
||||
tooltip={_i18n._(t`Disk:`) + ` ${Math.ceil(usage * 100 / capacity)}%, ${bytesToUnits(usage, 3)}`}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
renderConditions(node: Node) {
|
||||
renderConditions(node: Node): JSX.Element[] {
|
||||
if (!node.status.conditions) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
const conditions = node.getActiveConditions();
|
||||
return conditions.map(condition => {
|
||||
const { type } = condition
|
||||
const tooltipId = `node-${node.getName()}-condition-${type}`
|
||||
const { type } = condition;
|
||||
const tooltipId = `node-${node.getName()}-condition-${type}`;
|
||||
return (
|
||||
<div key={type} id={tooltipId} className={cssNames("condition", kebabCase(type))}>
|
||||
{type}
|
||||
@@ -111,11 +117,11 @@ export class Nodes extends React.Component<Props> {
|
||||
)}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>)
|
||||
})
|
||||
</div>);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<MainLayout>
|
||||
<KubeObjectListLayout
|
||||
@@ -125,21 +131,21 @@ export class Nodes extends React.Component<Props> {
|
||||
dependentStores={[podsStore]}
|
||||
isSelectable={false}
|
||||
sortingCallbacks={{
|
||||
[sortBy.name]: (node: Node) => node.getName(),
|
||||
[sortBy.cpu]: (node: Node) => nodesStore.getLastMetricValues(node, ["cpuUsage"]),
|
||||
[sortBy.memory]: (node: Node) => nodesStore.getLastMetricValues(node, ["memoryUsage"]),
|
||||
[sortBy.disk]: (node: Node) => nodesStore.getLastMetricValues(node, ["fsUsage"]),
|
||||
[sortBy.conditions]: (node: Node) => node.getNodeConditionText(),
|
||||
[sortBy.taints]: (node: Node) => node.getTaints().length,
|
||||
[sortBy.roles]: (node: Node) => node.getRoleLabels(),
|
||||
[sortBy.age]: (node: Node) => node.metadata.creationTimestamp,
|
||||
[sortBy.version]: (node: Node) => node.getKubeletVersion(),
|
||||
[sortBy.name]: (node: Node): string => node.getName(),
|
||||
[sortBy.cpu]: (node: Node): number[] => nodesStore.getLastMetricValues(node, ["cpuUsage"]),
|
||||
[sortBy.memory]: (node: Node): number[] => nodesStore.getLastMetricValues(node, ["memoryUsage"]),
|
||||
[sortBy.disk]: (node: Node): number[] => nodesStore.getLastMetricValues(node, ["fsUsage"]),
|
||||
[sortBy.conditions]: (node: Node): string => node.getNodeConditionText(),
|
||||
[sortBy.taints]: (node: Node): number => node.getTaints().length,
|
||||
[sortBy.roles]: (node: Node): string => node.getRoleLabels(),
|
||||
[sortBy.age]: (node: Node): string => node.metadata.creationTimestamp,
|
||||
[sortBy.version]: (node: Node): string => node.getKubeletVersion(),
|
||||
}}
|
||||
searchFilters={[
|
||||
(node: Node) => node.getSearchFields(),
|
||||
(node: Node) => node.getRoleLabels(),
|
||||
(node: Node) => node.getKubeletVersion(),
|
||||
(node: Node) => node.getNodeConditionText(),
|
||||
(node: Node): string[] => node.getSearchFields(),
|
||||
(node: Node): string => node.getRoleLabels(),
|
||||
(node: Node): string => node.getKubeletVersion(),
|
||||
(node: Node): string => node.getNodeConditionText(),
|
||||
]}
|
||||
renderHeaderTitle={<Trans>Nodes</Trans>}
|
||||
renderTableHeader={[
|
||||
@@ -153,7 +159,7 @@ export class Nodes extends React.Component<Props> {
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
{ title: <Trans>Conditions</Trans>, className: "conditions", sortBy: sortBy.conditions },
|
||||
]}
|
||||
renderTableContents={(node: Node) => {
|
||||
renderTableContents={(node: Node): (string | number | JSX.Element | JSX.Element[])[] => {
|
||||
const tooltipId = `node-taints-${node.getId()}`;
|
||||
return [
|
||||
node.getName(),
|
||||
@@ -170,14 +176,14 @@ export class Nodes extends React.Component<Props> {
|
||||
node.status.nodeInfo.kubeletVersion,
|
||||
node.getAge(),
|
||||
this.renderConditions(node),
|
||||
]
|
||||
];
|
||||
}}
|
||||
renderItemMenu={(item: Node) => {
|
||||
return <NodeMenu object={item}/>
|
||||
renderItemMenu={(item: Node): JSX.Element => {
|
||||
return <NodeMenu object={item}/>;
|
||||
}}
|
||||
/>
|
||||
</MainLayout>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user