diff --git a/src/common/cluster/list-api-resources.injectable.ts b/src/common/cluster/list-api-resources.injectable.ts index ed9d5c9c39..f744b192da 100644 --- a/src/common/cluster/list-api-resources.injectable.ts +++ b/src/common/cluster/list-api-resources.injectable.ts @@ -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; */ 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; + }; + }; }, });