From 836783fbc142947005270088825fe442b6354e40 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Tue, 25 Oct 2022 12:00:05 -0400 Subject: [PATCH] Convert Pod metrics to be injectable Signed-off-by: Sebastian Malton --- .../container-metrics.injectable.ts | 27 +++++++ .../metrics-detail-container.injectable.tsx | 34 +++++++++ .../+workloads-pods/metrics.injectable.ts | 27 +++++++ .../+workloads-pods/pod-details.tsx | 75 ++++--------------- 4 files changed, 104 insertions(+), 59 deletions(-) create mode 100644 src/renderer/components/+workloads-pods/container-metrics.injectable.ts create mode 100644 src/renderer/components/+workloads-pods/metrics-detail-container.injectable.tsx create mode 100644 src/renderer/components/+workloads-pods/metrics.injectable.ts diff --git a/src/renderer/components/+workloads-pods/container-metrics.injectable.ts b/src/renderer/components/+workloads-pods/container-metrics.injectable.ts new file mode 100644 index 0000000000..2b25bafb7a --- /dev/null +++ b/src/renderer/components/+workloads-pods/container-metrics.injectable.ts @@ -0,0 +1,27 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; +import { asyncComputed } from "@ogre-tools/injectable-react"; +import { now } from "mobx-utils"; +import type { Pod } from "../../../common/k8s-api/endpoints"; +import requestPodMetricsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics.injectable"; + +const podContainerMetricsInjectable = getInjectable({ + id: "pod-container-metrics", + instantiate: (di, pod) => { + const requestPodMetrics = di.inject(requestPodMetricsInjectable); + + return asyncComputed(() => { + now(60 * 1000); + + return requestPodMetrics([pod], pod.getNs(), "container, namespace"); + }); + }, + lifecycle: lifecycleEnum.keyedSingleton({ + getInstanceKey: (di, pod: Pod) => pod.getId(), + }), +}); + +export default podContainerMetricsInjectable; diff --git a/src/renderer/components/+workloads-pods/metrics-detail-container.injectable.tsx b/src/renderer/components/+workloads-pods/metrics-detail-container.injectable.tsx new file mode 100644 index 0000000000..1fef4faa18 --- /dev/null +++ b/src/renderer/components/+workloads-pods/metrics-detail-container.injectable.tsx @@ -0,0 +1,34 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import React from "react"; +import { ClusterMetricsResourceType } from "../../../common/cluster-types"; +import type { Pod } from "../../../common/k8s-api/endpoints"; +import enabledMetricsInjectable from "../../api/catalog/entity/metrics-enabled.injectable"; +import type { KubeObjectDetailsProps } from "../kube-object-details"; +import { kubeObjectDetailItemInjectionToken } from "../kube-object-details/kube-object-detail-items/kube-object-detail-item-injection-token"; +import { ResourceMetrics } from "../resource-metrics"; +import podMetricsInjectable from "./metrics.injectable"; +import { PodCharts, podMetricTabs } from "./pod-charts"; + +const podMetricsDetailsComponentInjectable = getInjectable({ + id: "pod-metrics-details-container", + instantiate: (di) => ({ + Component: ({ object }: KubeObjectDetailsProps) => ( + + + + ), + enabled: di.inject(enabledMetricsInjectable, ClusterMetricsResourceType.Pod), + orderNumber: -1, + }), + injectionToken: kubeObjectDetailItemInjectionToken, +}); + +export default podMetricsDetailsComponentInjectable; diff --git a/src/renderer/components/+workloads-pods/metrics.injectable.ts b/src/renderer/components/+workloads-pods/metrics.injectable.ts new file mode 100644 index 0000000000..b7d1b4225e --- /dev/null +++ b/src/renderer/components/+workloads-pods/metrics.injectable.ts @@ -0,0 +1,27 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; +import { asyncComputed } from "@ogre-tools/injectable-react"; +import { now } from "mobx-utils"; +import type { Pod } from "../../../common/k8s-api/endpoints"; +import requestPodMetricsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics.injectable"; + +const podMetricsInjectable = getInjectable({ + id: "pod-metrics", + instantiate: (di, pod) => { + const requestPodMetrics = di.inject(requestPodMetricsInjectable); + + return asyncComputed(() => { + now(60 * 1000); + + return requestPodMetrics([pod], pod.getNs()); + }); + }, + lifecycle: lifecycleEnum.keyedSingleton({ + getInstanceKey: (di, pod: Pod) => pod.getId(), + }), +}); + +export default podMetricsInjectable; diff --git a/src/renderer/components/+workloads-pods/pod-details.tsx b/src/renderer/components/+workloads-pods/pod-details.tsx index 726c5326b6..604cec5cd5 100644 --- a/src/renderer/components/+workloads-pods/pod-details.tsx +++ b/src/renderer/components/+workloads-pods/pod-details.tsx @@ -7,9 +7,8 @@ import "./pod-details.scss"; import React from "react"; import kebabCase from "lodash/kebabCase"; -import { disposeOnUnmount, observer } from "mobx-react"; +import { observer } from "mobx-react"; import { Link } from "react-router-dom"; -import { observable, reaction, makeObservable } from "mobx"; import { Pod } from "../../../common/k8s-api/endpoints"; import type { NodeApi, PriorityClassApi, RuntimeClassApi, ServiceAccountApi } from "../../../common/k8s-api/endpoints"; import { DrawerItem, DrawerTitle } from "../drawer"; @@ -19,67 +18,39 @@ import { PodDetailsContainer } from "./pod-details-container"; import { PodDetailsAffinities } from "./pod-details-affinities"; import { PodDetailsTolerations } from "./pod-details-tolerations"; import { PodDetailsSecrets } from "./pod-details-secrets"; -import { ResourceMetrics } from "../resource-metrics"; import type { KubeObjectDetailsProps } from "../kube-object-details"; import { getItemMetrics } from "../../../common/k8s-api/endpoints/metrics.api"; -import { PodCharts, podMetricTabs } from "./pod-charts"; -import { KubeObjectMeta } from "../kube-object-meta"; -import { ClusterMetricsResourceType } from "../../../common/cluster-types"; -import logger from "../../../common/logger"; +import type { Logger } from "../../../common/logger"; import { PodVolumes } from "./details/volumes/view"; -import type { PodMetricData, RequestPodMetrics } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics.injectable"; +import type { IAsyncComputed } from "@ogre-tools/injectable-react"; import { withInjectables } from "@ogre-tools/injectable-react"; -import requestPodMetricsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics.injectable"; -import type { GetActiveClusterEntity } from "../../api/catalog/entity/get-active-cluster-entity.injectable"; import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable"; -import getActiveClusterEntityInjectable from "../../api/catalog/entity/get-active-cluster-entity.injectable"; import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable"; import nodeApiInjectable from "../../../common/k8s-api/endpoints/node.api.injectable"; import runtimeClassApiInjectable from "../../../common/k8s-api/endpoints/runtime-class.api.injectable"; import serviceAccountApiInjectable from "../../../common/k8s-api/endpoints/service-account.api.injectable"; import priorityClassApiInjectable from "../../../common/k8s-api/endpoints/priority-class.api.injectable"; +import loggerInjectable from "../../../common/logger.injectable"; +import type { PodMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics.injectable"; +import podContainerMetricsInjectable from "./container-metrics.injectable"; export interface PodDetailsProps extends KubeObjectDetailsProps { } interface Dependencies { - requestPodMetrics: RequestPodMetrics; - getActiveClusterEntity: GetActiveClusterEntity; getDetailsUrl: GetDetailsUrl; nodeApi: NodeApi; priorityClassApi: PriorityClassApi; runtimeClassApi: RuntimeClassApi; serviceAccountApi: ServiceAccountApi; + logger: Logger; + containerMetrics: IAsyncComputed; } @observer class NonInjectedPodDetails extends React.Component { - @observable metrics: PodMetricData | null = null; - @observable containerMetrics: PodMetricData | null = null; - - constructor(props: PodDetailsProps & Dependencies) { - super(props); - makeObservable(this); - } - - componentDidMount() { - disposeOnUnmount(this, [ - reaction(() => this.props.object, () => { - this.metrics = null; - this.containerMetrics = null; - }), - ]); - } - - loadMetrics = async () => { - const { object: pod, requestPodMetrics } = this.props; - - this.metrics = await requestPodMetrics([pod], pod.getNs()); - this.containerMetrics = await requestPodMetrics([pod], pod.getNs(), "container, namespace"); - }; - render() { - const { object: pod, getActiveClusterEntity, getDetailsUrl, nodeApi } = this.props; + const { object: pod, getDetailsUrl, nodeApi, logger, containerMetrics } = this.props; if (!pod) { return null; @@ -96,7 +67,6 @@ class NonInjectedPodDetails extends React.Component - {!isMetricHidden && ( - - - - )} - - - {pod.getStatusMessage()} @@ -230,7 +187,7 @@ class NonInjectedPodDetails extends React.Component ))} @@ -243,12 +200,12 @@ class NonInjectedPodDetails extends React.Component(NonInjectedPodDetails, { getProps: (di, props) => ({ ...props, - requestPodMetrics: di.inject(requestPodMetricsInjectable), - getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable), getDetailsUrl: di.inject(getDetailsUrlInjectable), nodeApi: di.inject(nodeApiInjectable), priorityClassApi: di.inject(priorityClassApiInjectable), runtimeClassApi: di.inject(runtimeClassApiInjectable), serviceAccountApi: di.inject(serviceAccountApiInjectable), + logger: di.inject(loggerInjectable), + containerMetrics: di.inject(podContainerMetricsInjectable, props.object), }), });