cleanup Lens repo with tighter linting

Signed-off-by: Sebastian Malton <smalton@mirantis.com>
This commit is contained in:
Sebastian Malton committed 2020-07-09 17:00:23 -04:00
1 parent e468105143
commit b1ff34879a
470 files changed
+8447 -7443

No files matched your search

+4 -4
View File
@@ -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);
+46 -40
View File
@@ -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>
)
);
}
}