mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Broadcast cluster's disconnected state before stopping KubeAuthProxy (#4273)
This commit is contained in:
parent
8c9e3b2fdc
commit
8081d35f9c
@ -328,6 +328,8 @@ utils.describeIf(minikubeReady(TEST_NAMESPACE))("Minikube based tests", () => {
|
|||||||
}, 10*60*1000);
|
}, 10*60*1000);
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
|
await frame.click(`[data-testid="sidebar-cluster-dropdown"]`);
|
||||||
|
await frame.click(`.Menu >> text="Disconnect"`);
|
||||||
await cleanup();
|
await cleanup();
|
||||||
}, 10*60*1000);
|
}, 10*60*1000);
|
||||||
|
|
||||||
@ -337,6 +339,7 @@ utils.describeIf(minikubeReady(TEST_NAMESPACE))("Minikube based tests", () => {
|
|||||||
await frame.waitForSelector(`.Menu >> text="Settings"`);
|
await frame.waitForSelector(`.Menu >> text="Settings"`);
|
||||||
await frame.waitForSelector(`.Menu >> text="Disconnect"`);
|
await frame.waitForSelector(`.Menu >> text="Disconnect"`);
|
||||||
await frame.waitForSelector(`.Menu >> text="Delete"`);
|
await frame.waitForSelector(`.Menu >> text="Delete"`);
|
||||||
|
await frame.click(`[data-testid="sidebar-cluster-dropdown"]`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should navigate around common cluster pages", async () => {
|
it("should navigate around common cluster pages", async () => {
|
||||||
|
|||||||
@ -72,7 +72,12 @@ export async function start() {
|
|||||||
...process.env,
|
...process.env,
|
||||||
},
|
},
|
||||||
timeout: 100_000,
|
timeout: 100_000,
|
||||||
} as Parameters<typeof electron["launch"]>[0]);
|
});
|
||||||
|
|
||||||
|
const cleanup = async () => {
|
||||||
|
await app.close();
|
||||||
|
await remove(CICD).catch(noop);
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const window = await getMainWindow(app);
|
const window = await getMainWindow(app);
|
||||||
@ -80,14 +85,10 @@ export async function start() {
|
|||||||
return {
|
return {
|
||||||
app,
|
app,
|
||||||
window,
|
window,
|
||||||
cleanup: async () => {
|
cleanup,
|
||||||
await app.close();
|
|
||||||
await remove(CICD).catch(noop);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await app.close();
|
await cleanup();
|
||||||
await remove(CICD).catch(noop);
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,8 @@ jest.mock("winston", () => ({
|
|||||||
label: jest.fn(),
|
label: jest.fn(),
|
||||||
timestamp: jest.fn(),
|
timestamp: jest.fn(),
|
||||||
printf: jest.fn(),
|
printf: jest.fn(),
|
||||||
|
padLevels: jest.fn(),
|
||||||
|
ms: jest.fn(),
|
||||||
},
|
},
|
||||||
createLogger: jest.fn().mockReturnValue(logger),
|
createLogger: jest.fn().mockReturnValue(logger),
|
||||||
transports: {
|
transports: {
|
||||||
@ -49,12 +51,31 @@ jest.mock("../context-handler");
|
|||||||
jest.mock("request");
|
jest.mock("request");
|
||||||
jest.mock("request-promise-native");
|
jest.mock("request-promise-native");
|
||||||
|
|
||||||
|
jest.mock("electron", () => ({
|
||||||
|
app: {
|
||||||
|
getVersion: () => "99.99.99",
|
||||||
|
getName: () => "lens",
|
||||||
|
setName: jest.fn(),
|
||||||
|
setPath: jest.fn(),
|
||||||
|
getPath: () => "tmp",
|
||||||
|
getLocale: () => "en",
|
||||||
|
setLoginItemSettings: jest.fn(),
|
||||||
|
},
|
||||||
|
ipcMain: {
|
||||||
|
on: jest.fn(),
|
||||||
|
once: jest.fn(),
|
||||||
|
handle: jest.fn(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
import { Console } from "console";
|
import { Console } from "console";
|
||||||
import mockFs from "mock-fs";
|
import mockFs from "mock-fs";
|
||||||
|
import { AppPaths } from "../../common/app-paths";
|
||||||
import { Cluster } from "../cluster";
|
import { Cluster } from "../cluster";
|
||||||
import { Kubectl } from "../kubectl";
|
import { Kubectl } from "../kubectl";
|
||||||
|
|
||||||
console = new Console(process.stdout, process.stderr); // fix mockFS
|
console = new Console(process.stdout, process.stderr); // fix mockFS
|
||||||
|
AppPaths.init();
|
||||||
|
|
||||||
describe("create clusters", () => {
|
describe("create clusters", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@ -42,6 +42,7 @@ jest.mock("electron", () => ({
|
|||||||
},
|
},
|
||||||
ipcMain: {
|
ipcMain: {
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
|
once: jest.fn(),
|
||||||
handle: jest.fn(),
|
handle: jest.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|||||||
@ -34,7 +34,7 @@ import { DetectorRegistry } from "./cluster-detectors/detector-registry";
|
|||||||
import plimit from "p-limit";
|
import plimit from "p-limit";
|
||||||
import type { ClusterState, ClusterRefreshOptions, ClusterMetricsResourceType, ClusterId, ClusterMetadata, ClusterModel, ClusterPreferences, ClusterPrometheusPreferences, UpdateClusterModel, KubeAuthUpdate } from "../common/cluster-types";
|
import type { ClusterState, ClusterRefreshOptions, ClusterMetricsResourceType, ClusterId, ClusterMetadata, ClusterModel, ClusterPreferences, ClusterPrometheusPreferences, UpdateClusterModel, KubeAuthUpdate } from "../common/cluster-types";
|
||||||
import { ClusterMetadataKey, initialNodeShellImage, ClusterStatus } from "../common/cluster-types";
|
import { ClusterMetadataKey, initialNodeShellImage, ClusterStatus } from "../common/cluster-types";
|
||||||
import { storedKubeConfigFolder, toJS } from "../common/utils";
|
import { disposer, storedKubeConfigFolder, toJS } from "../common/utils";
|
||||||
import type { Response } from "request";
|
import type { Response } from "request";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,7 +53,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
|||||||
*/
|
*/
|
||||||
public contextHandler: ContextHandler;
|
public contextHandler: ContextHandler;
|
||||||
protected kubeconfigManager: KubeconfigManager;
|
protected kubeconfigManager: KubeconfigManager;
|
||||||
protected eventDisposers: Function[] = [];
|
protected eventDisposers = disposer();
|
||||||
protected activated = false;
|
protected activated = false;
|
||||||
private resourceAccessStatuses: Map<KubeApiResource, boolean> = new Map();
|
private resourceAccessStatuses: Map<KubeApiResource, boolean> = new Map();
|
||||||
|
|
||||||
@ -324,15 +324,6 @@ export class Cluster implements ClusterModel, ClusterState {
|
|||||||
this.getProxyKubeconfig();
|
this.getProxyKubeconfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* internal
|
|
||||||
*/
|
|
||||||
protected unbindEvents() {
|
|
||||||
logger.info(`[CLUSTER]: unbind events`, this.getMeta());
|
|
||||||
this.eventDisposers.forEach(dispose => dispose());
|
|
||||||
this.eventDisposers.length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param force force activation
|
* @param force force activation
|
||||||
* @internal
|
* @internal
|
||||||
@ -395,8 +386,13 @@ export class Cluster implements ClusterModel, ClusterState {
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
@action disconnect() {
|
@action disconnect() {
|
||||||
this.unbindEvents();
|
logger.info(`[CLUSTER]: disconnecting cluster`, { id: this.id });
|
||||||
this.contextHandler?.stopServer();
|
|
||||||
|
ipcMain.once(`cluster:${this.id}:frame-removed`, () => {
|
||||||
|
this.contextHandler?.stopServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.eventDisposers();
|
||||||
this.disconnected = true;
|
this.disconnected = true;
|
||||||
this.online = false;
|
this.online = false;
|
||||||
this.accessible = false;
|
this.accessible = false;
|
||||||
@ -405,7 +401,6 @@ export class Cluster implements ClusterModel, ClusterState {
|
|||||||
this.allowedNamespaces = [];
|
this.allowedNamespaces = [];
|
||||||
this.resourceAccessStatuses.clear();
|
this.resourceAccessStatuses.clear();
|
||||||
this.pushState();
|
this.pushState();
|
||||||
logger.info(`[CLUSTER]: disconnect`, this.getMeta());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -129,11 +129,11 @@ export class KubeAuthProxy {
|
|||||||
this.ready = false;
|
this.ready = false;
|
||||||
|
|
||||||
if (this.proxyProcess) {
|
if (this.proxyProcess) {
|
||||||
logger.debug("[KUBE-AUTH]: stopping local proxy", this.cluster.getMeta());
|
logger.info("[KUBE-AUTH]: stopping local proxy", { clusterId: this.cluster.id });
|
||||||
|
this.proxyProcess.kill();
|
||||||
this.proxyProcess.removeAllListeners();
|
this.proxyProcess.removeAllListeners();
|
||||||
this.proxyProcess.stderr.removeAllListeners();
|
this.proxyProcess.stderr.removeAllListeners();
|
||||||
this.proxyProcess.stdout.removeAllListeners();
|
this.proxyProcess.stdout.removeAllListeners();
|
||||||
this.proxyProcess.kill();
|
|
||||||
this.proxyProcess = null;
|
this.proxyProcess = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
import { action, IReactionDisposer, makeObservable, observable, when } from "mobx";
|
import { action, IReactionDisposer, makeObservable, observable, when } from "mobx";
|
||||||
import logger from "../../../main/logger";
|
import logger from "../../../main/logger";
|
||||||
|
import { broadcastMessage } from "../../../common/ipc";
|
||||||
import { clusterVisibilityHandler } from "../../../common/cluster-ipc";
|
import { clusterVisibilityHandler } from "../../../common/cluster-ipc";
|
||||||
import { ClusterStore } from "../../../common/cluster-store";
|
import { ClusterStore } from "../../../common/cluster-store";
|
||||||
import type { ClusterId } from "../../../common/cluster-types";
|
import type { ClusterId } from "../../../common/cluster-types";
|
||||||
@ -88,6 +89,7 @@ export class ClusterFrameHandler extends Singleton {
|
|||||||
logger.info(`[LENS-VIEW]: remove dashboard, clusterId=${clusterId}`);
|
logger.info(`[LENS-VIEW]: remove dashboard, clusterId=${clusterId}`);
|
||||||
this.views.delete(clusterId);
|
this.views.delete(clusterId);
|
||||||
iframe.parentNode.removeChild(iframe);
|
iframe.parentNode.removeChild(iframe);
|
||||||
|
broadcastMessage(`cluster:${clusterId}:frame-removed`);
|
||||||
dispose();
|
dispose();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user