1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Fix custom resources not having a fallback details component (#3542)

This commit is contained in:
Sebastian Malton 2021-08-03 12:31:44 -04:00 committed by GitHub
parent a6e91fc34a
commit 77077ef72c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 32 deletions

View File

@ -86,6 +86,16 @@ export class KubeStatus {
}
}
export interface KubeObjectStatus {
conditions?: {
lastTransitionTime: string;
message: string;
reason: string;
status: string;
type?: string;
}[];
}
export type KubeMetaField = keyof KubeObjectMetadata;
export class KubeObject<Metadata extends KubeObjectMetadata = KubeObjectMetadata, Status = any, Spec = any> implements ItemObject {

View File

@ -24,18 +24,18 @@ import "./crd-resource-details.scss";
import React from "react";
import jsonPath from "jsonpath";
import { observer } from "mobx-react";
import { computed, makeObservable } from "mobx";
import { cssNames } from "../../utils";
import { Badge } from "../badge";
import { DrawerItem } from "../drawer";
import type { KubeObjectDetailsProps } from "../kube-object";
import { crdStore } from "./crd.store";
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
import { Input } from "../input";
import type { AdditionalPrinterColumnsV1, CustomResourceDefinition } from "../../api/endpoints/crd.api";
import { parseJsonPath } from "../../utils/jsonPath";
import type { KubeObject, KubeObjectMetadata, KubeObjectStatus } from "../../api/kube-object";
interface Props extends KubeObjectDetailsProps<CustomResourceDefinition> {
interface Props extends KubeObjectDetailsProps<KubeObject> {
crd: CustomResourceDefinition;
}
function convertSpecValue(value: any): any {
@ -60,31 +60,22 @@ function convertSpecValue(value: any): any {
@observer
export class CrdResourceDetails extends React.Component<Props> {
constructor(props: Props) {
super(props);
makeObservable(this);
}
@computed get crd() {
return crdStore.getByObject(this.props.object);
}
renderAdditionalColumns(crd: CustomResourceDefinition, columns: AdditionalPrinterColumnsV1[]) {
renderAdditionalColumns(resource: KubeObject, columns: AdditionalPrinterColumnsV1[]) {
return columns.map(({ name, jsonPath: jp }) => (
<DrawerItem key={name} name={name} renderBoolean>
{convertSpecValue(jsonPath.value(crd, parseJsonPath(jp.slice(1))))}
{convertSpecValue(jsonPath.value(resource, parseJsonPath(jp.slice(1))))}
</DrawerItem>
));
}
renderStatus(crd: CustomResourceDefinition, columns: AdditionalPrinterColumnsV1[]) {
const showStatus = !columns.find(column => column.name == "Status") && crd.status?.conditions;
renderStatus(customResource: KubeObject<KubeObjectMetadata, KubeObjectStatus, any>, columns: AdditionalPrinterColumnsV1[]) {
const showStatus = !columns.find(column => column.name == "Status") && Array.isArray(customResource.status?.conditions);
if (!showStatus) {
return null;
}
const conditions = crd.status.conditions
const conditions = customResource.status.conditions
.filter(({ type, reason }) => type || reason)
.map(({ type, reason, message, status }) => ({ kind: type || reason, message, status }))
.map(({ kind, message, status }, index) => (
@ -104,17 +95,16 @@ export class CrdResourceDetails extends React.Component<Props> {
}
render() {
const { props: { object }, crd } = this;
const { props: { object, crd } } = this;
if (!object || !crd) {
return null;
}
const className = cssNames("CrdResourceDetails", crd.getResourceKind());
const extraColumns = crd.getPrinterColumns();
return (
<div className={className}>
<div className={cssNames("CrdResourceDetails", crd.getResourceKind())}>
<KubeObjectMeta object={object} />
{this.renderAdditionalColumns(object, extraColumns)}
{this.renderStatus(object, extraColumns)}

View File

@ -33,6 +33,8 @@ import { crdStore } from "../+custom-resources/crd.store";
import { KubeObjectMenu } from "./kube-object-menu";
import { KubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
import logger from "../../../main/logger";
import { CrdResourceDetails } from "../+custom-resources";
import { KubeObjectMeta } from "./kube-object-meta";
/**
* Used to store `object.selfLink` to show more info about resource in the details panel.
@ -111,10 +113,6 @@ export class KubeObjectDetails extends React.Component {
}
}
@computed get isCrdInstance() {
return !!crdStore.getByObject(this.object);
}
@disposeOnUnmount
loader = reaction(() => [
this.path,
@ -169,6 +167,23 @@ export class KubeObjectDetails extends React.Component {
<item.components.Details object={object} key={`object-details-${index}`} />
));
if (details.length === 0) {
const crd = crdStore.getByObject(object);
/**
* This is a fallback so that if a custom resource object doesn't have
* any defined details we should try and display at least some details
*/
if (crd) {
details.push(<CrdResourceDetails key={object.getId()} object={object} crd={crd} />);
}
}
if (details.length === 0) {
// if we still don't have any details to show, just show the standard object metadata
details.push(<KubeObjectMeta key={object.getId()} object={object} />);
}
return (
<Drawer
className="KubeObjectDetails flex column"

View File

@ -27,7 +27,7 @@ import { ConfigMapDetails } from "../components/+config-maps";
import { PodDisruptionBudgetDetails } from "../components/+config-pod-disruption-budgets";
import { ResourceQuotaDetails } from "../components/+config-resource-quotas";
import { SecretDetails } from "../components/+config-secrets";
import { CRDDetails, CrdResourceDetails } from "../components/+custom-resources";
import { CRDDetails } from "../components/+custom-resources";
import { EventDetails } from "../components/+events";
import { KubeEventDetails } from "../components/+events/kube-event-details";
import { NamespaceDetails } from "../components/+namespaces";
@ -445,12 +445,5 @@ export function intiKubeObjectDetailRegistry() {
Details: KubeEventDetails,
}
},
{
kind: "CustomResourceDefinition",
apiVersions: ["apiextensions.k8s.io/v1"],
components: {
Details: CrdResourceDetails,
}
}
]);
}