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

View File

@ -42,7 +42,9 @@ describe("cluster/namespaces - edit namespaces from previously opened tab", () =
windowDi.override(callForResourceInjectable, () => callForNamespaceMock);
});
builder.allowKubeResource("namespaces");
builder.allowKubeResource({
apiName: "namespaces",
});
});
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", () => {
beforeEach(() => {
builder.allowKubeResource("namespaces");
builder.allowKubeResource({
apiName: "namespaces",
});
});
it("renders", () => {

View File

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

View File

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

View File

@ -2,15 +2,20 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
import { computed } from "mobx";
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.
const allowedResourcesInjectable = getInjectable({
id: "allowed-resources",
instantiate: () => computed(() => new Set<string>()),
instantiate: () => computed(() => false),
injectionToken: shouldShowResourceInjectionToken,
lifecycle: lifecycleEnum.keyedSingleton({
getInstanceKey: (di, resource: KubeApiResourceDescriptor) => formatKubeApiResource(resource),
}),
});
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 { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
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 createListApiResourcesInjectable from "../../common/cluster/request-api-resources.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 broadcastMessageInjectable from "../../common/ipc/broadcast-message.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({
id: "create-cluster",
@ -30,7 +30,7 @@ const createClusterInjectable = getInjectable({
createKubectl: di.inject(createKubectlInjectable),
createContextHandler: di.inject(createContextHandlerInjectable),
createAuthorizationReview: di.inject(authorizationReviewInjectable),
createAuthorizationNamespaceReview: di.inject(createAuthorizationNamespaceReview),
requestNamespaceListPermissionsFor: di.inject(requestNamespaceListPermissionsForInjectable),
requestApiResources: di.inject(createListApiResourcesInjectable),
createListNamespaces: di.inject(listNamespacesInjectable),
logger: di.inject(loggerInjectable),

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.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 { RuntimeClassStore } from "./store";
@ -16,7 +17,9 @@ const runtimeClassStoreInjectable = getInjectable({
const api = di.inject(runtimeClassApiInjectable);
return new RuntimeClassStore(api);
return new RuntimeClassStore({
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,
});

View File

@ -7,6 +7,7 @@ import assert from "assert";
import getPodByIdInjectable from "../+workloads-pods/get-pod-by-id.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.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 { EventStore } from "./store";
@ -19,6 +20,7 @@ const eventStoreInjectable = getInjectable({
return new EventStore({
getPodById: di.inject(getPodByIdInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -5,7 +5,7 @@
import groupBy from "lodash/groupBy";
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 { autoBind } from "../../utils";
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 type { GetPodById } from "../+workloads-pods/get-pod-by-id.injectable";
interface Dependencies {
export interface EventStoreDependencies extends KubeObjectStoreDependencies {
getPodById: GetPodById;
}
export class EventStore extends KubeObjectStore<KubeEvent, KubeEventApi> {
constructor(
protected readonly dependencies: Dependencies,
protected readonly dependencies: EventStoreDependencies,
api: KubeEventApi,
opts: KubeObjectStoreOptions = {},
) {
super(api, { limit: 1000, ...opts });
super(dependencies, api, { limit: 1000, ...opts });
autoBind(this);
}

View File

@ -7,6 +7,7 @@ import assert from "assert";
import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.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 { JobStore } from "./store";
@ -19,6 +20,7 @@ const jobStoreInjectable = getInjectable({
return new JobStore({
getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

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

View File

@ -18,7 +18,6 @@ import { Icon } from "../icon";
import { TooltipPosition } from "../tooltip";
import { withInjectables } from "@ogre-tools/injectable-react";
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 workloadOverviewDetailsInjectable from "./workload-overview-details/workload-overview-details.injectable";
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 type { EventStore } from "../+events/store";
import eventStoreInjectable from "../+events/store.injectable";
import type { ClusterContext } from "../../cluster-frame-context/cluster-frame-context";
interface Dependencies {
detailComponents: IComputedValue<React.ElementType<{}>[]>;
clusterFrameContext: ClusterFrameContext;
clusterFrameContext: ClusterContext;
subscribeStores: SubscribeStores;
podStore: PodStore;
daemonSetStore: DaemonSetStore;

View File

@ -20,7 +20,6 @@ import { ResourceKindMap, ResourceNames } from "../../utils/rbac";
import { Icon } from "../icon";
import { TooltipPosition } from "../tooltip";
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 type { SubscribableStore, SubscribeStores } from "../../kube-watch-api/kube-watch-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 kubeSelectedUrlParamInjectable from "../kube-detail-params/kube-selected-url.injectable";
import toggleKubeDetailsPaneInjectable from "../kube-detail-params/toggle-details.injectable";
import type { ClusterContext } from "../../cluster-frame-context/cluster-frame-context";
export interface KubeObjectListLayoutProps<
K extends KubeObject,
@ -43,7 +43,7 @@ export interface KubeObjectListLayoutProps<
}
interface Dependencies {
clusterFrameContext: ClusterFrameContext;
clusterFrameContext: ClusterContext;
subscribeToStores: SubscribeStores;
kubeSelectedUrlParam: PageParam<string>;
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 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 { ClusterFrameContext } from "../../cluster-frame-context/cluster-frame-context";
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 startFrameInjectable from "../../start-frame/start-frame.injectable";
import type { NamespaceStore } from "../+namespaces/store";
@ -532,17 +530,8 @@ export const getApplicationBuilder = () => {
getTotalCount: () => namespaceItems.length,
} as Partial<NamespaceStore> as NamespaceStore;
const clusterFrameContextFake = new ClusterFrameContext(
clusterStub,
{
namespaceStore: namespaceStoreStub,
},
);
windowDi.override(namespaceStoreInjectable, () => namespaceStoreStub);
windowDi.override(hostedClusterInjectable, () => clusterStub);
windowDi.override(clusterFrameContextForNamespacedResourcesInjectable, () => clusterFrameContextFake);
});
return builder;

View File

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

View File

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