mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix cluster.test.ts tests
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
199f142559
commit
ffb840f0ed
@ -3,7 +3,6 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { ipcMain } from "electron";
|
||||
import { action, comparer, computed, makeObservable, observable, reaction, when } from "mobx";
|
||||
import { broadcastMessage } from "../ipc";
|
||||
import type { ClusterContextHandler } from "../../main/context-handler/context-handler";
|
||||
@ -14,7 +13,6 @@ import type { KubeconfigManager } from "../../main/kubeconfig-manager/kubeconfig
|
||||
import { loadConfigFromFile, loadConfigFromFileSync, validateKubeConfig } from "../kube-helpers";
|
||||
import type { KubeApiResource, KubeResource } from "../rbac";
|
||||
import { apiResourceRecord, apiResources } from "../rbac";
|
||||
import logger from "../../main/logger";
|
||||
import { VersionDetector } from "../../main/cluster-detectors/version-detector";
|
||||
import { DetectorRegistry } from "../../main/cluster-detectors/detector-registry";
|
||||
import plimit from "p-limit";
|
||||
@ -26,11 +24,13 @@ import { clusterListNamespaceForbiddenChannel } from "../ipc/cluster";
|
||||
import type { CanI } from "./authorization-review.injectable";
|
||||
import type { ListNamespaces } from "./list-namespaces.injectable";
|
||||
import assert from "assert";
|
||||
import type { Logger } from "../logger";
|
||||
|
||||
export interface ClusterDependencies {
|
||||
readonly directoryForKubeConfigs: string;
|
||||
createKubeconfigManager: (cluster: Cluster) => KubeconfigManager;
|
||||
createContextHandler: (cluster: Cluster) => ClusterContextHandler;
|
||||
readonly logger: Logger;
|
||||
createKubeconfigManager: (cluster: Cluster) => KubeconfigManager | undefined;
|
||||
createContextHandler: (cluster: Cluster) => ClusterContextHandler | undefined;
|
||||
createKubectl: (clusterVersion: string) => Kubectl;
|
||||
createAuthorizationReview: (config: KubeConfig) => CanI;
|
||||
createListNamespaces: (config: KubeConfig) => ListNamespaces;
|
||||
@ -256,17 +256,14 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
|
||||
this.apiUrl = cluster.server;
|
||||
|
||||
if (ipcMain) {
|
||||
// for the time being, until renderer gets its own cluster type
|
||||
this._contextHandler = this.dependencies.createContextHandler(this);
|
||||
this._proxyKubeconfigManager = this.dependencies.createKubeconfigManager(this);
|
||||
|
||||
logger.debug(`[CLUSTER]: Cluster init success`, {
|
||||
id: this.id,
|
||||
context: this.contextName,
|
||||
apiUrl: this.apiUrl,
|
||||
});
|
||||
}
|
||||
// for the time being, until renderer gets its own cluster type
|
||||
this._contextHandler = this.dependencies.createContextHandler(this);
|
||||
this._proxyKubeconfigManager = this.dependencies.createKubeconfigManager(this);
|
||||
this.dependencies.logger.debug(`[CLUSTER]: Cluster init success`, {
|
||||
id: this.id,
|
||||
context: this.contextName,
|
||||
apiUrl: this.apiUrl,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -309,7 +306,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
* @internal
|
||||
*/
|
||||
protected bindEvents() {
|
||||
logger.info(`[CLUSTER]: bind events`, this.getMeta());
|
||||
this.dependencies.logger.info(`[CLUSTER]: bind events`, this.getMeta());
|
||||
const refreshTimer = setInterval(() => !this.disconnected && this.refresh(), 30000); // every 30s
|
||||
const refreshMetadataTimer = setInterval(() => !this.disconnected && this.refreshMetadata(), 900000); // every 15 minutes
|
||||
|
||||
@ -330,13 +327,13 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
* @internal
|
||||
*/
|
||||
protected async recreateProxyKubeconfig() {
|
||||
logger.info("[CLUSTER]: Recreating proxy kubeconfig");
|
||||
this.dependencies.logger.info("[CLUSTER]: Recreating proxy kubeconfig");
|
||||
|
||||
try {
|
||||
await this.proxyKubeconfigManager.clear();
|
||||
await this.getProxyKubeconfig();
|
||||
} catch (error) {
|
||||
logger.error(`[CLUSTER]: failed to recreate proxy kubeconfig`, error);
|
||||
this.dependencies.logger.error(`[CLUSTER]: failed to recreate proxy kubeconfig`, error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,7 +347,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
return this.pushState();
|
||||
}
|
||||
|
||||
logger.info(`[CLUSTER]: activate`, this.getMeta());
|
||||
this.dependencies.logger.info(`[CLUSTER]: activate`, this.getMeta());
|
||||
|
||||
if (!this.eventsDisposer.length) {
|
||||
this.bindEvents();
|
||||
@ -368,7 +365,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
await this.refreshAccessibility();
|
||||
// download kubectl in background, so it's not blocking dashboard
|
||||
this.ensureKubectl()
|
||||
.catch(error => logger.warn(`[CLUSTER]: failed to download kubectl for clusterId=${this.id}`, error));
|
||||
.catch(error => this.dependencies.logger.warn(`[CLUSTER]: failed to download kubectl for clusterId=${this.id}`, error));
|
||||
this.broadcastConnectUpdate("Connected, waiting for view to load ...");
|
||||
}
|
||||
|
||||
@ -392,7 +389,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
*/
|
||||
@action
|
||||
async reconnect() {
|
||||
logger.info(`[CLUSTER]: reconnect`, this.getMeta());
|
||||
this.dependencies.logger.info(`[CLUSTER]: reconnect`, this.getMeta());
|
||||
await this.contextHandler?.restartServer();
|
||||
this.disconnected = false;
|
||||
}
|
||||
@ -402,10 +399,10 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
*/
|
||||
@action disconnect(): void {
|
||||
if (this.disconnected) {
|
||||
return void logger.debug("[CLUSTER]: already disconnected", { id: this.id });
|
||||
return void this.dependencies.logger.debug("[CLUSTER]: already disconnected", { id: this.id });
|
||||
}
|
||||
|
||||
logger.info(`[CLUSTER]: disconnecting`, { id: this.id });
|
||||
this.dependencies.logger.info(`[CLUSTER]: disconnecting`, { id: this.id });
|
||||
this.eventsDisposer();
|
||||
this.contextHandler?.stopServer();
|
||||
this.disconnected = true;
|
||||
@ -416,7 +413,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
this.allowedNamespaces = [];
|
||||
this.resourceAccessStatuses.clear();
|
||||
this.pushState();
|
||||
logger.info(`[CLUSTER]: disconnected`, { id: this.id });
|
||||
this.dependencies.logger.info(`[CLUSTER]: disconnected`, { id: this.id });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -425,7 +422,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
*/
|
||||
@action
|
||||
async refresh(opts: ClusterRefreshOptions = {}) {
|
||||
logger.info(`[CLUSTER]: refresh`, this.getMeta());
|
||||
this.dependencies.logger.info(`[CLUSTER]: refresh`, this.getMeta());
|
||||
await this.refreshConnectionStatus();
|
||||
|
||||
if (this.accessible) {
|
||||
@ -443,7 +440,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
*/
|
||||
@action
|
||||
async refreshMetadata() {
|
||||
logger.info(`[CLUSTER]: refreshMetadata`, this.getMeta());
|
||||
this.dependencies.logger.info(`[CLUSTER]: refreshMetadata`, this.getMeta());
|
||||
const metadata = await DetectorRegistry.getInstance().detectForCluster(this);
|
||||
const existingMetadata = this.metadata;
|
||||
|
||||
@ -514,7 +511,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
|
||||
return ClusterStatus.AccessGranted;
|
||||
} catch (error) {
|
||||
logger.error(`[CLUSTER]: Failed to connect to "${this.contextName}": ${error}`);
|
||||
this.dependencies.logger.error(`[CLUSTER]: Failed to connect to "${this.contextName}": ${error}`);
|
||||
|
||||
if (isRequestError(error)) {
|
||||
if (error.statusCode) {
|
||||
@ -594,7 +591,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
* @param state cluster state
|
||||
*/
|
||||
pushState(state = this.getState()) {
|
||||
logger.silly(`[CLUSTER]: push-state`, state);
|
||||
this.dependencies.logger.silly(`[CLUSTER]: push-state`, state);
|
||||
broadcastMessage("cluster:state", this.id, state);
|
||||
}
|
||||
|
||||
@ -617,7 +614,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
broadcastConnectUpdate(message: string, isError = false): void {
|
||||
const update: KubeAuthUpdate = { message, isError };
|
||||
|
||||
logger.debug(`[CLUSTER]: broadcasting connection update`, { ...update, meta: this.getMeta() });
|
||||
this.dependencies.logger.debug(`[CLUSTER]: broadcasting connection update`, { ...update, meta: this.getMeta() });
|
||||
broadcastMessage(`cluster:${this.id}:connection-update`, update);
|
||||
}
|
||||
|
||||
@ -637,7 +634,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
if (namespaceList.length === 0 && error instanceof HttpError && error.statusCode === 403) {
|
||||
const { response } = error as HttpError & { response: Response };
|
||||
|
||||
logger.info("[CLUSTER]: listing namespaces is forbidden, broadcasting", { clusterId: this.id, error: response.body });
|
||||
this.dependencies.logger.info("[CLUSTER]: listing namespaces is forbidden, broadcasting", { clusterId: this.id, error: response.body });
|
||||
broadcastMessage(clusterListNamespaceForbiddenChannel, this.id);
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ export interface Logger {
|
||||
error: (message: string, ...args: any) => void;
|
||||
debug: (message: string, ...args: any) => void;
|
||||
warn: (message: string, ...args: any) => void;
|
||||
silly: (message: string, ...args: any) => void;
|
||||
}
|
||||
|
||||
const logLevel = process.env.LOG_LEVEL
|
||||
|
||||
@ -3,32 +3,6 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
const logger = {
|
||||
silly: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
log: jest.fn(),
|
||||
info: jest.fn(),
|
||||
error: jest.fn(),
|
||||
crit: jest.fn(),
|
||||
};
|
||||
|
||||
jest.mock("winston", () => ({
|
||||
format: {
|
||||
colorize: jest.fn(),
|
||||
combine: jest.fn(),
|
||||
simple: jest.fn(),
|
||||
label: jest.fn(),
|
||||
timestamp: jest.fn(),
|
||||
printf: jest.fn(),
|
||||
splat: jest.fn(),
|
||||
},
|
||||
createLogger: jest.fn().mockReturnValue(logger),
|
||||
transports: {
|
||||
Console: jest.fn(),
|
||||
File: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock("../../common/ipc");
|
||||
jest.mock("request");
|
||||
jest.mock("request-promise-native");
|
||||
@ -109,6 +83,7 @@ describe("create clusters", () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cluster.disconnect();
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ import createContextHandlerInjectable from "../context-handler/create-context-ha
|
||||
import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
|
||||
import authorizationReviewInjectable from "../../common/cluster/authorization-review.injectable";
|
||||
import listNamespacesInjectable from "../../common/cluster/list-namespaces.injectable";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
|
||||
const createClusterInjectable = getInjectable({
|
||||
id: "create-cluster",
|
||||
@ -24,6 +25,7 @@ const createClusterInjectable = getInjectable({
|
||||
createContextHandler: di.inject(createContextHandlerInjectable),
|
||||
createAuthorizationReview: di.inject(authorizationReviewInjectable),
|
||||
createListNamespaces: di.inject(listNamespacesInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
};
|
||||
|
||||
return (model) => new Cluster(dependencies, model);
|
||||
|
||||
@ -108,6 +108,7 @@ export const getDiForUnitTesting = (
|
||||
debug: noop,
|
||||
error: (message: string, ...args: any) => console.error(message, ...args),
|
||||
info: noop,
|
||||
silly: noop,
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ import type { ClusterDependencies } from "../../common/cluster/cluster";
|
||||
import { Cluster } from "../../common/cluster/cluster";
|
||||
import directoryForKubeConfigsInjectable from "../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
||||
import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
|
||||
const createClusterInjectable = getInjectable({
|
||||
id: "create-cluster",
|
||||
@ -14,11 +15,12 @@ const createClusterInjectable = getInjectable({
|
||||
instantiate: (di) => {
|
||||
const dependencies: ClusterDependencies = {
|
||||
directoryForKubeConfigs: di.inject(directoryForKubeConfigsInjectable),
|
||||
createKubeconfigManager: () => { throw new Error("Tried to access back-end feature in front-end."); },
|
||||
createKubeconfigManager: () => undefined,
|
||||
createKubectl: () => { throw new Error("Tried to access back-end feature in front-end.");},
|
||||
createContextHandler: () => { throw new Error("Tried to access back-end feature in front-end."); },
|
||||
createContextHandler: () => undefined,
|
||||
createAuthorizationReview: () => { throw new Error("Tried to access back-end feature in front-end."); },
|
||||
createListNamespaces: () => { throw new Error("Tried to access back-end feature in front-end."); },
|
||||
logger: di.inject(loggerInjectable),
|
||||
};
|
||||
|
||||
return (model) => new Cluster(dependencies, model);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user