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

Refactoring ListApiResources

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-11-25 12:26:35 -05:00
parent c1c44471a3
commit 40a7bf8830

View File

@ -9,11 +9,9 @@ import type {
V1APIVersions,
} from "@kubernetes/client-node";
import { getInjectable } from "@ogre-tools/injectable";
import type { K8sRequest } from "../../main/k8s-request.injectable";
import k8SRequestInjectable from "../../main/k8s-request.injectable";
import type { Logger } from "../logger";
import loggerInjectable from "../logger.injectable";
import type { KubeApiResource, KubeResource } from "../rbac";
import type { KubeApiResource } from "../rbac";
import type { Cluster } from "./cluster";
import plimit from "p-limit";
@ -24,67 +22,77 @@ export type RequestListApiResources = () => Promise<KubeApiResource[]>;
*/
export type ListApiResources = (cluster: Cluster) => RequestListApiResources;
interface Dependencies {
logger: Logger;
k8sRequest: K8sRequest;
interface KubeResourceListGroup {
group: string;
path: string;
}
const listApiResources = ({ k8sRequest, logger }: Dependencies): ListApiResources => {
return (cluster) => {
const clusterRequest = (path: string) => k8sRequest(cluster, path);
const apiLimit = plimit(5);
return async () => {
const resources: KubeApiResource[] = [];
try {
const resourceListGroups:{ group:string;path:string }[] = [];
await Promise.all(
[
clusterRequest("/api").then((response:V1APIVersions)=>response.versions.forEach(version => resourceListGroups.push({ group:version, path:`/api/${version}` }))),
clusterRequest("/apis").then((response:V1APIGroupList) => response.groups.forEach(group => {
const preferredVersion = group.preferredVersion?.groupVersion;
if (preferredVersion) {
resourceListGroups.push({ group:group.name, path:`/apis/${preferredVersion}` });
}
})),
],
);
await Promise.all(
resourceListGroups.map(({ group, path }) => apiLimit(async () => {
const apiResources:V1APIResourceList = await clusterRequest(path);
if (apiResources.resources) {
resources.push(
...apiResources.resources.filter(resource => resource.verbs.includes("list")).map((resource) => ({
apiName: resource.name as KubeResource,
kind: resource.kind,
group,
})),
);
}
}),
),
);
} catch (error) {
logger.error(`[LIST-API-RESOURCES]: failed to list api resources: ${error}`);
}
return resources;
};
};
};
const listApiResourcesInjectable = getInjectable({
id: "list-api-resources",
instantiate: (di) => {
instantiate: (di): ListApiResources => {
const k8sRequest = di.inject(k8SRequestInjectable);
const logger = di.inject(loggerInjectable);
return listApiResources({ k8sRequest, logger });
return (cluster) => {
const apiLimit = plimit(5);
return async () => {
const kubeApiResources: KubeApiResource[] = [];
const resourceListGroups: KubeResourceListGroup[] = [];
try {
await Promise.all([
(async () => {
const { versions } = await k8sRequest(cluster, "/api") as V1APIVersions;
for (const version of versions) {
resourceListGroups.push({
group: version,
path: `/api/${version}`,
});
}
})(),
(async () => {
const { groups } = await k8sRequest(cluster, "/apis") as V1APIGroupList;
for (const { preferredVersion, name } of groups) {
const { groupVersion } = preferredVersion ?? {};
if (groupVersion) {
resourceListGroups.push({
group: name,
path: `/apis/${groupVersion}`,
});
}
}
})(),
]);
await Promise.all(
resourceListGroups.map(({ group, path }) => apiLimit(async () => {
const { resources } = await k8sRequest(cluster, path) as V1APIResourceList;
for (const resource of resources) {
if (!resource.verbs.includes("list")) {
continue;
}
kubeApiResources.push({
apiName: resource.name,
kind: resource.kind,
group,
namespaced: resource.namespaced,
});
}
})),
);
} catch (error) {
logger.error(`[LIST-API-RESOURCES]: failed to list api resources: ${error}`);
}
return kubeApiResources;
};
};
},
});