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

fix: various app-crashes related to KubeObject.spec.* access from "undefined"

fix: config-map-details crash

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2021-05-09 23:49:40 +03:00
parent e5c0fe5d65
commit f96b789280
21 changed files with 29 additions and 39 deletions

View File

@ -54,7 +54,7 @@ export class Cluster extends KubeObject {
static kind = "Cluster"; static kind = "Cluster";
static apiBase = "/apis/cluster.k8s.io/v1alpha1/clusters"; static apiBase = "/apis/cluster.k8s.io/v1alpha1/clusters";
spec: { declare spec: {
clusterNetwork?: { clusterNetwork?: {
serviceDomain?: string; serviceDomain?: string;
pods?: { pods?: {

View File

@ -22,7 +22,7 @@ export class CustomResourceDefinition extends KubeObject {
static namespaced = false; static namespaced = false;
static apiBase = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions"; static apiBase = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions";
spec: { declare spec: {
group: string; group: string;
version?: string; // deprecated in v1 api version?: string; // deprecated in v1 api
names: { names: {

View File

@ -48,7 +48,7 @@ export class CronJob extends KubeObject {
autoBind(this); autoBind(this);
} }
spec: { declare spec: {
schedule: string; schedule: string;
concurrencyPolicy: string; concurrencyPolicy: string;
suspend: boolean; suspend: boolean;

View File

@ -43,7 +43,7 @@ export class HorizontalPodAutoscaler extends KubeObject {
static namespaced = true; static namespaced = true;
static apiBase = "/apis/autoscaling/v2beta1/horizontalpodautoscalers"; static apiBase = "/apis/autoscaling/v2beta1/horizontalpodautoscalers";
spec: { declare spec: {
scaleTargetRef: { scaleTargetRef: {
kind: string; kind: string;
name: string; name: string;

View File

@ -72,7 +72,7 @@ export class Ingress extends KubeObject {
autoBind(this); autoBind(this);
} }
spec: { declare spec: {
tls: { tls: {
secretName: string; secretName: string;
}[]; }[];

View File

@ -40,7 +40,7 @@ export class LimitRange extends KubeObject {
autoBind(this); autoBind(this);
} }
spec: { declare spec: {
limits: LimitRangeItem[]; limits: LimitRangeItem[];
}; };

View File

@ -46,7 +46,7 @@ export class NetworkPolicy extends KubeObject {
autoBind(this); autoBind(this);
} }
spec: { declare spec: {
podSelector: { podSelector: {
matchLabels: { matchLabels: {
[label: string]: string; [label: string]: string;

View File

@ -39,7 +39,7 @@ export class Node extends KubeObject {
autoBind(this); autoBind(this);
} }
spec: { declare spec: {
podCIDR: string; podCIDR: string;
externalID: string; externalID: string;
taints?: { taints?: {

View File

@ -32,7 +32,7 @@ export class PersistentVolumeClaim extends KubeObject {
autoBind(this); autoBind(this);
} }
spec: { declare spec: {
accessModes: string[]; accessModes: string[];
storageClassName: string; storageClassName: string;
selector: { selector: {

View File

@ -14,7 +14,7 @@ export class PersistentVolume extends KubeObject {
autoBind(this); autoBind(this);
} }
spec: { declare spec: {
capacity: { capacity: {
storage: string; // 8Gi storage: string; // 8Gi
}; };

View File

@ -13,7 +13,7 @@ export class PodDisruptionBudget extends KubeObject {
autoBind(this); autoBind(this);
} }
spec: { declare spec: {
minAvailable: string; minAvailable: string;
maxUnavailable: string; maxUnavailable: string;
selector: { matchLabels: { [app: string]: string } }; selector: { matchLabels: { [app: string]: string } };

View File

@ -13,7 +13,7 @@ export class PodSecurityPolicy extends KubeObject {
autoBind(this); autoBind(this);
} }
spec: { declare spec: {
allowPrivilegeEscalation?: boolean; allowPrivilegeEscalation?: boolean;
allowedCSIDrivers?: { allowedCSIDrivers?: {
name: string; name: string;

View File

@ -40,7 +40,7 @@ export class ResourceQuota extends KubeObject {
this.spec = this.spec || {} as any; this.spec = this.spec || {} as any;
} }
spec: { declare spec: {
hard: IResourceQuotaValues; hard: IResourceQuotaValues;
scopeSelector?: { scopeSelector?: {
matchExpressions: { matchExpressions: {

View File

@ -25,7 +25,7 @@ export class SelfSubjectRulesReview extends KubeObject {
static namespaced = false; static namespaced = false;
static apiBase = "/apis/authorization.k8s.io/v1/selfsubjectrulesreviews"; static apiBase = "/apis/authorization.k8s.io/v1/selfsubjectrulesreviews";
spec: { declare spec: {
// todo: add more types from api docs // todo: add more types from api docs
namespace?: string; namespace?: string;
}; };

View File

@ -40,7 +40,7 @@ export class Service extends KubeObject {
autoBind(this); autoBind(this);
} }
spec: { declare spec: {
type: string; type: string;
clusterIP: string; clusterIP: string;
externalTrafficPolicy?: string; externalTrafficPolicy?: string;

View File

@ -144,7 +144,8 @@ export class KubeObject implements ItemObject {
apiVersion: string; apiVersion: string;
kind: string; kind: string;
metadata: IKubeObjectMetadata; metadata: IKubeObjectMetadata;
status?: any; // todo: type-safety support status?: any;
spec: any = {};
get selfLink() { get selfLink() {
return this.metadata.selfLink; return this.metadata.selfLink;

View File

@ -47,8 +47,6 @@ export interface IAffinity {
} }
export class WorkloadKubeObject extends KubeObject { export class WorkloadKubeObject extends KubeObject {
spec: any; // todo: add proper types
getSelectors(): string[] { getSelectors(): string[] {
const selector = this.spec.selector; const selector = this.spec.selector;

View File

@ -62,17 +62,17 @@ export class ConfigMapDetails extends React.Component<Props> {
const { object: configMap } = this.props; const { object: configMap } = this.props;
if (!configMap) return null; if (!configMap) return null;
const dataEntries = Object.entries(this.data); const data = Array.from(this.data.entries());
return ( return (
<div className="ConfigMapDetails"> <div className="ConfigMapDetails">
<KubeObjectMeta object={configMap}/> <KubeObjectMeta object={configMap}/>
{ {
dataEntries.length > 0 && ( data.length > 0 && (
<> <>
<DrawerTitle title="Data"/> <DrawerTitle title="Data"/>
{ {
dataEntries.map(([name, value]) => { data.map(([name, value]) => {
return ( return (
<div key={name} className="data"> <div key={name} className="data">
<div className="name">{name}</div> <div className="name">{name}</div>

View File

@ -1,19 +1,11 @@
import { import { action, comparer, computed, IReactionDisposer, IReactionOptions, makeObservable, observable, reaction, } from "mobx";
action,
comparer,
computed,
IReactionDisposer,
IReactionOptions,
observable,
reaction,
makeObservable,
} from "mobx";
import { autoBind, createStorage } from "../../utils"; import { autoBind, createStorage } from "../../utils";
import { KubeObjectStore, KubeObjectStoreLoadingParams } from "../../kube-object.store"; import { KubeObjectStore, KubeObjectStoreLoadingParams } from "../../kube-object.store";
import { Namespace, namespacesApi } from "../../api/endpoints/namespaces.api"; import { Namespace, namespacesApi } from "../../api/endpoints/namespaces.api";
import { createPageParam } from "../../navigation"; import { createPageParam } from "../../navigation";
import { apiManager } from "../../api/api-manager"; import { apiManager } from "../../api/api-manager";
// FIXME: something fishy with sync selected-namespaces with URL
const selectedNamespaces = createStorage<string[] | undefined>("selected_namespaces", undefined); const selectedNamespaces = createStorage<string[] | undefined>("selected_namespaces", undefined);
export const namespaceUrlParam = createPageParam<string[]>({ export const namespaceUrlParam = createPageParam<string[]>({

View File

@ -2,7 +2,7 @@ import "./pod-details-list.scss";
import React from "react"; import React from "react";
import kebabCase from "lodash/kebabCase"; import kebabCase from "lodash/kebabCase";
import { reaction, makeObservable } from "mobx"; import { reaction } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react"; import { disposeOnUnmount, observer } from "mobx-react";
import { podsStore } from "./pods.store"; import { podsStore } from "./pods.store";
import { Pod } from "../../api/endpoints"; import { Pod } from "../../api/endpoints";
@ -50,11 +50,6 @@ export class PodDetailsList extends React.Component<Props> {
[sortBy.memory]: (pod: Pod) => podsStore.getPodKubeMetrics(pod).memory, [sortBy.memory]: (pod: Pod) => podsStore.getPodKubeMetrics(pod).memory,
}; };
constructor(props: Props) {
super(props);
makeObservable(this);
}
componentDidMount() { componentDidMount() {
this.metricsWatcher.start(true); this.metricsWatcher.start(true);
disposeOnUnmount(this, [ disposeOnUnmount(this, [

View File

@ -1,6 +1,6 @@
// Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.) // Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.)
import { action, IObservableValue, makeObservable, observable, toJS, when, } from "mobx"; import { action, comparer, IObservableValue, makeObservable, observable, toJS, when, } from "mobx";
import produce, { Draft } from "immer"; import produce, { Draft } from "immer";
import { isEqual, isFunction, isPlainObject } from "lodash"; import { isEqual, isFunction, isPlainObject } from "lodash";
import logger from "../../main/logger"; import logger from "../../main/logger";
@ -36,7 +36,11 @@ export class StorageHelper<T> {
this.storage = options.storage; this.storage = options.storage;
this.defaultValue = options.defaultValue; this.defaultValue = options.defaultValue;
this.data = observable.box<T>(this.defaultValue); this.data = observable.box<T>(this.defaultValue, {
autoBind: true,
deep: true,
equals: comparer.structural,
});
this.data.observe_(({ newValue, oldValue }) => { this.data.observe_(({ newValue, oldValue }) => {
this.onChange(newValue as T, oldValue as T); this.onChange(newValue as T, oldValue as T);