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

Fix getLatestApiPrefixGroup to not fail when options.apiBase is not provided (#4462)

This commit is contained in:
Sebastian Malton 2021-11-30 11:27:20 -05:00
parent 45910043d7
commit fd84faf6ce
3 changed files with 63 additions and 40 deletions

View File

@ -25,6 +25,7 @@ import { KubeJsonApi } from "../kube-json-api";
import { KubeObject } from "../kube-object";
import AbortController from "abort-controller";
import { delay } from "../../utils/delay";
import { PassThrough } from "stream";
class TestKubeObject extends KubeObject {
static kind = "Pod";
@ -170,8 +171,7 @@ describe("KubeApi", () => {
const fallbackApiBase = "/apis/extensions/v1beta1/ingresses";
const kubeApi = new KubeApi({
request,
objectConstructor: KubeObject,
apiBase,
objectConstructor: Object.assign(KubeObject, { apiBase }),
fallbackApiBases: [fallbackApiBase],
checkPreferredVersion: true,
});
@ -304,19 +304,28 @@ describe("KubeApi", () => {
describe("watch", () => {
let api: TestKubeApi;
let stream: PassThrough;
beforeEach(() => {
api = new TestKubeApi({
request,
objectConstructor: TestKubeObject,
});
stream = new PassThrough();
});
afterEach(() => {
stream.end();
stream.destroy();
});
it("sends a valid watch request", () => {
const spy = jest.spyOn(request, "getResponse");
(fetch as any).mockResponse(async () => {
return {};
return {
body: stream,
};
});
api.watch({ namespace: "kube-system" });
@ -327,7 +336,9 @@ describe("KubeApi", () => {
const spy = jest.spyOn(request, "getResponse");
(fetch as any).mockResponse(async () => {
return {};
return {
body: stream,
};
});
api.watch({ namespace: "kube-system", timeout: 60 });
@ -342,7 +353,9 @@ describe("KubeApi", () => {
done();
});
return {};
return {
body: stream,
};
});
const abortController = new AbortController();
@ -364,20 +377,22 @@ describe("KubeApi", () => {
it("if request ended", (done) => {
const spy = jest.spyOn(request, "getResponse");
// we need to mock using jest as jest-fetch-mock doesn't support mocking the body completely
jest.spyOn(global, "fetch").mockImplementation(async () => {
return {
ok: true,
body: {
on: (eventName: string, callback: Function) => {
jest.spyOn(stream, "on").mockImplementation((eventName: string, callback: Function) => {
// End the request in 100ms.
if (eventName === "end") {
setTimeout(() => {
callback();
}, 100);
}
},
},
return stream;
});
// we need to mock using jest as jest-fetch-mock doesn't support mocking the body completely
jest.spyOn(global, "fetch").mockImplementation(async () => {
return {
ok: true,
body: stream,
} as any;
});
@ -397,7 +412,9 @@ describe("KubeApi", () => {
const spy = jest.spyOn(request, "getResponse");
(fetch as any).mockResponse(async () => {
return {};
return {
body: stream,
};
});
const timeoutSeconds = 1;
@ -418,20 +435,22 @@ describe("KubeApi", () => {
it("retries only once if request ends and timeout is set", (done) => {
const spy = jest.spyOn(request, "getResponse");
// we need to mock using jest as jest-fetch-mock doesn't support mocking the body completely
jest.spyOn(global, "fetch").mockImplementation(async () => {
return {
ok: true,
body: {
on: (eventName: string, callback: Function) => {
// End the request in 100ms
jest.spyOn(stream, "on").mockImplementation((eventName: string, callback: Function) => {
// End the request in 100ms.
if (eventName === "end") {
setTimeout(() => {
callback();
}, 100);
}
},
},
return stream;
});
// we need to mock using jest as jest-fetch-mock doesn't support mocking the body completely
jest.spyOn(global, "fetch").mockImplementation(async () => {
return {
ok: true,
body: stream,
} as any;
});

View File

@ -295,14 +295,18 @@ export class KubeApi<T extends KubeObject> {
*/
private async getLatestApiPrefixGroup() {
// Note that this.options.apiBase is the "full" url, whereas this.apiBase is parsed
const apiBases = [this.options.apiBase, ...this.options.fallbackApiBases];
const apiBases = [this.options.apiBase, this.objectConstructor.apiBase, ...this.options.fallbackApiBases];
for (const apiUrl of apiBases) {
if (!apiUrl) {
continue;
}
try {
// Split e.g. "/apis/extensions/v1beta1/ingresses" to parts
const { apiPrefix, apiGroup, apiVersionWithGroup, resource } = parseKubeApi(apiUrl);
// Request available resources
try {
const response = await this.request.get<IKubeResourceList>(`${apiPrefix}/${apiVersionWithGroup}`);
// If the resource is found in the group, use this apiUrl
@ -326,7 +330,7 @@ export class KubeApi<T extends KubeObject> {
return await this.getLatestApiPrefixGroup();
} catch (error) {
// If valid API wasn't found, log the error and return defaults below
logger.error(error);
logger.error(`[KUBE-API]: ${error}`);
}
}

View File

@ -219,7 +219,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
case "rejected":
if (onLoadFailure) {
onLoadFailure(result.reason.message);
onLoadFailure(result.reason.message || result.reason);
} else {
// if onLoadFailure is not provided then preserve old behaviour
throw result.reason;