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

Fix remaining type errors

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-11-28 09:46:59 -05:00
parent 4504283041
commit 153e2fc35a
19 changed files with 207 additions and 76 deletions

View File

@ -11,7 +11,9 @@ export type KubeResource =
"priorityclasses" | "runtimeclasses" | "priorityclasses" | "runtimeclasses" |
"roles" | "clusterroles" | "rolebindings" | "clusterrolebindings" | "serviceaccounts"; "roles" | "clusterroles" | "rolebindings" | "clusterrolebindings" | "serviceaccounts";
export interface KubeApiResource extends KubeApiResourceData, KubeApiResourceDescriptor { export interface KubeApiResource {
kind: string;
group?: string;
apiName: string; apiName: string;
namespaced: boolean; namespaced: boolean;
} }
@ -29,41 +31,160 @@ export const formatKubeApiResource = (res: KubeApiResourceDescriptor) => (
export interface KubeApiResourceData { export interface KubeApiResourceData {
kind: string; // resource type (e.g. "Namespace") kind: string; // resource type (e.g. "Namespace")
group?: string; // api-group group?: string; // api-group, if empty then "core"
namespaced: boolean;
} }
export const apiResourceRecord: Record<KubeResource, KubeApiResourceData> = { export const apiResourceRecord: Record<KubeResource, KubeApiResourceData> = {
"clusterroles": { kind: "ClusterRole", group: "rbac.authorization.k8s.io" }, clusterroles: {
"clusterrolebindings": { kind: "ClusterRoleBinding", group: "rbac.authorization.k8s.io" }, kind: "ClusterRole",
"configmaps": { kind: "ConfigMap" }, //empty group means "core" group: "rbac.authorization.k8s.io",
"cronjobs": { kind: "CronJob", group: "batch" }, namespaced: false,
"customresourcedefinitions": { kind: "CustomResourceDefinition", group: "apiextensions.k8s.io" }, },
"daemonsets": { kind: "DaemonSet", group: "apps" }, clusterrolebindings: {
"deployments": { kind: "Deployment", group: "apps" }, kind: "ClusterRoleBinding",
"endpoints": { kind: "Endpoint" }, group: "rbac.authorization.k8s.io",
"events": { kind: "Event" }, namespaced: false,
"horizontalpodautoscalers": { kind: "HorizontalPodAutoscaler", group: "autoscaling" }, },
"ingresses": { kind: "Ingress", group: "networking.k8s.io" }, configmaps: {
"jobs": { kind: "Job", group: "batch" }, kind: "ConfigMap",
"namespaces": { kind: "Namespace" }, namespaced: true,
"limitranges": { kind: "LimitRange" }, },
"leases": { kind: "Lease" }, cronjobs: {
"networkpolicies": { kind: "NetworkPolicy", group: "networking.k8s.io" }, kind: "CronJob",
"nodes": { kind: "Node" }, group: "batch",
"persistentvolumes": { kind: "PersistentVolume" }, namespaced: true,
"persistentvolumeclaims": { kind: "PersistentVolumeClaim" }, },
"pods": { kind: "Pod" }, customresourcedefinitions: {
"poddisruptionbudgets": { kind: "PodDisruptionBudget", group: "policy" }, kind: "CustomResourceDefinition",
"podsecuritypolicies": { kind: "PodSecurityPolicy", group: "policy" }, group: "apiextensions.k8s.io",
"priorityclasses": { kind: "PriorityClass", group: "scheduling.k8s.io" }, namespaced: false,
"runtimeclasses": { kind: "RuntimeClass", group: "node.k8s.io" }, },
"resourcequotas": { kind: "ResourceQuota" }, daemonsets: {
"replicasets": { kind: "ReplicaSet", group: "apps" }, kind: "DaemonSet",
"roles": { kind: "Role", group: "rbac.authorization.k8s.io" }, group: "apps",
"rolebindings": { kind: "RoleBinding", group: "rbac.authorization.k8s.io" }, namespaced: true,
"secrets": { kind: "Secret" }, },
"serviceaccounts": { kind: "ServiceAccount" }, deployments: {
"services": { kind: "Service" }, kind: "Deployment",
"statefulsets": { kind: "StatefulSet", group: "apps" }, group: "apps",
"storageclasses": { kind: "StorageClass", group: "storage.k8s.io" }, namespaced: true,
},
endpoints: {
kind: "Endpoint",
namespaced: true,
},
events: {
kind: "Event",
namespaced: true,
},
horizontalpodautoscalers: {
kind: "HorizontalPodAutoscaler",
group: "autoscaling",
namespaced: true,
},
ingresses: {
kind: "Ingress",
group: "networking.k8s.io",
namespaced: true,
},
jobs: {
kind: "Job",
group: "batch",
namespaced: true,
},
namespaces: {
kind: "Namespace",
namespaced: false,
},
limitranges: {
kind: "LimitRange",
namespaced: true,
},
leases: {
kind: "Lease",
namespaced: true,
},
networkpolicies: {
kind: "NetworkPolicy",
group: "networking.k8s.io",
namespaced: true,
},
nodes: {
kind: "Node",
namespaced: false,
},
persistentvolumes: {
kind: "PersistentVolume",
namespaced: false,
},
persistentvolumeclaims: {
kind: "PersistentVolumeClaim",
namespaced: true,
},
pods: {
kind: "Pod",
namespaced: true,
},
poddisruptionbudgets: {
kind: "PodDisruptionBudget",
group: "policy",
namespaced: true,
},
podsecuritypolicies: {
kind: "PodSecurityPolicy",
group: "policy",
namespaced: false,
},
priorityclasses: {
kind: "PriorityClass",
group: "scheduling.k8s.io",
namespaced: false,
},
runtimeclasses: {
kind: "RuntimeClass",
group: "node.k8s.io",
namespaced: false,
},
resourcequotas: {
kind: "ResourceQuota",
namespaced: true,
},
replicasets: {
kind: "ReplicaSet",
group: "apps",
namespaced: true,
},
roles: {
kind: "Role",
group: "rbac.authorization.k8s.io",
namespaced: true,
},
rolebindings: {
kind: "RoleBinding",
group: "rbac.authorization.k8s.io",
namespaced: true,
},
secrets: {
kind: "Secret",
namespaced: true,
},
serviceaccounts: {
kind: "ServiceAccount",
namespaced: true,
},
services: {
kind: "Service",
namespaced: true,
},
statefulsets: {
kind: "StatefulSet",
group: "apps",
namespaced: true,
},
storageclasses: {
kind: "StorageClass",
group: "storage.k8s.io",
namespaced: false,
},
}; };

View File

@ -98,7 +98,9 @@ describe("cluster/namespaces - edit namespace from new tab", () => {
}); });
}); });
builder.allowKubeResource("namespaces"); builder.allowKubeResource({
apiName: "namespaces",
});
}); });
describe("when navigating to namespaces", () => { describe("when navigating to namespaces", () => {

View File

@ -42,7 +42,9 @@ describe("cluster/namespaces - edit namespaces from previously opened tab", () =
windowDi.override(callForResourceInjectable, () => callForNamespaceMock); windowDi.override(callForResourceInjectable, () => callForNamespaceMock);
}); });
builder.allowKubeResource("namespaces"); builder.allowKubeResource({
apiName: "namespaces",
});
}); });
describe("given tab was previously opened, when application is started", () => { describe("given tab was previously opened, when application is started", () => {

View File

@ -50,7 +50,9 @@ describe("cluster - visibility of sidebar items", () => {
describe("when kube resource becomes allowed", () => { describe("when kube resource becomes allowed", () => {
beforeEach(() => { beforeEach(() => {
builder.allowKubeResource("namespaces"); builder.allowKubeResource({
apiName: "namespaces",
});
}); });
it("renders", () => { it("renders", () => {

View File

@ -13,7 +13,9 @@ describe("workload overview", () => {
beforeEach(async () => { beforeEach(async () => {
applicationBuilder = getApplicationBuilder().setEnvironmentToClusterFrame(); applicationBuilder = getApplicationBuilder().setEnvironmentToClusterFrame();
applicationBuilder.allowKubeResource("pods"); applicationBuilder.allowKubeResource({
apiName: "pods",
});
rendered = await applicationBuilder.render(); rendered = await applicationBuilder.render();
}); });

View File

@ -210,7 +210,7 @@ export class ClusterManager {
cluster.contextName = entity.spec.kubeconfigContext; cluster.contextName = entity.spec.kubeconfigContext;
if (entity.spec.accessibleNamespaces) { if (entity.spec.accessibleNamespaces) {
cluster.accessibleNamespaces = entity.spec.accessibleNamespaces; cluster.accessibleNamespaces.replace(entity.spec.accessibleNamespaces);
} }
if (entity.spec.metrics) { if (entity.spec.metrics) {

View File

@ -2,15 +2,20 @@
* Copyright (c) OpenLens Authors. All rights reserved. * Copyright (c) OpenLens Authors. All rights reserved.
* 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, lifecycleEnum } from "@ogre-tools/injectable";
import { computed } from "mobx"; import { computed } from "mobx";
import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token"; import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
import type { KubeApiResourceDescriptor } from "../../common/rbac";
import { formatKubeApiResource } from "../../common/rbac";
// TODO: Figure out implementation for this later. // TODO: Figure out implementation for this later.
const allowedResourcesInjectable = getInjectable({ const allowedResourcesInjectable = getInjectable({
id: "allowed-resources", id: "allowed-resources",
instantiate: () => computed(() => new Set<string>()), instantiate: () => computed(() => false),
injectionToken: shouldShowResourceInjectionToken, injectionToken: shouldShowResourceInjectionToken,
lifecycle: lifecycleEnum.keyedSingleton({
getInstanceKey: (di, resource: KubeApiResourceDescriptor) => formatKubeApiResource(resource),
}),
}); });
export default allowedResourcesInjectable; export default allowedResourcesInjectable;

View File

@ -11,7 +11,6 @@ import createKubectlInjectable from "../kubectl/create-kubectl.injectable";
import createContextHandlerInjectable from "../context-handler/create-context-handler.injectable"; import createContextHandlerInjectable from "../context-handler/create-context-handler.injectable";
import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token"; import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
import authorizationReviewInjectable from "../../common/cluster/authorization-review.injectable"; import authorizationReviewInjectable from "../../common/cluster/authorization-review.injectable";
import createAuthorizationNamespaceReview from "../../common/cluster/request-namespace-list-permissions.injectable";
import listNamespacesInjectable from "../../common/cluster/list-namespaces.injectable"; import listNamespacesInjectable from "../../common/cluster/list-namespaces.injectable";
import createListApiResourcesInjectable from "../../common/cluster/request-api-resources.injectable"; import createListApiResourcesInjectable from "../../common/cluster/request-api-resources.injectable";
import loggerInjectable from "../../common/logger.injectable"; import loggerInjectable from "../../common/logger.injectable";
@ -19,6 +18,7 @@ import detectorRegistryInjectable from "../cluster-detectors/detector-registry.i
import createVersionDetectorInjectable from "../cluster-detectors/create-version-detector.injectable"; import createVersionDetectorInjectable from "../cluster-detectors/create-version-detector.injectable";
import broadcastMessageInjectable from "../../common/ipc/broadcast-message.injectable"; import broadcastMessageInjectable from "../../common/ipc/broadcast-message.injectable";
import loadConfigfromFileInjectable from "../../common/kube-helpers/load-config-from-file.injectable"; import loadConfigfromFileInjectable from "../../common/kube-helpers/load-config-from-file.injectable";
import requestNamespaceListPermissionsForInjectable from "../../common/cluster/request-namespace-list-permissions.injectable";
const createClusterInjectable = getInjectable({ const createClusterInjectable = getInjectable({
id: "create-cluster", id: "create-cluster",
@ -30,7 +30,7 @@ const createClusterInjectable = getInjectable({
createKubectl: di.inject(createKubectlInjectable), createKubectl: di.inject(createKubectlInjectable),
createContextHandler: di.inject(createContextHandlerInjectable), createContextHandler: di.inject(createContextHandlerInjectable),
createAuthorizationReview: di.inject(authorizationReviewInjectable), createAuthorizationReview: di.inject(authorizationReviewInjectable),
createAuthorizationNamespaceReview: di.inject(createAuthorizationNamespaceReview), requestNamespaceListPermissionsFor: di.inject(requestNamespaceListPermissionsForInjectable),
requestApiResources: di.inject(createListApiResourcesInjectable), requestApiResources: di.inject(createListApiResourcesInjectable),
createListNamespaces: di.inject(listNamespacesInjectable), createListNamespaces: di.inject(listNamespacesInjectable),
logger: di.inject(loggerInjectable), logger: di.inject(loggerInjectable),

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert"; import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import runtimeClassApiInjectable from "../../../common/k8s-api/endpoints/runtime-class.api.injectable"; import runtimeClassApiInjectable from "../../../common/k8s-api/endpoints/runtime-class.api.injectable";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { RuntimeClassStore } from "./store"; import { RuntimeClassStore } from "./store";
@ -16,7 +17,9 @@ const runtimeClassStoreInjectable = getInjectable({
const api = di.inject(runtimeClassApiInjectable); const api = di.inject(runtimeClassApiInjectable);
return new RuntimeClassStore(api); return new RuntimeClassStore({
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
}, api);
}, },
injectionToken: kubeObjectStoreInjectionToken, injectionToken: kubeObjectStoreInjectionToken,
}); });

View File

@ -7,6 +7,7 @@ import assert from "assert";
import getPodByIdInjectable from "../+workloads-pods/get-pod-by-id.injectable"; import getPodByIdInjectable from "../+workloads-pods/get-pod-by-id.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import kubeEventApiInjectable from "../../../common/k8s-api/endpoints/events.api.injectable"; import kubeEventApiInjectable from "../../../common/k8s-api/endpoints/events.api.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { EventStore } from "./store"; import { EventStore } from "./store";
@ -19,6 +20,7 @@ const eventStoreInjectable = getInjectable({
return new EventStore({ return new EventStore({
getPodById: di.inject(getPodByIdInjectable), getPodById: di.inject(getPodByIdInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
}, api); }, api);
}, },
injectionToken: kubeObjectStoreInjectionToken, injectionToken: kubeObjectStoreInjectionToken,

View File

@ -5,7 +5,7 @@
import groupBy from "lodash/groupBy"; import groupBy from "lodash/groupBy";
import compact from "lodash/compact"; import compact from "lodash/compact";
import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import type { KubeObjectStoreDependencies, 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";
import { autoBind } from "../../utils"; import { autoBind } from "../../utils";
import type { KubeEvent, KubeEventApi } from "../../../common/k8s-api/endpoints/events.api"; import type { KubeEvent, KubeEventApi } from "../../../common/k8s-api/endpoints/events.api";
@ -13,17 +13,17 @@ 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";
interface Dependencies { export interface EventStoreDependencies extends KubeObjectStoreDependencies {
getPodById: GetPodById; getPodById: GetPodById;
} }
export class EventStore extends KubeObjectStore<KubeEvent, KubeEventApi> { export class EventStore extends KubeObjectStore<KubeEvent, KubeEventApi> {
constructor( constructor(
protected readonly dependencies: Dependencies, protected readonly dependencies: EventStoreDependencies,
api: KubeEventApi, api: KubeEventApi,
opts: KubeObjectStoreOptions = {}, opts: KubeObjectStoreOptions = {},
) { ) {
super(api, { limit: 1000, ...opts }); super(dependencies, api, { limit: 1000, ...opts });
autoBind(this); autoBind(this);
} }

View File

@ -7,6 +7,7 @@ import assert from "assert";
import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable"; import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import jobApiInjectable from "../../../common/k8s-api/endpoints/job.api.injectable"; import jobApiInjectable from "../../../common/k8s-api/endpoints/job.api.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { JobStore } from "./store"; import { JobStore } from "./store";
@ -19,6 +20,7 @@ const jobStoreInjectable = getInjectable({
return new JobStore({ return new JobStore({
getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable), getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
}, api); }, api);
}, },
injectionToken: kubeObjectStoreInjectionToken, injectionToken: kubeObjectStoreInjectionToken,

View File

@ -3,20 +3,20 @@
* 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 type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import type { KubeObjectStoreDependencies, 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";
import type { Job, JobApi } from "../../../common/k8s-api/endpoints/job.api"; import type { Job, JobApi } from "../../../common/k8s-api/endpoints/job.api";
import type { CronJob, Pod } from "../../../common/k8s-api/endpoints"; import type { CronJob, Pod } from "../../../common/k8s-api/endpoints";
import { PodStatusPhase } from "../../../common/k8s-api/endpoints"; import { PodStatusPhase } from "../../../common/k8s-api/endpoints";
import type { GetPodsByOwnerId } from "../+workloads-pods/get-pods-by-owner-id.injectable"; import type { GetPodsByOwnerId } from "../+workloads-pods/get-pods-by-owner-id.injectable";
interface Dependencies { interface Dependencies extends KubeObjectStoreDependencies {
getPodsByOwnerId: GetPodsByOwnerId; getPodsByOwnerId: GetPodsByOwnerId;
} }
export class JobStore extends KubeObjectStore<Job, JobApi> { export class JobStore extends KubeObjectStore<Job, JobApi> {
constructor(protected readonly dependencies: Dependencies, api: JobApi, opts?: KubeObjectStoreOptions) { constructor(protected readonly dependencies: Dependencies, api: JobApi, opts?: KubeObjectStoreOptions) {
super(api, opts); super(dependencies, api, opts);
} }
getChildPods(job: Job): Pod[] { getChildPods(job: Job): Pod[] {

View File

@ -18,7 +18,6 @@ import { Icon } from "../icon";
import { TooltipPosition } from "../tooltip"; import { TooltipPosition } from "../tooltip";
import { withInjectables } from "@ogre-tools/injectable-react"; import { withInjectables } from "@ogre-tools/injectable-react";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import type { ClusterFrameContext } from "../../cluster-frame-context/cluster-frame-context";
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api"; import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
import workloadOverviewDetailsInjectable from "./workload-overview-details/workload-overview-details.injectable"; import workloadOverviewDetailsInjectable from "./workload-overview-details/workload-overview-details.injectable";
import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout"; import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout";
@ -35,10 +34,11 @@ import jobStoreInjectable from "../+workloads-jobs/store.injectable";
import statefulSetStoreInjectable from "../+workloads-statefulsets/store.injectable"; import statefulSetStoreInjectable from "../+workloads-statefulsets/store.injectable";
import type { EventStore } from "../+events/store"; import type { EventStore } from "../+events/store";
import eventStoreInjectable from "../+events/store.injectable"; import eventStoreInjectable from "../+events/store.injectable";
import type { ClusterContext } from "../../cluster-frame-context/cluster-frame-context";
interface Dependencies { interface Dependencies {
detailComponents: IComputedValue<React.ElementType<{}>[]>; detailComponents: IComputedValue<React.ElementType<{}>[]>;
clusterFrameContext: ClusterFrameContext; clusterFrameContext: ClusterContext;
subscribeStores: SubscribeStores; subscribeStores: SubscribeStores;
podStore: PodStore; podStore: PodStore;
daemonSetStore: DaemonSetStore; daemonSetStore: DaemonSetStore;

View File

@ -20,7 +20,6 @@ import { ResourceKindMap, ResourceNames } from "../../utils/rbac";
import { Icon } from "../icon"; import { Icon } from "../icon";
import { TooltipPosition } from "../tooltip"; import { TooltipPosition } from "../tooltip";
import { withInjectables } from "@ogre-tools/injectable-react"; import { withInjectables } from "@ogre-tools/injectable-react";
import type { ClusterFrameContext } from "../../cluster-frame-context/cluster-frame-context";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import type { SubscribableStore, SubscribeStores } from "../../kube-watch-api/kube-watch-api"; import type { SubscribableStore, SubscribeStores } from "../../kube-watch-api/kube-watch-api";
import type { KubeApi } from "../../../common/k8s-api/kube-api"; import type { KubeApi } from "../../../common/k8s-api/kube-api";
@ -29,6 +28,7 @@ import type { PageParam } from "../../navigation";
import type { ToggleKubeDetailsPane } from "../kube-detail-params/toggle-details.injectable"; import type { ToggleKubeDetailsPane } from "../kube-detail-params/toggle-details.injectable";
import kubeSelectedUrlParamInjectable from "../kube-detail-params/kube-selected-url.injectable"; import kubeSelectedUrlParamInjectable from "../kube-detail-params/kube-selected-url.injectable";
import toggleKubeDetailsPaneInjectable from "../kube-detail-params/toggle-details.injectable"; import toggleKubeDetailsPaneInjectable from "../kube-detail-params/toggle-details.injectable";
import type { ClusterContext } from "../../cluster-frame-context/cluster-frame-context";
export interface KubeObjectListLayoutProps< export interface KubeObjectListLayoutProps<
K extends KubeObject, K extends KubeObject,
@ -43,7 +43,7 @@ export interface KubeObjectListLayoutProps<
} }
interface Dependencies { interface Dependencies {
clusterFrameContext: ClusterFrameContext; clusterFrameContext: ClusterContext;
subscribeToStores: SubscribeStores; subscribeToStores: SubscribeStores;
kubeSelectedUrlParam: PageParam<string>; kubeSelectedUrlParam: PageParam<string>;
toggleKubeDetailsPane: ToggleKubeDetailsPane; toggleKubeDetailsPane: ToggleKubeDetailsPane;

View File

@ -22,9 +22,7 @@ import navigateToPreferencesInjectable from "../../../features/preferences/commo
import type { NavigateToHelmCharts } from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable"; import type { NavigateToHelmCharts } from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable";
import navigateToHelmChartsInjectable from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable"; import navigateToHelmChartsInjectable from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable";
import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable";
import { ClusterFrameContext } from "../../cluster-frame-context/cluster-frame-context";
import type { Cluster } from "../../../common/cluster/cluster"; import type { Cluster } from "../../../common/cluster/cluster";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import startMainApplicationInjectable from "../../../main/start-main-application/start-main-application.injectable"; import startMainApplicationInjectable from "../../../main/start-main-application/start-main-application.injectable";
import startFrameInjectable from "../../start-frame/start-frame.injectable"; import startFrameInjectable from "../../start-frame/start-frame.injectable";
import type { NamespaceStore } from "../+namespaces/store"; import type { NamespaceStore } from "../+namespaces/store";
@ -532,17 +530,8 @@ export const getApplicationBuilder = () => {
getTotalCount: () => namespaceItems.length, getTotalCount: () => namespaceItems.length,
} as Partial<NamespaceStore> as NamespaceStore; } as Partial<NamespaceStore> as NamespaceStore;
const clusterFrameContextFake = new ClusterFrameContext(
clusterStub,
{
namespaceStore: namespaceStoreStub,
},
);
windowDi.override(namespaceStoreInjectable, () => namespaceStoreStub); windowDi.override(namespaceStoreInjectable, () => namespaceStoreStub);
windowDi.override(hostedClusterInjectable, () => clusterStub); windowDi.override(hostedClusterInjectable, () => clusterStub);
windowDi.override(clusterFrameContextForNamespacedResourcesInjectable, () => clusterFrameContextFake);
}); });
return builder; return builder;

View File

@ -10,7 +10,7 @@ const kubeWatchApiInjectable = getInjectable({
id: "kube-watch-api", id: "kube-watch-api",
instantiate: (di) => new KubeWatchApi({ instantiate: (di) => new KubeWatchApi({
clusterFrameContext: di.inject(clusterFrameContextForNamespacedResourcesInjectable), clusterContext: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
}), }),
}); });

View File

@ -6,10 +6,10 @@ import { comparer, reaction } from "mobx";
import type { Disposer } from "../../common/utils"; import type { Disposer } from "../../common/utils";
import { disposer, getOrInsert, noop, WrappedAbortController } from "../../common/utils"; import { disposer, getOrInsert, noop, WrappedAbortController } from "../../common/utils";
import { once } from "lodash"; import { once } from "lodash";
import type { ClusterFrameContext } from "../cluster-frame-context/cluster-frame-context";
import logger from "../../common/logger"; import logger from "../../common/logger";
import type { KubeObjectStoreLoadAllParams, KubeObjectStoreSubscribeParams } from "../../common/k8s-api/kube-object.store"; import type { KubeObjectStoreLoadAllParams, KubeObjectStoreSubscribeParams } from "../../common/k8s-api/kube-object.store";
import AbortController from "abort-controller"; import AbortController from "abort-controller";
import type { ClusterContext } from "../cluster-frame-context/cluster-frame-context";
// Kubernetes watch-api client // Kubernetes watch-api client
// API: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams // API: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams
@ -68,7 +68,7 @@ export interface KubeWatchSubscribeStoreOptions {
} }
interface Dependencies { interface Dependencies {
clusterFrameContext: ClusterFrameContext; readonly clusterContext: ClusterContext;
} }
export interface SubscribableStore { export interface SubscribableStore {
@ -86,7 +86,7 @@ export type SubscribeStores = (stores: SubscribableStore[], opts?: KubeWatchSubs
export class KubeWatchApi { export class KubeWatchApi {
readonly #watch = new WatchCount(); readonly #watch = new WatchCount();
constructor(private dependencies: Dependencies) {} constructor(private readonly dependencies: Dependencies) {}
private subscribeStore({ store, parent, namespaces, onLoadFailure }: SubscribeStoreParams): Disposer { private subscribeStore({ store, parent, namespaces, onLoadFailure }: SubscribeStoreParams): Disposer {
const isNamespaceFilterWatch = !namespaces; const isNamespaceFilterWatch = !namespaces;
@ -96,7 +96,7 @@ export class KubeWatchApi {
return () => this.#watch.dec(store); return () => this.#watch.dec(store);
} }
namespaces ??= this.dependencies.clusterFrameContext?.contextNamespaces ?? []; namespaces ??= this.dependencies.clusterContext?.contextNamespaces ?? [];
let childController = new WrappedAbortController(parent); let childController = new WrappedAbortController(parent);
const unsubscribe = disposer(); const unsubscribe = disposer();
@ -123,7 +123,7 @@ export class KubeWatchApi {
const cancelReloading = isNamespaceFilterWatch && store.api.isNamespaced const cancelReloading = isNamespaceFilterWatch && store.api.isNamespaced
? reaction( ? reaction(
// Note: must slice because reaction won't fire if it isn't there // Note: must slice because reaction won't fire if it isn't there
() => [this.dependencies.clusterFrameContext.contextNamespaces.slice(), this.dependencies.clusterFrameContext.hasSelectedAll] as const, () => [this.dependencies.clusterContext.contextNamespaces.slice(), this.dependencies.clusterContext.hasSelectedAll] as const,
([namespaces, curSelectedAll], [prevNamespaces, prevSelectedAll]) => { ([namespaces, curSelectedAll], [prevNamespaces, prevSelectedAll]) => {
if (curSelectedAll && prevSelectedAll) { if (curSelectedAll && prevSelectedAll) {
const action = namespaces.length > prevNamespaces.length ? "created" : "deleted"; const action = namespaces.length > prevNamespaces.length ? "created" : "deleted";

View File

@ -5,6 +5,7 @@
import type { KubeResource } from "../../common/rbac"; import type { KubeResource } from "../../common/rbac";
import { apiResourceRecord } from "../../common/rbac"; import { apiResourceRecord } from "../../common/rbac";
import { object } from "../../common/utils";
export const ResourceNames: Record<KubeResource, string> = { export const ResourceNames: Record<KubeResource, string> = {
"namespaces": "Namespaces", "namespaces": "Namespaces",
@ -42,7 +43,7 @@ export const ResourceNames: Record<KubeResource, string> = {
"serviceaccounts": "Service Accounts", "serviceaccounts": "Service Accounts",
}; };
export const ResourceKindMap: Record<string, KubeResource> = Object.fromEntries( export const ResourceKindMap = object.fromEntries(
Object.entries(apiResourceRecord) object.entries(apiResourceRecord)
.map(([resource, { kind }]) => [kind, resource as KubeResource]), .map(([resource, { kind }]) => [kind, resource]),
); );