diff --git a/src/utils/kubernetes/httproute-list.js b/src/utils/kubernetes/httproute-list.js index df147d169..1198c1d05 100644 --- a/src/utils/kubernetes/httproute-list.js +++ b/src/utils/kubernetes/httproute-list.js @@ -1,4 +1,4 @@ -import { CoreV1Api, CustomObjectsApi } from "@kubernetes/client-node"; +import { CustomObjectsApi } from "@kubernetes/client-node"; import { getKubeConfig, getKubernetes, HTTPROUTE_API_GROUP, HTTPROUTE_API_VERSION } from "utils/config/kubernetes"; import createLogger from "utils/logger"; @@ -7,49 +7,28 @@ const logger = createLogger("httproute-list"); const kc = getKubeConfig(); export default async function listHttpRoute() { - const crd = kc.makeApiClient(CustomObjectsApi); - const core = kc.makeApiClient(CoreV1Api); const { gateway } = getKubernetes(); - let httpRouteList = []; if (gateway) { - // httproutes - const getHttpRoutes = async (namespace) => - crd - .listNamespacedCustomObject({ - group: HTTPROUTE_API_GROUP, - version: HTTPROUTE_API_VERSION, - namespace, - plural: "httproutes", - }) - .then((response) => { - return response.items; - }) - .catch((error) => { - logger.error("Error getting httproutes: %d %s %s", error.statusCode, error.body, error.response); - logger.debug(error); - return null; - }); - // namespaces - const namespaces = await core - .listNamespace() - .then((response) => response.items.map((ns) => ns.metadata.name)) + const crd = kc.makeApiClient(CustomObjectsApi); + + const httpRoutes = await crd + .listClusterCustomObject({ + group: HTTPROUTE_API_GROUP, + version: HTTPROUTE_API_VERSION, + plural: "httproutes", + }) + .then((response) => { + return response?.items ?? []; + }) .catch((error) => { - logger.error("Error getting namespaces: %d %s %s", error.statusCode, error.body, error.response); + logger.error("Error getting httproutes: %d %s %s", error.statusCode, error.body, error.response); logger.debug(error); - return null; + return []; }); - if (namespaces) { - const httpRouteListUnfiltered = await Promise.all( - namespaces.map(async (namespace) => { - const httpRoutes = await getHttpRoutes(namespace); - return httpRoutes; - }), - ); - - httpRouteList = httpRouteListUnfiltered.flat().filter((httpRoute) => httpRoute); - } + return httpRoutes; } - return httpRouteList; + + return []; } diff --git a/src/utils/kubernetes/httproute-list.test.js b/src/utils/kubernetes/httproute-list.test.js index 384c7eca0..ab6221bf5 100644 --- a/src/utils/kubernetes/httproute-list.test.js +++ b/src/utils/kubernetes/httproute-list.test.js @@ -3,19 +3,12 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; const { state, getKubernetes, getKubeConfig, logger } = vi.hoisted(() => { const state = { enabled: true, - namespaces: ["a", "b"], - routesByNs: { - a: [{ metadata: { name: "r1" } }], - b: [{ metadata: { name: "r2" } }], - }, + items: [{ metadata: { name: "r1" } }, { metadata: { name: "r2" } }], crd: { - listNamespacedCustomObject: vi.fn(async ({ namespace }) => ({ items: state.routesByNs[namespace] ?? [] })), - }, - core: { - listNamespace: vi.fn(async () => ({ items: state.namespaces.map((n) => ({ metadata: { name: n } })) })), + listClusterCustomObject: vi.fn(async () => ({ items: state.items })), }, kc: { - makeApiClient: vi.fn((Api) => (Api.name === "CoreV1Api" ? state.core : state.crd)), + makeApiClient: vi.fn(() => state.crd), }, }; @@ -28,7 +21,6 @@ const { state, getKubernetes, getKubeConfig, logger } = vi.hoisted(() => { }); vi.mock("@kubernetes/client-node", () => ({ - CoreV1Api: class CoreV1Api {}, CustomObjectsApi: class CustomObjectsApi {}, })); @@ -47,11 +39,7 @@ describe("utils/kubernetes/httproute-list", () => { beforeEach(() => { vi.clearAllMocks(); state.enabled = true; - state.namespaces = ["a", "b"]; - state.routesByNs = { - a: [{ metadata: { name: "r1" } }], - b: [{ metadata: { name: "r2" } }], - }; + state.items = [{ metadata: { name: "r1" } }, { metadata: { name: "r2" } }]; }); it("returns an empty list when gateway discovery is disabled", async () => { @@ -64,19 +52,18 @@ describe("utils/kubernetes/httproute-list", () => { expect(result).toEqual([]); }); - it("lists namespaces and aggregates httproutes", async () => { + it("lists httproutes", async () => { vi.resetModules(); const listHttpRoute = (await import("./httproute-list")).default; const result = await listHttpRoute(); expect(result.map((r) => r.metadata.name)).toEqual(["r1", "r2"]); - expect(state.core.listNamespace).toHaveBeenCalled(); - expect(state.crd.listNamespacedCustomObject).toHaveBeenCalledTimes(2); + expect(state.crd.listClusterCustomObject).toHaveBeenCalled(); }); - it("logs and returns [] when namespace listing fails", async () => { - state.core.listNamespace.mockRejectedValueOnce({ statusCode: 500, body: "boom", response: "resp" }); + it("logs and returns [] when cluster listing fails", async () => { + state.crd.listClusterCustomObject.mockRejectedValueOnce({ statusCode: 500, body: "boom", response: "resp" }); vi.resetModules(); const listHttpRoute = (await import("./httproute-list")).default; @@ -87,20 +74,4 @@ describe("utils/kubernetes/httproute-list", () => { expect(logger.error).toHaveBeenCalled(); expect(logger.debug).toHaveBeenCalled(); }); - - it("skips namespaces whose httproute queries fail", async () => { - state.crd.listNamespacedCustomObject.mockImplementation(async ({ namespace }) => { - if (namespace === "b") throw { statusCode: 500, body: "boom", response: "resp" }; - return { items: state.routesByNs[namespace] ?? [] }; - }); - - vi.resetModules(); - const listHttpRoute = (await import("./httproute-list")).default; - - const result = await listHttpRoute(); - - expect(result.map((r) => r.metadata.name)).toEqual(["r1"]); - expect(logger.error).toHaveBeenCalled(); - expect(logger.debug).toHaveBeenCalled(); - }); });