mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Check object instanceof on all detail panels (#4054)
* Check object instanceof on all detail panels Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix unit tests - Remove prettier as snapShot testing is too tight of a bound Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
dabfce3609
commit
052d12fc19
@ -357,7 +357,6 @@
|
|||||||
"postcss": "^8.3.6",
|
"postcss": "^8.3.6",
|
||||||
"postcss-loader": "4.3.0",
|
"postcss-loader": "4.3.0",
|
||||||
"postinstall-postinstall": "^2.1.0",
|
"postinstall-postinstall": "^2.1.0",
|
||||||
"prettier": "^2.4.1",
|
|
||||||
"progress-bar-webpack-plugin": "^2.1.0",
|
"progress-bar-webpack-plugin": "^2.1.0",
|
||||||
"randomcolor": "^0.6.2",
|
"randomcolor": "^0.6.2",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
import styles from "./catalog.module.css";
|
import styles from "./catalog.module.css";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { action, computed } from "mobx";
|
import { action, computed } from "mobx";
|
||||||
import type { CatalogEntity } from "../../api/catalog-entity";
|
import { CatalogEntity } from "../../api/catalog-entity";
|
||||||
import type { ItemObject } from "../../../common/item.store";
|
import type { ItemObject } from "../../../common/item.store";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { navigation } from "../../navigation";
|
import { navigation } from "../../navigation";
|
||||||
@ -33,7 +33,11 @@ import type { CatalogEntityRegistry } from "../../api/catalog-entity-registry";
|
|||||||
const css = makeCss(styles);
|
const css = makeCss(styles);
|
||||||
|
|
||||||
export class CatalogEntityItem<T extends CatalogEntity> implements ItemObject {
|
export class CatalogEntityItem<T extends CatalogEntity> implements ItemObject {
|
||||||
constructor(public entity: T, private registry: CatalogEntityRegistry) {}
|
constructor(public entity: T, private registry: CatalogEntityRegistry) {
|
||||||
|
if (!(entity instanceof CatalogEntity)) {
|
||||||
|
throw Object.assign(new TypeError("CatalogEntityItem cannot wrap a non-CatalogEntity type"), { typeof: typeof entity, prototype: Object.getPrototypeOf(entity) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get kind() {
|
get kind() {
|
||||||
return this.entity.kind;
|
return this.entity.kind;
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import { Catalog } from "./catalog";
|
|||||||
import { createMemoryHistory } from "history";
|
import { createMemoryHistory } from "history";
|
||||||
import { mockWindow } from "../../../../__mocks__/windowMock";
|
import { mockWindow } from "../../../../__mocks__/windowMock";
|
||||||
import { kubernetesClusterCategory } from "../../../common/catalog-entities/kubernetes-cluster";
|
import { kubernetesClusterCategory } from "../../../common/catalog-entities/kubernetes-cluster";
|
||||||
import { catalogCategoryRegistry, CatalogCategoryRegistry } from "../../../common/catalog";
|
import { catalogCategoryRegistry, CatalogCategoryRegistry, CatalogEntity, CatalogEntityActionContext, CatalogEntityData } from "../../../common/catalog";
|
||||||
import { CatalogEntityRegistry } from "../../../renderer/api/catalog-entity-registry";
|
import { CatalogEntityRegistry } from "../../../renderer/api/catalog-entity-registry";
|
||||||
import { CatalogEntityDetailRegistry } from "../../../extensions/registries";
|
import { CatalogEntityDetailRegistry } from "../../../extensions/registries";
|
||||||
import { CatalogEntityItem } from "./catalog-entity-item";
|
import { CatalogEntityItem } from "./catalog-entity-item";
|
||||||
@ -46,6 +46,18 @@ jest.mock("@electron/remote", () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
class MockCatalogEntity extends CatalogEntity {
|
||||||
|
public apiVersion = "api";
|
||||||
|
public kind = "kind";
|
||||||
|
|
||||||
|
constructor(data: CatalogEntityData, public onRun: (context: CatalogEntityActionContext) => void | Promise<void>) {
|
||||||
|
super(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public onContextMenuOpen(): void | Promise<void> {}
|
||||||
|
public onSettingsOpen(): void | Promise<void> {}
|
||||||
|
}
|
||||||
|
|
||||||
describe("<Catalog />", () => {
|
describe("<Catalog />", () => {
|
||||||
const history = createMemoryHistory();
|
const history = createMemoryHistory();
|
||||||
const mockLocation = {
|
const mockLocation = {
|
||||||
@ -66,13 +78,10 @@ describe("<Catalog />", () => {
|
|||||||
url: "",
|
url: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
const catalogEntityUid = "a_catalogEntity_uid";
|
function createMockCatalogEntity(onRun: (context: CatalogEntityActionContext) => void | Promise<void>) {
|
||||||
const catalogEntity = {
|
return new MockCatalogEntity({
|
||||||
enabled: true,
|
|
||||||
apiVersion: "api",
|
|
||||||
kind: "kind",
|
|
||||||
metadata: {
|
metadata: {
|
||||||
uid: catalogEntityUid,
|
uid: "a_catalogEntity_uid",
|
||||||
name: "a catalog entity",
|
name: "a catalog entity",
|
||||||
labels: {
|
labels: {
|
||||||
test: "label",
|
test: "label",
|
||||||
@ -82,14 +91,8 @@ describe("<Catalog />", () => {
|
|||||||
phase: "",
|
phase: "",
|
||||||
},
|
},
|
||||||
spec: {},
|
spec: {},
|
||||||
};
|
}, onRun);
|
||||||
const catalogEntityItemMethods = {
|
}
|
||||||
getId: () => catalogEntity.metadata.uid,
|
|
||||||
getName: () => catalogEntity.metadata.name,
|
|
||||||
onContextMenuOpen: () => {},
|
|
||||||
onSettingsOpen: () => {},
|
|
||||||
onRun: () => {},
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
CatalogEntityDetailRegistry.createInstance();
|
CatalogEntityDetailRegistry.createInstance();
|
||||||
@ -117,11 +120,7 @@ describe("<Catalog />", () => {
|
|||||||
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
||||||
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
||||||
const onRun = jest.fn();
|
const onRun = jest.fn();
|
||||||
const catalogEntityItem = new CatalogEntityItem({
|
const catalogEntityItem = new CatalogEntityItem(createMockCatalogEntity(onRun), catalogEntityRegistry);
|
||||||
...catalogEntity,
|
|
||||||
...catalogEntityItemMethods,
|
|
||||||
onRun,
|
|
||||||
}, catalogEntityRegistry);
|
|
||||||
|
|
||||||
// mock as if there is a selected item > the detail panel opens
|
// mock as if there is a selected item > the detail panel opens
|
||||||
jest
|
jest
|
||||||
@ -130,29 +129,8 @@ describe("<Catalog />", () => {
|
|||||||
|
|
||||||
catalogEntityRegistry.addOnBeforeRun(
|
catalogEntityRegistry.addOnBeforeRun(
|
||||||
(event) => {
|
(event) => {
|
||||||
expect(event.target).toMatchInlineSnapshot(`
|
expect(event.target.getId()).toBe("a_catalogEntity_uid");
|
||||||
Object {
|
expect(event.target.getName()).toBe("a catalog entity");
|
||||||
"apiVersion": "api",
|
|
||||||
"enabled": true,
|
|
||||||
"getId": [Function],
|
|
||||||
"getName": [Function],
|
|
||||||
"kind": "kind",
|
|
||||||
"metadata": Object {
|
|
||||||
"labels": Object {
|
|
||||||
"test": "label",
|
|
||||||
},
|
|
||||||
"name": "a catalog entity",
|
|
||||||
"uid": "a_catalogEntity_uid",
|
|
||||||
},
|
|
||||||
"onContextMenuOpen": [Function],
|
|
||||||
"onRun": [MockFunction],
|
|
||||||
"onSettingsOpen": [Function],
|
|
||||||
"spec": Object {},
|
|
||||||
"status": Object {
|
|
||||||
"phase": "",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(onRun).toHaveBeenCalled();
|
expect(onRun).toHaveBeenCalled();
|
||||||
@ -178,11 +156,7 @@ describe("<Catalog />", () => {
|
|||||||
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
||||||
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
||||||
const onRun = jest.fn();
|
const onRun = jest.fn();
|
||||||
const catalogEntityItem = new CatalogEntityItem({
|
const catalogEntityItem = new CatalogEntityItem(createMockCatalogEntity(onRun), catalogEntityRegistry);
|
||||||
...catalogEntity,
|
|
||||||
...catalogEntityItemMethods,
|
|
||||||
onRun,
|
|
||||||
}, catalogEntityRegistry);
|
|
||||||
|
|
||||||
// mock as if there is a selected item > the detail panel opens
|
// mock as if there is a selected item > the detail panel opens
|
||||||
jest
|
jest
|
||||||
@ -216,11 +190,7 @@ describe("<Catalog />", () => {
|
|||||||
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
||||||
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
||||||
const onRun = jest.fn();
|
const onRun = jest.fn();
|
||||||
const catalogEntityItem = new CatalogEntityItem({
|
const catalogEntityItem = new CatalogEntityItem(createMockCatalogEntity(onRun), catalogEntityRegistry);
|
||||||
...catalogEntity,
|
|
||||||
...catalogEntityItemMethods,
|
|
||||||
onRun,
|
|
||||||
}, catalogEntityRegistry);
|
|
||||||
|
|
||||||
// mock as if there is a selected item > the detail panel opens
|
// mock as if there is a selected item > the detail panel opens
|
||||||
jest
|
jest
|
||||||
@ -255,11 +225,7 @@ describe("<Catalog />", () => {
|
|||||||
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
||||||
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
||||||
const onRun = jest.fn(() => done());
|
const onRun = jest.fn(() => done());
|
||||||
const catalogEntityItem = new CatalogEntityItem({
|
const catalogEntityItem = new CatalogEntityItem(createMockCatalogEntity(onRun), catalogEntityRegistry);
|
||||||
...catalogEntity,
|
|
||||||
...catalogEntityItemMethods,
|
|
||||||
onRun,
|
|
||||||
}, catalogEntityRegistry);
|
|
||||||
|
|
||||||
// mock as if there is a selected item > the detail panel opens
|
// mock as if there is a selected item > the detail panel opens
|
||||||
jest
|
jest
|
||||||
@ -289,11 +255,7 @@ describe("<Catalog />", () => {
|
|||||||
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
||||||
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
||||||
const onRun = jest.fn();
|
const onRun = jest.fn();
|
||||||
const catalogEntityItem = new CatalogEntityItem({
|
const catalogEntityItem = new CatalogEntityItem(createMockCatalogEntity(onRun), catalogEntityRegistry);
|
||||||
...catalogEntity,
|
|
||||||
...catalogEntityItemMethods,
|
|
||||||
onRun,
|
|
||||||
}, catalogEntityRegistry);
|
|
||||||
|
|
||||||
// mock as if there is a selected item > the detail panel opens
|
// mock as if there is a selected item > the detail panel opens
|
||||||
jest
|
jest
|
||||||
@ -330,11 +292,7 @@ describe("<Catalog />", () => {
|
|||||||
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);
|
||||||
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
const catalogEntityStore = new CatalogEntityStore(catalogEntityRegistry);
|
||||||
const onRun = jest.fn();
|
const onRun = jest.fn();
|
||||||
const catalogEntityItem = new CatalogEntityItem({
|
const catalogEntityItem = new CatalogEntityItem(createMockCatalogEntity(onRun), catalogEntityRegistry);
|
||||||
...catalogEntity,
|
|
||||||
...catalogEntityItemMethods,
|
|
||||||
onRun,
|
|
||||||
}, catalogEntityRegistry);
|
|
||||||
|
|
||||||
// mock as if there is a selected item > the detail panel opens
|
// mock as if there is a selected item > the detail panel opens
|
||||||
jest
|
jest
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import { Table, TableCell, TableHead, TableRow } from "../table";
|
|||||||
import { apiManager } from "../../../common/k8s-api/api-manager";
|
import { apiManager } from "../../../common/k8s-api/api-manager";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
export interface HpaDetailsProps extends KubeObjectDetailsProps<HorizontalPodAutoscaler> {
|
export interface HpaDetailsProps extends KubeObjectDetailsProps<HorizontalPodAutoscaler> {
|
||||||
}
|
}
|
||||||
@ -80,17 +81,13 @@ export class HpaDetails extends React.Component<HpaDetailsProps> {
|
|||||||
<TableCell className="metrics">Current / Target</TableCell>
|
<TableCell className="metrics">Current / Target</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{
|
{
|
||||||
hpa.getMetrics().map((metric, index) => {
|
hpa.getMetrics()
|
||||||
const name = renderName(metric);
|
.map((metric, index) => (
|
||||||
const values = hpa.getMetricValues(metric);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TableRow key={index}>
|
<TableRow key={index}>
|
||||||
<TableCell className="name">{name}</TableCell>
|
<TableCell className="name">{renderName(metric)}</TableCell>
|
||||||
<TableCell className="metrics">{values}</TableCell>
|
<TableCell className="metrics">{hpa.getMetricValues(metric)}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
</Table>
|
</Table>
|
||||||
);
|
);
|
||||||
@ -99,7 +96,16 @@ export class HpaDetails extends React.Component<HpaDetailsProps> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: hpa } = this.props;
|
const { object: hpa } = this.props;
|
||||||
|
|
||||||
if (!hpa) return null;
|
if (!hpa) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(hpa instanceof HorizontalPodAutoscaler)) {
|
||||||
|
logger.error("[HpaDetails]: passed object that is not an instanceof HorizontalPodAutoscaler", hpa);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { scaleTargetRef } = hpa.spec;
|
const { scaleTargetRef } = hpa.spec;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import { LimitPart, LimitRange, LimitRangeItem, Resource } from "../../../common
|
|||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
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";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<LimitRange> {
|
interface Props extends KubeObjectDetailsProps<LimitRange> {
|
||||||
}
|
}
|
||||||
@ -57,15 +58,13 @@ function renderResourceLimits(limit: LimitRangeItem, resource: Resource) {
|
|||||||
|
|
||||||
function renderLimitDetails(limits: LimitRangeItem[], resources: Resource[]) {
|
function renderLimitDetails(limits: LimitRangeItem[], resources: Resource[]) {
|
||||||
|
|
||||||
return resources.map(resource =>
|
return resources.map(resource => (
|
||||||
<DrawerItem key={resource} name={resource}>
|
<DrawerItem key={resource} name={resource}>
|
||||||
{
|
{
|
||||||
limits.map(limit =>
|
limits.map(limit => renderResourceLimits(limit, resource))
|
||||||
renderResourceLimits(limit, resource)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
@ -73,7 +72,16 @@ export class LimitRangeDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: limitRange } = this.props;
|
const { object: limitRange } = this.props;
|
||||||
|
|
||||||
if (!limitRange) return null;
|
if (!limitRange) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(limitRange instanceof LimitRange)) {
|
||||||
|
logger.error("[LimitRangeDetails]: passed object that is not an instanceof LimitRange", limitRange);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const containerLimits = limitRange.getContainerLimits();
|
const containerLimits = limitRange.getContainerLimits();
|
||||||
const podLimits = limitRange.getPodLimits();
|
const podLimits = limitRange.getPodLimits();
|
||||||
const pvcLimits = limitRange.getPVCLimits();
|
const pvcLimits = limitRange.getPVCLimits();
|
||||||
|
|||||||
@ -30,8 +30,9 @@ import { Input } from "../input";
|
|||||||
import { Button } from "../button";
|
import { Button } from "../button";
|
||||||
import { configMapsStore } from "./config-maps.store";
|
import { configMapsStore } from "./config-maps.store";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import type { ConfigMap } from "../../../common/k8s-api/endpoints";
|
import { ConfigMap } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<ConfigMap> {
|
interface Props extends KubeObjectDetailsProps<ConfigMap> {
|
||||||
}
|
}
|
||||||
@ -82,7 +83,16 @@ export class ConfigMapDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: configMap } = this.props;
|
const { object: configMap } = this.props;
|
||||||
|
|
||||||
if (!configMap) return null;
|
if (!configMap) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(configMap instanceof ConfigMap)) {
|
||||||
|
logger.error("[ConfigMapDetails]: passed object that is not an instanceof ConfigMap", configMap);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const data = Array.from(this.data.entries());
|
const data = Array.from(this.data.entries());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -93,8 +103,7 @@ export class ConfigMapDetails extends React.Component<Props> {
|
|||||||
<>
|
<>
|
||||||
<DrawerTitle title="Data"/>
|
<DrawerTitle title="Data"/>
|
||||||
{
|
{
|
||||||
data.map(([name, value]) => {
|
data.map(([name, value]) => (
|
||||||
return (
|
|
||||||
<div key={name} className="data">
|
<div key={name} className="data">
|
||||||
<div className="name">{name}</div>
|
<div className="name">{name}</div>
|
||||||
<div className="flex gaps align-flex-start">
|
<div className="flex gaps align-flex-start">
|
||||||
@ -107,8 +116,7 @@ export class ConfigMapDetails extends React.Component<Props> {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
<Button
|
<Button
|
||||||
primary
|
primary
|
||||||
|
|||||||
@ -26,8 +26,9 @@ import { observer } from "mobx-react";
|
|||||||
import { DrawerItem } from "../drawer";
|
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 type { PodDisruptionBudget } from "../../../common/k8s-api/endpoints";
|
import { PodDisruptionBudget } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<PodDisruptionBudget> {
|
interface Props extends KubeObjectDetailsProps<PodDisruptionBudget> {
|
||||||
}
|
}
|
||||||
@ -38,7 +39,16 @@ export class PodDisruptionBudgetDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: pdb } = this.props;
|
const { object: pdb } = this.props;
|
||||||
|
|
||||||
if (!pdb) return null;
|
if (!pdb) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pdb instanceof PodDisruptionBudget)) {
|
||||||
|
logger.error("[PodDisruptionBudgetDetails]: passed object that is not an instanceof PodDisruptionBudget", pdb);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const selectors = pdb.getSelectors();
|
const selectors = pdb.getSelectors();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -26,10 +26,11 @@ import { observer } from "mobx-react";
|
|||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { cpuUnitsToNumber, cssNames, unitsToBytes, metricUnitsToNumber } from "../../utils";
|
import { cpuUnitsToNumber, cssNames, unitsToBytes, metricUnitsToNumber } from "../../utils";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import type { 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 { KubeObjectMeta } from "../kube-object-meta";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<ResourceQuota> {
|
interface Props extends KubeObjectDetailsProps<ResourceQuota> {
|
||||||
}
|
}
|
||||||
@ -77,7 +78,15 @@ export class ResourceQuotaDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: quota } = this.props;
|
const { object: quota } = this.props;
|
||||||
|
|
||||||
if (!quota) return null;
|
if (!quota) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(quota instanceof ResourceQuota)) {
|
||||||
|
logger.error("[ResourceQuotaDetails]: passed object that is not an instanceof ResourceQuota", quota);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ResourceQuotaDetails">
|
<div className="ResourceQuotaDetails">
|
||||||
|
|||||||
@ -33,8 +33,9 @@ import { base64 } from "../../utils";
|
|||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { secretsStore } from "./secrets.store";
|
import { secretsStore } from "./secrets.store";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import type { Secret } from "../../../common/k8s-api/endpoints";
|
import { Secret } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Secret> {
|
interface Props extends KubeObjectDetailsProps<Secret> {
|
||||||
}
|
}
|
||||||
@ -84,7 +85,15 @@ export class SecretDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: secret } = this.props;
|
const { object: secret } = this.props;
|
||||||
|
|
||||||
if (!secret) return null;
|
if (!secret) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(secret instanceof Secret)) {
|
||||||
|
logger.error("[SecretDetails]: passed object that is not an instanceof Secret", secret);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="SecretDetails">
|
<div className="SecretDetails">
|
||||||
|
|||||||
@ -24,7 +24,7 @@ import "./crd-details.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import type { CustomResourceDefinition } from "../../../common/k8s-api/endpoints/crd.api";
|
import { CustomResourceDefinition } from "../../../common/k8s-api/endpoints/crd.api";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
import { ThemeStore } from "../../theme.store";
|
import { ThemeStore } from "../../theme.store";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
@ -35,6 +35,7 @@ import { Input } from "../input";
|
|||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
import MonacoEditor from "react-monaco-editor";
|
import MonacoEditor from "react-monaco-editor";
|
||||||
import { UserStore } from "../../../common/user-store";
|
import { UserStore } from "../../../common/user-store";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<CustomResourceDefinition> {
|
interface Props extends KubeObjectDetailsProps<CustomResourceDefinition> {
|
||||||
}
|
}
|
||||||
@ -44,7 +45,16 @@ export class CRDDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: crd } = this.props;
|
const { object: crd } = this.props;
|
||||||
|
|
||||||
if (!crd) return null;
|
if (!crd) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(crd instanceof CustomResourceDefinition)) {
|
||||||
|
logger.error("[CRDDetails]: passed object that is not an instanceof CustomResourceDefinition", crd);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { plural, singular, kind, listKind } = crd.getNames();
|
const { plural, singular, kind, listKind } = crd.getNames();
|
||||||
const printerColumns = crd.getPrinterColumns();
|
const printerColumns = crd.getPrinterColumns();
|
||||||
const validation = crd.getValidation();
|
const validation = crd.getValidation();
|
||||||
|
|||||||
@ -30,9 +30,10 @@ 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 { KubeObjectMeta } from "../kube-object-meta";
|
||||||
import { Input } from "../input";
|
import { Input } from "../input";
|
||||||
import type { AdditionalPrinterColumnsV1, CustomResourceDefinition } from "../../../common/k8s-api/endpoints/crd.api";
|
import { AdditionalPrinterColumnsV1, CustomResourceDefinition } from "../../../common/k8s-api/endpoints/crd.api";
|
||||||
import { parseJsonPath } from "../../utils/jsonPath";
|
import { parseJsonPath } from "../../utils/jsonPath";
|
||||||
import type { KubeObject, KubeObjectMetadata, KubeObjectStatus } from "../../../common/k8s-api/kube-object";
|
import { KubeObject, KubeObjectMetadata, KubeObjectStatus } from "../../../common/k8s-api/kube-object";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<KubeObject> {
|
interface Props extends KubeObjectDetailsProps<KubeObject> {
|
||||||
crd: CustomResourceDefinition;
|
crd: CustomResourceDefinition;
|
||||||
@ -101,6 +102,18 @@ export class CrdResourceDetails extends React.Component<Props> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(object instanceof KubeObject)) {
|
||||||
|
logger.error("[CrdResourceDetails]: passed object that is not an instanceof KubeObject", object);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(crd instanceof CustomResourceDefinition)) {
|
||||||
|
logger.error("[CrdResourceDetails]: passed crd that is not an instanceof CustomResourceDefinition", crd);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const extraColumns = crd.getPrinterColumns();
|
const extraColumns = crd.getPrinterColumns();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -27,12 +27,13 @@ import { DrawerItem, DrawerTitle } from "../drawer";
|
|||||||
import { Link } from "react-router-dom";
|
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 type { KubeEvent } from "../../../common/k8s-api/endpoints/events.api";
|
import { KubeEvent } from "../../../common/k8s-api/endpoints/events.api";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import { LocaleDate } from "../locale-date";
|
import { LocaleDate } from "../locale-date";
|
||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
import { apiManager } from "../../../common/k8s-api/api-manager";
|
import { apiManager } from "../../../common/k8s-api/api-manager";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<KubeEvent> {
|
interface Props extends KubeObjectDetailsProps<KubeEvent> {
|
||||||
}
|
}
|
||||||
@ -42,7 +43,16 @@ export class EventDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: event } = this.props;
|
const { object: event } = this.props;
|
||||||
|
|
||||||
if (!event) return null;
|
if (!event) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(event instanceof KubeEvent)) {
|
||||||
|
logger.error("[EventDetails]: passed object that is not an instanceof KubeEvent", event);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { message, reason, count, type, involvedObject } = event;
|
const { message, reason, count, type, involvedObject } = event;
|
||||||
const { kind, name, namespace, fieldPath } = involvedObject;
|
const { kind, name, namespace, fieldPath } = involvedObject;
|
||||||
|
|
||||||
|
|||||||
@ -23,11 +23,12 @@ import "./kube-event-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
import { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
import { LocaleDate } from "../locale-date";
|
import { LocaleDate } from "../locale-date";
|
||||||
import { eventStore } from "./event.store";
|
import { eventStore } from "./event.store";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
export interface KubeEventDetailsProps {
|
export interface KubeEventDetailsProps {
|
||||||
object: KubeObject;
|
object: KubeObject;
|
||||||
@ -41,6 +42,17 @@ export class KubeEventDetails extends React.Component<KubeEventDetailsProps> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object } = this.props;
|
const { object } = this.props;
|
||||||
|
|
||||||
|
if (!object) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(object instanceof KubeObject)) {
|
||||||
|
logger.error("[KubeEventDetails]: passed object that is not an instanceof KubeObject", object);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const events = eventStore.getEventsByObject(object);
|
const events = eventStore.getEventsByObject(object);
|
||||||
|
|
||||||
if (!events.length) {
|
if (!events.length) {
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
|||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Namespace> {
|
interface Props extends KubeObjectDetailsProps<Namespace> {
|
||||||
}
|
}
|
||||||
@ -81,7 +82,16 @@ export class NamespaceDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: namespace } = this.props;
|
const { object: namespace } = this.props;
|
||||||
|
|
||||||
if (!namespace) return null;
|
if (!namespace) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(namespace instanceof Namespace)) {
|
||||||
|
logger.error("[NamespaceDetails]: passed object that is not an instanceof Namespace", namespace);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const status = namespace.getStatus();
|
const status = namespace.getStatus();
|
||||||
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.Namespace);
|
const isMetricHidden = getActiveClusterEntity()?.isMetricHidden(ClusterMetricsResourceType.Namespace);
|
||||||
|
|
||||||
|
|||||||
@ -25,9 +25,10 @@ import React from "react";
|
|||||||
import { observer } from "mobx-react";
|
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 type { Endpoint } from "../../../common/k8s-api/endpoints";
|
import { Endpoint } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
import { EndpointSubsetList } from "./endpoint-subset-list";
|
import { EndpointSubsetList } from "./endpoint-subset-list";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Endpoint> {
|
interface Props extends KubeObjectDetailsProps<Endpoint> {
|
||||||
}
|
}
|
||||||
@ -37,7 +38,15 @@ export class EndpointDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: endpoint } = this.props;
|
const { object: endpoint } = this.props;
|
||||||
|
|
||||||
if (!endpoint) return null;
|
if (!endpoint) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(endpoint instanceof Endpoint)) {
|
||||||
|
logger.error("[EndpointDetails]: passed object that is not an instanceof Endpoint", endpoint);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="EndpointDetails">
|
<div className="EndpointDetails">
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import React from "react";
|
|||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { makeObservable, observable, reaction } from "mobx";
|
import { makeObservable, observable, reaction } from "mobx";
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import type { ILoadBalancerIngress, Ingress } from "../../../common/k8s-api/endpoints";
|
import { ILoadBalancerIngress, 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 { ResourceMetrics } from "../resource-metrics";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
@ -35,6 +35,7 @@ import { getBackendServiceNamePort, getMetricsForIngress, IIngressMetrics } from
|
|||||||
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
import { boundMethod } from "../../utils";
|
import { boundMethod } from "../../utils";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Ingress> {
|
interface Props extends KubeObjectDetailsProps<Ingress> {
|
||||||
}
|
}
|
||||||
@ -132,6 +133,12 @@ export class IngressDetails extends React.Component<Props> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(ingress instanceof Ingress)) {
|
||||||
|
logger.error("[IngressDetails]: passed object that is not an instanceof Ingress", ingress);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { spec, status } = ingress;
|
const { spec, status } = ingress;
|
||||||
const ingressPoints = status?.loadBalancer?.ingress;
|
const ingressPoints = status?.loadBalancer?.ingress;
|
||||||
const { metrics } = this;
|
const { metrics } = this;
|
||||||
|
|||||||
@ -24,12 +24,13 @@ import "./network-policy-details.scss";
|
|||||||
import get from "lodash/get";
|
import get from "lodash/get";
|
||||||
import React, { Fragment } from "react";
|
import React, { Fragment } from "react";
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import type { IPolicyEgress, IPolicyIngress, IPolicyIpBlock, IPolicySelector, NetworkPolicy } from "../../../common/k8s-api/endpoints/network-policy.api";
|
import { IPolicyEgress, IPolicyIngress, IPolicyIpBlock, IPolicySelector, NetworkPolicy } from "../../../common/k8s-api/endpoints/network-policy.api";
|
||||||
import { Badge } from "../badge";
|
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 { KubeObjectMeta } from "../kube-object-meta";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<NetworkPolicy> {
|
interface Props extends KubeObjectDetailsProps<NetworkPolicy> {
|
||||||
}
|
}
|
||||||
@ -117,6 +118,13 @@ export class NetworkPolicyDetails extends React.Component<Props> {
|
|||||||
if (!policy) {
|
if (!policy) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(policy instanceof NetworkPolicy)) {
|
||||||
|
logger.error("[NetworkPolicyDetails]: passed object that is not an instanceof NetworkPolicy", policy);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { ingress, egress } = policy.spec;
|
const { ingress, egress } = policy.spec;
|
||||||
const selector = policy.getMatchLabels();
|
const selector = policy.getMatchLabels();
|
||||||
|
|
||||||
|
|||||||
@ -26,13 +26,14 @@ 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 type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import type { Service } from "../../../common/k8s-api/endpoints";
|
import { Service } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
import { ServicePortComponent } from "./service-port-component";
|
import { ServicePortComponent } from "./service-port-component";
|
||||||
import { endpointStore } from "../+network-endpoints/endpoints.store";
|
import { endpointStore } from "../+network-endpoints/endpoints.store";
|
||||||
import { ServiceDetailsEndpoint } from "./service-details-endpoint";
|
import { ServiceDetailsEndpoint } from "./service-details-endpoint";
|
||||||
import { kubeWatchApi } from "../../../common/k8s-api/kube-watch-api";
|
import { kubeWatchApi } from "../../../common/k8s-api/kube-watch-api";
|
||||||
import { portForwardStore } from "../../port-forward";
|
import { portForwardStore } from "../../port-forward";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Service> {
|
interface Props extends KubeObjectDetailsProps<Service> {
|
||||||
}
|
}
|
||||||
@ -54,7 +55,16 @@ export class ServiceDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: service } = this.props;
|
const { object: service } = this.props;
|
||||||
|
|
||||||
if (!service) return null;
|
if (!service) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(service instanceof Service)) {
|
||||||
|
logger.error("[ServiceDetails]: passed object that is not an instanceof Service", service);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { spec } = service;
|
const { spec } = service;
|
||||||
const endpoint = endpointStore.getByName(service.getName(), service.getNs());
|
const endpoint = endpointStore.getByName(service.getName(), service.getNs());
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
|||||||
import { NodeDetailsResources } from "./node-details-resources";
|
import { NodeDetailsResources } from "./node-details-resources";
|
||||||
import { DrawerTitle } from "../drawer/drawer-title";
|
import { DrawerTitle } from "../drawer/drawer-title";
|
||||||
import { boundMethod } from "../../utils";
|
import { boundMethod } from "../../utils";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Node> {
|
interface Props extends KubeObjectDetailsProps<Node> {
|
||||||
}
|
}
|
||||||
@ -72,7 +73,16 @@ export class NodeDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: node } = this.props;
|
const { object: node } = this.props;
|
||||||
|
|
||||||
if (!node) return null;
|
if (!node) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(node instanceof Node)) {
|
||||||
|
logger.error("[NodeDetails]: passed object that is not an instanceof Node", node);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { status } = node;
|
const { status } = node;
|
||||||
const { nodeInfo, addresses } = status;
|
const { nodeInfo, addresses } = status;
|
||||||
const conditions = node.getActiveConditions();
|
const conditions = node.getActiveConditions();
|
||||||
|
|||||||
@ -25,22 +25,26 @@ import React from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import type { 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 { KubeObjectMeta } from "../kube-object-meta";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<PodSecurityPolicy> {
|
interface Props extends KubeObjectDetailsProps<PodSecurityPolicy> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface RuleGroup {
|
||||||
|
rule: string;
|
||||||
|
ranges?: {
|
||||||
|
max: number;
|
||||||
|
min: number;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class PodSecurityPolicyDetails extends React.Component<Props> {
|
export class PodSecurityPolicyDetails extends React.Component<Props> {
|
||||||
renderRuleGroup(
|
renderRuleGroup( title: React.ReactNode, group: RuleGroup) {
|
||||||
title: React.ReactNode,
|
|
||||||
group: {
|
|
||||||
rule: string;
|
|
||||||
ranges?: { max: number; min: number }[];
|
|
||||||
}) {
|
|
||||||
if (!group) return null;
|
if (!group) return null;
|
||||||
const { rule, ranges } = group;
|
const { rule, ranges } = group;
|
||||||
|
|
||||||
@ -67,6 +71,13 @@ export class PodSecurityPolicyDetails extends React.Component<Props> {
|
|||||||
if (!psp) {
|
if (!psp) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(psp instanceof PodSecurityPolicy)) {
|
||||||
|
logger.error("[PodSecurityPolicyDetails]: passed object that is not an instanceof PodSecurityPolicy", psp);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
allowedHostPaths, allowedCapabilities, allowedCSIDrivers, allowedFlexVolumes, allowedProcMountTypes,
|
allowedHostPaths, allowedCapabilities, allowedCSIDrivers, allowedFlexVolumes, allowedProcMountTypes,
|
||||||
allowedUnsafeSysctls, allowPrivilegeEscalation, defaultAddCapabilities, forbiddenSysctls, fsGroup,
|
allowedUnsafeSysctls, allowPrivilegeEscalation, defaultAddCapabilities, forbiddenSysctls, fsGroup,
|
||||||
@ -172,14 +183,14 @@ export class PodSecurityPolicyDetails extends React.Component<Props> {
|
|||||||
<TableCell>Path Prefix</TableCell>
|
<TableCell>Path Prefix</TableCell>
|
||||||
<TableCell>Read-only</TableCell>
|
<TableCell>Read-only</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{allowedHostPaths.map(({ pathPrefix, readOnly }, index) => {
|
{
|
||||||
return (
|
allowedHostPaths.map(({ pathPrefix, readOnly }, index) => (
|
||||||
<TableRow key={index}>
|
<TableRow key={index}>
|
||||||
<TableCell>{pathPrefix}</TableCell>
|
<TableCell>{pathPrefix}</TableCell>
|
||||||
<TableCell>{readOnly ? "Yes" : "No"}</TableCell>
|
<TableCell>{readOnly ? "Yes" : "No"}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
))
|
||||||
})}
|
}
|
||||||
</Table>
|
</Table>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -193,7 +204,7 @@ export class PodSecurityPolicyDetails extends React.Component<Props> {
|
|||||||
<>
|
<>
|
||||||
<DrawerTitle title="Runtime Class"/>
|
<DrawerTitle title="Runtime Class"/>
|
||||||
<DrawerItem name="Allowed Runtime Class Names">
|
<DrawerItem name="Allowed Runtime Class Names">
|
||||||
{(runtimeClass.allowedRuntimeClassNames || []).join(", ") || "-"}
|
{runtimeClass.allowedRuntimeClassNames?.join(", ") || "-"}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name="Default Runtime Class Name">
|
<DrawerItem name="Default Runtime Class Name">
|
||||||
{runtimeClass.defaultRuntimeClassName || "-"}
|
{runtimeClass.defaultRuntimeClassName || "-"}
|
||||||
|
|||||||
@ -27,11 +27,12 @@ import { DrawerItem, DrawerTitle } from "../drawer";
|
|||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
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 type { StorageClass } from "../../../common/k8s-api/endpoints";
|
import { StorageClass } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
import { storageClassStore } from "./storage-class.store";
|
import { storageClassStore } from "./storage-class.store";
|
||||||
import { VolumeDetailsList } from "../+storage-volumes/volume-details-list";
|
import { VolumeDetailsList } from "../+storage-volumes/volume-details-list";
|
||||||
import { volumesStore } from "../+storage-volumes/volumes.store";
|
import { volumesStore } from "../+storage-volumes/volumes.store";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<StorageClass> {
|
interface Props extends KubeObjectDetailsProps<StorageClass> {
|
||||||
}
|
}
|
||||||
@ -44,9 +45,18 @@ export class StorageClassDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: storageClass } = this.props;
|
const { object: storageClass } = this.props;
|
||||||
const persistentVolumes = storageClassStore.getPersistentVolumes(storageClass);
|
|
||||||
|
|
||||||
if (!storageClass) return null;
|
if (!storageClass) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(storageClass instanceof StorageClass)) {
|
||||||
|
logger.error("[StorageClassDetails]: passed object that is not an instanceof StorageClass", storageClass);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const persistentVolumes = storageClassStore.getPersistentVolumes(storageClass);
|
||||||
const { provisioner, parameters, mountOptions } = storageClass;
|
const { provisioner, parameters, mountOptions } = storageClass;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
|||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
import { boundMethod } from "../../utils";
|
import { boundMethod } from "../../utils";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<PersistentVolumeClaim> {
|
interface Props extends KubeObjectDetailsProps<PersistentVolumeClaim> {
|
||||||
}
|
}
|
||||||
@ -68,6 +69,13 @@ export class PersistentVolumeClaimDetails extends React.Component<Props> {
|
|||||||
if (!volumeClaim) {
|
if (!volumeClaim) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(volumeClaim instanceof PersistentVolumeClaim)) {
|
||||||
|
logger.error("[PersistentVolumeClaimDetails]: passed object that is not an instanceof PersistentVolumeClaim", volumeClaim);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { storageClassName, accessModes } = volumeClaim.spec;
|
const { storageClassName, accessModes } = volumeClaim.spec;
|
||||||
const { metrics } = this;
|
const { metrics } = this;
|
||||||
const pods = volumeClaim.getPods(podsStore.items);
|
const pods = volumeClaim.getPods(podsStore.items);
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import { PersistentVolume, pvcApi } 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 { KubeObjectMeta } from "../kube-object-meta";
|
||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<PersistentVolume> {
|
interface Props extends KubeObjectDetailsProps<PersistentVolume> {
|
||||||
}
|
}
|
||||||
@ -43,6 +44,13 @@ export class PersistentVolumeDetails extends React.Component<Props> {
|
|||||||
if (!volume) {
|
if (!volume) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(volume instanceof PersistentVolume)) {
|
||||||
|
logger.error("[PersistentVolumeDetails]: passed object that is not an instanceof PersistentVolume", volume);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { accessModes, capacity, persistentVolumeReclaimPolicy, storageClassName, claimRef, flexVolume, mountOptions, nfs } = volume.spec;
|
const { accessModes, capacity, persistentVolumeReclaimPolicy, storageClassName, claimRef, flexVolume, mountOptions, nfs } = volume.spec;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -31,8 +31,9 @@ import { Link } from "react-router-dom";
|
|||||||
import { cronJobStore } from "./cronjob.store";
|
import { cronJobStore } from "./cronjob.store";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
import type { CronJob, Job } from "../../../common/k8s-api/endpoints";
|
import { CronJob, Job } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<CronJob> {
|
interface Props extends KubeObjectDetailsProps<CronJob> {
|
||||||
}
|
}
|
||||||
@ -46,18 +47,27 @@ export class CronJobDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: cronJob } = this.props;
|
const { object: cronJob } = this.props;
|
||||||
|
|
||||||
if (!cronJob) return null;
|
if (!cronJob) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cronJob instanceof CronJob)) {
|
||||||
|
logger.error("[CronJobDetails]: passed object that is not an instanceof CronJob", cronJob);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const childJobs = jobStore.getJobsByOwner(cronJob);
|
const childJobs = jobStore.getJobsByOwner(cronJob);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="CronJobDetails">
|
<div className="CronJobDetails">
|
||||||
<KubeObjectMeta object={cronJob}/>
|
<KubeObjectMeta object={cronJob}/>
|
||||||
<DrawerItem name="Schedule">
|
<DrawerItem name="Schedule">
|
||||||
{cronJob.isNeverRun() ? (
|
{
|
||||||
<>
|
cronJob.isNeverRun()
|
||||||
never ({cronJob.getSchedule()})
|
? `never (${cronJob.getSchedule()})`
|
||||||
</>
|
: cronJob.getSchedule()
|
||||||
) : cronJob.getSchedule()}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name="Active">
|
<DrawerItem name="Active">
|
||||||
{cronJobStore.getActiveJobsNum(cronJob)}
|
{cronJobStore.getActiveJobsNum(cronJob)}
|
||||||
|
|||||||
@ -40,6 +40,7 @@ import { KubeObjectMeta } from "../kube-object-meta";
|
|||||||
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
import { boundMethod } from "../../utils";
|
import { boundMethod } from "../../utils";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<DaemonSet> {
|
interface Props extends KubeObjectDetailsProps<DaemonSet> {
|
||||||
}
|
}
|
||||||
@ -72,7 +73,16 @@ export class DaemonSetDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: daemonSet } = this.props;
|
const { object: daemonSet } = this.props;
|
||||||
|
|
||||||
if (!daemonSet) return null;
|
if (!daemonSet) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(daemonSet instanceof DaemonSet)) {
|
||||||
|
logger.error("[DaemonSetDetails]: passed object that is not an instanceof DaemonSet", daemonSet);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { spec } = daemonSet;
|
const { spec } = daemonSet;
|
||||||
const selectors = daemonSet.getSelectors();
|
const selectors = daemonSet.getSelectors();
|
||||||
const images = daemonSet.getImages();
|
const images = daemonSet.getImages();
|
||||||
|
|||||||
@ -42,6 +42,7 @@ import { DeploymentReplicaSets } from "./deployment-replicasets";
|
|||||||
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
import { boundMethod } from "../../utils";
|
import { boundMethod } from "../../utils";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Deployment> {
|
interface Props extends KubeObjectDetailsProps<Deployment> {
|
||||||
}
|
}
|
||||||
@ -75,7 +76,16 @@ export class DeploymentDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: deployment } = this.props;
|
const { object: deployment } = this.props;
|
||||||
|
|
||||||
if (!deployment) return null;
|
if (!deployment) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(deployment instanceof Deployment)) {
|
||||||
|
logger.error("[DeploymentDetails]: passed object that is not an instanceof Deployment", deployment);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { status, spec } = deployment;
|
const { status, spec } = deployment;
|
||||||
const nodeSelector = deployment.getNodeSelectors();
|
const nodeSelector = deployment.getNodeSelectors();
|
||||||
const selectors = deployment.getSelectors();
|
const selectors = deployment.getSelectors();
|
||||||
|
|||||||
@ -44,6 +44,7 @@ import { ResourceMetrics } from "../resource-metrics";
|
|||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
import { apiManager } from "../../../common/k8s-api/api-manager";
|
import { apiManager } from "../../../common/k8s-api/api-manager";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Job> {
|
interface Props extends KubeObjectDetailsProps<Job> {
|
||||||
}
|
}
|
||||||
@ -71,7 +72,16 @@ export class JobDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: job } = this.props;
|
const { object: job } = this.props;
|
||||||
|
|
||||||
if (!job) return null;
|
if (!job) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(job instanceof Job)) {
|
||||||
|
logger.error("[JobDetails]: passed object that is not an instanceof Job", job);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const selectors = job.getSelectors();
|
const selectors = job.getSelectors();
|
||||||
const nodeSelector = job.getNodeSelectors();
|
const nodeSelector = job.getNodeSelectors();
|
||||||
const images = job.getImages();
|
const images = job.getImages();
|
||||||
|
|||||||
@ -43,6 +43,7 @@ import { KubeObjectMeta } from "../kube-object-meta";
|
|||||||
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Pod> {
|
interface Props extends KubeObjectDetailsProps<Pod> {
|
||||||
}
|
}
|
||||||
@ -77,7 +78,16 @@ export class PodDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: pod } = this.props;
|
const { object: pod } = this.props;
|
||||||
|
|
||||||
if (!pod) return null;
|
if (!pod) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pod instanceof Pod)) {
|
||||||
|
logger.error("[PodDetails]: passed object that is not an instanceof Pod", pod);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { status, spec } = pod;
|
const { status, spec } = pod;
|
||||||
const { conditions, podIP } = status;
|
const { conditions, podIP } = status;
|
||||||
const podIPs = pod.getIPs();
|
const podIPs = pod.getIPs();
|
||||||
|
|||||||
@ -39,6 +39,7 @@ import { KubeObjectMeta } from "../kube-object-meta";
|
|||||||
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
import { boundMethod } from "../../utils";
|
import { boundMethod } from "../../utils";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<ReplicaSet> {
|
interface Props extends KubeObjectDetailsProps<ReplicaSet> {
|
||||||
}
|
}
|
||||||
@ -71,7 +72,16 @@ export class ReplicaSetDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: replicaSet } = this.props;
|
const { object: replicaSet } = this.props;
|
||||||
|
|
||||||
if (!replicaSet) return null;
|
if (!replicaSet) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(replicaSet instanceof ReplicaSet)) {
|
||||||
|
logger.error("[ReplicaSetDetails]: passed object that is not an instanceof ReplicaSet", replicaSet);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { metrics } = this;
|
const { metrics } = this;
|
||||||
const { status } = replicaSet;
|
const { status } = replicaSet;
|
||||||
const { availableReplicas, replicas } = status;
|
const { availableReplicas, replicas } = status;
|
||||||
|
|||||||
@ -40,6 +40,7 @@ import { KubeObjectMeta } from "../kube-object-meta";
|
|||||||
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
import { getActiveClusterEntity } from "../../api/catalog-entity-registry";
|
||||||
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
import { ClusterMetricsResourceType } from "../../../common/cluster-types";
|
||||||
import { boundMethod } from "../../utils";
|
import { boundMethod } from "../../utils";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<StatefulSet> {
|
interface Props extends KubeObjectDetailsProps<StatefulSet> {
|
||||||
}
|
}
|
||||||
@ -72,7 +73,16 @@ export class StatefulSetDetails extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { object: statefulSet } = this.props;
|
const { object: statefulSet } = this.props;
|
||||||
|
|
||||||
if (!statefulSet) return null;
|
if (!statefulSet) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(statefulSet instanceof StatefulSet)) {
|
||||||
|
logger.error("[StatefulSetDetails]: passed object that is not an instanceof StatefulSet", statefulSet);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const images = statefulSet.getImages();
|
const images = statefulSet.getImages();
|
||||||
const selectors = statefulSet.getSelectors();
|
const selectors = statefulSet.getSelectors();
|
||||||
const nodeSelector = statefulSet.getNodeSelectors();
|
const nodeSelector = statefulSet.getNodeSelectors();
|
||||||
|
|||||||
@ -20,13 +20,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import type { KubeMetaField, KubeObject } from "../../../common/k8s-api/kube-object";
|
import { KubeMetaField, KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
import { DrawerItem, DrawerItemLabels } from "../drawer";
|
import { DrawerItem, DrawerItemLabels } from "../drawer";
|
||||||
import { apiManager } from "../../../common/k8s-api/api-manager";
|
import { apiManager } from "../../../common/k8s-api/api-manager";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||||
import { LocaleDate } from "../locale-date";
|
import { LocaleDate } from "../locale-date";
|
||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
export interface KubeObjectMetaProps {
|
export interface KubeObjectMetaProps {
|
||||||
object: KubeObject;
|
object: KubeObject;
|
||||||
@ -46,6 +47,17 @@ export class KubeObjectMeta extends React.Component<KubeObjectMetaProps> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object } = this.props;
|
const { object } = this.props;
|
||||||
|
|
||||||
|
if (!object) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(object instanceof KubeObject)) {
|
||||||
|
logger.error("[KubeObjectMeta]: passed object that is not an instanceof KubeObject", object);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getNs, getLabels, getResourceVersion, selfLink, getAnnotations,
|
getNs, getLabels, getResourceVersion, selfLink, getAnnotations,
|
||||||
getFinalizers, getId, getAge, getName, metadata: { creationTimestamp },
|
getFinalizers, getId, getAge, getName, metadata: { creationTimestamp },
|
||||||
|
|||||||
@ -11220,11 +11220,6 @@ prepend-http@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
|
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
|
||||||
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
|
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
|
||||||
|
|
||||||
prettier@^2.4.1:
|
|
||||||
version "2.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
|
|
||||||
integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
|
|
||||||
|
|
||||||
pretty-error@^2.1.1:
|
pretty-error@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3"
|
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user