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:
parent
45910043d7
commit
fd84faf6ce
@ -25,6 +25,7 @@ import { KubeJsonApi } from "../kube-json-api";
|
|||||||
import { KubeObject } from "../kube-object";
|
import { KubeObject } from "../kube-object";
|
||||||
import AbortController from "abort-controller";
|
import AbortController from "abort-controller";
|
||||||
import { delay } from "../../utils/delay";
|
import { delay } from "../../utils/delay";
|
||||||
|
import { PassThrough } from "stream";
|
||||||
|
|
||||||
class TestKubeObject extends KubeObject {
|
class TestKubeObject extends KubeObject {
|
||||||
static kind = "Pod";
|
static kind = "Pod";
|
||||||
@ -170,8 +171,7 @@ describe("KubeApi", () => {
|
|||||||
const fallbackApiBase = "/apis/extensions/v1beta1/ingresses";
|
const fallbackApiBase = "/apis/extensions/v1beta1/ingresses";
|
||||||
const kubeApi = new KubeApi({
|
const kubeApi = new KubeApi({
|
||||||
request,
|
request,
|
||||||
objectConstructor: KubeObject,
|
objectConstructor: Object.assign(KubeObject, { apiBase }),
|
||||||
apiBase,
|
|
||||||
fallbackApiBases: [fallbackApiBase],
|
fallbackApiBases: [fallbackApiBase],
|
||||||
checkPreferredVersion: true,
|
checkPreferredVersion: true,
|
||||||
});
|
});
|
||||||
@ -304,19 +304,28 @@ describe("KubeApi", () => {
|
|||||||
|
|
||||||
describe("watch", () => {
|
describe("watch", () => {
|
||||||
let api: TestKubeApi;
|
let api: TestKubeApi;
|
||||||
|
let stream: PassThrough;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
api = new TestKubeApi({
|
api = new TestKubeApi({
|
||||||
request,
|
request,
|
||||||
objectConstructor: TestKubeObject,
|
objectConstructor: TestKubeObject,
|
||||||
});
|
});
|
||||||
|
stream = new PassThrough();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
stream.end();
|
||||||
|
stream.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends a valid watch request", () => {
|
it("sends a valid watch request", () => {
|
||||||
const spy = jest.spyOn(request, "getResponse");
|
const spy = jest.spyOn(request, "getResponse");
|
||||||
|
|
||||||
(fetch as any).mockResponse(async () => {
|
(fetch as any).mockResponse(async () => {
|
||||||
return {};
|
return {
|
||||||
|
body: stream,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
api.watch({ namespace: "kube-system" });
|
api.watch({ namespace: "kube-system" });
|
||||||
@ -327,7 +336,9 @@ describe("KubeApi", () => {
|
|||||||
const spy = jest.spyOn(request, "getResponse");
|
const spy = jest.spyOn(request, "getResponse");
|
||||||
|
|
||||||
(fetch as any).mockResponse(async () => {
|
(fetch as any).mockResponse(async () => {
|
||||||
return {};
|
return {
|
||||||
|
body: stream,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
api.watch({ namespace: "kube-system", timeout: 60 });
|
api.watch({ namespace: "kube-system", timeout: 60 });
|
||||||
@ -342,7 +353,9 @@ describe("KubeApi", () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
return {};
|
return {
|
||||||
|
body: stream,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
@ -364,20 +377,22 @@ describe("KubeApi", () => {
|
|||||||
it("if request ended", (done) => {
|
it("if request ended", (done) => {
|
||||||
const spy = jest.spyOn(request, "getResponse");
|
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(stream, "on").mockImplementation((eventName: string, callback: Function) => {
|
||||||
jest.spyOn(global, "fetch").mockImplementation(async () => {
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
body: {
|
|
||||||
on: (eventName: string, callback: Function) => {
|
|
||||||
// End the request in 100ms.
|
// End the request in 100ms.
|
||||||
if (eventName === "end") {
|
if (eventName === "end") {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
callback();
|
callback();
|
||||||
}, 100);
|
}, 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;
|
} as any;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -397,7 +412,9 @@ describe("KubeApi", () => {
|
|||||||
const spy = jest.spyOn(request, "getResponse");
|
const spy = jest.spyOn(request, "getResponse");
|
||||||
|
|
||||||
(fetch as any).mockResponse(async () => {
|
(fetch as any).mockResponse(async () => {
|
||||||
return {};
|
return {
|
||||||
|
body: stream,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const timeoutSeconds = 1;
|
const timeoutSeconds = 1;
|
||||||
@ -418,20 +435,22 @@ describe("KubeApi", () => {
|
|||||||
it("retries only once if request ends and timeout is set", (done) => {
|
it("retries only once if request ends and timeout is set", (done) => {
|
||||||
const spy = jest.spyOn(request, "getResponse");
|
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(stream, "on").mockImplementation((eventName: string, callback: Function) => {
|
||||||
jest.spyOn(global, "fetch").mockImplementation(async () => {
|
// End the request in 100ms.
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
body: {
|
|
||||||
on: (eventName: string, callback: Function) => {
|
|
||||||
// End the request in 100ms
|
|
||||||
if (eventName === "end") {
|
if (eventName === "end") {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
callback();
|
callback();
|
||||||
}, 100);
|
}, 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;
|
} as any;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -295,14 +295,18 @@ export class KubeApi<T extends KubeObject> {
|
|||||||
*/
|
*/
|
||||||
private async getLatestApiPrefixGroup() {
|
private async getLatestApiPrefixGroup() {
|
||||||
// Note that this.options.apiBase is the "full" url, whereas this.apiBase is parsed
|
// 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) {
|
for (const apiUrl of apiBases) {
|
||||||
|
if (!apiUrl) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
// Split e.g. "/apis/extensions/v1beta1/ingresses" to parts
|
// Split e.g. "/apis/extensions/v1beta1/ingresses" to parts
|
||||||
const { apiPrefix, apiGroup, apiVersionWithGroup, resource } = parseKubeApi(apiUrl);
|
const { apiPrefix, apiGroup, apiVersionWithGroup, resource } = parseKubeApi(apiUrl);
|
||||||
|
|
||||||
// Request available resources
|
// Request available resources
|
||||||
try {
|
|
||||||
const response = await this.request.get<IKubeResourceList>(`${apiPrefix}/${apiVersionWithGroup}`);
|
const response = await this.request.get<IKubeResourceList>(`${apiPrefix}/${apiVersionWithGroup}`);
|
||||||
|
|
||||||
// If the resource is found in the group, use this apiUrl
|
// 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();
|
return await this.getLatestApiPrefixGroup();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// If valid API wasn't found, log the error and return defaults below
|
// If valid API wasn't found, log the error and return defaults below
|
||||||
logger.error(error);
|
logger.error(`[KUBE-API]: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -219,7 +219,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
|
|||||||
|
|
||||||
case "rejected":
|
case "rejected":
|
||||||
if (onLoadFailure) {
|
if (onLoadFailure) {
|
||||||
onLoadFailure(result.reason.message);
|
onLoadFailure(result.reason.message || result.reason);
|
||||||
} else {
|
} else {
|
||||||
// if onLoadFailure is not provided then preserve old behaviour
|
// if onLoadFailure is not provided then preserve old behaviour
|
||||||
throw result.reason;
|
throw result.reason;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user