mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Refactor kube detail components and add KubeEvents automatically to all custom resources (#6468)
* Support Events on CustomResourece details panel Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove unnecessary check Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove legacy KubeObjectMeta use from non-metrics details Signed-off-by: Sebastian Malton <sebastian@malton.name> * Change orderNumber of default KubeMetaDetails Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove last use of legacy global getActiveClusterEntity Signed-off-by: Sebastian Malton <sebastian@malton.name> * Refactor ResourceMetrics to use IAsyncComputed - Introduce first use for namespace metrics Signed-off-by: Sebastian Malton <sebastian@malton.name> * Introduce metrics details item for Ingress Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove legacyStore for nodes Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove legacyStore for ingresses Signed-off-by: Sebastian Malton <sebastian@malton.name> * Replace NodeMetrics in details with injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * Change namespace metrics details to use more injectables Signed-off-by: Sebastian Malton <sebastian@malton.name> * Change ingress metrics details to use more injectables Signed-off-by: Sebastian Malton <sebastian@malton.name> * Change PersistentVolumeClaim metrics to be injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * Change DaemonSet metrics to be injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * Change Deployment metrics to be injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * Change Job metrics to be injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * Convert Pod metrics to be injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * Make ReplicaSet metrics details injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * Make StatefulSet metrics component injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove dead code Signed-off-by: Sebastian Malton <sebastian@malton.name> * Introduce fix for metrics components visible on all details Signed-off-by: Sebastian Malton <sebastian@malton.name> * Use the new and correct enabled check Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove legacy global for daemonSetStore Signed-off-by: Sebastian Malton <sebastian@malton.name> * Switch components to be static to help with React performance Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove legacy store of CronJobs Signed-off-by: Sebastian Malton <sebastian@malton.name> * Make DeploymentReplicaSets injectable to fix build error Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix up remove dead code Signed-off-by: Sebastian Malton <sebastian@malton.name> * Allow use of ResourceMetrics without IAsyncComputed Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix metrics not updating correctly Signed-off-by: Sebastian Malton <sebastian@malton.name> * Update snapshots because moving KubeObjectMeta out of CustomResourceDetails Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * Update more snapshots Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix test failures due to newer dep versions Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix type errors from new asyncComputed Signed-off-by: Sebastian Malton <sebastian@malton.name> Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
d05189d008
commit
83d2b12cca
@ -24,7 +24,7 @@ const requestPodMetricsForJobsInjectable = getInjectable({
|
|||||||
instantiate: (di): RequestPodMetricsForJobs => {
|
instantiate: (di): RequestPodMetricsForJobs => {
|
||||||
const requestMetrics = di.inject(requestMetricsInjectable);
|
const requestMetrics = di.inject(requestMetricsInjectable);
|
||||||
|
|
||||||
return (jobs, namespace, selector) => {
|
return (jobs, namespace, selector = "") => {
|
||||||
const podSelector = jobs.map(job => `${job.getName()}-[[:alnum:]]{5}`).join("|");
|
const podSelector = jobs.map(job => `${job.getName()}-[[:alnum:]]{5}`).join("|");
|
||||||
const opts = { category: "pods", pods: podSelector, namespace, selector };
|
const opts = { category: "pods", pods: podSelector, namespace, selector };
|
||||||
|
|
||||||
|
|||||||
16
src/common/utils/sort-function.ts
Normal file
16
src/common/utils/sort-function.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an ordering function based on the function getter
|
||||||
|
*/
|
||||||
|
export function byValue<T>(getOrderValue: (src: T) => number): (left: T, right: T) => number {
|
||||||
|
return (left, right) => {
|
||||||
|
const leftValue = getOrderValue(left);
|
||||||
|
const rightValue = getOrderValue(right);
|
||||||
|
|
||||||
|
return leftValue - rightValue;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -302,11 +302,63 @@ exports[`disable kube object detail items when cluster is not relevant given ext
|
|||||||
<div
|
<div
|
||||||
class="drawer-content flex column box grow"
|
class="drawer-content flex column box grow"
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Created
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
<unknown>
|
||||||
|
ago
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Name
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
some-name
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Namespace
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
some-namespace
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
data-testid="some-kube-object-detail-item"
|
data-testid="some-kube-object-detail-item"
|
||||||
>
|
>
|
||||||
Some detail
|
Some detail
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerTitle flex gaps align-center title"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Events
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@ -792,6 +844,15 @@ exports[`disable kube object detail items when cluster is not relevant given ext
|
|||||||
some-namespace
|
some-namespace
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerTitle flex gaps align-center title"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Events
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@ -1277,6 +1338,15 @@ exports[`disable kube object detail items when cluster is not relevant given not
|
|||||||
some-namespace
|
some-namespace
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerTitle flex gaps align-center title"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Events
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import extensionShouldBeEnabledForClusterFrameInjectable from "../../../../rende
|
|||||||
import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager.injectable";
|
import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
import { KubeObjectDetails } from "../../../../renderer/components/kube-object-details";
|
import { KubeObjectDetails } from "../../../../renderer/components/kube-object-details";
|
||||||
import type { ApiManager } from "../../../../common/k8s-api/api-manager";
|
import type { ApiManager } from "../../../../common/k8s-api/api-manager";
|
||||||
|
import type { KubeObjectStore } from "../../../../common/k8s-api/kube-object.store";
|
||||||
|
|
||||||
describe("disable kube object detail items when cluster is not relevant", () => {
|
describe("disable kube object detail items when cluster is not relevant", () => {
|
||||||
let builder: ApplicationBuilder;
|
let builder: ApplicationBuilder;
|
||||||
@ -32,16 +33,11 @@ describe("disable kube object detail items when cluster is not relevant", () =>
|
|||||||
builder.setEnvironmentToClusterFrame();
|
builder.setEnvironmentToClusterFrame();
|
||||||
|
|
||||||
builder.beforeWindowStart((windowDi) => {
|
builder.beforeWindowStart((windowDi) => {
|
||||||
windowDi.override(
|
windowDi.override(apiManagerInjectable, () => ({
|
||||||
apiManagerInjectable,
|
|
||||||
() =>
|
|
||||||
({
|
|
||||||
getStore: () => ({
|
getStore: () => ({
|
||||||
getByPath: () =>
|
loadFromPath: async () => getKubeObjectStub("some-kind", "some-api-version"),
|
||||||
getKubeObjectStub("some-kind", "some-api-version"),
|
}) as Partial<KubeObjectStore> as KubeObjectStore,
|
||||||
}),
|
}) as Partial<ApiManager> as ApiManager);
|
||||||
} as unknown as ApiManager),
|
|
||||||
);
|
|
||||||
|
|
||||||
windowDi.unoverride(extensionShouldBeEnabledForClusterFrameInjectable);
|
windowDi.unoverride(extensionShouldBeEnabledForClusterFrameInjectable);
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import { KubeObject } from "../../../../common/k8s-api/kube-object";
|
|||||||
import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager.injectable";
|
import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
import { KubeObjectDetails } from "../../../../renderer/components/kube-object-details";
|
import { KubeObjectDetails } from "../../../../renderer/components/kube-object-details";
|
||||||
import type { ApiManager } from "../../../../common/k8s-api/api-manager";
|
import type { ApiManager } from "../../../../common/k8s-api/api-manager";
|
||||||
|
import type { KubeObjectStore } from "../../../../common/k8s-api/kube-object.store";
|
||||||
|
|
||||||
describe("reactively hide kube object detail item", () => {
|
describe("reactively hide kube object detail item", () => {
|
||||||
let builder: ApplicationBuilder;
|
let builder: ApplicationBuilder;
|
||||||
@ -28,16 +29,11 @@ describe("reactively hide kube object detail item", () => {
|
|||||||
builder.setEnvironmentToClusterFrame();
|
builder.setEnvironmentToClusterFrame();
|
||||||
|
|
||||||
builder.beforeWindowStart((windowDi) => {
|
builder.beforeWindowStart((windowDi) => {
|
||||||
windowDi.override(
|
windowDi.override(apiManagerInjectable, () => ({
|
||||||
apiManagerInjectable,
|
|
||||||
() =>
|
|
||||||
({
|
|
||||||
getStore: () => ({
|
getStore: () => ({
|
||||||
getByPath: () =>
|
loadFromPath: async () => getKubeObjectStub("some-kind", "some-api-version"),
|
||||||
getKubeObjectStub("some-kind", "some-api-version"),
|
}) as Partial<KubeObjectStore> as KubeObjectStore,
|
||||||
}),
|
}) as Partial<ApiManager> as ApiManager);
|
||||||
} as unknown as ApiManager),
|
|
||||||
);
|
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
windowDi.register(testRouteInjectable, testRouteComponentInjectable);
|
windowDi.register(testRouteInjectable, testRouteComponentInjectable);
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { asLegacyGlobalFunctionForExtensionApi } from "../../../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
|
|
||||||
import getActiveClusterEntityInjectable from "./get-active-cluster-entity.injectable";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated use `di.inject(getActiveClusterEntityInjectable)` instead
|
|
||||||
*/
|
|
||||||
export const getActiveClusterEntity = asLegacyGlobalFunctionForExtensionApi(getActiveClusterEntityInjectable);
|
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* 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 { computed } from "mobx";
|
||||||
|
import type { ClusterMetricsResourceType } from "../../../../common/cluster-types";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../../components/kube-object-details/current-kube-object-in-details.injectable";
|
||||||
|
import enabledMetricsInjectable from "./metrics-enabled.injectable";
|
||||||
|
|
||||||
|
const metricsDetailsComponentEnabledInjectable = getInjectable({
|
||||||
|
id: "metrics-details-component-enabled",
|
||||||
|
instantiate: (di, kind) => {
|
||||||
|
const metricsEnabled = di.inject(enabledMetricsInjectable, kind);
|
||||||
|
const currentKubeObjectInDetails = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return computed(() => {
|
||||||
|
const current = currentKubeObjectInDetails.value.get();
|
||||||
|
|
||||||
|
if (!current?.object) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return current.object.kind == kind && metricsEnabled.get();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, kind: ClusterMetricsResourceType) => kind,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default metricsDetailsComponentEnabledInjectable;
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* 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 { computed } from "mobx";
|
||||||
|
import type { ClusterMetricsResourceType } from "../../../../common/cluster-types";
|
||||||
|
import getActiveClusterEntityInjectable from "./get-active-cluster-entity.injectable";
|
||||||
|
|
||||||
|
const enabledMetricsInjectable = getInjectable({
|
||||||
|
id: "enabled-metrics",
|
||||||
|
instantiate: (di, kind) => {
|
||||||
|
const getActiveClusterEntity = di.inject(getActiveClusterEntityInjectable);
|
||||||
|
|
||||||
|
return computed(() => !getActiveClusterEntity()?.isMetricHidden(kind));
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, kind: ClusterMetricsResourceType) => kind,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default enabledMetricsInjectable;
|
||||||
@ -16,7 +16,6 @@ import type { HorizontalPodAutoscalerMetricSpec, HorizontalPodAutoscalerMetricTa
|
|||||||
import { HorizontalPodAutoscaler, HpaMetricType } from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api";
|
import { HorizontalPodAutoscaler, HpaMetricType } from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
|
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
@ -121,8 +120,6 @@ class NonInjectedHpaDetails extends React.Component<HpaDetailsProps & Dependenci
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="HpaDetails">
|
<div className="HpaDetails">
|
||||||
<KubeObjectMeta object={hpa}/>
|
|
||||||
|
|
||||||
<DrawerItem name="Reference">
|
<DrawerItem name="Reference">
|
||||||
{scaleTargetRef && (
|
{scaleTargetRef && (
|
||||||
<Link to={getDetailsUrl(apiManager.lookupApiLink(scaleTargetRef, hpa))}>
|
<Link to={getDetailsUrl(apiManager.lookupApiLink(scaleTargetRef, hpa))}>
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import React from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import type { Lease } from "../../../common/k8s-api/endpoints";
|
import type { Lease } from "../../../common/k8s-api/endpoints";
|
||||||
|
|
||||||
export interface LeaseDetailsProps extends KubeObjectDetailsProps<Lease> {
|
export interface LeaseDetailsProps extends KubeObjectDetailsProps<Lease> {
|
||||||
@ -23,8 +22,6 @@ export class LeaseDetails extends React.Component<LeaseDetailsProps> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="LeaseDetails">
|
<div className="LeaseDetails">
|
||||||
<KubeObjectMeta object={lease} />
|
|
||||||
|
|
||||||
<DrawerItem name="Holder Identity">
|
<DrawerItem name="Holder Identity">
|
||||||
{lease.getHolderIdentity()}
|
{lease.getHolderIdentity()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { observer } from "mobx-react";
|
|||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import type { LimitRangeItem } from "../../../common/k8s-api/endpoints/limit-range.api";
|
import type { LimitRangeItem } from "../../../common/k8s-api/endpoints/limit-range.api";
|
||||||
import { LimitPart, LimitRange, Resource } from "../../../common/k8s-api/endpoints/limit-range.api";
|
import { LimitPart, LimitRange, Resource } from "../../../common/k8s-api/endpoints/limit-range.api";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { DrawerItem } from "../drawer/drawer-item";
|
import { DrawerItem } from "../drawer/drawer-item";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
@ -73,8 +72,6 @@ export class LimitRangeDetails extends React.Component<LimitRangeDetailsProps> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="LimitRangeDetails">
|
<div className="LimitRangeDetails">
|
||||||
<KubeObjectMeta object={limitRange}/>
|
|
||||||
|
|
||||||
{containerLimits.length > 0 && (
|
{containerLimits.length > 0 && (
|
||||||
<DrawerItem name="Container Limits" labelsOnly>
|
<DrawerItem name="Container Limits" labelsOnly>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import { Input } from "../input";
|
|||||||
import { Button } from "../button";
|
import { Button } from "../button";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { ConfigMap } from "../../../common/k8s-api/endpoints";
|
import { ConfigMap } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import type { Logger } from "../../../common/logger";
|
import type { Logger } from "../../../common/logger";
|
||||||
import type { ConfigMapStore } from "./store";
|
import type { ConfigMapStore } from "./store";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
@ -95,7 +94,6 @@ class NonInjectedConfigMapDetails extends React.Component<ConfigMapDetailsProps
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ConfigMapDetails">
|
<div className="ConfigMapDetails">
|
||||||
<KubeObjectMeta object={configMap}/>
|
|
||||||
{
|
{
|
||||||
data.length > 0 && (
|
data.length > 0 && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { DrawerItem } from "../drawer";
|
|||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { PodDisruptionBudget } from "../../../common/k8s-api/endpoints";
|
import { PodDisruptionBudget } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
export interface PodDisruptionBudgetDetailsProps extends KubeObjectDetailsProps<PodDisruptionBudget> {
|
export interface PodDisruptionBudgetDetailsProps extends KubeObjectDetailsProps<PodDisruptionBudget> {
|
||||||
@ -37,8 +36,6 @@ export class PodDisruptionBudgetDetails extends React.Component<PodDisruptionBud
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="PdbDetails">
|
<div className="PdbDetails">
|
||||||
<KubeObjectMeta object={pdb}/>
|
|
||||||
|
|
||||||
{selectors.length > 0 && (
|
{selectors.length > 0 && (
|
||||||
<DrawerItem name="Selector" labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { observer } from "mobx-react";
|
|||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import type { PriorityClass } from "../../../common/k8s-api/endpoints";
|
import type { PriorityClass } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
|
|
||||||
export interface PriorityClassesDetailsProps extends KubeObjectDetailsProps<PriorityClass> {
|
export interface PriorityClassesDetailsProps extends KubeObjectDetailsProps<PriorityClass> {
|
||||||
}
|
}
|
||||||
@ -23,8 +22,6 @@ export class PriorityClassesDetails extends React.Component<PriorityClassesDetai
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="PriorityClassesDetails">
|
<div className="PriorityClassesDetails">
|
||||||
<KubeObjectMeta object={pc} />
|
|
||||||
|
|
||||||
<DrawerItem name="Description">
|
<DrawerItem name="Description">
|
||||||
{pc.getDescription()}
|
{pc.getDescription()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import type { KubeObjectDetailsProps } from "../kube-object-details";
|
|||||||
import { ResourceQuota } from "../../../common/k8s-api/endpoints/resource-quota.api";
|
import { ResourceQuota } from "../../../common/k8s-api/endpoints/resource-quota.api";
|
||||||
import { LineProgress } from "../line-progress";
|
import { LineProgress } from "../line-progress";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
export interface ResourceQuotaDetailsProps extends KubeObjectDetailsProps<ResourceQuota> {
|
export interface ResourceQuotaDetailsProps extends KubeObjectDetailsProps<ResourceQuota> {
|
||||||
@ -93,8 +92,6 @@ export class ResourceQuotaDetails extends React.Component<ResourceQuotaDetailsPr
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ResourceQuotaDetails">
|
<div className="ResourceQuotaDetails">
|
||||||
<KubeObjectMeta object={quota}/>
|
|
||||||
|
|
||||||
<DrawerItem name="Quotas" className="quota-list">
|
<DrawerItem name="Quotas" className="quota-list">
|
||||||
{renderQuotas(quota)}
|
{renderQuotas(quota)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { observer } from "mobx-react";
|
|||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import type { RuntimeClass } from "../../../common/k8s-api/endpoints";
|
import type { RuntimeClass } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { RuntimeClassDetailsTolerations } from "./runtime-classes-details-tolerations";
|
import { RuntimeClassDetailsTolerations } from "./runtime-classes-details-tolerations";
|
||||||
|
|
||||||
@ -26,8 +25,6 @@ export class RuntimeClassesDetails extends React.Component<RuntimeClassesDetails
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="RuntimeClassesDetails">
|
<div className="RuntimeClassesDetails">
|
||||||
<KubeObjectMeta object={rc} />
|
|
||||||
|
|
||||||
<DrawerItem name="Handler">
|
<DrawerItem name="Handler">
|
||||||
{rc.getHandler()}
|
{rc.getHandler()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|||||||
@ -16,7 +16,6 @@ import { base64, toggle } from "../../utils";
|
|||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { Secret } from "../../../common/k8s-api/endpoints";
|
import { Secret } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import type { Logger } from "../../../common/logger";
|
import type { Logger } from "../../../common/logger";
|
||||||
import type { SecretStore } from "./store";
|
import type { SecretStore } from "./store";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
@ -161,7 +160,6 @@ class NonInjectedSecretDetails extends React.Component<SecretDetailsProps & Depe
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="SecretDetails">
|
<div className="SecretDetails">
|
||||||
<KubeObjectMeta object={secret}/>
|
|
||||||
<DrawerItem name="Type">
|
<DrawerItem name="Type">
|
||||||
{secret.type}
|
{secret.type}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|||||||
@ -5,35 +5,6 @@ exports[`<CustomResourceDetails /> with a CRD with a boolean field should displa
|
|||||||
<div
|
<div
|
||||||
class="CrdResourceDetails MyCrd"
|
class="CrdResourceDetails MyCrd"
|
||||||
>
|
>
|
||||||
<div
|
|
||||||
class="DrawerItem"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="name"
|
|
||||||
>
|
|
||||||
Created
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="value"
|
|
||||||
>
|
|
||||||
<unknown>
|
|
||||||
ago
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="DrawerItem"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="name"
|
|
||||||
>
|
|
||||||
Name
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="value"
|
|
||||||
>
|
|
||||||
first-crd
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="DrawerItem"
|
class="DrawerItem"
|
||||||
>
|
>
|
||||||
@ -57,35 +28,6 @@ exports[`<CustomResourceDetails /> with a CRD with a boolean field should displa
|
|||||||
<div
|
<div
|
||||||
class="CrdResourceDetails MyCrd"
|
class="CrdResourceDetails MyCrd"
|
||||||
>
|
>
|
||||||
<div
|
|
||||||
class="DrawerItem"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="name"
|
|
||||||
>
|
|
||||||
Created
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="value"
|
|
||||||
>
|
|
||||||
<unknown>
|
|
||||||
ago
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="DrawerItem"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="name"
|
|
||||||
>
|
|
||||||
Name
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="value"
|
|
||||||
>
|
|
||||||
first-crd
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="DrawerItem"
|
class="DrawerItem"
|
||||||
>
|
>
|
||||||
@ -109,35 +51,6 @@ exports[`<CustomResourceDetails /> with a CRD with a number field should display
|
|||||||
<div
|
<div
|
||||||
class="CrdResourceDetails MyCrd"
|
class="CrdResourceDetails MyCrd"
|
||||||
>
|
>
|
||||||
<div
|
|
||||||
class="DrawerItem"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="name"
|
|
||||||
>
|
|
||||||
Created
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="value"
|
|
||||||
>
|
|
||||||
<unknown>
|
|
||||||
ago
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="DrawerItem"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="name"
|
|
||||||
>
|
|
||||||
Name
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="value"
|
|
||||||
>
|
|
||||||
first-crd
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="DrawerItem"
|
class="DrawerItem"
|
||||||
>
|
>
|
||||||
@ -161,35 +74,6 @@ exports[`<CustomResourceDetails /> with a CRD with a number field should display
|
|||||||
<div
|
<div
|
||||||
class="CrdResourceDetails MyCrd"
|
class="CrdResourceDetails MyCrd"
|
||||||
>
|
>
|
||||||
<div
|
|
||||||
class="DrawerItem"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="name"
|
|
||||||
>
|
|
||||||
Created
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="value"
|
|
||||||
>
|
|
||||||
<unknown>
|
|
||||||
ago
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="DrawerItem"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="name"
|
|
||||||
>
|
|
||||||
Name
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="value"
|
|
||||||
>
|
|
||||||
first-crd
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="DrawerItem"
|
class="DrawerItem"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import { DrawerItem, DrawerTitle } from "../drawer";
|
|||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import { Input } from "../input";
|
import { Input } from "../input";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { MonacoEditor } from "../monaco-editor";
|
import { MonacoEditor } from "../monaco-editor";
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
@ -42,8 +41,6 @@ export class CRDDetails extends React.Component<CRDDetailsProps> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="CRDDetails">
|
<div className="CRDDetails">
|
||||||
<KubeObjectMeta object={crd}/>
|
|
||||||
|
|
||||||
<DrawerItem name="Group">
|
<DrawerItem name="Group">
|
||||||
{crd.getGroup()}
|
{crd.getGroup()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { cssNames } from "../../utils";
|
|||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { Input } from "../input";
|
import { Input } from "../input";
|
||||||
import type { AdditionalPrinterColumnsV1 } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
import type { AdditionalPrinterColumnsV1 } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
||||||
import { CustomResourceDefinition } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
import { CustomResourceDefinition } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
||||||
@ -21,7 +20,7 @@ import { KubeObject } from "../../../common/k8s-api/kube-object";
|
|||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
export interface CustomResourceDetailsProps extends KubeObjectDetailsProps<KubeObject> {
|
export interface CustomResourceDetailsProps extends KubeObjectDetailsProps<KubeObject> {
|
||||||
crd: CustomResourceDefinition;
|
crd?: CustomResourceDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertSpecValue(value: unknown): React.ReactNode {
|
function convertSpecValue(value: unknown): React.ReactNode {
|
||||||
@ -129,7 +128,6 @@ export class CustomResourceDetails extends React.Component<CustomResourceDetails
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cssNames("CrdResourceDetails", crd.getResourceKind())}>
|
<div className={cssNames("CrdResourceDetails", crd.getResourceKind())}>
|
||||||
<KubeObjectMeta object={object} />
|
|
||||||
{this.renderAdditionalColumns(object, extraColumns)}
|
{this.renderAdditionalColumns(object, extraColumns)}
|
||||||
{this.renderStatus(object, extraColumns)}
|
{this.renderStatus(object, extraColumns)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -58,7 +58,6 @@ export class CustomResourceDefinitionStore extends KubeObjectStore<CustomResourc
|
|||||||
}
|
}
|
||||||
|
|
||||||
getByObject(obj: KubeObject) {
|
getByObject(obj: KubeObject) {
|
||||||
if (!obj) return null;
|
|
||||||
const { kind, apiVersion } = obj;
|
const { kind, apiVersion } = obj;
|
||||||
|
|
||||||
return this.items.find(crd => (
|
return this.items.find(crd => (
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import { Link } from "react-router-dom";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { KubeEvent } from "../../../common/k8s-api/endpoints/events.api";
|
import { KubeEvent } from "../../../common/k8s-api/endpoints/events.api";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
@ -52,8 +51,6 @@ const NonInjectedEventDetails = observer(({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cssNames("EventDetails", className)}>
|
<div className={cssNames("EventDetails", className)}>
|
||||||
<KubeObjectMeta object={event}/>
|
|
||||||
|
|
||||||
<DrawerItem name="Message">
|
<DrawerItem name="Message">
|
||||||
{message}
|
{message}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|||||||
@ -13,13 +13,13 @@ import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
|||||||
import { Pod } from "../../../common/k8s-api/endpoints/pod.api";
|
import { Pod } from "../../../common/k8s-api/endpoints/pod.api";
|
||||||
import type { GetPodById } from "../+workloads-pods/get-pod-by-id.injectable";
|
import type { GetPodById } from "../+workloads-pods/get-pod-by-id.injectable";
|
||||||
|
|
||||||
export interface EventStoreDependencies {
|
interface Dependencies {
|
||||||
getPodById: GetPodById;
|
getPodById: GetPodById;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EventStore extends KubeObjectStore<KubeEvent, KubeEventApi> {
|
export class EventStore extends KubeObjectStore<KubeEvent, KubeEventApi> {
|
||||||
constructor(
|
constructor(
|
||||||
protected readonly dependencies: EventStoreDependencies,
|
protected readonly dependencies: Dependencies,
|
||||||
api: KubeEventApi,
|
api: KubeEventApi,
|
||||||
opts: KubeObjectStoreOptions = {},
|
opts: KubeObjectStoreOptions = {},
|
||||||
) {
|
) {
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { IAsyncComputed } from "@ogre-tools/injectable-react";
|
||||||
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import React from "react";
|
||||||
|
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
||||||
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
|
import type { Namespace } from "../../../common/k8s-api/endpoints";
|
||||||
|
import type { PodMetricInNamespaceData } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-in-namespace.injectable";
|
||||||
|
import metricsDetailsComponentEnabledInjectable from "../../api/catalog/entity/metrics-details-component-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 namespaceMetricsInjectable from "./metrics.injectable";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
metrics: IAsyncComputed<PodMetricInNamespaceData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedNamespaceMetricsDetailsComponent = ({
|
||||||
|
object,
|
||||||
|
metrics,
|
||||||
|
}: KubeObjectDetailsProps<Namespace> & Dependencies) => (
|
||||||
|
<ResourceMetrics
|
||||||
|
tabs={podMetricTabs}
|
||||||
|
object={object}
|
||||||
|
metrics={metrics}
|
||||||
|
>
|
||||||
|
<PodCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
);
|
||||||
|
|
||||||
|
const NamespaceMetricsDetailsComponent = withInjectables<Dependencies, KubeObjectDetailsProps<Namespace>>(NonInjectedNamespaceMetricsDetailsComponent, {
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
metrics: di.inject(namespaceMetricsInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const namespaceMetricsDetailsComponentInjectable = getInjectable({
|
||||||
|
id: "namespace-metrics-details-component",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
Component: NamespaceMetricsDetailsComponent,
|
||||||
|
enabled: di.inject(metricsDetailsComponentEnabledInjectable, ClusterMetricsResourceType.Namespace),
|
||||||
|
orderNumber: -1,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default namespaceMetricsDetailsComponentInjectable;
|
||||||
29
src/renderer/components/+namespaces/metrics.injectable.ts
Normal file
29
src/renderer/components/+namespaces/metrics.injectable.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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 { Namespace } from "../../../common/k8s-api/endpoints";
|
||||||
|
import requestPodMetricsInNamespaceInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-in-namespace.injectable";
|
||||||
|
|
||||||
|
const namespaceMetricsInjectable = getInjectable({
|
||||||
|
id: "namespace-metrics",
|
||||||
|
instantiate: (di, namespace) => {
|
||||||
|
const requestPodMetricsInNamespace = di.inject(requestPodMetricsInNamespaceInjectable);
|
||||||
|
|
||||||
|
return asyncComputed({
|
||||||
|
getValueFromObservedPromise: async () => {
|
||||||
|
now(60 * 1000); // Update every minute
|
||||||
|
|
||||||
|
return requestPodMetricsInNamespace(namespace.getName());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, namespace: Namespace) => namespace.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default namespaceMetricsInjectable;
|
||||||
@ -6,7 +6,7 @@
|
|||||||
import "./namespace-details.scss";
|
import "./namespace-details.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { computed, makeObservable, observable, reaction } from "mobx";
|
import { computed, makeObservable } from "mobx";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
@ -14,42 +14,32 @@ import { Namespace } from "../../../common/k8s-api/endpoints";
|
|||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { Spinner } from "../spinner";
|
import { Spinner } from "../spinner";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { ResourceMetrics } from "../resource-metrics";
|
|
||||||
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
|
||||||
import logger from "../../../common/logger";
|
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
|
||||||
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
||||||
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.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 type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
|
||||||
import type { ResourceQuotaStore } from "../+config-resource-quotas/store";
|
import type { ResourceQuotaStore } from "../+config-resource-quotas/store";
|
||||||
import type { LimitRangeStore } from "../+config-limit-ranges/store";
|
import type { LimitRangeStore } from "../+config-limit-ranges/store";
|
||||||
import getActiveClusterEntityInjectable from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
|
||||||
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
|
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
|
||||||
import limitRangeStoreInjectable from "../+config-limit-ranges/store.injectable";
|
import limitRangeStoreInjectable from "../+config-limit-ranges/store.injectable";
|
||||||
import resourceQuotaStoreInjectable from "../+config-resource-quotas/store.injectable";
|
import resourceQuotaStoreInjectable from "../+config-resource-quotas/store.injectable";
|
||||||
import type { PodMetricInNamespaceData, RequestPodMetricsInNamespace } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-in-namespace.injectable";
|
import type { Logger } from "../../../common/logger";
|
||||||
import requestPodMetricsInNamespaceInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-in-namespace.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
|
|
||||||
export interface NamespaceDetailsProps extends KubeObjectDetailsProps<Namespace> {
|
export interface NamespaceDetailsProps extends KubeObjectDetailsProps<Namespace> {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
subscribeStores: SubscribeStores;
|
subscribeStores: SubscribeStores;
|
||||||
getActiveClusterEntity: GetActiveClusterEntity;
|
|
||||||
getDetailsUrl: GetDetailsUrl;
|
getDetailsUrl: GetDetailsUrl;
|
||||||
resourceQuotaStore: ResourceQuotaStore;
|
resourceQuotaStore: ResourceQuotaStore;
|
||||||
limitRangeStore: LimitRangeStore;
|
limitRangeStore: LimitRangeStore;
|
||||||
requestPodMetricsInNamespace: RequestPodMetricsInNamespace;
|
logger: Logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class NonInjectedNamespaceDetails extends React.Component<NamespaceDetailsProps & Dependencies> {
|
class NonInjectedNamespaceDetails extends React.Component<NamespaceDetailsProps & Dependencies> {
|
||||||
@observable metrics: PodMetricInNamespaceData | null = null;
|
|
||||||
|
|
||||||
constructor(props: NamespaceDetailsProps & Dependencies) {
|
constructor(props: NamespaceDetailsProps & Dependencies) {
|
||||||
super(props);
|
super(props);
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
@ -57,10 +47,6 @@ class NonInjectedNamespaceDetails extends React.Component<NamespaceDetailsProps
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
disposeOnUnmount(this, [
|
disposeOnUnmount(this, [
|
||||||
reaction(() => this.props.object, () => {
|
|
||||||
this.metrics = null;
|
|
||||||
}),
|
|
||||||
|
|
||||||
this.props.subscribeStores([
|
this.props.subscribeStores([
|
||||||
this.props.resourceQuotaStore,
|
this.props.resourceQuotaStore,
|
||||||
this.props.limitRangeStore,
|
this.props.limitRangeStore,
|
||||||
@ -80,40 +66,23 @@ class NonInjectedNamespaceDetails extends React.Component<NamespaceDetailsProps
|
|||||||
return this.props.limitRangeStore.getAllByNs(namespace);
|
return this.props.limitRangeStore.getAllByNs(namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMetrics = async () => {
|
|
||||||
this.metrics = await this.props.requestPodMetricsInNamespace(this.props.object.getName());
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: namespace, getActiveClusterEntity, resourceQuotaStore, getDetailsUrl, limitRangeStore } = this.props;
|
const { object: namespace, resourceQuotaStore, getDetailsUrl, limitRangeStore } = this.props;
|
||||||
|
|
||||||
if (!namespace) {
|
if (!namespace) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(namespace instanceof Namespace)) {
|
if (!(namespace instanceof Namespace)) {
|
||||||
logger.error("[NamespaceDetails]: passed object that is not an instanceof Namespace", namespace);
|
this.props.logger.error("[NamespaceDetails]: passed object that is not an instanceof Namespace", namespace);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const status = namespace.getStatus();
|
const status = namespace.getStatus();
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.Namespace);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="NamespaceDetails">
|
<div className="NamespaceDetails">
|
||||||
{!isMetricHidden && (
|
|
||||||
<ResourceMetrics
|
|
||||||
loader={this.loadMetrics}
|
|
||||||
tabs={podMetricTabs}
|
|
||||||
object={namespace}
|
|
||||||
metrics={this.metrics}
|
|
||||||
>
|
|
||||||
<PodCharts />
|
|
||||||
</ResourceMetrics>
|
|
||||||
)}
|
|
||||||
<KubeObjectMeta object={namespace}/>
|
|
||||||
|
|
||||||
<DrawerItem name="Status">
|
<DrawerItem name="Status">
|
||||||
<span className={cssNames("status", status.toLowerCase())}>{status}</span>
|
<span className={cssNames("status", status.toLowerCase())}>{status}</span>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
@ -143,11 +112,10 @@ export const NamespaceDetails = withInjectables<Dependencies, NamespaceDetailsPr
|
|||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
...props,
|
...props,
|
||||||
subscribeStores: di.inject(subscribeStoresInjectable),
|
subscribeStores: di.inject(subscribeStoresInjectable),
|
||||||
getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable),
|
|
||||||
getDetailsUrl: di.inject(getDetailsUrlInjectable),
|
getDetailsUrl: di.inject(getDetailsUrlInjectable),
|
||||||
limitRangeStore: di.inject(limitRangeStoreInjectable),
|
limitRangeStore: di.inject(limitRangeStoreInjectable),
|
||||||
resourceQuotaStore: di.inject(resourceQuotaStoreInjectable),
|
resourceQuotaStore: di.inject(resourceQuotaStoreInjectable),
|
||||||
requestPodMetricsInNamespace: di.inject(requestPodMetricsInNamespaceInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { observer } from "mobx-react";
|
|||||||
import { DrawerTitle } from "../drawer";
|
import { DrawerTitle } from "../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { Endpoints } from "../../../common/k8s-api/endpoints";
|
import { Endpoints } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { EndpointSubsetList } from "./endpoint-subset-list";
|
import { EndpointSubsetList } from "./endpoint-subset-list";
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
@ -34,7 +33,6 @@ export class EndpointsDetails extends React.Component<EndpointsDetailsProps> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="EndpointDetails">
|
<div className="EndpointDetails">
|
||||||
<KubeObjectMeta object={endpoint}/>
|
|
||||||
<DrawerTitle>Subsets</DrawerTitle>
|
<DrawerTitle>Subsets</DrawerTitle>
|
||||||
{
|
{
|
||||||
endpoint.getEndpointSubsets().map((subset) => (
|
endpoint.getEndpointSubsets().map((subset) => (
|
||||||
|
|||||||
@ -6,54 +6,26 @@
|
|||||||
import "./ingress-details.scss";
|
import "./ingress-details.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { makeObservable, observable, reaction } from "mobx";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import type { ILoadBalancerIngress } from "../../../common/k8s-api/endpoints";
|
import type { ILoadBalancerIngress } from "../../../common/k8s-api/endpoints";
|
||||||
import { Ingress } from "../../../common/k8s-api/endpoints";
|
import { Ingress } from "../../../common/k8s-api/endpoints";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import { ResourceMetrics } from "../resource-metrics";
|
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { IngressCharts } from "./ingress-charts";
|
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { computeRuleDeclarations } from "../../../common/k8s-api/endpoints/ingress.api";
|
import { computeRuleDeclarations } from "../../../common/k8s-api/endpoints/ingress.api";
|
||||||
import { getActiveClusterEntity } from "../../api/catalog/entity/legacy-globals";
|
import type { Logger } from "../../../common/logger";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
|
||||||
import logger from "../../../common/logger";
|
|
||||||
import type { IngressMetricData, RequestIngressMetrics } from "../../../common/k8s-api/endpoints/metrics.api/request-ingress-metrics.injectable";
|
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import requestIngressMetricsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-ingress-metrics.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
|
|
||||||
export interface IngressDetailsProps extends KubeObjectDetailsProps<Ingress> {
|
export interface IngressDetailsProps extends KubeObjectDetailsProps<Ingress> {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
requestIngressMetrics: RequestIngressMetrics;
|
logger: Logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class NonInjectedIngressDetails extends React.Component<IngressDetailsProps & Dependencies> {
|
class NonInjectedIngressDetails extends React.Component<IngressDetailsProps & Dependencies> {
|
||||||
@observable metrics: IngressMetricData | null = null;
|
|
||||||
|
|
||||||
constructor(props: IngressDetailsProps & Dependencies) {
|
|
||||||
super(props);
|
|
||||||
makeObservable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
disposeOnUnmount(this, [
|
|
||||||
reaction(() => this.props.object, () => {
|
|
||||||
this.metrics = null;
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadMetrics = async () => {
|
|
||||||
const { object: ingress, requestIngressMetrics } = this.props;
|
|
||||||
|
|
||||||
this.metrics = await requestIngressMetrics(ingress.getName(), ingress.getNs());
|
|
||||||
};
|
|
||||||
|
|
||||||
renderPaths(ingress: Ingress) {
|
renderPaths(ingress: Ingress) {
|
||||||
return ingress.getRules()
|
return ingress.getRules()
|
||||||
.map((rule, index) => (
|
.map((rule, index) => (
|
||||||
@ -124,7 +96,7 @@ class NonInjectedIngressDetails extends React.Component<IngressDetailsProps & De
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: ingress } = this.props;
|
const { object: ingress, logger } = this.props;
|
||||||
|
|
||||||
if (!ingress) {
|
if (!ingress) {
|
||||||
return null;
|
return null;
|
||||||
@ -136,25 +108,10 @@ class NonInjectedIngressDetails extends React.Component<IngressDetailsProps & De
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.Ingress);
|
|
||||||
const port = ingress.getServiceNamePort();
|
const port = ingress.getServiceNamePort();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="IngressDetails">
|
<div className="IngressDetails">
|
||||||
{!isMetricHidden && (
|
|
||||||
<ResourceMetrics
|
|
||||||
loader={this.loadMetrics}
|
|
||||||
tabs={[
|
|
||||||
"Network",
|
|
||||||
"Duration",
|
|
||||||
]}
|
|
||||||
object={ingress}
|
|
||||||
metrics={this.metrics}
|
|
||||||
>
|
|
||||||
<IngressCharts/>
|
|
||||||
</ResourceMetrics>
|
|
||||||
)}
|
|
||||||
<KubeObjectMeta object={ingress}/>
|
|
||||||
<DrawerItem name="Ports">
|
<DrawerItem name="Ports">
|
||||||
{ingress.getPorts()}
|
{ingress.getPorts()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
@ -181,6 +138,6 @@ class NonInjectedIngressDetails extends React.Component<IngressDetailsProps & De
|
|||||||
export const IngressDetails = withInjectables<Dependencies, IngressDetailsProps>(NonInjectedIngressDetails, {
|
export const IngressDetails = withInjectables<Dependencies, IngressDetailsProps>(NonInjectedIngressDetails, {
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
...props,
|
...props,
|
||||||
requestIngressMetrics: di.inject(requestIngressMetricsInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -32,16 +32,19 @@ interface Dependencies {
|
|||||||
filterByNamespace: FilterByNamespace;
|
filterByNamespace: FilterByNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
const NonInjectedIngresses = observer((props: Dependencies) => {
|
||||||
class NonInjectedIngresses extends React.Component<Dependencies> {
|
const {
|
||||||
render() {
|
ingressStore,
|
||||||
|
filterByNamespace,
|
||||||
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SiblingsInTabLayout>
|
<SiblingsInTabLayout>
|
||||||
<KubeObjectListLayout
|
<KubeObjectListLayout
|
||||||
isConfigurable
|
isConfigurable
|
||||||
tableId="network_ingresses"
|
tableId="network_ingresses"
|
||||||
className="Ingresses"
|
className="Ingresses"
|
||||||
store={this.props.ingressStore}
|
store={ ingressStore }
|
||||||
sortingCallbacks={ {
|
sortingCallbacks={ {
|
||||||
[columnId.name]: ingress => ingress.getName(),
|
[columnId.name]: ingress => ingress.getName(),
|
||||||
[columnId.namespace]: ingress => ingress.getNs(),
|
[columnId.namespace]: ingress => ingress.getNs(),
|
||||||
@ -66,7 +69,7 @@ class NonInjectedIngresses extends React.Component<Dependencies> {
|
|||||||
<a
|
<a
|
||||||
key="namespace"
|
key="namespace"
|
||||||
className="filterNamespace"
|
className="filterNamespace"
|
||||||
onClick={prevDefault(() => this.props.filterByNamespace(ingress.getNs()))}
|
onClick={prevDefault(() => filterByNamespace(ingress.getNs()))}
|
||||||
>
|
>
|
||||||
{ingress.getNs()}
|
{ingress.getNs()}
|
||||||
</a>,
|
</a>,
|
||||||
@ -100,17 +103,15 @@ class NonInjectedIngresses extends React.Component<Dependencies> {
|
|||||||
|
|
||||||
return lines * lineHeight + paddings;
|
return lines * lineHeight + paddings;
|
||||||
},
|
},
|
||||||
}}
|
} } />
|
||||||
/>
|
|
||||||
</SiblingsInTabLayout>
|
</SiblingsInTabLayout>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
export const Ingresses = withInjectables<Dependencies>(NonInjectedIngresses, {
|
export const Ingresses = withInjectables<Dependencies>(NonInjectedIngresses, {
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
...props,
|
...props,
|
||||||
filterByNamespace: di.inject(filterByNamespaceInjectable),
|
|
||||||
ingressStore: di.inject(ingressStoreInjectable),
|
ingressStore: di.inject(ingressStoreInjectable),
|
||||||
|
filterByNamespace: di.inject(filterByNamespaceInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { IAsyncComputed } from "@ogre-tools/injectable-react";
|
||||||
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import React from "react";
|
||||||
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
|
import type { Ingress } from "../../../common/k8s-api/endpoints";
|
||||||
|
import type { IngressMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-ingress-metrics.injectable";
|
||||||
|
import metricsDetailsComponentEnabledInjectable from "../../api/catalog/entity/metrics-details-component-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 { IngressCharts } from "./ingress-charts";
|
||||||
|
import ingressMetricsInjectable from "./metrics.injectable";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
metrics: IAsyncComputed<IngressMetricData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedIngressMetricsDetailsComponent = ({
|
||||||
|
object,
|
||||||
|
metrics,
|
||||||
|
}: KubeObjectDetailsProps<Ingress> & Dependencies) => (
|
||||||
|
<ResourceMetrics
|
||||||
|
tabs={[
|
||||||
|
"Network",
|
||||||
|
"Duration",
|
||||||
|
]}
|
||||||
|
object={object}
|
||||||
|
metrics={metrics}
|
||||||
|
>
|
||||||
|
<IngressCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
);
|
||||||
|
|
||||||
|
const IngressMetricsDetailsComponent = withInjectables<Dependencies, KubeObjectDetailsProps<Ingress>>(NonInjectedIngressMetricsDetailsComponent, {
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
metrics: di.inject(ingressMetricsInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const ingressMetricsDetailsComponentInjectable = getInjectable({
|
||||||
|
id: "ingress-metrics-details-component",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
Component: IngressMetricsDetailsComponent,
|
||||||
|
enabled: di.inject(metricsDetailsComponentEnabledInjectable, ClusterMetricsResourceType.Ingress),
|
||||||
|
orderNumber: -1,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ingressMetricsDetailsComponentInjectable;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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 { Ingress } from "../../../common/k8s-api/endpoints";
|
||||||
|
import requestIngressMetricsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-ingress-metrics.injectable";
|
||||||
|
|
||||||
|
const ingressMetricsInjectable = getInjectable({
|
||||||
|
id: "ingress-metrics",
|
||||||
|
instantiate: (di, ingress) => {
|
||||||
|
const requestIngressMetrics = di.inject(requestIngressMetricsInjectable);
|
||||||
|
|
||||||
|
return asyncComputed({
|
||||||
|
getValueFromObservedPromise: async () => {
|
||||||
|
now(60 * 1000); // Update every minute
|
||||||
|
|
||||||
|
return requestIngressMetrics(ingress.getName(), ingress.getNs());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, ingress: Ingress) => ingress.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ingressMetricsInjectable;
|
||||||
@ -13,7 +13,6 @@ import { Badge } from "../badge";
|
|||||||
import { SubTitle } from "../layout/sub-title";
|
import { SubTitle } from "../layout/sub-title";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
import type { LabelMatchExpression, LabelSelector } from "../../../common/k8s-api/kube-object";
|
import type { LabelMatchExpression, LabelSelector } from "../../../common/k8s-api/kube-object";
|
||||||
import { isEmpty } from "lodash";
|
import { isEmpty } from "lodash";
|
||||||
@ -170,8 +169,6 @@ export class NetworkPolicyDetails extends React.Component<NetworkPolicyDetailsPr
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.NetworkPolicyDetails}>
|
<div className={styles.NetworkPolicyDetails}>
|
||||||
<KubeObjectMeta object={policy}/>
|
|
||||||
|
|
||||||
<DrawerItem name="Pod Selector" labelsOnly={selector.length > 0}>
|
<DrawerItem name="Pod Selector" labelsOnly={selector.length > 0}>
|
||||||
{
|
{
|
||||||
selector.length > 0
|
selector.length > 0
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { DrawerItem, DrawerTitle } from "../drawer";
|
|||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { Service } from "../../../common/k8s-api/endpoints";
|
import { Service } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { ServicePortComponent } from "./service-port-component";
|
import { ServicePortComponent } from "./service-port-component";
|
||||||
import type { EndpointsStore } from "../+network-endpoints/store";
|
import type { EndpointsStore } from "../+network-endpoints/store";
|
||||||
import { ServiceDetailsEndpoint } from "./service-details-endpoint";
|
import { ServiceDetailsEndpoint } from "./service-details-endpoint";
|
||||||
@ -75,8 +74,6 @@ class NonInjectedServiceDetails extends React.Component<ServiceDetailsProps & De
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ServicesDetails">
|
<div className="ServicesDetails">
|
||||||
<KubeObjectMeta object={service}/>
|
|
||||||
|
|
||||||
<DrawerItem name="Selector" labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{service.getSelector().map(selector => <Badge key={selector} label={selector}/>)}
|
{service.getSelector().map(selector => <Badge key={selector} label={selector}/>)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|||||||
@ -11,26 +11,18 @@ import kebabCase from "lodash/kebabCase";
|
|||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { DrawerItem, DrawerItemLabels } from "../drawer";
|
import { DrawerItem, DrawerItemLabels } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { ResourceMetrics } from "../resource-metrics";
|
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { formatNodeTaint, Node } from "../../../common/k8s-api/endpoints";
|
import { formatNodeTaint, Node } from "../../../common/k8s-api/endpoints";
|
||||||
import { NodeCharts } from "./node-charts";
|
|
||||||
import { makeObservable, observable, reaction } from "mobx";
|
|
||||||
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
|
||||||
import { NodeDetailsResources } from "./details-resources";
|
import { NodeDetailsResources } from "./details-resources";
|
||||||
import { DrawerTitle } from "../drawer/drawer-title";
|
import { DrawerTitle } from "../drawer/drawer-title";
|
||||||
import logger from "../../../common/logger";
|
import type { Logger } from "../../../common/logger";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
||||||
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
||||||
import type { PodStore } from "../+workloads-pods/store";
|
import type { PodStore } from "../+workloads-pods/store";
|
||||||
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
||||||
import type { GetActiveClusterEntity } from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
import getActiveClusterEntityInjectable from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
|
||||||
import type { ClusterMetricData, RequestClusterMetricsByNodeNames } from "../../../common/k8s-api/endpoints/metrics.api/request-cluster-metrics-by-node-names.injectable";
|
|
||||||
import requestClusterMetricsByNodeNamesInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-cluster-metrics-by-node-names.injectable";
|
|
||||||
|
|
||||||
export interface NodeDetailsProps extends KubeObjectDetailsProps<Node> {
|
export interface NodeDetailsProps extends KubeObjectDetailsProps<Node> {
|
||||||
}
|
}
|
||||||
@ -38,39 +30,21 @@ export interface NodeDetailsProps extends KubeObjectDetailsProps<Node> {
|
|||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
subscribeStores: SubscribeStores;
|
subscribeStores: SubscribeStores;
|
||||||
podStore: PodStore;
|
podStore: PodStore;
|
||||||
getActiveClusterEntity: GetActiveClusterEntity;
|
logger: Logger;
|
||||||
requestClusterMetricsByNodeNames: RequestClusterMetricsByNodeNames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class NonInjectedNodeDetails extends React.Component<NodeDetailsProps & Dependencies> {
|
class NonInjectedNodeDetails extends React.Component<NodeDetailsProps & Dependencies> {
|
||||||
@observable metrics: ClusterMetricData | null = null;
|
|
||||||
|
|
||||||
constructor(props: NodeDetailsProps & Dependencies) {
|
|
||||||
super(props);
|
|
||||||
makeObservable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
disposeOnUnmount(this, [
|
disposeOnUnmount(this, [
|
||||||
reaction(() => this.props.object.getName(), () => {
|
|
||||||
this.metrics = null;
|
|
||||||
}),
|
|
||||||
|
|
||||||
this.props.subscribeStores([
|
this.props.subscribeStores([
|
||||||
this.props.podStore,
|
this.props.podStore,
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMetrics = async () => {
|
|
||||||
const { object: node, requestClusterMetricsByNodeNames } = this.props;
|
|
||||||
|
|
||||||
this.metrics = await requestClusterMetricsByNodeNames([node.getName()]);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: node, podStore, getActiveClusterEntity } = this.props;
|
const { object: node, podStore, logger } = this.props;
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return null;
|
return null;
|
||||||
@ -86,27 +60,9 @@ class NonInjectedNodeDetails extends React.Component<NodeDetailsProps & Dependen
|
|||||||
const conditions = node.getActiveConditions();
|
const conditions = node.getActiveConditions();
|
||||||
const taints = node.getTaints();
|
const taints = node.getTaints();
|
||||||
const childPods = podStore.getPodsByNode(node.getName());
|
const childPods = podStore.getPodsByNode(node.getName());
|
||||||
const { metrics } = this;
|
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.Node);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="NodeDetails">
|
<div className="NodeDetails">
|
||||||
{!isMetricHidden && podStore.isLoaded && (
|
|
||||||
<ResourceMetrics
|
|
||||||
loader={this.loadMetrics}
|
|
||||||
tabs={[
|
|
||||||
"CPU",
|
|
||||||
"Memory",
|
|
||||||
"Disk",
|
|
||||||
"Pods",
|
|
||||||
]}
|
|
||||||
object={node}
|
|
||||||
metrics={metrics}
|
|
||||||
>
|
|
||||||
<NodeCharts/>
|
|
||||||
</ResourceMetrics>
|
|
||||||
)}
|
|
||||||
<KubeObjectMeta object={node} hideFields={["labels", "annotations", "uid", "resourceVersion", "selfLink"]}/>
|
|
||||||
{addresses && (
|
{addresses && (
|
||||||
<DrawerItem name="Addresses">
|
<DrawerItem name="Addresses">
|
||||||
{
|
{
|
||||||
@ -197,8 +153,7 @@ export const NodeDetails = withInjectables<Dependencies, NodeDetailsProps>(NonIn
|
|||||||
...props,
|
...props,
|
||||||
subscribeStores: di.inject(subscribeStoresInjectable),
|
subscribeStores: di.inject(subscribeStoresInjectable),
|
||||||
podStore: di.inject(podStoreInjectable),
|
podStore: di.inject(podStoreInjectable),
|
||||||
getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
requestClusterMetricsByNodeNames: di.inject(requestClusterMetricsByNodeNamesInjectable),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { asLegacyGlobalForExtensionApi } from "../../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
|
|
||||||
import nodeStoreInjectable from "./store.injectable";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated use `di.inject(nodeStoreInjectable)` instead
|
|
||||||
*/
|
|
||||||
export const nodeStore = asLegacyGlobalForExtensionApi(nodeStoreInjectable);
|
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { IAsyncComputed } from "@ogre-tools/injectable-react";
|
||||||
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import React from "react";
|
||||||
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
|
import type { Node } from "../../../common/k8s-api/endpoints";
|
||||||
|
import type { ClusterMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-cluster-metrics-by-node-names.injectable";
|
||||||
|
import metricsDetailsComponentEnabledInjectable from "../../api/catalog/entity/metrics-details-component-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 nodeMetricsInjectable from "./metrics.injectable";
|
||||||
|
import { NodeCharts } from "./node-charts";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
metrics: IAsyncComputed<ClusterMetricData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedNodeMetricsDetailsComponent = ({
|
||||||
|
object,
|
||||||
|
metrics,
|
||||||
|
}: KubeObjectDetailsProps<Node> & Dependencies) => (
|
||||||
|
<ResourceMetrics
|
||||||
|
tabs={[
|
||||||
|
"CPU",
|
||||||
|
"Memory",
|
||||||
|
"Disk",
|
||||||
|
"Pods",
|
||||||
|
]}
|
||||||
|
object={object}
|
||||||
|
metrics={metrics}
|
||||||
|
>
|
||||||
|
<NodeCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
);
|
||||||
|
|
||||||
|
const NodeMetricsDetailsComponent = withInjectables<Dependencies, KubeObjectDetailsProps<Node>>(NonInjectedNodeMetricsDetailsComponent, {
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
metrics: di.inject(nodeMetricsInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const nodeMetricsDetailsComponentInjectable = getInjectable({
|
||||||
|
id: "node-metrics-details-component",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
Component: NodeMetricsDetailsComponent,
|
||||||
|
enabled: di.inject(metricsDetailsComponentEnabledInjectable, ClusterMetricsResourceType.Node),
|
||||||
|
orderNumber: -1,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default nodeMetricsDetailsComponentInjectable;
|
||||||
29
src/renderer/components/+nodes/metrics.injectable.ts
Normal file
29
src/renderer/components/+nodes/metrics.injectable.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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 { Node } from "../../../common/k8s-api/endpoints";
|
||||||
|
import requestClusterMetricsByNodeNamesInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-cluster-metrics-by-node-names.injectable";
|
||||||
|
|
||||||
|
const nodeMetricsInjectable = getInjectable({
|
||||||
|
id: "node-metrics",
|
||||||
|
instantiate: (di, node) => {
|
||||||
|
const requestClusterMetricsByNodeNames = di.inject(requestClusterMetricsByNodeNamesInjectable);
|
||||||
|
|
||||||
|
return asyncComputed({
|
||||||
|
getValueFromObservedPromise: () => {
|
||||||
|
now(60 * 1000);
|
||||||
|
|
||||||
|
return requestClusterMetricsByNodeNames([node.getName()]);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, node: Node) => node.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default nodeMetricsInjectable;
|
||||||
@ -12,7 +12,6 @@ import type { KubeObjectDetailsProps } from "../kube-object-details";
|
|||||||
import { PodSecurityPolicy } from "../../../common/k8s-api/endpoints";
|
import { PodSecurityPolicy } from "../../../common/k8s-api/endpoints";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
export interface PodSecurityPolicyDetailsProps extends KubeObjectDetailsProps<PodSecurityPolicy> {
|
export interface PodSecurityPolicyDetailsProps extends KubeObjectDetailsProps<PodSecurityPolicy> {
|
||||||
@ -74,8 +73,6 @@ export class PodSecurityPolicyDetails extends React.Component<PodSecurityPolicyD
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="PodSecurityPolicyDetails">
|
<div className="PodSecurityPolicyDetails">
|
||||||
<KubeObjectMeta object={psp}/>
|
|
||||||
|
|
||||||
{allowedCapabilities && (
|
{allowedCapabilities && (
|
||||||
<DrawerItem name="Allowed Capabilities">
|
<DrawerItem name="Allowed Capabilities">
|
||||||
{allowedCapabilities.join(", ")}
|
{allowedCapabilities.join(", ")}
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import { Badge } from "../badge";
|
|||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { StorageClass } from "../../../common/k8s-api/endpoints";
|
import { StorageClass } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import type { StorageClassStore } from "./store";
|
import type { StorageClassStore } from "./store";
|
||||||
import { VolumeDetailsList } from "../+storage-volumes/volume-details-list";
|
import { VolumeDetailsList } from "../+storage-volumes/volume-details-list";
|
||||||
import type { PersistentVolumeStore } from "../+storage-volumes/store";
|
import type { PersistentVolumeStore } from "../+storage-volumes/store";
|
||||||
@ -60,8 +59,6 @@ class NonInjectedStorageClassDetails extends React.Component<StorageClassDetails
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="StorageClassDetails">
|
<div className="StorageClassDetails">
|
||||||
<KubeObjectMeta object={storageClass}/>
|
|
||||||
|
|
||||||
{provisioner && (
|
{provisioner && (
|
||||||
<DrawerItem name="Provisioner" labelsOnly>
|
<DrawerItem name="Provisioner" labelsOnly>
|
||||||
<Badge label={provisioner}/>
|
<Badge label={provisioner}/>
|
||||||
|
|||||||
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { IAsyncComputed } from "@ogre-tools/injectable-react";
|
||||||
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import React from "react";
|
||||||
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
|
import type { PersistentVolumeClaim } from "../../../common/k8s-api/endpoints";
|
||||||
|
import type { PersistentVolumeClaimMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-persistent-volume-claim-metrics.injectable";
|
||||||
|
import metricsDetailsComponentEnabledInjectable from "../../api/catalog/entity/metrics-details-component-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 persistentVolumeClaimMetricsInjectable from "./metrics.injectable";
|
||||||
|
import { VolumeClaimDiskChart } from "./volume-claim-disk-chart";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
metrics: IAsyncComputed<PersistentVolumeClaimMetricData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedPersistentVolumeClaimMetricsDetailsComponent = ({
|
||||||
|
object,
|
||||||
|
metrics,
|
||||||
|
}: KubeObjectDetailsProps<PersistentVolumeClaim> & Dependencies) => (
|
||||||
|
<ResourceMetrics
|
||||||
|
tabs={[
|
||||||
|
"Disk",
|
||||||
|
]}
|
||||||
|
object={object}
|
||||||
|
metrics={metrics}
|
||||||
|
>
|
||||||
|
<VolumeClaimDiskChart />
|
||||||
|
</ResourceMetrics>
|
||||||
|
);
|
||||||
|
|
||||||
|
const PersistentVolumeClaimMetricsDetailsComponent = withInjectables<Dependencies, KubeObjectDetailsProps<PersistentVolumeClaim>>(NonInjectedPersistentVolumeClaimMetricsDetailsComponent, {
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
metrics: di.inject(persistentVolumeClaimMetricsInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const persistentVolumeClaimMetricsDetailsComponentInjectable = getInjectable({
|
||||||
|
id: "persistent-volume-claim-metrics-details-component",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
Component: PersistentVolumeClaimMetricsDetailsComponent,
|
||||||
|
enabled: di.inject(metricsDetailsComponentEnabledInjectable, ClusterMetricsResourceType.VolumeClaim),
|
||||||
|
orderNumber: -1,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default persistentVolumeClaimMetricsDetailsComponentInjectable;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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 { PersistentVolumeClaim } from "../../../common/k8s-api/endpoints";
|
||||||
|
import requestPersistentVolumeClaimMetricsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-persistent-volume-claim-metrics.injectable";
|
||||||
|
|
||||||
|
const persistentVolumeClaimMetricsInjectable = getInjectable({
|
||||||
|
id: "persistent-volume-claim-metrics",
|
||||||
|
instantiate: (di, persistentVolumeClaim) => {
|
||||||
|
const requestPersistentVolumeClaimMetrics = di.inject(requestPersistentVolumeClaimMetricsInjectable);
|
||||||
|
|
||||||
|
return asyncComputed({
|
||||||
|
getValueFromObservedPromise: () => {
|
||||||
|
now(60 * 1000); // update every minute
|
||||||
|
|
||||||
|
return requestPersistentVolumeClaimMetrics(persistentVolumeClaim);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, persistentVolumeClaim: PersistentVolumeClaim) => persistentVolumeClaim.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default persistentVolumeClaimMetricsInjectable;
|
||||||
@ -6,64 +6,37 @@
|
|||||||
import "./volume-claim-details.scss";
|
import "./volume-claim-details.scss";
|
||||||
|
|
||||||
import React, { Fragment } from "react";
|
import React, { Fragment } from "react";
|
||||||
import { makeObservable, observable, reaction } from "mobx";
|
import { observer } from "mobx-react";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { ResourceMetrics } from "../resource-metrics";
|
|
||||||
import { VolumeClaimDiskChart } from "./volume-claim-disk-chart";
|
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { PersistentVolumeClaim, storageClassApi } from "../../../common/k8s-api/endpoints";
|
import type { StorageClassApi } from "../../../common/k8s-api/endpoints";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
import { PersistentVolumeClaim } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import type { Logger } from "../../../common/logger";
|
||||||
import logger from "../../../common/logger";
|
|
||||||
import type { PersistentVolumeClaimMetricData, RequestPersistentVolumeClaimMetrics } from "../../../common/k8s-api/endpoints/metrics.api/request-persistent-volume-claim-metrics.injectable";
|
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import requestPersistentVolumeClaimMetricsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-persistent-volume-claim-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 type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
|
||||||
import type { PodStore } from "../+workloads-pods/store";
|
import type { PodStore } from "../+workloads-pods/store";
|
||||||
import getActiveClusterEntityInjectable from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
|
||||||
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
|
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
|
||||||
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
||||||
import { stopPropagation } from "../../../renderer/utils";
|
import { stopPropagation } from "../../../renderer/utils";
|
||||||
|
import storageClassApiInjectable from "../../../common/k8s-api/endpoints/storage-class.api.injectable";
|
||||||
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
|
|
||||||
export interface PersistentVolumeClaimDetailsProps extends KubeObjectDetailsProps<PersistentVolumeClaim> {
|
export interface PersistentVolumeClaimDetailsProps extends KubeObjectDetailsProps<PersistentVolumeClaim> {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
requestPersistentVolumeClaimMetrics: RequestPersistentVolumeClaimMetrics;
|
|
||||||
getActiveClusterEntity: GetActiveClusterEntity;
|
|
||||||
getDetailsUrl: GetDetailsUrl;
|
getDetailsUrl: GetDetailsUrl;
|
||||||
podStore: PodStore;
|
podStore: PodStore;
|
||||||
|
storageClassApi: StorageClassApi;
|
||||||
|
logger: Logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class NonInjectedPersistentVolumeClaimDetails extends React.Component<PersistentVolumeClaimDetailsProps & Dependencies> {
|
class NonInjectedPersistentVolumeClaimDetails extends React.Component<PersistentVolumeClaimDetailsProps & Dependencies> {
|
||||||
@observable metrics: PersistentVolumeClaimMetricData | null = null;
|
|
||||||
|
|
||||||
constructor(props: PersistentVolumeClaimDetailsProps & Dependencies) {
|
|
||||||
super(props);
|
|
||||||
makeObservable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
disposeOnUnmount(this, [
|
|
||||||
reaction(() => this.props.object, () => {
|
|
||||||
this.metrics = null;
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadMetrics = async () => {
|
|
||||||
const { object: volumeClaim, requestPersistentVolumeClaimMetrics } = this.props;
|
|
||||||
|
|
||||||
this.metrics = await requestPersistentVolumeClaimMetrics(volumeClaim);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: volumeClaim, getActiveClusterEntity, podStore, getDetailsUrl } = this.props;
|
const { object: volumeClaim, podStore, getDetailsUrl, storageClassApi, logger } = this.props;
|
||||||
|
|
||||||
if (!volumeClaim) {
|
if (!volumeClaim) {
|
||||||
return null;
|
return null;
|
||||||
@ -77,27 +50,13 @@ class NonInjectedPersistentVolumeClaimDetails extends React.Component<Persistent
|
|||||||
|
|
||||||
const { storageClassName, accessModes } = volumeClaim.spec;
|
const { storageClassName, accessModes } = volumeClaim.spec;
|
||||||
const pods = volumeClaim.getPods(podStore.items);
|
const pods = volumeClaim.getPods(podStore.items);
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.VolumeClaim);
|
|
||||||
|
|
||||||
const storageClassDetailsUrl = getDetailsUrl(storageClassApi.getUrl({
|
const storageClassDetailsUrl = getDetailsUrl(storageClassApi.formatUrlForNotListing({
|
||||||
name: storageClassName,
|
name: storageClassName,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="PersistentVolumeClaimDetails">
|
<div className="PersistentVolumeClaimDetails">
|
||||||
{!isMetricHidden && (
|
|
||||||
<ResourceMetrics
|
|
||||||
loader={this.loadMetrics}
|
|
||||||
tabs={[
|
|
||||||
"Disk",
|
|
||||||
]}
|
|
||||||
object={volumeClaim}
|
|
||||||
metrics={this.metrics}
|
|
||||||
>
|
|
||||||
<VolumeClaimDiskChart />
|
|
||||||
</ResourceMetrics>
|
|
||||||
)}
|
|
||||||
<KubeObjectMeta object={volumeClaim} />
|
|
||||||
<DrawerItem name="Access Modes">
|
<DrawerItem name="Access Modes">
|
||||||
{accessModes?.join(", ")}
|
{accessModes?.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
@ -147,9 +106,9 @@ class NonInjectedPersistentVolumeClaimDetails extends React.Component<Persistent
|
|||||||
export const PersistentVolumeClaimDetails = withInjectables<Dependencies, PersistentVolumeClaimDetailsProps>(NonInjectedPersistentVolumeClaimDetails, {
|
export const PersistentVolumeClaimDetails = withInjectables<Dependencies, PersistentVolumeClaimDetailsProps>(NonInjectedPersistentVolumeClaimDetails, {
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
...props,
|
...props,
|
||||||
requestPersistentVolumeClaimMetrics: di.inject(requestPersistentVolumeClaimMetricsInjectable),
|
|
||||||
getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable),
|
|
||||||
getDetailsUrl: di.inject(getDetailsUrlInjectable),
|
getDetailsUrl: di.inject(getDetailsUrlInjectable),
|
||||||
podStore: di.inject(podStoreInjectable),
|
podStore: di.inject(podStoreInjectable),
|
||||||
|
storageClassApi: di.inject(storageClassApiInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import { DrawerItem, DrawerTitle } from "../drawer";
|
|||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { PersistentVolume, persistentVolumeClaimApi, storageClassApi } from "../../../common/k8s-api/endpoints";
|
import { PersistentVolume, persistentVolumeClaimApi, storageClassApi } from "../../../common/k8s-api/endpoints";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
import { stopPropagation } from "../../../renderer/utils";
|
import { stopPropagation } from "../../../renderer/utils";
|
||||||
@ -44,7 +43,6 @@ export class PersistentVolumeDetails extends React.Component<PersistentVolumeDet
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="PersistentVolumeDetails">
|
<div className="PersistentVolumeDetails">
|
||||||
<KubeObjectMeta object={volume} />
|
|
||||||
<DrawerItem name="Capacity">
|
<DrawerItem name="Capacity">
|
||||||
{capacity?.storage}
|
{capacity?.storage}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import { autoBind, ObservableHashSet, prevDefault } from "../../../utils";
|
|||||||
import { AddRemoveButtons } from "../../add-remove-buttons";
|
import { AddRemoveButtons } from "../../add-remove-buttons";
|
||||||
import { DrawerTitle } from "../../drawer";
|
import { DrawerTitle } from "../../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../../kube-object-details";
|
||||||
import { KubeObjectMeta } from "../../kube-object-meta";
|
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../../table";
|
import { Table, TableCell, TableHead, TableRow } from "../../table";
|
||||||
import { ClusterRoleBindingDialog } from "./dialog";
|
import { ClusterRoleBindingDialog } from "./dialog";
|
||||||
import { clusterRoleBindingStore } from "./legacy-store";
|
import { clusterRoleBindingStore } from "./legacy-store";
|
||||||
@ -76,8 +75,6 @@ class NonInjectedClusterRoleBindingDetails extends React.Component<ClusterRoleBi
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ClusterRoleBindingDetails">
|
<div className="ClusterRoleBindingDetails">
|
||||||
<KubeObjectMeta object={clusterRoleBinding} />
|
|
||||||
|
|
||||||
<DrawerTitle>Reference</DrawerTitle>
|
<DrawerTitle>Reference</DrawerTitle>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import React from "react";
|
|||||||
|
|
||||||
import { DrawerTitle } from "../../drawer";
|
import { DrawerTitle } from "../../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../../kube-object-details";
|
||||||
import { KubeObjectMeta } from "../../kube-object-meta";
|
|
||||||
import type { ClusterRole } from "../../../../common/k8s-api/endpoints";
|
import type { ClusterRole } from "../../../../common/k8s-api/endpoints";
|
||||||
|
|
||||||
export interface ClusterRoleDetailsProps extends KubeObjectDetailsProps<ClusterRole> {
|
export interface ClusterRoleDetailsProps extends KubeObjectDetailsProps<ClusterRole> {
|
||||||
@ -26,8 +25,6 @@ export class ClusterRoleDetails extends React.Component<ClusterRoleDetailsProps>
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ClusterRoleDetails">
|
<div className="ClusterRoleDetails">
|
||||||
<KubeObjectMeta object={clusterRole}/>
|
|
||||||
|
|
||||||
<DrawerTitle>Rules</DrawerTitle>
|
<DrawerTitle>Rules</DrawerTitle>
|
||||||
{rules.map(({ resourceNames, apiGroups, resources, verbs }, index) => {
|
{rules.map(({ resourceNames, apiGroups, resources, verbs }, index) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import { prevDefault } from "../../../utils";
|
|||||||
import { AddRemoveButtons } from "../../add-remove-buttons";
|
import { AddRemoveButtons } from "../../add-remove-buttons";
|
||||||
import { DrawerTitle } from "../../drawer";
|
import { DrawerTitle } from "../../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../../kube-object-details";
|
||||||
import { KubeObjectMeta } from "../../kube-object-meta";
|
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../../table";
|
import { Table, TableCell, TableHead, TableRow } from "../../table";
|
||||||
import { RoleBindingDialog } from "./dialog";
|
import { RoleBindingDialog } from "./dialog";
|
||||||
import { roleBindingStore } from "./legacy-store";
|
import { roleBindingStore } from "./legacy-store";
|
||||||
@ -71,8 +70,6 @@ class NonInjectedRoleBindingDetails extends React.Component<RoleBindingDetailsPr
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="RoleBindingDetails">
|
<div className="RoleBindingDetails">
|
||||||
<KubeObjectMeta object={roleBinding} />
|
|
||||||
|
|
||||||
<DrawerTitle>Reference</DrawerTitle>
|
<DrawerTitle>Reference</DrawerTitle>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import React from "react";
|
|||||||
import type { Role } from "../../../../common/k8s-api/endpoints";
|
import type { Role } from "../../../../common/k8s-api/endpoints";
|
||||||
import { DrawerTitle } from "../../drawer";
|
import { DrawerTitle } from "../../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../../kube-object-details";
|
||||||
import { KubeObjectMeta } from "../../kube-object-meta";
|
|
||||||
|
|
||||||
export interface RoleDetailsProps extends KubeObjectDetailsProps<Role> {
|
export interface RoleDetailsProps extends KubeObjectDetailsProps<Role> {
|
||||||
}
|
}
|
||||||
@ -26,7 +25,6 @@ export class RoleDetails extends React.Component<RoleDetailsProps> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="RoleDetails">
|
<div className="RoleDetails">
|
||||||
<KubeObjectMeta object={role}/>
|
|
||||||
<DrawerTitle>Rules</DrawerTitle>
|
<DrawerTitle>Rules</DrawerTitle>
|
||||||
{rules.map(({ resourceNames, apiGroups, resources, verbs }, index) => {
|
{rules.map(({ resourceNames, apiGroups, resources, verbs }, index) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import type { Secret, ServiceAccount } from "../../../../common/k8s-api/endpoint
|
|||||||
import { DrawerItem, DrawerTitle } from "../../drawer";
|
import { DrawerItem, DrawerTitle } from "../../drawer";
|
||||||
import { Icon } from "../../icon";
|
import { Icon } from "../../icon";
|
||||||
import type { KubeObjectDetailsProps } from "../../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../../kube-object-details";
|
||||||
import { KubeObjectMeta } from "../../kube-object-meta";
|
|
||||||
import { Spinner } from "../../spinner";
|
import { Spinner } from "../../spinner";
|
||||||
import { ServiceAccountsSecret } from "./secret";
|
import { ServiceAccountsSecret } from "./secret";
|
||||||
import type { SecretStore } from "../../+config-secrets/store";
|
import type { SecretStore } from "../../+config-secrets/store";
|
||||||
@ -137,8 +136,6 @@ class NonInjectedServiceAccountsDetails extends React.Component<ServiceAccountsD
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ServiceAccountsDetails">
|
<div className="ServiceAccountsDetails">
|
||||||
<KubeObjectMeta object={serviceAccount}/>
|
|
||||||
|
|
||||||
{tokens.length > 0 && (
|
{tokens.length > 0 && (
|
||||||
<DrawerItem name="Tokens" className="links">
|
<DrawerItem name="Tokens" className="links">
|
||||||
{this.renderSecretLinks(tokens)}
|
{this.renderSecretLinks(tokens)}
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import type { KubeObjectDetailsProps } from "../kube-object-details";
|
|||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
import type { Job } from "../../../common/k8s-api/endpoints";
|
import type { Job } from "../../../common/k8s-api/endpoints";
|
||||||
import { CronJob } from "../../../common/k8s-api/endpoints";
|
import { CronJob } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
||||||
@ -61,7 +60,6 @@ class NonInjectedCronJobDetails extends React.Component<CronJobDetailsProps & De
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="CronJobDetails">
|
<div className="CronJobDetails">
|
||||||
<KubeObjectMeta object={cronJob}/>
|
|
||||||
<DrawerItem name="Schedule">
|
<DrawerItem name="Schedule">
|
||||||
{
|
{
|
||||||
cronJob.isNeverRun()
|
cronJob.isNeverRun()
|
||||||
|
|||||||
@ -13,11 +13,9 @@ import moment from "moment";
|
|||||||
import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout";
|
import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout";
|
||||||
import { KubeObjectAge } from "../kube-object/age";
|
import { KubeObjectAge } from "../kube-object/age";
|
||||||
import type { CronJobStore } from "./store";
|
import type { CronJobStore } from "./store";
|
||||||
import type { JobStore } from "../+workloads-jobs/store";
|
|
||||||
import type { EventStore } from "../+events/store";
|
import type { EventStore } from "../+events/store";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import cronJobStoreInjectable from "./store.injectable";
|
import cronJobStoreInjectable from "./store.injectable";
|
||||||
import jobStoreInjectable from "../+workloads-jobs/store.injectable";
|
|
||||||
import eventStoreInjectable from "../+events/store.injectable";
|
import eventStoreInjectable from "../+events/store.injectable";
|
||||||
import { prevDefault } from "../../utils";
|
import { prevDefault } from "../../utils";
|
||||||
import type { FilterByNamespace } from "../+namespaces/namespace-select-filter-model/filter-by-namespace.injectable";
|
import type { FilterByNamespace } from "../+namespaces/namespace-select-filter-model/filter-by-namespace.injectable";
|
||||||
@ -35,20 +33,16 @@ enum columnId {
|
|||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
cronJobStore: CronJobStore;
|
cronJobStore: CronJobStore;
|
||||||
jobStore: JobStore;
|
|
||||||
eventStore: EventStore;
|
eventStore: EventStore;
|
||||||
filterByNamespace: FilterByNamespace;
|
filterByNamespace: FilterByNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
const NonInjectedCronJobs = observer((props: Dependencies) => {
|
||||||
class NonInjectedCronJobs extends React.Component<Dependencies>{
|
|
||||||
render() {
|
|
||||||
const {
|
const {
|
||||||
cronJobStore,
|
cronJobStore,
|
||||||
eventStore,
|
eventStore,
|
||||||
jobStore,
|
|
||||||
filterByNamespace,
|
filterByNamespace,
|
||||||
} = this.props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SiblingsInTabLayout>
|
<SiblingsInTabLayout>
|
||||||
@ -57,7 +51,7 @@ class NonInjectedCronJobs extends React.Component<Dependencies>{
|
|||||||
tableId="workload_cronjobs"
|
tableId="workload_cronjobs"
|
||||||
className="CronJobs"
|
className="CronJobs"
|
||||||
store={cronJobStore}
|
store={cronJobStore}
|
||||||
dependentStores={[jobStore, eventStore]}
|
dependentStores={[eventStore]}
|
||||||
sortingCallbacks={{
|
sortingCallbacks={{
|
||||||
[columnId.name]: cronJob => cronJob.getName(),
|
[columnId.name]: cronJob => cronJob.getName(),
|
||||||
[columnId.namespace]: cronJob => cronJob.getNs(),
|
[columnId.namespace]: cronJob => cronJob.getNs(),
|
||||||
@ -104,15 +98,13 @@ class NonInjectedCronJobs extends React.Component<Dependencies>{
|
|||||||
/>
|
/>
|
||||||
</SiblingsInTabLayout>
|
</SiblingsInTabLayout>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
export const CronJobs = withInjectables<Dependencies>(NonInjectedCronJobs, {
|
export const CronJobs = withInjectables<Dependencies>(NonInjectedCronJobs, {
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
...props,
|
...props,
|
||||||
cronJobStore: di.inject(cronJobStoreInjectable),
|
cronJobStore: di.inject(cronJobStoreInjectable),
|
||||||
eventStore: di.inject(eventStoreInjectable),
|
eventStore: di.inject(eventStoreInjectable),
|
||||||
jobStore: di.inject(jobStoreInjectable),
|
|
||||||
filterByNamespace: di.inject(filterByNamespaceInjectable),
|
filterByNamespace: di.inject(filterByNamespaceInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -16,22 +16,16 @@ import type { DaemonSetStore } from "./store";
|
|||||||
import type { PodStore } from "../+workloads-pods/store";
|
import type { PodStore } from "../+workloads-pods/store";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { DaemonSet } from "../../../common/k8s-api/endpoints";
|
import { DaemonSet } from "../../../common/k8s-api/endpoints";
|
||||||
import { ResourceMetrics, ResourceMetricsText } from "../resource-metrics";
|
|
||||||
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
|
||||||
import { makeObservable, observable, reaction } from "mobx";
|
|
||||||
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import type { Logger } from "../../../common/logger";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
|
||||||
import logger from "../../../common/logger";
|
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
||||||
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
||||||
import daemonSetStoreInjectable from "./store.injectable";
|
import daemonSetStoreInjectable from "./store.injectable";
|
||||||
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
||||||
import type { GetActiveClusterEntity } from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
|
||||||
import getActiveClusterEntityInjectable from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
import getActiveClusterEntityInjectable from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
||||||
import type { DaemonSetPodMetricData, RequestPodMetricsForDaemonSets } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-daemon-sets.injectable";
|
|
||||||
import requestPodMetricsForDaemonSetsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-daemon-sets.injectable";
|
import requestPodMetricsForDaemonSetsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-daemon-sets.injectable";
|
||||||
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
|
|
||||||
export interface DaemonSetDetailsProps extends KubeObjectDetailsProps<DaemonSet> {
|
export interface DaemonSetDetailsProps extends KubeObjectDetailsProps<DaemonSet> {
|
||||||
}
|
}
|
||||||
@ -40,38 +34,21 @@ interface Dependencies {
|
|||||||
subscribeStores: SubscribeStores;
|
subscribeStores: SubscribeStores;
|
||||||
daemonSetStore: DaemonSetStore;
|
daemonSetStore: DaemonSetStore;
|
||||||
podStore: PodStore;
|
podStore: PodStore;
|
||||||
getActiveClusterEntity: GetActiveClusterEntity;
|
logger: Logger;
|
||||||
requestPodMetricsForDaemonSets: RequestPodMetricsForDaemonSets;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class NonInjectedDaemonSetDetails extends React.Component<DaemonSetDetailsProps & Dependencies> {
|
class NonInjectedDaemonSetDetails extends React.Component<DaemonSetDetailsProps & Dependencies> {
|
||||||
@observable metrics: DaemonSetPodMetricData | null = null;
|
|
||||||
|
|
||||||
constructor(props: DaemonSetDetailsProps & Dependencies) {
|
|
||||||
super(props);
|
|
||||||
makeObservable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
disposeOnUnmount(this, [
|
disposeOnUnmount(this, [
|
||||||
reaction(() => this.props.object, () => {
|
|
||||||
this.metrics = null;
|
|
||||||
}),
|
|
||||||
this.props.subscribeStores([
|
this.props.subscribeStores([
|
||||||
this.props.podStore,
|
this.props.podStore,
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMetrics = async () => {
|
|
||||||
const { object: daemonSet, requestPodMetricsForDaemonSets } = this.props;
|
|
||||||
|
|
||||||
this.metrics = await requestPodMetricsForDaemonSets([daemonSet], daemonSet.getNs());
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: daemonSet, daemonSetStore, podStore, getActiveClusterEntity } = this.props;
|
const { object: daemonSet, daemonSetStore, logger } = this.props;
|
||||||
|
|
||||||
if (!daemonSet) {
|
if (!daemonSet) {
|
||||||
return null;
|
return null;
|
||||||
@ -88,21 +65,9 @@ class NonInjectedDaemonSetDetails extends React.Component<DaemonSetDetailsProps
|
|||||||
const images = daemonSet.getImages();
|
const images = daemonSet.getImages();
|
||||||
const nodeSelector = daemonSet.getNodeSelectors();
|
const nodeSelector = daemonSet.getNodeSelectors();
|
||||||
const childPods = daemonSetStore.getChildPods(daemonSet);
|
const childPods = daemonSetStore.getChildPods(daemonSet);
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.DaemonSet);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="DaemonSetDetails">
|
<div className="DaemonSetDetails">
|
||||||
{!isMetricHidden && podStore.isLoaded && (
|
|
||||||
<ResourceMetrics
|
|
||||||
loader={this.loadMetrics}
|
|
||||||
tabs={podMetricTabs}
|
|
||||||
object={daemonSet}
|
|
||||||
metrics={this.metrics}
|
|
||||||
>
|
|
||||||
<PodCharts/>
|
|
||||||
</ResourceMetrics>
|
|
||||||
)}
|
|
||||||
<KubeObjectMeta object={daemonSet}/>
|
|
||||||
{selectors.length > 0 && (
|
{selectors.length > 0 && (
|
||||||
<DrawerItem name="Selector" labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
@ -132,7 +97,6 @@ class NonInjectedDaemonSetDetails extends React.Component<DaemonSetDetailsProps
|
|||||||
<DrawerItem name="Pod Status" className="pod-status">
|
<DrawerItem name="Pod Status" className="pod-status">
|
||||||
<PodDetailsStatuses pods={childPods}/>
|
<PodDetailsStatuses pods={childPods}/>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<ResourceMetricsText metrics={this.metrics}/>
|
|
||||||
<PodDetailsList pods={childPods} owner={daemonSet}/>
|
<PodDetailsList pods={childPods} owner={daemonSet}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -147,5 +111,6 @@ export const DaemonSetDetails = withInjectables<Dependencies, DaemonSetDetailsPr
|
|||||||
podStore: di.inject(podStoreInjectable),
|
podStore: di.inject(podStoreInjectable),
|
||||||
getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable),
|
getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable),
|
||||||
requestPodMetricsForDaemonSets: di.inject(requestPodMetricsForDaemonSetsInjectable),
|
requestPodMetricsForDaemonSets: di.inject(requestPodMetricsForDaemonSetsInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
|||||||
import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout";
|
import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout";
|
||||||
import { KubeObjectAge } from "../kube-object/age";
|
import { KubeObjectAge } from "../kube-object/age";
|
||||||
import type { DaemonSetStore } from "./store";
|
import type { DaemonSetStore } from "./store";
|
||||||
import type { PodStore } from "../+workloads-pods/store";
|
|
||||||
import type { EventStore } from "../+events/store";
|
import type { EventStore } from "../+events/store";
|
||||||
import { prevDefault } from "../../utils";
|
import { prevDefault } from "../../utils";
|
||||||
import type { FilterByNamespace } from "../+namespaces/namespace-select-filter-model/filter-by-namespace.injectable";
|
import type { FilterByNamespace } from "../+namespaces/namespace-select-filter-model/filter-by-namespace.injectable";
|
||||||
@ -22,7 +21,6 @@ import { withInjectables } from "@ogre-tools/injectable-react";
|
|||||||
import daemonSetStoreInjectable from "./store.injectable";
|
import daemonSetStoreInjectable from "./store.injectable";
|
||||||
import eventStoreInjectable from "../+events/store.injectable";
|
import eventStoreInjectable from "../+events/store.injectable";
|
||||||
import filterByNamespaceInjectable from "../+namespaces/namespace-select-filter-model/filter-by-namespace.injectable";
|
import filterByNamespaceInjectable from "../+namespaces/namespace-select-filter-model/filter-by-namespace.injectable";
|
||||||
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
|
||||||
|
|
||||||
enum columnId {
|
enum columnId {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -34,24 +32,18 @@ enum columnId {
|
|||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
daemonSetStore: DaemonSetStore;
|
daemonSetStore: DaemonSetStore;
|
||||||
podStore: PodStore;
|
|
||||||
eventStore: EventStore;
|
eventStore: EventStore;
|
||||||
filterByNamespace: FilterByNamespace;
|
filterByNamespace: FilterByNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
const NonInjectedDaemonSets = observer((props: Dependencies) => {
|
||||||
class NonInjectedDaemonSets extends React.Component<Dependencies> {
|
|
||||||
getPodsLength(daemonSet: DaemonSet) {
|
|
||||||
return this.props.daemonSetStore.getChildPods(daemonSet).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
const {
|
||||||
daemonSetStore,
|
daemonSetStore,
|
||||||
eventStore,
|
eventStore,
|
||||||
filterByNamespace,
|
filterByNamespace,
|
||||||
podStore,
|
} = props;
|
||||||
} = this.props;
|
|
||||||
|
const getPodsLength = (daemonSet: DaemonSet) => daemonSetStore.getChildPods(daemonSet).length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SiblingsInTabLayout>
|
<SiblingsInTabLayout>
|
||||||
@ -60,11 +52,11 @@ class NonInjectedDaemonSets extends React.Component<Dependencies> {
|
|||||||
tableId="workload_daemonsets"
|
tableId="workload_daemonsets"
|
||||||
className="DaemonSets"
|
className="DaemonSets"
|
||||||
store={daemonSetStore}
|
store={daemonSetStore}
|
||||||
dependentStores={[podStore, eventStore]} // status icon component uses event store
|
dependentStores={[eventStore]} // status icon component uses event store
|
||||||
sortingCallbacks={{
|
sortingCallbacks={{
|
||||||
[columnId.name]: daemonSet => daemonSet.getName(),
|
[columnId.name]: daemonSet => daemonSet.getName(),
|
||||||
[columnId.namespace]: daemonSet => daemonSet.getNs(),
|
[columnId.namespace]: daemonSet => daemonSet.getNs(),
|
||||||
[columnId.pods]: daemonSet => this.getPodsLength(daemonSet),
|
[columnId.pods]: daemonSet => getPodsLength(daemonSet),
|
||||||
[columnId.age]: daemonSet => -daemonSet.getCreationTimestamp(),
|
[columnId.age]: daemonSet => -daemonSet.getCreationTimestamp(),
|
||||||
}}
|
}}
|
||||||
searchFilters={[
|
searchFilters={[
|
||||||
@ -89,7 +81,7 @@ class NonInjectedDaemonSets extends React.Component<Dependencies> {
|
|||||||
>
|
>
|
||||||
{daemonSet.getNs()}
|
{daemonSet.getNs()}
|
||||||
</a>,
|
</a>,
|
||||||
this.getPodsLength(daemonSet),
|
getPodsLength(daemonSet),
|
||||||
<KubeObjectStatusIcon key="icon" object={daemonSet} />,
|
<KubeObjectStatusIcon key="icon" object={daemonSet} />,
|
||||||
daemonSet.getNodeSelectors().map(selector => (
|
daemonSet.getNodeSelectors().map(selector => (
|
||||||
<Badge
|
<Badge
|
||||||
@ -103,8 +95,7 @@ class NonInjectedDaemonSets extends React.Component<Dependencies> {
|
|||||||
/>
|
/>
|
||||||
</SiblingsInTabLayout>
|
</SiblingsInTabLayout>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
export const DaemonSets = withInjectables<Dependencies>(NonInjectedDaemonSets, {
|
export const DaemonSets = withInjectables<Dependencies>(NonInjectedDaemonSets, {
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
@ -112,6 +103,5 @@ export const DaemonSets = withInjectables<Dependencies>(NonInjectedDaemonSets, {
|
|||||||
daemonSetStore: di.inject(daemonSetStoreInjectable),
|
daemonSetStore: di.inject(daemonSetStoreInjectable),
|
||||||
eventStore: di.inject(eventStoreInjectable),
|
eventStore: di.inject(eventStoreInjectable),
|
||||||
filterByNamespace: di.inject(filterByNamespaceInjectable),
|
filterByNamespace: di.inject(filterByNamespaceInjectable),
|
||||||
podStore: di.inject(podStoreInjectable),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { IAsyncComputed } from "@ogre-tools/injectable-react";
|
||||||
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import React from "react";
|
||||||
|
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
||||||
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
|
import type { DaemonSet } from "../../../common/k8s-api/endpoints";
|
||||||
|
import type { DaemonSetPodMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-daemon-sets.injectable";
|
||||||
|
import metricsDetailsComponentEnabledInjectable from "../../api/catalog/entity/metrics-details-component-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 daemonSetMetricsInjectable from "./metrics.injectable";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
metrics: IAsyncComputed<DaemonSetPodMetricData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedDaemonSetMetricsDetailsComponent = ({
|
||||||
|
object,
|
||||||
|
metrics,
|
||||||
|
}: KubeObjectDetailsProps<DaemonSet> & Dependencies) => (
|
||||||
|
<ResourceMetrics
|
||||||
|
tabs={podMetricTabs}
|
||||||
|
object={object}
|
||||||
|
metrics={metrics}
|
||||||
|
>
|
||||||
|
<PodCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
);
|
||||||
|
|
||||||
|
const DaemonSetMetricsDetailsComponent = withInjectables<Dependencies, KubeObjectDetailsProps<DaemonSet>>(NonInjectedDaemonSetMetricsDetailsComponent, {
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
metrics: di.inject(daemonSetMetricsInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const daemonSetMetricsDetailsComponentInjectable = getInjectable({
|
||||||
|
id: "daemon-set-metrics-details-component",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
Component: DaemonSetMetricsDetailsComponent,
|
||||||
|
enabled: di.inject(metricsDetailsComponentEnabledInjectable, ClusterMetricsResourceType.DaemonSet),
|
||||||
|
orderNumber: -1,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default daemonSetMetricsDetailsComponentInjectable;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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 { DaemonSet } from "../../../common/k8s-api/endpoints";
|
||||||
|
import requestPodMetricsForDaemonSetsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-daemon-sets.injectable";
|
||||||
|
|
||||||
|
const daemonSetMetricsInjectable = getInjectable({
|
||||||
|
id: "daemon-set-metrics",
|
||||||
|
instantiate: (di, daemonSet) => {
|
||||||
|
const requestPodMetricsForDaemonSets = di.inject(requestPodMetricsForDaemonSetsInjectable);
|
||||||
|
|
||||||
|
return asyncComputed({
|
||||||
|
getValueFromObservedPromise: () => {
|
||||||
|
now(60 * 1000); // update every minute
|
||||||
|
|
||||||
|
return requestPodMetricsForDaemonSets([daemonSet], daemonSet.getNs());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, daemonSet: DaemonSet) => daemonSet.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default daemonSetMetricsInjectable;
|
||||||
@ -14,70 +14,40 @@ import { Deployment } from "../../../common/k8s-api/endpoints";
|
|||||||
import { PodDetailsTolerations } from "../+workloads-pods/pod-details-tolerations";
|
import { PodDetailsTolerations } from "../+workloads-pods/pod-details-tolerations";
|
||||||
import { PodDetailsAffinities } from "../+workloads-pods/pod-details-affinities";
|
import { PodDetailsAffinities } from "../+workloads-pods/pod-details-affinities";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { ResourceMetrics, ResourceMetricsText } from "../resource-metrics";
|
|
||||||
import type { DeploymentStore } from "./store";
|
import type { DeploymentStore } from "./store";
|
||||||
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
|
||||||
import { makeObservable, observable, reaction } from "mobx";
|
|
||||||
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import type { ReplicaSetStore } from "../+workloads-replicasets/store";
|
import type { ReplicaSetStore } from "../+workloads-replicasets/store";
|
||||||
import { DeploymentReplicaSets } from "./deployment-replicasets";
|
import { DeploymentReplicaSets } from "./deployment-replicasets";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
import type { Logger } from "../../../common/logger";
|
||||||
import logger from "../../../common/logger";
|
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
||||||
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
||||||
import type { PodStore } from "../+workloads-pods/store";
|
|
||||||
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
|
||||||
import replicaSetStoreInjectable from "../+workloads-replicasets/store.injectable";
|
import replicaSetStoreInjectable from "../+workloads-replicasets/store.injectable";
|
||||||
import deploymentStoreInjectable from "./store.injectable";
|
import deploymentStoreInjectable from "./store.injectable";
|
||||||
import type { GetActiveClusterEntity } from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
import getActiveClusterEntityInjectable from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
|
||||||
import type { DeploymentPodMetricData, RequestPodMetricsForDeployments } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-deployments.injectable";
|
|
||||||
import requestPodMetricsForDeploymentsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-deployments.injectable";
|
|
||||||
|
|
||||||
export interface DeploymentDetailsProps extends KubeObjectDetailsProps<Deployment> {
|
export interface DeploymentDetailsProps extends KubeObjectDetailsProps<Deployment> {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
subscribeStores: SubscribeStores;
|
subscribeStores: SubscribeStores;
|
||||||
podStore: PodStore;
|
|
||||||
replicaSetStore: ReplicaSetStore;
|
replicaSetStore: ReplicaSetStore;
|
||||||
deploymentStore: DeploymentStore;
|
deploymentStore: DeploymentStore;
|
||||||
getActiveClusterEntity: GetActiveClusterEntity;
|
logger: Logger;
|
||||||
requestPodMetricsForDeployments: RequestPodMetricsForDeployments;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class NonInjectedDeploymentDetails extends React.Component<DeploymentDetailsProps & Dependencies> {
|
class NonInjectedDeploymentDetails extends React.Component<DeploymentDetailsProps & Dependencies> {
|
||||||
@observable metrics: DeploymentPodMetricData | null = null;
|
|
||||||
|
|
||||||
constructor(props: DeploymentDetailsProps & Dependencies) {
|
|
||||||
super(props);
|
|
||||||
makeObservable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
disposeOnUnmount(this, [
|
disposeOnUnmount(this, [
|
||||||
reaction(() => this.props.object, () => {
|
|
||||||
this.metrics = null;
|
|
||||||
}),
|
|
||||||
|
|
||||||
this.props.subscribeStores([
|
this.props.subscribeStores([
|
||||||
this.props.podStore,
|
|
||||||
this.props.replicaSetStore,
|
this.props.replicaSetStore,
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMetrics = async () => {
|
|
||||||
const { object: deployment, requestPodMetricsForDeployments } = this.props;
|
|
||||||
|
|
||||||
this.metrics = await requestPodMetricsForDeployments([deployment], deployment.getNs());
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: deployment, podStore, replicaSetStore, deploymentStore, getActiveClusterEntity } = this.props;
|
const { object: deployment, replicaSetStore, deploymentStore, logger } = this.props;
|
||||||
|
|
||||||
if (!deployment) {
|
if (!deployment) {
|
||||||
return null;
|
return null;
|
||||||
@ -94,21 +64,9 @@ class NonInjectedDeploymentDetails extends React.Component<DeploymentDetailsProp
|
|||||||
const selectors = deployment.getSelectors();
|
const selectors = deployment.getSelectors();
|
||||||
const childPods = deploymentStore.getChildPods(deployment);
|
const childPods = deploymentStore.getChildPods(deployment);
|
||||||
const replicaSets = replicaSetStore.getReplicaSetsByOwner(deployment);
|
const replicaSets = replicaSetStore.getReplicaSetsByOwner(deployment);
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.Deployment);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="DeploymentDetails">
|
<div className="DeploymentDetails">
|
||||||
{!isMetricHidden && podStore.isLoaded && (
|
|
||||||
<ResourceMetrics
|
|
||||||
loader={this.loadMetrics}
|
|
||||||
tabs={podMetricTabs}
|
|
||||||
object={deployment}
|
|
||||||
metrics={this.metrics}
|
|
||||||
>
|
|
||||||
<PodCharts/>
|
|
||||||
</ResourceMetrics>
|
|
||||||
)}
|
|
||||||
<KubeObjectMeta object={deployment}/>
|
|
||||||
<DrawerItem name="Replicas">
|
<DrawerItem name="Replicas">
|
||||||
{`${spec.replicas} desired, ${status?.updatedReplicas ?? 0} updated, `}
|
{`${spec.replicas} desired, ${status?.updatedReplicas ?? 0} updated, `}
|
||||||
{`${status?.replicas ?? 0} total, ${status?.availableReplicas ?? 0} available, `}
|
{`${status?.replicas ?? 0} total, ${status?.availableReplicas ?? 0} available, `}
|
||||||
@ -159,7 +117,6 @@ class NonInjectedDeploymentDetails extends React.Component<DeploymentDetailsProp
|
|||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<PodDetailsTolerations workload={deployment}/>
|
<PodDetailsTolerations workload={deployment}/>
|
||||||
<PodDetailsAffinities workload={deployment}/>
|
<PodDetailsAffinities workload={deployment}/>
|
||||||
<ResourceMetricsText metrics={this.metrics}/>
|
|
||||||
<DeploymentReplicaSets replicaSets={replicaSets}/>
|
<DeploymentReplicaSets replicaSets={replicaSets}/>
|
||||||
<PodDetailsList pods={childPods} owner={deployment}/>
|
<PodDetailsList pods={childPods} owner={deployment}/>
|
||||||
</div>
|
</div>
|
||||||
@ -171,11 +128,9 @@ export const DeploymentDetails = withInjectables<Dependencies, DeploymentDetails
|
|||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
...props,
|
...props,
|
||||||
subscribeStores: di.inject(subscribeStoresInjectable),
|
subscribeStores: di.inject(subscribeStoresInjectable),
|
||||||
podStore: di.inject(podStoreInjectable),
|
|
||||||
replicaSetStore: di.inject(replicaSetStoreInjectable),
|
replicaSetStore: di.inject(replicaSetStoreInjectable),
|
||||||
deploymentStore: di.inject(deploymentStoreInjectable),
|
deploymentStore: di.inject(deploymentStoreInjectable),
|
||||||
getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
requestPodMetricsForDeployments: di.inject(requestPodMetricsForDeploymentsInjectable),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import "./deployment-replicasets.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import type { ReplicaSet } from "../../../common/k8s-api/endpoints";
|
import type { ReplicaSet } from "../../../common/k8s-api/endpoints";
|
||||||
import type { KubeObjectMenuProps } from "../kube-object-menu";
|
|
||||||
import { KubeObjectMenu } from "../kube-object-menu";
|
import { KubeObjectMenu } from "../kube-object-menu";
|
||||||
import { Spinner } from "../spinner";
|
import { Spinner } from "../spinner";
|
||||||
import { prevDefault, stopPropagation } from "../../utils";
|
import { prevDefault, stopPropagation } from "../../utils";
|
||||||
@ -30,6 +29,11 @@ enum sortBy {
|
|||||||
age = "age",
|
age = "age",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
replicaSetStore: ReplicaSetStore;
|
||||||
|
showDetails: ShowDetails;
|
||||||
|
}
|
||||||
|
|
||||||
export interface DeploymentReplicaSetsProps {
|
export interface DeploymentReplicaSetsProps {
|
||||||
replicaSets: ReplicaSet[];
|
replicaSets: ReplicaSet[];
|
||||||
}
|
}
|
||||||
@ -96,7 +100,7 @@ class NonInjectedDeploymentReplicaSets extends React.Component<DeploymentReplica
|
|||||||
<TableCell className="pods">{this.getPodsLength(replica)}</TableCell>
|
<TableCell className="pods">{this.getPodsLength(replica)}</TableCell>
|
||||||
<TableCell className="age"><KubeObjectAge key="age" object={replica} /></TableCell>
|
<TableCell className="age"><KubeObjectAge key="age" object={replica} /></TableCell>
|
||||||
<TableCell className="actions" onClick={stopPropagation}>
|
<TableCell className="actions" onClick={stopPropagation}>
|
||||||
<ReplicaSetMenu object={replica} />
|
<KubeObjectMenu object={replica} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))
|
))
|
||||||
@ -114,9 +118,3 @@ export const DeploymentReplicaSets = withInjectables<Dependencies, DeploymentRep
|
|||||||
showDetails: di.inject(showDetailsInjectable),
|
showDetails: di.inject(showDetailsInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export function ReplicaSetMenu(props: KubeObjectMenuProps<ReplicaSet>) {
|
|
||||||
return (
|
|
||||||
<KubeObjectMenu {...props}/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { IAsyncComputed } from "@ogre-tools/injectable-react";
|
||||||
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import React from "react";
|
||||||
|
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
||||||
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
|
import type { Deployment } from "../../../common/k8s-api/endpoints";
|
||||||
|
import type { DeploymentPodMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-deployments.injectable";
|
||||||
|
import metricsDetailsComponentEnabledInjectable from "../../api/catalog/entity/metrics-details-component-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 deploymentMetricsInjectable from "./metrics.injectable";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
metrics: IAsyncComputed<DeploymentPodMetricData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedDeploymentMetricsDetailsComponent = ({
|
||||||
|
object,
|
||||||
|
metrics,
|
||||||
|
}: KubeObjectDetailsProps<Deployment> & Dependencies) => (
|
||||||
|
<ResourceMetrics
|
||||||
|
tabs={podMetricTabs}
|
||||||
|
object={object}
|
||||||
|
metrics={metrics}
|
||||||
|
>
|
||||||
|
<PodCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
);
|
||||||
|
|
||||||
|
const DeploymentMetricsDetailsComponent = withInjectables<Dependencies, KubeObjectDetailsProps<Deployment>>(NonInjectedDeploymentMetricsDetailsComponent, {
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
metrics: di.inject(deploymentMetricsInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const deploymentMetricsDetailsComponentInjectable = getInjectable({
|
||||||
|
id: "deployment-metrics-details-component",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
Component: DeploymentMetricsDetailsComponent,
|
||||||
|
enabled: di.inject(metricsDetailsComponentEnabledInjectable, ClusterMetricsResourceType.Deployment),
|
||||||
|
orderNumber: -1,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default deploymentMetricsDetailsComponentInjectable;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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 { Deployment } from "../../../common/k8s-api/endpoints";
|
||||||
|
import requestPodMetricsForDeploymentsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-deployments.injectable";
|
||||||
|
|
||||||
|
const deploymentMetricsInjectable = getInjectable({
|
||||||
|
id: "deployment-metrics",
|
||||||
|
instantiate: (di, deployment) => {
|
||||||
|
const requestPodMetricsForDeployments = di.inject(requestPodMetricsForDeploymentsInjectable);
|
||||||
|
|
||||||
|
return asyncComputed({
|
||||||
|
getValueFromObservedPromise: () => {
|
||||||
|
now(60 * 1000);
|
||||||
|
|
||||||
|
return requestPodMetricsForDeployments([deployment], deployment.getNs());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, deployment: Deployment) => deployment.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default deploymentMetricsInjectable;
|
||||||
@ -17,22 +17,14 @@ import type { JobStore } from "./store";
|
|||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { Job } from "../../../common/k8s-api/endpoints";
|
import { Job } from "../../../common/k8s-api/endpoints";
|
||||||
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import type { Logger } from "../../../common/logger";
|
||||||
import { makeObservable, observable, reaction } from "mobx";
|
|
||||||
import { podMetricTabs, PodCharts } from "../+workloads-pods/pod-charts";
|
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
|
||||||
import { ResourceMetrics } from "../resource-metrics";
|
|
||||||
import logger from "../../../common/logger";
|
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
||||||
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
||||||
import type { PodStore } from "../+workloads-pods/store";
|
import type { PodStore } from "../+workloads-pods/store";
|
||||||
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
||||||
import jobStoreInjectable from "./store.injectable";
|
import jobStoreInjectable from "./store.injectable";
|
||||||
import type { GetActiveClusterEntity } from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
import getActiveClusterEntityInjectable from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
|
||||||
import type { JobPodMetricData, RequestPodMetricsForJobs } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-jobs.injectable";
|
|
||||||
import requestPodMetricsForJobsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-jobs.injectable";
|
|
||||||
|
|
||||||
export interface JobDetailsProps extends KubeObjectDetailsProps<Job> {
|
export interface JobDetailsProps extends KubeObjectDetailsProps<Job> {
|
||||||
}
|
}
|
||||||
@ -41,38 +33,21 @@ interface Dependencies {
|
|||||||
subscribeStores: SubscribeStores;
|
subscribeStores: SubscribeStores;
|
||||||
podStore: PodStore;
|
podStore: PodStore;
|
||||||
jobStore: JobStore;
|
jobStore: JobStore;
|
||||||
getActiveClusterEntity: GetActiveClusterEntity;
|
logger: Logger;
|
||||||
requestPodMetricsForJobs: RequestPodMetricsForJobs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class NonInjectedJobDetails extends React.Component<JobDetailsProps & Dependencies> {
|
class NonInjectedJobDetails extends React.Component<JobDetailsProps & Dependencies> {
|
||||||
@observable metrics: JobPodMetricData | null = null;
|
|
||||||
|
|
||||||
constructor(props: JobDetailsProps & Dependencies) {
|
|
||||||
super(props);
|
|
||||||
makeObservable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
disposeOnUnmount(this, [
|
disposeOnUnmount(this, [
|
||||||
reaction(() => this.props.object, () => {
|
|
||||||
this.metrics = null;
|
|
||||||
}),
|
|
||||||
this.props.subscribeStores([
|
this.props.subscribeStores([
|
||||||
this.props.podStore,
|
this.props.podStore,
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMetrics = async () => {
|
|
||||||
const { object: job, requestPodMetricsForJobs } = this.props;
|
|
||||||
|
|
||||||
this.metrics = await requestPodMetricsForJobs([job], job.getNs(), "");
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: job, jobStore, getActiveClusterEntity } = this.props;
|
const { object: job, jobStore, logger } = this.props;
|
||||||
|
|
||||||
if (!job) {
|
if (!job) {
|
||||||
return null;
|
return null;
|
||||||
@ -89,21 +64,9 @@ class NonInjectedJobDetails extends React.Component<JobDetailsProps & Dependenci
|
|||||||
const images = job.getImages();
|
const images = job.getImages();
|
||||||
const childPods = jobStore.getChildPods(job);
|
const childPods = jobStore.getChildPods(job);
|
||||||
const condition = job.getCondition();
|
const condition = job.getCondition();
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.Job);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="JobDetails">
|
<div className="JobDetails">
|
||||||
{!isMetricHidden && (
|
|
||||||
<ResourceMetrics
|
|
||||||
loader={this.loadMetrics}
|
|
||||||
tabs={podMetricTabs}
|
|
||||||
object={job}
|
|
||||||
metrics={this.metrics}
|
|
||||||
>
|
|
||||||
<PodCharts />
|
|
||||||
</ResourceMetrics>
|
|
||||||
)}
|
|
||||||
<KubeObjectMeta object={job}/>
|
|
||||||
<DrawerItem name="Selector" labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
Object.keys(selectors).map(label => <Badge key={label} label={label}/>)
|
Object.keys(selectors).map(label => <Badge key={label} label={label}/>)
|
||||||
@ -161,8 +124,7 @@ export const JobDetails = withInjectables<Dependencies, JobDetailsProps>(NonInje
|
|||||||
subscribeStores: di.inject(subscribeStoresInjectable),
|
subscribeStores: di.inject(subscribeStoresInjectable),
|
||||||
podStore: di.inject(podStoreInjectable),
|
podStore: di.inject(podStoreInjectable),
|
||||||
jobStore: di.inject(jobStoreInjectable),
|
jobStore: di.inject(jobStoreInjectable),
|
||||||
getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
requestPodMetricsForJobs: di.inject(requestPodMetricsForJobsInjectable),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -35,14 +35,12 @@ interface Dependencies {
|
|||||||
filterByNamespace: FilterByNamespace;
|
filterByNamespace: FilterByNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
const NonInjectedJobs = observer((props: Dependencies) => {
|
||||||
class NonInjectedJobs extends React.Component<Dependencies> {
|
|
||||||
render() {
|
|
||||||
const {
|
const {
|
||||||
eventStore,
|
eventStore,
|
||||||
filterByNamespace,
|
filterByNamespace,
|
||||||
jobStore,
|
jobStore,
|
||||||
} = this.props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SiblingsInTabLayout>
|
<SiblingsInTabLayout>
|
||||||
@ -94,8 +92,7 @@ class NonInjectedJobs extends React.Component<Dependencies> {
|
|||||||
/>
|
/>
|
||||||
</SiblingsInTabLayout>
|
</SiblingsInTabLayout>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
export const Jobs = withInjectables<Dependencies>(NonInjectedJobs, {
|
export const Jobs = withInjectables<Dependencies>(NonInjectedJobs, {
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
|
|||||||
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* 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 { type IAsyncComputed, withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import React from "react";
|
||||||
|
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
||||||
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
|
import type { Job } from "../../../common/k8s-api/endpoints";
|
||||||
|
import type { JobPodMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-jobs.injectable";
|
||||||
|
import metricsDetailsComponentEnabledInjectable from "../../api/catalog/entity/metrics-details-component-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 jobMetricsInjectable from "./metrics.injectable";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
metrics: IAsyncComputed<JobPodMetricData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedJobMetricsDetailsComponent = ({
|
||||||
|
object,
|
||||||
|
metrics,
|
||||||
|
}: KubeObjectDetailsProps<Job> & Dependencies) => (
|
||||||
|
<ResourceMetrics
|
||||||
|
tabs={podMetricTabs}
|
||||||
|
object={object}
|
||||||
|
metrics={metrics}
|
||||||
|
>
|
||||||
|
<PodCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
);
|
||||||
|
|
||||||
|
const JobMetricsDetailsComponent = withInjectables<Dependencies, KubeObjectDetailsProps<Job>>(NonInjectedJobMetricsDetailsComponent, {
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
metrics: di.inject(jobMetricsInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const jobMetricsDetailsComponentInjectable = getInjectable({
|
||||||
|
id: "job-metrics-details-component",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
Component: JobMetricsDetailsComponent,
|
||||||
|
enabled: di.inject(metricsDetailsComponentEnabledInjectable, ClusterMetricsResourceType.Job),
|
||||||
|
orderNumber: -1,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default jobMetricsDetailsComponentInjectable;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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 { Job } from "../../../common/k8s-api/endpoints";
|
||||||
|
import requestPodMetricsForJobsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-jobs.injectable";
|
||||||
|
|
||||||
|
const jobMetricsInjectable = getInjectable({
|
||||||
|
id: "job-metrics",
|
||||||
|
instantiate: (di, job) => {
|
||||||
|
const requestPodMetricsForJobs = di.inject(requestPodMetricsForJobsInjectable);
|
||||||
|
|
||||||
|
return asyncComputed({
|
||||||
|
getValueFromObservedPromise: () => {
|
||||||
|
now(60 * 1000);
|
||||||
|
|
||||||
|
return requestPodMetricsForJobs([job], job.getNs());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, job: Job) => job.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default jobMetricsInjectable;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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({
|
||||||
|
getValueFromObservedPromise: () => {
|
||||||
|
now(60 * 1000);
|
||||||
|
|
||||||
|
return requestPodMetrics([pod], pod.getNs(), "container, namespace");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, pod: Pod) => pod.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default podContainerMetricsInjectable;
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* 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 { type IAsyncComputed, withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import React from "react";
|
||||||
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
|
import type { Pod } from "../../../common/k8s-api/endpoints";
|
||||||
|
import type { PodMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics.injectable";
|
||||||
|
import metricsDetailsComponentEnabledInjectable from "../../api/catalog/entity/metrics-details-component-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";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
metrics: IAsyncComputed<PodMetricData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedPodMetricsDetailsComponent = ({
|
||||||
|
object,
|
||||||
|
metrics,
|
||||||
|
}: KubeObjectDetailsProps<Pod> & Dependencies) => (
|
||||||
|
<ResourceMetrics
|
||||||
|
tabs={podMetricTabs}
|
||||||
|
object={object}
|
||||||
|
metrics={metrics}
|
||||||
|
>
|
||||||
|
<PodCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
);
|
||||||
|
|
||||||
|
const PodMetricsDetailsComponent = withInjectables<Dependencies, KubeObjectDetailsProps<Pod>>(NonInjectedPodMetricsDetailsComponent, {
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
metrics: di.inject(podMetricsInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const podMetricsDetailsComponentInjectable = getInjectable({
|
||||||
|
id: "pod-metrics-details-container",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
Component: PodMetricsDetailsComponent,
|
||||||
|
enabled: di.inject(metricsDetailsComponentEnabledInjectable, ClusterMetricsResourceType.Pod),
|
||||||
|
orderNumber: -1,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default podMetricsDetailsComponentInjectable;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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({
|
||||||
|
getValueFromObservedPromise: () => {
|
||||||
|
now(60 * 1000);
|
||||||
|
|
||||||
|
return requestPodMetrics([pod], pod.getNs());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, pod: Pod) => pod.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default podMetricsInjectable;
|
||||||
@ -7,9 +7,8 @@ import "./pod-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { observable, reaction, makeObservable } from "mobx";
|
|
||||||
import { Pod } from "../../../common/k8s-api/endpoints";
|
import { Pod } from "../../../common/k8s-api/endpoints";
|
||||||
import type { NodeApi, PriorityClassApi, RuntimeClassApi, ServiceAccountApi } from "../../../common/k8s-api/endpoints";
|
import type { NodeApi, PriorityClassApi, RuntimeClassApi, ServiceAccountApi } from "../../../common/k8s-api/endpoints";
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
@ -19,67 +18,39 @@ import { PodDetailsContainer } from "./pod-details-container";
|
|||||||
import { PodDetailsAffinities } from "./pod-details-affinities";
|
import { PodDetailsAffinities } from "./pod-details-affinities";
|
||||||
import { PodDetailsTolerations } from "./pod-details-tolerations";
|
import { PodDetailsTolerations } from "./pod-details-tolerations";
|
||||||
import { PodDetailsSecrets } from "./pod-details-secrets";
|
import { PodDetailsSecrets } from "./pod-details-secrets";
|
||||||
import { ResourceMetrics } from "../resource-metrics";
|
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { getItemMetrics } from "../../../common/k8s-api/endpoints/metrics.api";
|
import { getItemMetrics } from "../../../common/k8s-api/endpoints/metrics.api";
|
||||||
import { PodCharts, podMetricTabs } from "./pod-charts";
|
import type { Logger } from "../../../common/logger";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
|
||||||
import logger from "../../../common/logger";
|
|
||||||
import { PodVolumes } from "./details/volumes/view";
|
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 { 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 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 getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
|
||||||
import nodeApiInjectable from "../../../common/k8s-api/endpoints/node.api.injectable";
|
import nodeApiInjectable from "../../../common/k8s-api/endpoints/node.api.injectable";
|
||||||
import runtimeClassApiInjectable from "../../../common/k8s-api/endpoints/runtime-class.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 serviceAccountApiInjectable from "../../../common/k8s-api/endpoints/service-account.api.injectable";
|
||||||
import priorityClassApiInjectable from "../../../common/k8s-api/endpoints/priority-class.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<Pod> {
|
export interface PodDetailsProps extends KubeObjectDetailsProps<Pod> {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
requestPodMetrics: RequestPodMetrics;
|
|
||||||
getActiveClusterEntity: GetActiveClusterEntity;
|
|
||||||
getDetailsUrl: GetDetailsUrl;
|
getDetailsUrl: GetDetailsUrl;
|
||||||
nodeApi: NodeApi;
|
nodeApi: NodeApi;
|
||||||
priorityClassApi: PriorityClassApi;
|
priorityClassApi: PriorityClassApi;
|
||||||
runtimeClassApi: RuntimeClassApi;
|
runtimeClassApi: RuntimeClassApi;
|
||||||
serviceAccountApi: ServiceAccountApi;
|
serviceAccountApi: ServiceAccountApi;
|
||||||
|
logger: Logger;
|
||||||
|
containerMetrics: IAsyncComputed<PodMetricData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class NonInjectedPodDetails extends React.Component<PodDetailsProps & Dependencies> {
|
class NonInjectedPodDetails extends React.Component<PodDetailsProps & Dependencies> {
|
||||||
@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() {
|
render() {
|
||||||
const { object: pod, getActiveClusterEntity, getDetailsUrl, nodeApi } = this.props;
|
const { object: pod, getDetailsUrl, nodeApi, logger, containerMetrics } = this.props;
|
||||||
|
|
||||||
if (!pod) {
|
if (!pod) {
|
||||||
return null;
|
return null;
|
||||||
@ -96,7 +67,6 @@ class NonInjectedPodDetails extends React.Component<PodDetailsProps & Dependenci
|
|||||||
const podIPs = pod.getIPs();
|
const podIPs = pod.getIPs();
|
||||||
const { nodeName } = spec ?? {};
|
const { nodeName } = spec ?? {};
|
||||||
const nodeSelector = pod.getNodeSelectors();
|
const nodeSelector = pod.getNodeSelectors();
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.Pod);
|
|
||||||
const initContainers = pod.getInitContainers();
|
const initContainers = pod.getInitContainers();
|
||||||
const containers = pod.getContainers();
|
const containers = pod.getContainers();
|
||||||
|
|
||||||
@ -105,39 +75,26 @@ class NonInjectedPodDetails extends React.Component<PodDetailsProps & Dependenci
|
|||||||
const runtimeClassName = pod.getRuntimeClassName();
|
const runtimeClassName = pod.getRuntimeClassName();
|
||||||
const serviceAccountName = pod.getServiceAccountName();
|
const serviceAccountName = pod.getServiceAccountName();
|
||||||
|
|
||||||
const priorityClassDetailsUrl = getDetailsUrl(this.props.priorityClassApi.getUrl({
|
const priorityClassDetailsUrl = getDetailsUrl(this.props.priorityClassApi.formatUrlForNotListing({
|
||||||
name: priorityClassName,
|
name: priorityClassName,
|
||||||
}));
|
}));
|
||||||
const runtimeClassDetailsUrl = getDetailsUrl(this.props.runtimeClassApi.getUrl({
|
const runtimeClassDetailsUrl = getDetailsUrl(this.props.runtimeClassApi.formatUrlForNotListing({
|
||||||
name: runtimeClassName,
|
name: runtimeClassName,
|
||||||
}));
|
}));
|
||||||
const serviceAccountDetailsUrl = getDetailsUrl(this.props.serviceAccountApi.getUrl({
|
const serviceAccountDetailsUrl = getDetailsUrl(this.props.serviceAccountApi.formatUrlForNotListing({
|
||||||
name: serviceAccountName,
|
name: serviceAccountName,
|
||||||
namespace,
|
namespace,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="PodDetails">
|
<div className="PodDetails">
|
||||||
{!isMetricHidden && (
|
|
||||||
<ResourceMetrics
|
|
||||||
loader={this.loadMetrics}
|
|
||||||
tabs={podMetricTabs}
|
|
||||||
object={pod}
|
|
||||||
metrics={this.metrics}
|
|
||||||
>
|
|
||||||
<PodCharts />
|
|
||||||
</ResourceMetrics>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<KubeObjectMeta object={pod} />
|
|
||||||
|
|
||||||
<DrawerItem name="Status">
|
<DrawerItem name="Status">
|
||||||
<span className={cssNames("status", kebabCase(pod.getStatusMessage()))}>
|
<span className={cssNames("status", kebabCase(pod.getStatusMessage()))}>
|
||||||
{pod.getStatusMessage()}
|
{pod.getStatusMessage()}
|
||||||
</span>
|
</span>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name="Node" hidden={!nodeName}>
|
<DrawerItem name="Node" hidden={!nodeName}>
|
||||||
<Link to={getDetailsUrl(nodeApi.getUrl({ name: nodeName }))}>
|
<Link to={getDetailsUrl(nodeApi.formatUrlForNotListing({ name: nodeName }))}>
|
||||||
{nodeName}
|
{nodeName}
|
||||||
</Link>
|
</Link>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
@ -230,7 +187,7 @@ class NonInjectedPodDetails extends React.Component<PodDetailsProps & Dependenci
|
|||||||
key={container.name}
|
key={container.name}
|
||||||
pod={pod}
|
pod={pod}
|
||||||
container={container}
|
container={container}
|
||||||
metrics={getItemMetrics(toJS(this.containerMetrics), container.name)}
|
metrics={getItemMetrics(toJS(containerMetrics.value.get()), container.name)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
@ -243,12 +200,12 @@ class NonInjectedPodDetails extends React.Component<PodDetailsProps & Dependenci
|
|||||||
export const PodDetails = withInjectables<Dependencies, PodDetailsProps>(NonInjectedPodDetails, {
|
export const PodDetails = withInjectables<Dependencies, PodDetailsProps>(NonInjectedPodDetails, {
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
...props,
|
...props,
|
||||||
requestPodMetrics: di.inject(requestPodMetricsInjectable),
|
|
||||||
getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable),
|
|
||||||
getDetailsUrl: di.inject(getDetailsUrlInjectable),
|
getDetailsUrl: di.inject(getDetailsUrlInjectable),
|
||||||
nodeApi: di.inject(nodeApiInjectable),
|
nodeApi: di.inject(nodeApiInjectable),
|
||||||
priorityClassApi: di.inject(priorityClassApiInjectable),
|
priorityClassApi: di.inject(priorityClassApiInjectable),
|
||||||
runtimeClassApi: di.inject(runtimeClassApiInjectable),
|
runtimeClassApi: di.inject(runtimeClassApiInjectable),
|
||||||
serviceAccountApi: di.inject(serviceAccountApiInjectable),
|
serviceAccountApi: di.inject(serviceAccountApiInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
containerMetrics: di.inject(podContainerMetricsInjectable, props.object),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* 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 { type IAsyncComputed, withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import React from "react";
|
||||||
|
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
||||||
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
|
import type { ReplicaSet } from "../../../common/k8s-api/endpoints";
|
||||||
|
import type { ReplicaSetPodMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-replica-sets.injectable";
|
||||||
|
import metricsDetailsComponentEnabledInjectable from "../../api/catalog/entity/metrics-details-component-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 replicaSetMetricsInjectable from "./metrics.injectable";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
metrics: IAsyncComputed<ReplicaSetPodMetricData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedReplicaSetMetricsDetailsComponent = ({
|
||||||
|
object,
|
||||||
|
metrics,
|
||||||
|
}: KubeObjectDetailsProps<ReplicaSet> & Dependencies) => (
|
||||||
|
<ResourceMetrics
|
||||||
|
tabs={podMetricTabs}
|
||||||
|
object={object}
|
||||||
|
metrics={metrics}
|
||||||
|
>
|
||||||
|
<PodCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
);
|
||||||
|
|
||||||
|
const ReplicaSetMetricsDetailsComponent = withInjectables<Dependencies, KubeObjectDetailsProps<ReplicaSet>>(NonInjectedReplicaSetMetricsDetailsComponent, {
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
metrics: di.inject(replicaSetMetricsInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const replicaSetMetricsDetailsComponentInjectable = getInjectable({
|
||||||
|
id: "replica-set-metrics-details-component",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
Component: ReplicaSetMetricsDetailsComponent,
|
||||||
|
enabled: di.inject(metricsDetailsComponentEnabledInjectable, ClusterMetricsResourceType.ReplicaSet),
|
||||||
|
orderNumber: -1,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default replicaSetMetricsDetailsComponentInjectable;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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 { ReplicaSet } from "../../../common/k8s-api/endpoints";
|
||||||
|
import requestPodMetricsForReplicaSetsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-replica-sets.injectable";
|
||||||
|
|
||||||
|
const replicaSetMetricsInjectable = getInjectable({
|
||||||
|
id: "replica-set-metrics",
|
||||||
|
instantiate: (di, replicaSet) => {
|
||||||
|
const requestPodMetricsForReplicaSets = di.inject(requestPodMetricsForReplicaSetsInjectable);
|
||||||
|
|
||||||
|
return asyncComputed({
|
||||||
|
getValueFromObservedPromise: async () => {
|
||||||
|
now(60 * 1000); // update every minute
|
||||||
|
|
||||||
|
return requestPodMetricsForReplicaSets([replicaSet], replicaSet.getNs());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, replicaSet: ReplicaSet) => replicaSet.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default replicaSetMetricsInjectable;
|
||||||
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
import "./replicaset-details.scss";
|
import "./replicaset-details.scss";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { makeObservable, observable, reaction } from "mobx";
|
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses";
|
import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses";
|
||||||
@ -14,12 +13,8 @@ import { PodDetailsAffinities } from "../+workloads-pods/pod-details-affinities"
|
|||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { ReplicaSet } from "../../../common/k8s-api/endpoints";
|
import { ReplicaSet } from "../../../common/k8s-api/endpoints";
|
||||||
import { ResourceMetrics, ResourceMetricsText } from "../resource-metrics";
|
|
||||||
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
|
||||||
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import type { Logger } from "../../../common/logger";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
|
||||||
import logger from "../../../common/logger";
|
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
||||||
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
||||||
@ -27,10 +22,7 @@ import type { PodStore } from "../+workloads-pods/store";
|
|||||||
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
||||||
import type { ReplicaSetStore } from "./store";
|
import type { ReplicaSetStore } from "./store";
|
||||||
import replicaSetStoreInjectable from "./store.injectable";
|
import replicaSetStoreInjectable from "./store.injectable";
|
||||||
import type { GetActiveClusterEntity } from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
import getActiveClusterEntityInjectable from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
|
||||||
import type { ReplicaSetPodMetricData, RequestPodMetricsForReplicaSets } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-replica-sets.injectable";
|
|
||||||
import requestPodMetricsForReplicaSetsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-replica-sets.injectable";
|
|
||||||
|
|
||||||
export interface ReplicaSetDetailsProps extends KubeObjectDetailsProps<ReplicaSet> {
|
export interface ReplicaSetDetailsProps extends KubeObjectDetailsProps<ReplicaSet> {
|
||||||
}
|
}
|
||||||
@ -39,39 +31,20 @@ interface Dependencies {
|
|||||||
subscribeStores: SubscribeStores;
|
subscribeStores: SubscribeStores;
|
||||||
podStore: PodStore;
|
podStore: PodStore;
|
||||||
replicaSetStore: ReplicaSetStore;
|
replicaSetStore: ReplicaSetStore;
|
||||||
getActiveClusterEntity: GetActiveClusterEntity;
|
logger: Logger;
|
||||||
requestPodMetricsForReplicaSets: RequestPodMetricsForReplicaSets;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class NonInjectedReplicaSetDetails extends React.Component<ReplicaSetDetailsProps & Dependencies> {
|
class NonInjectedReplicaSetDetails extends React.Component<ReplicaSetDetailsProps & Dependencies> {
|
||||||
@observable metrics: ReplicaSetPodMetricData | null = null;
|
|
||||||
|
|
||||||
constructor(props: ReplicaSetDetailsProps & Dependencies) {
|
|
||||||
super(props);
|
|
||||||
makeObservable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
disposeOnUnmount(this, [
|
disposeOnUnmount(this, [
|
||||||
reaction(() => this.props.object, () => {
|
|
||||||
this.metrics = null;
|
|
||||||
}),
|
|
||||||
|
|
||||||
this.props.subscribeStores([
|
this.props.subscribeStores([
|
||||||
this.props.podStore,
|
this.props.podStore,
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMetrics = async () => {
|
|
||||||
const { object: replicaSet, requestPodMetricsForReplicaSets } = this.props;
|
|
||||||
|
|
||||||
this.metrics = await requestPodMetricsForReplicaSets([replicaSet], replicaSet.getNs());
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: replicaSet, podStore, replicaSetStore, getActiveClusterEntity } = this.props;
|
const { object: replicaSet, replicaSetStore, logger } = this.props;
|
||||||
|
|
||||||
if (!replicaSet) {
|
if (!replicaSet) {
|
||||||
return null;
|
return null;
|
||||||
@ -88,21 +61,9 @@ class NonInjectedReplicaSetDetails extends React.Component<ReplicaSetDetailsProp
|
|||||||
const nodeSelector = replicaSet.getNodeSelectors();
|
const nodeSelector = replicaSet.getNodeSelectors();
|
||||||
const images = replicaSet.getImages();
|
const images = replicaSet.getImages();
|
||||||
const childPods = replicaSetStore.getChildPods(replicaSet);
|
const childPods = replicaSetStore.getChildPods(replicaSet);
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.ReplicaSet);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ReplicaSetDetails">
|
<div className="ReplicaSetDetails">
|
||||||
{!isMetricHidden && podStore.isLoaded && (
|
|
||||||
<ResourceMetrics
|
|
||||||
loader={this.loadMetrics}
|
|
||||||
tabs={podMetricTabs}
|
|
||||||
object={replicaSet}
|
|
||||||
metrics={this.metrics}
|
|
||||||
>
|
|
||||||
<PodCharts/>
|
|
||||||
</ResourceMetrics>
|
|
||||||
)}
|
|
||||||
<KubeObjectMeta object={replicaSet}/>
|
|
||||||
{selectors.length > 0 && (
|
{selectors.length > 0 && (
|
||||||
<DrawerItem name="Selector" labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
@ -132,7 +93,6 @@ class NonInjectedReplicaSetDetails extends React.Component<ReplicaSetDetailsProp
|
|||||||
<DrawerItem name="Pod Status" className="pod-status">
|
<DrawerItem name="Pod Status" className="pod-status">
|
||||||
<PodDetailsStatuses pods={childPods}/>
|
<PodDetailsStatuses pods={childPods}/>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<ResourceMetricsText metrics={this.metrics}/>
|
|
||||||
<PodDetailsList pods={childPods} owner={replicaSet}/>
|
<PodDetailsList pods={childPods} owner={replicaSet}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -145,7 +105,6 @@ export const ReplicaSetDetails = withInjectables<Dependencies, ReplicaSetDetails
|
|||||||
subscribeStores: di.inject(subscribeStoresInjectable),
|
subscribeStores: di.inject(subscribeStoresInjectable),
|
||||||
podStore: di.inject(podStoreInjectable),
|
podStore: di.inject(podStoreInjectable),
|
||||||
replicaSetStore: di.inject(replicaSetStoreInjectable),
|
replicaSetStore: di.inject(replicaSetStoreInjectable),
|
||||||
getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
requestPodMetricsForReplicaSets: di.inject(requestPodMetricsForReplicaSetsInjectable),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -35,14 +35,12 @@ interface Dependencies {
|
|||||||
filterByNamespace: FilterByNamespace;
|
filterByNamespace: FilterByNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
const NonInjectedReplicaSets = observer((props: Dependencies) => {
|
||||||
class NonInjectedReplicaSets extends React.Component<Dependencies> {
|
|
||||||
render() {
|
|
||||||
const {
|
const {
|
||||||
eventStore,
|
eventStore,
|
||||||
filterByNamespace,
|
filterByNamespace,
|
||||||
replicaSetStore,
|
replicaSetStore,
|
||||||
} = this.props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SiblingsInTabLayout>
|
<SiblingsInTabLayout>
|
||||||
@ -91,8 +89,7 @@ class NonInjectedReplicaSets extends React.Component<Dependencies> {
|
|||||||
/>
|
/>
|
||||||
</SiblingsInTabLayout>
|
</SiblingsInTabLayout>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
export const ReplicaSets = withInjectables<Dependencies>(NonInjectedReplicaSets, {
|
export const ReplicaSets = withInjectables<Dependencies>(NonInjectedReplicaSets, {
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
|
|||||||
@ -9,12 +9,12 @@ import { PodStatusPhase } from "../../../common/k8s-api/endpoints/pod.api";
|
|||||||
import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store";
|
import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store";
|
||||||
import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
|
import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
|
||||||
|
|
||||||
export interface ReplicaSetStoreDependencies {
|
interface Dependencies {
|
||||||
getPodsByOwnerId: GetPodsByOwnerId;
|
getPodsByOwnerId: GetPodsByOwnerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ReplicaSetStore extends KubeObjectStore<ReplicaSet, ReplicaSetApi> {
|
export class ReplicaSetStore extends KubeObjectStore<ReplicaSet, ReplicaSetApi> {
|
||||||
constructor(protected readonly dependencies: ReplicaSetStoreDependencies, api: ReplicaSetApi, opts?: KubeObjectStoreOptions) {
|
constructor(protected readonly dependencies: Dependencies, api: ReplicaSetApi, opts?: KubeObjectStoreOptions) {
|
||||||
super(api, opts);
|
super(api, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* 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 { type IAsyncComputed, withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import React from "react";
|
||||||
|
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
||||||
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
|
import type { StatefulSet } from "../../../common/k8s-api/endpoints";
|
||||||
|
import type { StatefulSetPodMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-stateful-sets.injectable";
|
||||||
|
import metricsDetailsComponentEnabledInjectable from "../../api/catalog/entity/metrics-details-component-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 statefulSetMetricsInjectable from "./metrics.injectable";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
metrics: IAsyncComputed<StatefulSetPodMetricData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedStatefulSetMetricsDetailsComponent = ({
|
||||||
|
object,
|
||||||
|
metrics,
|
||||||
|
}: KubeObjectDetailsProps<StatefulSet> & Dependencies) => (
|
||||||
|
<ResourceMetrics
|
||||||
|
tabs={podMetricTabs}
|
||||||
|
object={object}
|
||||||
|
metrics={metrics}
|
||||||
|
>
|
||||||
|
<PodCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
);
|
||||||
|
|
||||||
|
const StatefulSetMetricsDetailsComponent = withInjectables<Dependencies, KubeObjectDetailsProps<StatefulSet>>(NonInjectedStatefulSetMetricsDetailsComponent, {
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
metrics: di.inject(statefulSetMetricsInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const statefulSetMetricsDetailsComponentInjectable = getInjectable({
|
||||||
|
id: "stateful-set-metrics-details-component",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
Component: StatefulSetMetricsDetailsComponent,
|
||||||
|
enabled: di.inject(metricsDetailsComponentEnabledInjectable, ClusterMetricsResourceType.StatefulSet),
|
||||||
|
orderNumber: -1,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default statefulSetMetricsDetailsComponentInjectable;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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 { StatefulSet } from "../../../common/k8s-api/endpoints";
|
||||||
|
import requestPodMetricsForStatefulSetsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-stateful-sets.injectable";
|
||||||
|
|
||||||
|
const statefulSetMetricsInjectable = getInjectable({
|
||||||
|
id: "stateful-set-metrics",
|
||||||
|
instantiate: (di, statefulSet) => {
|
||||||
|
const requestPodMetricsForStatefulSets = di.inject(requestPodMetricsForStatefulSetsInjectable);
|
||||||
|
|
||||||
|
return asyncComputed({
|
||||||
|
getValueFromObservedPromise: async () => {
|
||||||
|
now(60 * 1000);
|
||||||
|
|
||||||
|
return requestPodMetricsForStatefulSets([statefulSet], statefulSet.getNs());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, statefulSet: StatefulSet) => statefulSet.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default statefulSetMetricsInjectable;
|
||||||
@ -7,7 +7,6 @@ import "./statefulset-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { makeObservable, observable, reaction } from "mobx";
|
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses";
|
import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses";
|
||||||
@ -16,22 +15,15 @@ import { PodDetailsAffinities } from "../+workloads-pods/pod-details-affinities"
|
|||||||
import type { StatefulSetStore } from "./store";
|
import type { StatefulSetStore } from "./store";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { StatefulSet } from "../../../common/k8s-api/endpoints";
|
import { StatefulSet } from "../../../common/k8s-api/endpoints";
|
||||||
import { ResourceMetrics, ResourceMetricsText } from "../resource-metrics";
|
|
||||||
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
|
||||||
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import type { Logger } from "../../../common/logger";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
|
||||||
import logger from "../../../common/logger";
|
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
||||||
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
|
||||||
import type { PodStore } from "../+workloads-pods/store";
|
import type { PodStore } from "../+workloads-pods/store";
|
||||||
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
||||||
import statefulSetStoreInjectable from "./store.injectable";
|
import statefulSetStoreInjectable from "./store.injectable";
|
||||||
import type { GetActiveClusterEntity } from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
import getActiveClusterEntityInjectable from "../../api/catalog/entity/get-active-cluster-entity.injectable";
|
|
||||||
import type { RequestPodMetricsForStatefulSets, StatefulSetPodMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-stateful-sets.injectable";
|
|
||||||
import requestPodMetricsForStatefulSetsInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-pod-metrics-for-stateful-sets.injectable";
|
|
||||||
|
|
||||||
export interface StatefulSetDetailsProps extends KubeObjectDetailsProps<StatefulSet> {
|
export interface StatefulSetDetailsProps extends KubeObjectDetailsProps<StatefulSet> {
|
||||||
}
|
}
|
||||||
@ -40,39 +32,21 @@ interface Dependencies {
|
|||||||
subscribeStores: SubscribeStores;
|
subscribeStores: SubscribeStores;
|
||||||
podStore: PodStore;
|
podStore: PodStore;
|
||||||
statefulSetStore: StatefulSetStore;
|
statefulSetStore: StatefulSetStore;
|
||||||
getActiveClusterEntity: GetActiveClusterEntity;
|
logger: Logger;
|
||||||
requestPodMetricsForStatefulSets: RequestPodMetricsForStatefulSets;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class NonInjectedStatefulSetDetails extends React.Component<StatefulSetDetailsProps & Dependencies> {
|
class NonInjectedStatefulSetDetails extends React.Component<StatefulSetDetailsProps & Dependencies> {
|
||||||
@observable metrics: StatefulSetPodMetricData | null = null;
|
|
||||||
|
|
||||||
constructor(props: StatefulSetDetailsProps & Dependencies) {
|
|
||||||
super(props);
|
|
||||||
makeObservable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
disposeOnUnmount(this, [
|
disposeOnUnmount(this, [
|
||||||
reaction(() => this.props.object, () => {
|
|
||||||
this.metrics = null;
|
|
||||||
}),
|
|
||||||
|
|
||||||
this.props.subscribeStores([
|
this.props.subscribeStores([
|
||||||
this.props.podStore,
|
this.props.podStore,
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMetrics = async () => {
|
|
||||||
const { object: statefulSet, requestPodMetricsForStatefulSets } = this.props;
|
|
||||||
|
|
||||||
this.metrics = await requestPodMetricsForStatefulSets([statefulSet], statefulSet.getNs());
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: statefulSet, podStore, statefulSetStore, getActiveClusterEntity } = this.props;
|
const { object: statefulSet, statefulSetStore, logger } = this.props;
|
||||||
|
|
||||||
if (!statefulSet) {
|
if (!statefulSet) {
|
||||||
return null;
|
return null;
|
||||||
@ -88,21 +62,9 @@ class NonInjectedStatefulSetDetails extends React.Component<StatefulSetDetailsPr
|
|||||||
const selectors = statefulSet.getSelectors();
|
const selectors = statefulSet.getSelectors();
|
||||||
const nodeSelector = statefulSet.getNodeSelectors();
|
const nodeSelector = statefulSet.getNodeSelectors();
|
||||||
const childPods = statefulSetStore.getChildPods(statefulSet);
|
const childPods = statefulSetStore.getChildPods(statefulSet);
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.StatefulSet);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="StatefulSetDetails">
|
<div className="StatefulSetDetails">
|
||||||
{!isMetricHidden && podStore.isLoaded && (
|
|
||||||
<ResourceMetrics
|
|
||||||
loader={this.loadMetrics}
|
|
||||||
tabs={podMetricTabs}
|
|
||||||
object={statefulSet}
|
|
||||||
metrics={this.metrics}
|
|
||||||
>
|
|
||||||
<PodCharts/>
|
|
||||||
</ResourceMetrics>
|
|
||||||
)}
|
|
||||||
<KubeObjectMeta object={statefulSet}/>
|
|
||||||
{selectors.length && (
|
{selectors.length && (
|
||||||
<DrawerItem name="Selector" labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
@ -131,7 +93,6 @@ class NonInjectedStatefulSetDetails extends React.Component<StatefulSetDetailsPr
|
|||||||
<DrawerItem name="Pod Status" className="pod-status">
|
<DrawerItem name="Pod Status" className="pod-status">
|
||||||
<PodDetailsStatuses pods={childPods}/>
|
<PodDetailsStatuses pods={childPods}/>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<ResourceMetricsText metrics={this.metrics}/>
|
|
||||||
<PodDetailsList pods={childPods} owner={statefulSet}/>
|
<PodDetailsList pods={childPods} owner={statefulSet}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -144,8 +105,7 @@ export const StatefulSetDetails = withInjectables<Dependencies, StatefulSetDetai
|
|||||||
subscribeStores: di.inject(subscribeStoresInjectable),
|
subscribeStores: di.inject(subscribeStoresInjectable),
|
||||||
podStore: di.inject(podStoreInjectable),
|
podStore: di.inject(podStoreInjectable),
|
||||||
statefulSetStore: di.inject(statefulSetStoreInjectable),
|
statefulSetStore: di.inject(statefulSetStoreInjectable),
|
||||||
getActiveClusterEntity: di.inject(getActiveClusterEntityInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
requestPodMetricsForStatefulSets: di.inject(requestPodMetricsForStatefulSetsInjectable),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -13,13 +13,11 @@ import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
|||||||
import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout";
|
import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout";
|
||||||
import { KubeObjectAge } from "../kube-object/age";
|
import { KubeObjectAge } from "../kube-object/age";
|
||||||
import type { StatefulSetStore } from "./store";
|
import type { StatefulSetStore } from "./store";
|
||||||
import type { PodStore } from "../+workloads-pods/store";
|
|
||||||
import type { EventStore } from "../+events/store";
|
import type { EventStore } from "../+events/store";
|
||||||
import type { FilterByNamespace } from "../+namespaces/namespace-select-filter-model/filter-by-namespace.injectable";
|
import type { FilterByNamespace } from "../+namespaces/namespace-select-filter-model/filter-by-namespace.injectable";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import eventStoreInjectable from "../+events/store.injectable";
|
import eventStoreInjectable from "../+events/store.injectable";
|
||||||
import filterByNamespaceInjectable from "../+namespaces/namespace-select-filter-model/filter-by-namespace.injectable";
|
import filterByNamespaceInjectable from "../+namespaces/namespace-select-filter-model/filter-by-namespace.injectable";
|
||||||
import podStoreInjectable from "../+workloads-pods/store.injectable";
|
|
||||||
import statefulSetStoreInjectable from "./store.injectable";
|
import statefulSetStoreInjectable from "./store.injectable";
|
||||||
import { prevDefault } from "../../utils";
|
import { prevDefault } from "../../utils";
|
||||||
|
|
||||||
@ -33,26 +31,22 @@ enum columnId {
|
|||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
statefulSetStore: StatefulSetStore;
|
statefulSetStore: StatefulSetStore;
|
||||||
podStore: PodStore;
|
|
||||||
eventStore: EventStore;
|
eventStore: EventStore;
|
||||||
filterByNamespace: FilterByNamespace;
|
filterByNamespace: FilterByNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
const renderPodCounts = (statefulSet: StatefulSet) => {
|
||||||
class NonInjectedStatefulSets extends React.Component<Dependencies> {
|
|
||||||
renderPods(statefulSet: StatefulSet) {
|
|
||||||
const { readyReplicas, currentReplicas } = statefulSet.status ?? {};
|
const { readyReplicas, currentReplicas } = statefulSet.status ?? {};
|
||||||
|
|
||||||
return `${readyReplicas || 0}/${currentReplicas || 0}`;
|
return `${readyReplicas || 0}/${currentReplicas || 0}`;
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
const NonInjectedStatefulSets = observer((props: Dependencies) => {
|
||||||
const {
|
const {
|
||||||
eventStore,
|
eventStore,
|
||||||
filterByNamespace,
|
filterByNamespace,
|
||||||
podStore,
|
|
||||||
statefulSetStore,
|
statefulSetStore,
|
||||||
} = this.props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SiblingsInTabLayout>
|
<SiblingsInTabLayout>
|
||||||
@ -61,7 +55,7 @@ class NonInjectedStatefulSets extends React.Component<Dependencies> {
|
|||||||
tableId="workload_statefulsets"
|
tableId="workload_statefulsets"
|
||||||
className="StatefulSets"
|
className="StatefulSets"
|
||||||
store={statefulSetStore}
|
store={statefulSetStore}
|
||||||
dependentStores={[podStore, eventStore]} // status icon component uses event store, details component uses podStore
|
dependentStores={[eventStore]}
|
||||||
sortingCallbacks={{
|
sortingCallbacks={{
|
||||||
[columnId.name]: statefulSet => statefulSet.getName(),
|
[columnId.name]: statefulSet => statefulSet.getName(),
|
||||||
[columnId.namespace]: statefulSet => statefulSet.getNs(),
|
[columnId.namespace]: statefulSet => statefulSet.getNs(),
|
||||||
@ -89,7 +83,7 @@ class NonInjectedStatefulSets extends React.Component<Dependencies> {
|
|||||||
>
|
>
|
||||||
{statefulSet.getNs()}
|
{statefulSet.getNs()}
|
||||||
</a>,
|
</a>,
|
||||||
this.renderPods(statefulSet),
|
renderPodCounts(statefulSet),
|
||||||
statefulSet.getReplicas(),
|
statefulSet.getReplicas(),
|
||||||
<KubeObjectStatusIcon key="icon" object={statefulSet} />,
|
<KubeObjectStatusIcon key="icon" object={statefulSet} />,
|
||||||
<KubeObjectAge key="age" object={statefulSet} />,
|
<KubeObjectAge key="age" object={statefulSet} />,
|
||||||
@ -97,15 +91,13 @@ class NonInjectedStatefulSets extends React.Component<Dependencies> {
|
|||||||
/>
|
/>
|
||||||
</SiblingsInTabLayout>
|
</SiblingsInTabLayout>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
export const StatefulSets = withInjectables<Dependencies>(NonInjectedStatefulSets, {
|
export const StatefulSets = withInjectables<Dependencies>(NonInjectedStatefulSets, {
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
...props,
|
...props,
|
||||||
eventStore: di.inject(eventStoreInjectable),
|
eventStore: di.inject(eventStoreInjectable),
|
||||||
filterByNamespace: di.inject(filterByNamespaceInjectable),
|
filterByNamespace: di.inject(filterByNamespaceInjectable),
|
||||||
podStore: di.inject(podStoreInjectable),
|
|
||||||
statefulSetStore: di.inject(statefulSetStoreInjectable),
|
statefulSetStore: di.inject(statefulSetStoreInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,10 +3,15 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { computed } from "mobx";
|
|
||||||
import kubeDetailsUrlParamInjectable from "../kube-detail-params/kube-details-url.injectable";
|
import kubeDetailsUrlParamInjectable from "../kube-detail-params/kube-details-url.injectable";
|
||||||
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
import loggerInjectable from "../../../common/logger.injectable";
|
import { asyncComputed } from "@ogre-tools/injectable-react";
|
||||||
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
|
|
||||||
|
export type CurrentKubeObject =
|
||||||
|
| undefined
|
||||||
|
| { object: KubeObject; error?: undefined }
|
||||||
|
| { object?: undefined; error: string };
|
||||||
|
|
||||||
const currentKubeObjectInDetailsInjectable = getInjectable({
|
const currentKubeObjectInDetailsInjectable = getInjectable({
|
||||||
id: "current-kube-object-in-details",
|
id: "current-kube-object-in-details",
|
||||||
@ -14,20 +19,24 @@ const currentKubeObjectInDetailsInjectable = getInjectable({
|
|||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const urlParam = di.inject(kubeDetailsUrlParamInjectable);
|
const urlParam = di.inject(kubeDetailsUrlParamInjectable);
|
||||||
const apiManager = di.inject(apiManagerInjectable);
|
const apiManager = di.inject(apiManagerInjectable);
|
||||||
const logger = di.inject(loggerInjectable);
|
|
||||||
|
|
||||||
return computed(() => {
|
return asyncComputed({
|
||||||
|
getValueFromObservedPromise: async (): Promise<CurrentKubeObject> => {
|
||||||
const path = urlParam.get();
|
const path = urlParam.get();
|
||||||
|
const store = apiManager.getStore(path);
|
||||||
|
|
||||||
try {
|
if (!store) {
|
||||||
return apiManager.getStore(path)?.getByPath(path);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error(
|
|
||||||
`[KUBE-OBJECT-DETAILS]: failed to get store or object ${path}: ${error}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const object = await store.loadFromPath(path);
|
||||||
|
|
||||||
|
return { object };
|
||||||
|
} catch (error) {
|
||||||
|
return { error: String(error) };
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* 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 { computed } from "mobx";
|
||||||
|
import React from "react";
|
||||||
|
import { CustomResourceDetails } from "../+custom-resources";
|
||||||
|
import customResourceDefinitionStoreInjectable from "../+custom-resources/definition.store.injectable";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "./current-kube-object-in-details.injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "./kube-object-detail-items/kube-object-detail-item-injection-token";
|
||||||
|
|
||||||
|
const customResourceDetailItemInjectable = getInjectable({
|
||||||
|
id: "custom-resource-detail-item",
|
||||||
|
instantiate: (di) => {
|
||||||
|
const customResourceDefinitionStore = di.inject(customResourceDefinitionStoreInjectable);
|
||||||
|
const currentKubeObjectInDetails = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
const currentCustomResourceDefinition = computed(() => {
|
||||||
|
const { object } = currentKubeObjectInDetails.value.get() ?? {};
|
||||||
|
|
||||||
|
if (!object) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return customResourceDefinitionStore.getByObject(object);
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: ({ object }) => <CustomResourceDetails object={object} crd={currentCustomResourceDefinition.get()} />,
|
||||||
|
enabled: computed(() => Boolean(currentCustomResourceDefinition.get())),
|
||||||
|
orderNumber: 100,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default customResourceDetailItemInjectable;
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* 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 { computed } from "mobx";
|
||||||
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "./kube-object-detail-items/kube-object-detail-item-injection-token";
|
||||||
|
|
||||||
|
const defaultKubeObjectMetaDetailsItemInjectable = getInjectable({
|
||||||
|
id: "default-kube-object-meta-details-item",
|
||||||
|
instantiate: () => ({
|
||||||
|
Component: KubeObjectMeta,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: 0,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default defaultKubeObjectMetaDetailsItemInjectable;
|
||||||
@ -17,7 +17,7 @@ const clusterRoleBindingDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: ClusterRoleBindingDetails,
|
Component: ClusterRoleBindingDetails,
|
||||||
enabled: computed(() => isClusterRoleBinding(kubeObject.get())),
|
enabled: computed(() => isClusterRoleBinding(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const clusterRoleDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: ClusterRoleDetails,
|
Component: ClusterRoleDetails,
|
||||||
enabled: computed(() => isClusterRole(kubeObject.get())),
|
enabled: computed(() => isClusterRole(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const configMapDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: ConfigMapDetails,
|
Component: ConfigMapDetails,
|
||||||
enabled: computed(() => isConfigMap(kubeObject.get())),
|
enabled: computed(() => isConfigMap(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const cronJobDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: CronJobDetails,
|
Component: CronJobDetails,
|
||||||
enabled: computed(() => isCronJob(kubeObject.get())),
|
enabled: computed(() => isCronJob(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const customResourceDefinitionsDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: CRDDetails,
|
Component: CRDDetails,
|
||||||
enabled: computed(() => isCustomResourceDefinition(kubeObject.get())),
|
enabled: computed(() => isCustomResourceDefinition(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const daemonSetDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: DaemonSetDetails,
|
Component: DaemonSetDetails,
|
||||||
enabled: computed(() => isDaemonSet(kubeObject.get())),
|
enabled: computed(() => isDaemonSet(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const deploymentDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: DeploymentDetails,
|
Component: DeploymentDetails,
|
||||||
enabled: computed(() => isDeployment(kubeObject.get())),
|
enabled: computed(() => isDeployment(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const endpointsDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: EndpointsDetails,
|
Component: EndpointsDetails,
|
||||||
enabled: computed(() => isEndpoint(kubeObject.get())),
|
enabled: computed(() => isEndpoint(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const eventsDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: EventDetails,
|
Component: EventDetails,
|
||||||
enabled: computed(() => isEvent(kubeObject.get())),
|
enabled: computed(() => isEvent(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const horizontalPodAutoscalerDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: HpaDetails,
|
Component: HpaDetails,
|
||||||
enabled: computed(() => isHorizontalPodAutoscaler(kubeObject.get())),
|
enabled: computed(() => isHorizontalPodAutoscaler(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const ingressDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: IngressDetails,
|
Component: IngressDetails,
|
||||||
enabled: computed(() => isIngress(kubeObject.get())),
|
enabled: computed(() => isIngress(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const jobDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: JobDetails,
|
Component: JobDetails,
|
||||||
enabled: computed(() => isJob(kubeObject.get())),
|
enabled: computed(() => isJob(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -6,78 +6,16 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
import { KubeEventDetails } from "../../../+events/kube-event-details";
|
import { KubeEventDetails } from "../../../+events/kube-event-details";
|
||||||
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
|
||||||
import { isClusterRole } from "./cluster-role-detail-item.injectable";
|
|
||||||
import { isClusterRoleBinding } from "./cluster-role-binding-detail-item.injectable";
|
|
||||||
import { isCronJob } from "./cron-job-detail-item.injectable";
|
|
||||||
import { isDaemonSet } from "./daemon-set-detail-item.injectable";
|
|
||||||
import { isDeployment } from "./deployment-detail-item.injectable";
|
|
||||||
import { isEndpoint } from "./endpoints-detail-item.injectable";
|
|
||||||
import { isHorizontalPodAutoscaler } from "./horizontal-pod-autoscaler-detail-item.injectable";
|
|
||||||
import { isIngress } from "./ingress-detail-item.injectable";
|
|
||||||
import { isJob } from "./job-detail-item.injectable";
|
|
||||||
import { isNetworkPolicy } from "./network-policy-detail-item.injectable";
|
|
||||||
import { isPersistentVolume } from "./persistent-volume-detail-item.injectable";
|
|
||||||
import { isPersistentVolumeClaim } from "./persistent-volume-claim-detail-item.injectable";
|
|
||||||
import { isNode } from "./node-detail-item.injectable";
|
|
||||||
import { isPod } from "./pod-detail-item.injectable";
|
|
||||||
import { isReplicaSet } from "./replica-set-detail-item.injectable";
|
|
||||||
import { isRole } from "./role-detail-item.injectable";
|
|
||||||
import { isRoleBinding } from "./role-binding-detail-item.injectable";
|
|
||||||
import { isService } from "./service-detail-item.injectable";
|
|
||||||
import { isServiceAccount } from "./service-account-detail-item.injectable";
|
|
||||||
import { isStatefulSet } from "./stateful-set-detail-item.injectable";
|
|
||||||
import { isStorageClass } from "./storage-class-detail-item.injectable";
|
|
||||||
|
|
||||||
const kubeEventDetailItemInjectable = getInjectable({
|
const kubeEventDetailItemInjectable = getInjectable({
|
||||||
id: "kube-event-detail-item",
|
id: "kube-event-detail-item",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: () => ({
|
||||||
const currentKubeObjectInDetails = di.inject(
|
|
||||||
currentKubeObjectInDetailsInjectable,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
Component: KubeEventDetails,
|
Component: KubeEventDetails,
|
||||||
|
enabled: computed(() => true),
|
||||||
enabled: computed(() => {
|
orderNumber: Infinity,
|
||||||
const kubeObject = currentKubeObjectInDetails.get();
|
|
||||||
|
|
||||||
if (!kubeObject) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const predicates = [
|
|
||||||
isClusterRole,
|
|
||||||
isClusterRoleBinding,
|
|
||||||
isCronJob,
|
|
||||||
isDaemonSet,
|
|
||||||
isDeployment,
|
|
||||||
isEndpoint,
|
|
||||||
isHorizontalPodAutoscaler,
|
|
||||||
isIngress,
|
|
||||||
isJob,
|
|
||||||
isNetworkPolicy,
|
|
||||||
isNode,
|
|
||||||
isPersistentVolume,
|
|
||||||
isPersistentVolumeClaim,
|
|
||||||
isPod,
|
|
||||||
isReplicaSet,
|
|
||||||
isRole,
|
|
||||||
isRoleBinding,
|
|
||||||
isService,
|
|
||||||
isServiceAccount,
|
|
||||||
isStatefulSet,
|
|
||||||
isStorageClass,
|
|
||||||
];
|
|
||||||
|
|
||||||
return predicates.some((predicate) => predicate(kubeObject));
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
orderNumber: 355,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
injectionToken: kubeObjectDetailItemInjectionToken,
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const leaseDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: LeaseDetails,
|
Component: LeaseDetails,
|
||||||
enabled: computed(() => isLease(kubeObject.get())),
|
enabled: computed(() => isLease(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const limitRangeDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: LimitRangeDetails,
|
Component: LimitRangeDetails,
|
||||||
enabled: computed(() => isLimitRange(kubeObject.get())),
|
enabled: computed(() => isLimitRange(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const namespacesDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: NamespaceDetails,
|
Component: NamespaceDetails,
|
||||||
enabled: computed(() => isNamespace(kubeObject.get())),
|
enabled: computed(() => isNamespace(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const networkPolicyDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: NetworkPolicyDetails,
|
Component: NetworkPolicyDetails,
|
||||||
enabled: computed(() => isNetworkPolicy(kubeObject.get())),
|
enabled: computed(() => isNetworkPolicy(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const nodeDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: NodeDetails,
|
Component: NodeDetails,
|
||||||
enabled: computed(() => isNode(kubeObject.get())),
|
enabled: computed(() => isNode(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const persistentVolumeClaimDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: PersistentVolumeClaimDetails,
|
Component: PersistentVolumeClaimDetails,
|
||||||
enabled: computed(() => isPersistentVolumeClaim(kubeObject.get())),
|
enabled: computed(() => isPersistentVolumeClaim(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const persistentVolumeDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: PersistentVolumeDetails,
|
Component: PersistentVolumeDetails,
|
||||||
enabled: computed(() => isPersistentVolume(kubeObject.get())),
|
enabled: computed(() => isPersistentVolume(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const podDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: PodDetails,
|
Component: PodDetails,
|
||||||
enabled: computed(() => isPod(kubeObject.get())),
|
enabled: computed(() => isPod(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const podDisruptionBudgetDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: PodDisruptionBudgetDetails,
|
Component: PodDisruptionBudgetDetails,
|
||||||
enabled: computed(() => isPodDisruptionBudget(kubeObject.get())),
|
enabled: computed(() => isPodDisruptionBudget(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user