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

Remove all usages of legacy global logger

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-12-22 08:23:41 -05:00
parent 1456e1e597
commit ade0775061
107 changed files with 852 additions and 606 deletions

View File

@ -0,0 +1,9 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getGlobalOverride } from "../test-utils/get-global-override";
import pathToNpmCliInjectable from "./path-to-npm-cli.injectable";
export default getGlobalOverride(pathToNpmCliInjectable, () => "/some/npm/cli/path");

View File

@ -0,0 +1,13 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
const pathToNpmCliInjectable = getInjectable({
id: "path-to-npm-cli",
instantiate: () => __non_webpack_require__.resolve("npm"),
causesSideEffects: true,
});
export default pathToNpmCliInjectable;

View File

@ -9,13 +9,14 @@
import { ipcMain, ipcRenderer, webContents } from "electron";
import { toJS } from "../utils/toJS";
import logger from "../../main/logger";
import type { ClusterFrameInfo } from "../cluster-frames";
import { clusterFrameMap } from "../cluster-frames";
import type { Disposer } from "../utils";
import ipcMainInjectable from "../../main/utils/channel/ipc-main/ipc-main.injectable";
import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import ipcRendererInjectable from "../../renderer/utils/channel/ipc-renderer.injectable";
import { asLegacyGlobalForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
import loggerInjectable from "../logger.injectable";
export const broadcastMainChannel = "ipc:broadcast-main";
@ -42,6 +43,8 @@ export async function broadcastMessage(channel: string, ...args: any[]): Promise
return;
}
const logger = asLegacyGlobalForExtensionApi(loggerInjectable);
ipcMain.listeners(channel).forEach((func) => func({
processId: undefined, frameId: undefined, sender: undefined, senderFrame: undefined,
}, ...args));

View File

@ -11,6 +11,7 @@ import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting";
import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
import directoryForUserDataInjectable from "../../app-paths/directory-for-user-data/directory-for-user-data.injectable";
import loggerInjectable from "../../logger.injectable";
import type { ApiManager } from "../api-manager";
import apiManagerInjectable from "../api-manager/manager.injectable";
import { KubeApi } from "../kube-api";
@ -64,6 +65,7 @@ describe("ApiManager", () => {
});
const kubeStore = new TestStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, kubeApi);
apiManager.registerApi(apiBase, kubeApi);

View File

@ -3,6 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { noop } from "../../utils";
import type { KubeApi } from "../kube-api";
import { KubeObject } from "../kube-object";
import type { KubeObjectStoreLoadingParams } from "../kube-object.store";
@ -18,6 +19,13 @@ class FakeKubeObjectStore extends KubeObjectStore<KubeObject> {
isGlobalWatchEnabled: () => true,
isLoadingAll: () => true,
},
logger: {
debug: noop,
error: noop,
info: noop,
silly: noop,
warn: noop,
},
}, api as KubeApi<KubeObject>);
}

View File

@ -14,7 +14,7 @@ import type { KubeApiQueryParams, KubeApi, KubeApiWatchCallback } from "./kube-a
import { parseKubeApi } from "./kube-api-parse";
import type { RequestInit } from "node-fetch";
import type { Patch } from "rfc6902";
import logger from "../logger";
import type { Logger } from "../logger";
import assert from "assert";
import type { PartialDeep } from "type-fest";
import { entries } from "../utils/objects";
@ -86,6 +86,7 @@ export type JsonPatch = Patch;
export interface KubeObjectStoreDependencies {
readonly context: ClusterContext;
readonly logger: Logger;
}
export abstract class KubeObjectStore<
@ -498,7 +499,7 @@ export abstract class KubeObjectStore<
const { type, object } = event;
if (!object.metadata?.uid) {
logger.warn("[KUBE-STORE]: watch event did not have defined .metadata.uid, skipping", { event });
this.dependencies.logger.warn("[KUBE-STORE]: watch event did not have defined .metadata.uid, skipping", { event });
// Other parts of the code will break if this happens
continue;
}
@ -528,7 +529,7 @@ export abstract class KubeObjectStore<
break;
}
} catch (error) {
logger.error("[KUBE-STORE]: failed to handle event from watch buffer", { error, event });
this.dependencies.logger.error("[KUBE-STORE]: failed to handle event from watch buffer", { error, event });
}
}

View File

@ -5,7 +5,6 @@
import { KubeConfig } from "@kubernetes/client-node";
import yaml from "js-yaml";
import logger from "../main/logger";
import type { Cluster, Context, User } from "@kubernetes/client-node/dist/config_types";
import { newClusters, newContexts, newUsers } from "@kubernetes/client-node/dist/config_types";
import { isDefined } from "./utils";
@ -220,8 +219,6 @@ export function dumpConfigYaml(kubeConfig: PartialDeep<KubeConfig>): string {
users,
};
logger.debug("Dumping KubeConfig:", config);
// skipInvalid: true makes dump ignore undefined values
return yaml.dump(config, { skipInvalid: true });
}

View File

@ -3,8 +3,6 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { asLegacyGlobalForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
import loggerInjectable from "./logger.injectable";
export interface Logger {
info: (message: string, ...args: any) => void;
@ -13,10 +11,3 @@ export interface Logger {
warn: (message: string, ...args: any) => void;
silly: (message: string, ...args: any) => void;
}
/**
* @deprecated use `di.inject(loggerInjectable)` instead
*/
const logger = asLegacyGlobalForExtensionApi(loggerInjectable);
export default logger;

View File

@ -11,8 +11,10 @@ import { Util } from "./utils";
import * as Catalog from "./catalog";
import * as Types from "./types";
import * as Proxy from "./proxy";
import loggerInjectable from "../../common/logger.injectable";
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
import logger from "../../common/logger";
const logger = asLegacyGlobalForExtensionApi(loggerInjectable);
export {
App,

View File

@ -21,6 +21,8 @@ import type { KubeJsonApiDataFor, KubeObject } from "../../common/k8s-api/kube-o
import type { KubeApi } from "../../common/k8s-api/kube-api";
import clusterFrameContextForNamespacedResourcesInjectable from "../../renderer/cluster-frame-context/for-namespaced-resources.injectable";
import type { ClusterContext } from "../../renderer/cluster-frame-context/cluster-frame-context";
import loggerInjectable from "../../common/logger.injectable";
import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
export const apiManager = asLegacyGlobalForExtensionApi(apiManagerInjectable);
export const forCluster = asLegacyGlobalFunctionForExtensionApi(createKubeApiForClusterInjectable);
@ -104,9 +106,12 @@ export abstract class KubeObjectStore<
*/
constructor();
constructor(api?: A, opts?: KubeObjectStoreOptions) {
const di = getLegacyGlobalDiForExtensionApi();
super(
{
context: asLegacyGlobalForExtensionApi(clusterFrameContextForNamespacedResourcesInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
},
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
api!,

View File

@ -3,11 +3,14 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import loggerInjectable from "../../common/logger.injectable";
import { ExtensionInstallationStateStore } from "./extension-installation-state-store";
const extensionInstallationStateStoreInjectable = getInjectable({
id: "extension-installation-state-store",
instantiate: () => new ExtensionInstallationStateStore(),
instantiate: (di) => new ExtensionInstallationStateStore({
logger: di.inject(loggerInjectable),
}),
});
export default extensionInstallationStateStoreInjectable;

View File

@ -4,12 +4,12 @@
*/
import { action, computed, observable } from "mobx";
import logger from "../../main/logger";
import { disposer } from "../../renderer/utils";
import type { ExtendableDisposer } from "../../renderer/utils";
import * as uuid from "uuid";
import { broadcastMessage } from "../../common/ipc";
import { ipcRenderer } from "electron";
import type { Logger } from "../../common/logger";
export enum ExtensionInstallationState {
INSTALLING = "installing",
@ -17,26 +17,29 @@ export enum ExtensionInstallationState {
IDLE = "idle",
}
interface Dependencies {
readonly logger: Logger;
}
const Prefix = "[ExtensionInstallationStore]";
const installingFromMainChannel = "extension-installation-state-store:install";
const clearInstallingFromMainChannel = "extension-installation-state-store:clear-install";
export class ExtensionInstallationStateStore {
private InstallingFromMainChannel =
"extension-installation-state-store:install";
private readonly preInstallIds = observable.set<string>();
private readonly uninstallingExtensions = observable.set<string>();
private readonly installingExtensions = observable.set<string>();
private ClearInstallingFromMainChannel =
"extension-installation-state-store:clear-install";
private PreInstallIds = observable.set<string>();
private UninstallingExtensions = observable.set<string>();
private InstallingExtensions = observable.set<string>();
constructor(private readonly dependencies: Dependencies) {}
bindIpcListeners = () => {
ipcRenderer
.on(this.InstallingFromMainChannel, (event, extId) => {
.on(installingFromMainChannel, (event, extId) => {
this.setInstalling(extId);
})
.on(this.ClearInstallingFromMainChannel, (event, extId) => {
.on(clearInstallingFromMainChannel, (event, extId) => {
this.clearInstalling(extId);
});
};
@ -47,7 +50,7 @@ export class ExtensionInstallationStateStore {
* @throws if state is not IDLE
*/
@action setInstalling = (extId: string): void => {
logger.debug(`${Prefix}: trying to set ${extId} as installing`);
this.dependencies.logger.debug(`${Prefix}: trying to set ${extId} as installing`);
const curState = this.getInstallationState(extId);
@ -57,7 +60,7 @@ export class ExtensionInstallationStateStore {
);
}
this.InstallingExtensions.add(extId);
this.installingExtensions.add(extId);
};
/**
@ -65,7 +68,7 @@ export class ExtensionInstallationStateStore {
* @param extId the ID of the extension
*/
setInstallingFromMain = (extId: string): void => {
broadcastMessage(this.InstallingFromMainChannel, extId);
broadcastMessage(installingFromMainChannel, extId);
};
/**
@ -73,7 +76,7 @@ export class ExtensionInstallationStateStore {
* @param extId the ID of the extension
*/
clearInstallingFromMain = (extId: string): void => {
broadcastMessage(this.ClearInstallingFromMainChannel, extId);
broadcastMessage(clearInstallingFromMainChannel, extId);
};
/**
@ -85,14 +88,14 @@ export class ExtensionInstallationStateStore {
@action startPreInstall = (): ExtendableDisposer => {
const preInstallStepId = uuid.v4();
logger.debug(
this.dependencies.logger.debug(
`${Prefix}: starting a new preinstall phase: ${preInstallStepId}`,
);
this.PreInstallIds.add(preInstallStepId);
this.preInstallIds.add(preInstallStepId);
return disposer(() => {
this.PreInstallIds.delete(preInstallStepId);
logger.debug(`${Prefix}: ending a preinstall phase: ${preInstallStepId}`);
this.preInstallIds.delete(preInstallStepId);
this.dependencies.logger.debug(`${Prefix}: ending a preinstall phase: ${preInstallStepId}`);
});
};
@ -102,7 +105,7 @@ export class ExtensionInstallationStateStore {
* @throws if state is not IDLE
*/
@action setUninstalling = (extId: string): void => {
logger.debug(`${Prefix}: trying to set ${extId} as uninstalling`);
this.dependencies.logger.debug(`${Prefix}: trying to set ${extId} as uninstalling`);
const curState = this.getInstallationState(extId);
@ -112,7 +115,7 @@ export class ExtensionInstallationStateStore {
);
}
this.UninstallingExtensions.add(extId);
this.uninstallingExtensions.add(extId);
};
/**
@ -121,13 +124,13 @@ export class ExtensionInstallationStateStore {
* @throws if state is not INSTALLING
*/
@action clearInstalling = (extId: string): void => {
logger.debug(`${Prefix}: trying to clear ${extId} as installing`);
this.dependencies.logger.debug(`${Prefix}: trying to clear ${extId} as installing`);
const curState = this.getInstallationState(extId);
switch (curState) {
case ExtensionInstallationState.INSTALLING:
return void this.InstallingExtensions.delete(extId);
return void this.installingExtensions.delete(extId);
default:
throw new Error(
`${Prefix}: cannot clear INSTALLING state for ${extId}, it is currently ${curState}`,
@ -141,13 +144,13 @@ export class ExtensionInstallationStateStore {
* @throws if state is not UNINSTALLING
*/
@action clearUninstalling = (extId: string): void => {
logger.debug(`${Prefix}: trying to clear ${extId} as uninstalling`);
this.dependencies.logger.debug(`${Prefix}: trying to clear ${extId} as uninstalling`);
const curState = this.getInstallationState(extId);
switch (curState) {
case ExtensionInstallationState.UNINSTALLING:
return void this.UninstallingExtensions.delete(extId);
return void this.uninstallingExtensions.delete(extId);
default:
throw new Error(
`${Prefix}: cannot clear UNINSTALLING state for ${extId}, it is currently ${curState}`,
@ -160,11 +163,11 @@ export class ExtensionInstallationStateStore {
* @param extId The ID of the extension
*/
getInstallationState = (extId: string): ExtensionInstallationState => {
if (this.InstallingExtensions.has(extId)) {
if (this.installingExtensions.has(extId)) {
return ExtensionInstallationState.INSTALLING;
}
if (this.UninstallingExtensions.has(extId)) {
if (this.uninstallingExtensions.has(extId)) {
return ExtensionInstallationState.UNINSTALLING;
}
@ -197,14 +200,14 @@ export class ExtensionInstallationStateStore {
* The current number of extensions installing
*/
@computed get installing(): number {
return this.InstallingExtensions.size;
return this.installingExtensions.size;
}
/**
* The current number of extensions uninstalling
*/
get uninstalling(): number {
return this.UninstallingExtensions.size;
return this.uninstallingExtensions.size;
}
/**
@ -225,7 +228,7 @@ export class ExtensionInstallationStateStore {
* The current number of extensions preinstalling
*/
get preinstalling(): number {
return this.PreInstallIds.size;
return this.preInstallIds.size;
}
/**

View File

@ -3,6 +3,8 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import pathToNpmCliInjectable from "../../common/app-paths/path-to-npm-cli.injectable";
import loggerInjectable from "../../common/logger.injectable";
import { ExtensionInstaller } from "./extension-installer";
import extensionPackageRootDirectoryInjectable from "./extension-package-root-directory/extension-package-root-directory.injectable";
@ -11,6 +13,8 @@ const extensionInstallerInjectable = getInjectable({
instantiate: (di) => new ExtensionInstaller({
extensionPackageRootDirectory: di.inject(extensionPackageRootDirectoryInjectable),
logger: di.inject(loggerInjectable),
pathToNpmCli: di.inject(pathToNpmCliInjectable),
}),
});

View File

@ -5,12 +5,14 @@
import AwaitLock from "await-lock";
import child_process from "child_process";
import logger from "../../main/logger";
import type { Logger } from "../../common/logger";
const logModule = "[EXTENSION-INSTALLER]";
interface Dependencies {
extensionPackageRootDirectory: string;
readonly extensionPackageRootDirectory: string;
readonly logger: Logger;
readonly pathToNpmCli: string;
}
const baseNpmInstallArgs = [
@ -27,13 +29,9 @@ const baseNpmInstallArgs = [
* Installs dependencies for extensions
*/
export class ExtensionInstaller {
private installLock = new AwaitLock();
private readonly installLock = new AwaitLock();
constructor(private dependencies: Dependencies) {}
get npmPath() {
return __non_webpack_require__.resolve("npm");
}
constructor(private readonly dependencies: Dependencies) {}
/**
* Install single package using npm
@ -43,9 +41,9 @@ export class ExtensionInstaller {
await this.installLock.acquireAsync();
try {
logger.info(`${logModule} installing package from ${name} to ${this.dependencies.extensionPackageRootDirectory}`);
this.dependencies.logger.info(`${logModule} installing package from ${name} to ${this.dependencies.extensionPackageRootDirectory}`);
await this.npm(...baseNpmInstallArgs, name);
logger.info(`${logModule} package ${name} installed to ${this.dependencies.extensionPackageRootDirectory}`);
this.dependencies.logger.info(`${logModule} package ${name} installed to ${this.dependencies.extensionPackageRootDirectory}`);
} finally {
this.installLock.release();
}
@ -53,7 +51,7 @@ export class ExtensionInstaller {
private npm(...args: string[]): Promise<void> {
return new Promise((resolve, reject) => {
const child = child_process.fork(this.npmPath, args, {
const child = child_process.fork(this.dependencies.pathToNpmCli, args, {
cwd: this.dependencies.extensionPackageRootDirectory,
silent: true,
env: {},

View File

@ -4,12 +4,11 @@
*/
import { ipcMain } from "electron";
import { IpcPrefix, IpcRegistrar } from "./ipc-registrar";
import { Disposers } from "../lens-extension";
import { Disposers, lensExtensionDependencies } from "../lens-extension";
import type { LensMainExtension } from "../lens-main-extension";
import type { Disposer } from "../../common/utils";
import { once } from "lodash";
import { ipcMainHandle } from "../../common/ipc";
import logger from "../../main/logger";
export abstract class IpcMain extends IpcRegistrar {
constructor(extension: LensMainExtension) {
@ -28,12 +27,12 @@ export abstract class IpcMain extends IpcRegistrar {
listen(channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => any): Disposer {
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
const cleanup = once(() => {
logger.info(`[IPC-RENDERER]: removing extension listener`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
this.extension[lensExtensionDependencies].logger.info(`[IPC-RENDERER]: removing extension listener`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
return ipcMain.removeListener(prefixedChannel, listener);
});
logger.info(`[IPC-RENDERER]: adding extension listener`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
this.extension[lensExtensionDependencies].logger.info(`[IPC-RENDERER]: adding extension listener`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
ipcMain.addListener(prefixedChannel, listener);
this.extension[Disposers].push(cleanup);
@ -48,10 +47,10 @@ export abstract class IpcMain extends IpcRegistrar {
handle(channel: string, handler: (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any): void {
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
logger.info(`[IPC-RENDERER]: adding extension handler`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
this.extension[lensExtensionDependencies].logger.info(`[IPC-RENDERER]: adding extension handler`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
ipcMainHandle(prefixedChannel, handler);
this.extension[Disposers].push(() => {
logger.info(`[IPC-RENDERER]: removing extension handler`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
this.extension[lensExtensionDependencies].logger.info(`[IPC-RENDERER]: removing extension handler`, { channel, extension: { name: this.extension.name, version: this.extension.version }});
return ipcMain.removeHandler(prefixedChannel);
});

View File

@ -12,7 +12,7 @@ export const IpcPrefix = Symbol();
export abstract class IpcRegistrar extends Singleton {
readonly [IpcPrefix]: string;
constructor(protected extension: LensExtension) {
constructor(protected readonly extension: LensExtension) {
super();
this[IpcPrefix] = createHash("sha256").update(extension.id).digest("hex");
}

View File

@ -4,6 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import clusterStoreInjectable from "../../common/cluster-store/cluster-store.injectable";
import loggerInjectable from "../../common/logger.injectable";
import catalogEntityRegistryInjectable from "../catalog/entity-registry.injectable";
import clustersThatAreBeingDeletedInjectable from "./are-being-deleted.injectable";
import { ClusterManager } from "./manager";
@ -17,6 +18,7 @@ const clusterManagerInjectable = getInjectable({
catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable),
clustersThatAreBeingDeleted: di.inject(clustersThatAreBeingDeletedInjectable),
visibleCluster: di.inject(visibleClusterInjectable),
logger: di.inject(loggerInjectable),
}),
});

View File

@ -4,13 +4,10 @@
*/
import "../../common/ipc/cluster";
import type http from "http";
import type { IObservableValue, ObservableSet } from "mobx";
import { action, makeObservable, observe, reaction, toJS } from "mobx";
import type { Cluster } from "../../common/cluster/cluster";
import logger from "../logger";
import { apiKubePrefix } from "../../common/vars";
import { getClusterIdFromHost, isErrnoException } from "../../common/utils";
import { isErrnoException } from "../../common/utils";
import type { KubernetesClusterPrometheusMetrics } from "../../common/catalog-entities/kubernetes-cluster";
import { isKubernetesCluster, KubernetesCluster, LensKubernetesClusterStatus } from "../../common/catalog-entities/kubernetes-cluster";
import { ipcMainOn } from "../../common/ipc";
@ -18,6 +15,7 @@ import { once } from "lodash";
import type { ClusterStore } from "../../common/cluster-store/cluster-store";
import type { ClusterId } from "../../common/cluster-types";
import type { CatalogEntityRegistry } from "../catalog";
import type { Logger } from "../../common/logger";
const logPrefix = "[CLUSTER-MANAGER]:";
@ -28,6 +26,7 @@ interface Dependencies {
readonly catalogEntityRegistry: CatalogEntityRegistry;
readonly clustersThatAreBeingDeleted: ObservableSet<ClusterId>;
readonly visibleCluster: IObservableValue<ClusterId | null>;
readonly logger: Logger;
}
export class ClusterManager {
@ -80,7 +79,7 @@ export class ClusterManager {
@action
protected updateCatalog(clusters: Cluster[]) {
logger.debug("[CLUSTER-MANAGER]: updating catalog from cluster store");
this.dependencies.logger.debug("[CLUSTER-MANAGER]: updating catalog from cluster store");
for (const cluster of clusters) {
this.updateEntityFromCluster(cluster);
@ -146,31 +145,31 @@ export class ClusterManager {
} else {
entity.status.phase = (() => {
if (!cluster) {
logger.debug(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="no cluster"`);
this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="no cluster"`);
return LensKubernetesClusterStatus.DISCONNECTED;
}
if (cluster.accessible) {
logger.debug(`${logPrefix} setting entity ${entity.getName()} to CONNECTED, reason="cluster is accessible"`);
this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to CONNECTED, reason="cluster is accessible"`);
return LensKubernetesClusterStatus.CONNECTED;
}
if (!cluster.disconnected) {
logger.debug(`${logPrefix} setting entity ${entity.getName()} to CONNECTING, reason="cluster is not disconnected"`);
this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to CONNECTING, reason="cluster is not disconnected"`);
return LensKubernetesClusterStatus.CONNECTING;
}
// Extensions are not allowed to use the Lens specific status phases
if (!lensSpecificClusterStatuses.has(entity?.status?.phase)) {
logger.debug(`${logPrefix} not clearing entity ${entity.getName()} status, reason="custom string"`);
this.dependencies.logger.debug(`${logPrefix} not clearing entity ${entity.getName()} status, reason="custom string"`);
return entity.status.phase;
}
logger.debug(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="fallthrough"`);
this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="fallthrough"`);
return LensKubernetesClusterStatus.DISCONNECTED;
})();
@ -200,9 +199,9 @@ export class ClusterManager {
this.dependencies.store.addCluster(model);
} catch (error) {
if (isErrnoException(error) && error.code === "ENOENT" && error.path === entity.spec.kubeconfigPath) {
logger.warn(`${logPrefix} kubeconfig file disappeared`, model);
this.dependencies.logger.warn(`${logPrefix} kubeconfig file disappeared`, model);
} else {
logger.error(`${logPrefix} failed to add cluster: ${error}`, model);
this.dependencies.logger.error(`${logPrefix} failed to add cluster: ${error}`, model);
}
}
} else {
@ -235,7 +234,7 @@ export class ClusterManager {
}
protected onNetworkOffline = () => {
logger.info(`${logPrefix} network is offline`);
this.dependencies.logger.info(`${logPrefix} network is offline`);
this.dependencies.store.clustersList.forEach((cluster) => {
if (!cluster.disconnected) {
cluster.online = false;
@ -246,7 +245,7 @@ export class ClusterManager {
};
protected onNetworkOnline = () => {
logger.info(`${logPrefix} network is online`);
this.dependencies.logger.info(`${logPrefix} network is online`);
this.dependencies.store.clustersList.forEach((cluster) => {
if (!cluster.disconnected) {
cluster.refreshConnectionStatus().catch((e) => e);
@ -259,27 +258,6 @@ export class ClusterManager {
cluster.disconnect();
});
}
getClusterForRequest = (req: http.IncomingMessage): Cluster | undefined => {
if (!req.headers.host) {
return undefined;
}
// lens-server is connecting to 127.0.0.1:<port>/<uid>
if (req.url && req.headers.host.startsWith("127.0.0.1")) {
const clusterId = req.url.split("/")[1];
const cluster = this.dependencies.store.getById(clusterId);
if (cluster) {
// we need to swap path prefix so that request is proxied to kube api
req.url = req.url.replace(`/${clusterId}`, apiKubePrefix);
}
return cluster;
}
return this.dependencies.store.getById(getClusterIdFromHost(req.headers.host));
};
}
export function catalogEntityFromCluster(cluster: Cluster) {

View File

@ -11,6 +11,7 @@ import kubeAuthProxyCertificateInjectable from "./kube-auth-proxy-certificate.in
import loggerInjectable from "../../common/logger.injectable";
import waitUntilPortIsUsedInjectable from "./wait-until-port-is-used/wait-until-port-is-used.injectable";
import lensK8sProxyPathInjectable from "./lens-k8s-proxy-path.injectable";
import getPortFromStreamInjectable from "../utils/get-port-from-stream.injectable";
export type CreateKubeAuthProxy = (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => KubeAuthProxy;
@ -23,6 +24,7 @@ const createKubeAuthProxyInjectable = getInjectable({
spawn: di.inject(spawnInjectable),
logger: di.inject(loggerInjectable),
waitUntilPortIsUsed: di.inject(waitUntilPortIsUsedInjectable),
getPortFromStream: di.inject(getPortFromStreamInjectable),
};
return (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => {

View File

@ -6,7 +6,7 @@
import type { ChildProcess } from "child_process";
import { randomBytes } from "crypto";
import type { Cluster } from "../../common/cluster/cluster";
import { getPortFrom } from "../utils/get-port";
import type { GetPortFromStream } from "../utils/get-port-from-stream.injectable";
import { makeObservable, observable, when } from "mobx";
import type { SelfSignedCert } from "selfsigned";
import assert from "assert";
@ -23,9 +23,10 @@ const startingServeRegex = Object.assign(TypedRegEx(startingServeMatcher, "i"),
export interface KubeAuthProxyDependencies {
readonly proxyBinPath: string;
readonly proxyCert: SelfSignedCert;
readonly spawn: Spawn;
readonly logger: Logger;
readonly waitUntilPortIsUsed: WaitUntilPortIsUsed;
spawn: Spawn;
waitUntilPortIsUsed: WaitUntilPortIsUsed;
getPortFromStream: GetPortFromStream;
}
export class KubeAuthProxy {
@ -101,7 +102,7 @@ export class KubeAuthProxy {
}
});
this._port = await getPortFrom(this.proxyProcess.stdout, {
this._port = await this.dependencies.getPortFromStream(this.proxyProcess.stdout, {
lineRegex: startingServeRegex,
onFind: () => this.cluster.broadcastConnectUpdate("Authentication proxy started"),
});

View File

@ -17,6 +17,7 @@ import kubectlVersionMapInjectable from "./version-map.injectable";
import getDirnameOfPathInjectable from "../../common/path/get-dirname.injectable";
import joinPathsInjectable from "../../common/path/join-paths.injectable";
import getBasenameOfPathInjectable from "../../common/path/get-basename.injectable";
import loggerInjectable from "../../common/logger.injectable";
const createKubectlInjectable = getInjectable({
id: "create-kubectl",
@ -32,6 +33,7 @@ const createKubectlInjectable = getInjectable({
baseBundeledBinariesDirectory: di.inject(baseBundledBinariesDirectoryInjectable),
bundledKubectlVersion: di.inject(bundledKubectlVersionInjectable),
kubectlVersionMap: di.inject(kubectlVersionMapInjectable),
logger: di.inject(loggerInjectable),
getDirnameOfPath: di.inject(getDirnameOfPathInjectable),
joinPaths: di.inject(joinPathsInjectable),
getBasenameOfPath: di.inject(getBasenameOfPathInjectable),

View File

@ -5,7 +5,6 @@
import fs from "fs";
import { promiseExecFile } from "../../common/utils/promise-exec";
import logger from "../logger";
import { ensureDir, pathExists } from "fs-extra";
import * as lockFile from "proper-lockfile";
import { SemVer, coerce } from "semver";
@ -18,6 +17,7 @@ import type { JoinPaths } from "../../common/path/join-paths.injectable";
import type { GetDirnameOfPath } from "../../common/path/get-dirname.injectable";
import type { GetBasenameOfPath } from "../../common/path/get-basename.injectable";
import type { NormalizedPlatform } from "../../common/vars/normalized-platform.injectable";
import type { Logger } from "../../common/logger";
const initScriptVersionString = "# lens-initscript v3";
@ -36,6 +36,7 @@ export interface KubectlDependencies {
};
readonly bundledKubectlVersion: string;
readonly kubectlVersionMap: Map<string, string>;
readonly logger: Logger;
joinPaths: JoinPaths;
getDirnameOfPath: GetDirnameOfPath;
getBasenameOfPath: GetBasenameOfPath;
@ -67,13 +68,13 @@ export class Kubectl {
*/
if (fromMajorMinor) {
this.kubectlVersion = fromMajorMinor;
logger.debug(`Set kubectl version ${this.kubectlVersion} for cluster version ${clusterVersion} using version map`);
this.dependencies.logger.debug(`Set kubectl version ${this.kubectlVersion} for cluster version ${clusterVersion} using version map`);
} else {
/* this is the version (without possible prelease tag) to get from the download mirror */
const ver = coerce(version.format()) ?? bundledVersion;
this.kubectlVersion = ver.format();
logger.debug(`Set kubectl version ${this.kubectlVersion} for cluster version ${clusterVersion} using fallback`);
this.dependencies.logger.debug(`Set kubectl version ${this.kubectlVersion} for cluster version ${clusterVersion} using fallback`);
}
this.url = `${this.getDownloadMirror()}/v${this.kubectlVersion}/bin/${this.dependencies.normalizedDownloadPlatform}/${this.dependencies.normalizedDownloadArch}/${this.dependencies.kubectlBinaryName}`;
@ -115,14 +116,14 @@ export class Kubectl {
try {
if (!await this.ensureKubectl()) {
logger.error("Failed to ensure kubectl, fallback to the bundled version");
this.dependencies.logger.error("Failed to ensure kubectl, fallback to the bundled version");
return this.getBundledPath();
}
return this.path;
} catch (err) {
logger.error("Failed to ensure kubectl, fallback to the bundled version", err);
this.dependencies.logger.error("Failed to ensure kubectl, fallback to the bundled version", err);
return this.getBundledPath();
}
@ -135,7 +136,7 @@ export class Kubectl {
return this.dirname;
} catch (err) {
logger.error("Failed to get biniary directory", err);
this.dependencies.logger.error("Failed to get biniary directory", err);
return "";
}
@ -164,13 +165,13 @@ export class Kubectl {
}
if (version === this.kubectlVersion) {
logger.debug(`Local kubectl is version ${this.kubectlVersion}`);
this.dependencies.logger.debug(`Local kubectl is version ${this.kubectlVersion}`);
return true;
}
logger.error(`Local kubectl is version ${version}, expected ${this.kubectlVersion}, unlinking`);
this.dependencies.logger.error(`Local kubectl is version ${version}, expected ${this.kubectlVersion}, unlinking`);
} catch (error) {
logger.error(`Local kubectl failed to run properly (${error}), unlinking`);
this.dependencies.logger.error(`Local kubectl failed to run properly (${error}), unlinking`);
}
await fs.promises.unlink(this.path);
}
@ -190,7 +191,7 @@ export class Kubectl {
return true;
} catch (err) {
logger.error(`Could not copy the bundled kubectl to app-data: ${err}`);
this.dependencies.logger.error(`Could not copy the bundled kubectl to app-data: ${err}`);
return false;
}
@ -205,7 +206,7 @@ export class Kubectl {
}
if (Kubectl.invalidBundle) {
logger.error(`Detected invalid bundle binary, returning ...`);
this.dependencies.logger.error(`Detected invalid bundle binary, returning ...`);
return false;
}
@ -215,7 +216,7 @@ export class Kubectl {
try {
const release = await lockFile.lock(this.dirname);
logger.debug(`Acquired a lock for ${this.kubectlVersion}`);
this.dependencies.logger.debug(`Acquired a lock for ${this.kubectlVersion}`);
const bundled = await this.checkBundled();
let isValid = await this.checkBinary(this.path, !bundled);
@ -223,8 +224,8 @@ export class Kubectl {
try {
await this.downloadKubectl();
} catch (error) {
logger.error(`[KUBECTL]: failed to download kubectl`, error);
logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
this.dependencies.logger.error(`[KUBECTL]: failed to download kubectl`, error);
this.dependencies.logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
await release();
return false;
@ -234,18 +235,18 @@ export class Kubectl {
}
if (!isValid) {
logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
this.dependencies.logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
await release();
return false;
}
logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
this.dependencies.logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
await release();
return true;
} catch (error) {
logger.error(`[KUBECTL]: Failed to get a lock for ${this.kubectlVersion}`, error);
this.dependencies.logger.error(`[KUBECTL]: Failed to get a lock for ${this.kubectlVersion}`, error);
return false;
}
@ -254,7 +255,7 @@ export class Kubectl {
public async downloadKubectl() {
await ensureDir(this.dependencies.getDirnameOfPath(this.path), 0o755);
logger.info(`Downloading kubectl ${this.kubectlVersion} from ${this.url} to ${this.path}`);
this.dependencies.logger.info(`Downloading kubectl ${this.kubectlVersion} from ${this.url} to ${this.path}`);
const downloadStream = got.stream({ url: this.url, decompress: true });
const fileWriteStream = fs.createWriteStream(this.path, { mode: 0o755 });
@ -263,7 +264,7 @@ export class Kubectl {
try {
await pipeline(downloadStream, fileWriteStream);
await fs.promises.chmod(this.path, 0o755);
logger.debug("kubectl binary download finished");
this.dependencies.logger.debug("kubectl binary download finished");
} catch (error) {
await fs.promises.unlink(this.path).catch(noop);
throw error;

View File

@ -0,0 +1,45 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injectable";
import { getClusterIdFromHost } from "../../common/utils";
import { apiKubePrefix } from "../../common/vars";
import type { GetClusterForRequest } from "./lens-proxy";
const getClusterForRequestInjectable = getInjectable({
id: "get-cluster-for-request",
instantiate: (di): GetClusterForRequest => {
const getClusterById = di.inject(getClusterByIdInjectable);
return (req) => {
if (!req.headers.host) {
return undefined;
}
// lens-server is connecting to 127.0.0.1:<port>/<uid>
if (req.url && req.headers.host.startsWith("127.0.0.1")) {
const clusterId = req.url.split("/")[1];
const cluster = getClusterById(clusterId);
if (cluster) {
// we need to swap path prefix so that request is proxied to kube api
req.url = req.url.replace(`/${clusterId}`, apiKubePrefix);
}
return cluster;
}
const clusterId = getClusterIdFromHost(req.headers.host);
if (!clusterId) {
return undefined;
}
return getClusterById(clusterId);
};
},
});
export default getClusterForRequestInjectable;

View File

@ -7,13 +7,13 @@ import { LensProxy } from "./lens-proxy";
import { kubeApiUpgradeRequest } from "./proxy-functions";
import routerInjectable from "../router/router.injectable";
import httpProxy from "http-proxy";
import clusterManagerInjectable from "../cluster/manager.injectable";
import shellApiRequestInjectable from "./proxy-functions/shell-api-request/shell-api-request.injectable";
import shellApiRequestInjectable from "./proxy-functions/shell-api-request.injectable";
import lensProxyPortInjectable from "./lens-proxy-port.injectable";
import contentSecurityPolicyInjectable from "../../common/vars/content-security-policy.injectable";
import emitAppEventInjectable from "../../common/app-event-bus/emit-event.injectable";
import loggerInjectable from "../../common/logger.injectable";
import lensProxyCertificateInjectable from "../../common/certificate/lens-proxy-certificate.injectable";
import getClusterForRequestInjectable from "./get-cluster-for-request.injectable";
const lensProxyInjectable = getInjectable({
id: "lens-proxy",
@ -23,7 +23,7 @@ const lensProxyInjectable = getInjectable({
proxy: httpProxy.createProxy(),
kubeApiUpgradeRequest,
shellApiRequest: di.inject(shellApiRequestInjectable),
getClusterForRequest: di.inject(clusterManagerInjectable).getClusterForRequest,
getClusterForRequest: di.inject(getClusterForRequestInjectable),
lensProxyPort: di.inject(lensProxyPortInjectable),
contentSecurityPolicy: di.inject(contentSecurityPolicyInjectable),
emitAppEvent: di.inject(emitAppEventInjectable),

View File

@ -19,14 +19,14 @@ import type { EmitAppEvent } from "../../common/app-event-bus/emit-event.injecta
import type { Logger } from "../../common/logger";
import type { SelfSignedCert } from "selfsigned";
type GetClusterForRequest = (req: http.IncomingMessage) => Cluster | undefined;
export type GetClusterForRequest = (req: http.IncomingMessage) => Cluster | undefined;
export type ServerIncomingMessage = SetRequired<http.IncomingMessage, "url" | "method">;
export type LensProxyApiRequest = (args: ProxyApiRequestArgs) => void | Promise<void>;
interface Dependencies {
getClusterForRequest: GetClusterForRequest;
shellApiRequest: (args: ProxyApiRequestArgs) => void | Promise<void>;
kubeApiUpgradeRequest: (args: ProxyApiRequestArgs) => void | Promise<void>;
shellApiRequest: LensProxyApiRequest;
kubeApiUpgradeRequest: LensProxyApiRequest;
emitAppEvent: EmitAppEvent;
readonly router: Router;
readonly proxy: httpProxy;

View File

@ -0,0 +1,42 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import shellRequestAuthenticatorInjectable from "./shell-request-authenticator/shell-request-authenticator.injectable";
import openShellSessionInjectable from "../../shell-session/create-shell-session.injectable";
import type { LensProxyApiRequest } from "../lens-proxy";
import URLParse from "url-parse";
import { Server as WebSocketServer } from "ws";
import loggerInjectable from "../../../common/logger.injectable";
import getClusterForRequestInjectable from "../get-cluster-for-request.injectable";
const shellApiRequestInjectable = getInjectable({
id: "shell-api-request",
instantiate: (di): LensProxyApiRequest => {
const openShellSession = di.inject(openShellSessionInjectable);
const authenticateRequest = di.inject(shellRequestAuthenticatorInjectable).authenticate;
const getClusterForRequest = di.inject(getClusterForRequestInjectable);
const logger = di.inject(loggerInjectable);
return ({ req, socket, head }) => {
const cluster = getClusterForRequest(req);
const { query: { node: nodeName, shellToken, id: tabId }} = new URLParse(req.url, true);
if (!tabId || !cluster || !authenticateRequest(cluster.id, tabId, shellToken)) {
socket.write("Invalid shell request");
socket.end();
} else {
const ws = new WebSocketServer({ noServer: true });
ws.handleUpgrade(req, socket, head, (websocket) => {
openShellSession({ websocket, cluster, tabId, nodeName })
.catch(error => logger.error(`[SHELL-SESSION]: failed to open a ${nodeName ? "node" : "local"} shell`, error));
});
}
};
},
});
export default shellApiRequestInjectable;

View File

@ -1,21 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { shellApiRequest } from "./shell-api-request";
import shellRequestAuthenticatorInjectable from "./shell-request-authenticator/shell-request-authenticator.injectable";
import clusterManagerInjectable from "../../../cluster/manager.injectable";
import openShellSessionInjectable from "../../../shell-session/create-shell-session.injectable";
const shellApiRequestInjectable = getInjectable({
id: "shell-api-request",
instantiate: (di) => shellApiRequest({
openShellSession: di.inject(openShellSessionInjectable),
authenticateRequest: di.inject(shellRequestAuthenticatorInjectable).authenticate,
clusterManager: di.inject(clusterManagerInjectable),
}),
});
export default shellApiRequestInjectable;

View File

@ -1,36 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import logger from "../../../logger";
import { Server as WebSocketServer } from "ws";
import type { ProxyApiRequestArgs } from "../types";
import type { ClusterManager } from "../../../cluster/manager";
import URLParse from "url-parse";
import type { ClusterId } from "../../../../common/cluster-types";
import type { OpenShellSession } from "../../../shell-session/create-shell-session.injectable";
interface Dependencies {
authenticateRequest: (clusterId: ClusterId, tabId: string, shellToken: string | undefined) => boolean;
openShellSession: OpenShellSession;
clusterManager: ClusterManager;
}
export const shellApiRequest = ({ openShellSession, authenticateRequest, clusterManager }: Dependencies) => ({ req, socket, head }: ProxyApiRequestArgs): void => {
const cluster = clusterManager.getClusterForRequest(req);
const { query: { node: nodeName, shellToken, id: tabId }} = new URLParse(req.url, true);
if (!tabId || !cluster || !authenticateRequest(cluster.id, tabId, shellToken)) {
socket.write("Invalid shell request");
return void socket.end();
}
const ws = new WebSocketServer({ noServer: true });
ws.handleUpgrade(req, socket, head, (websocket) => {
openShellSession({ websocket, cluster, tabId, nodeName })
.catch(error => logger.error(`[SHELL-SESSION]: failed to open a ${nodeName ? "node" : "local"} shell`, error));
});
};

View File

@ -2,9 +2,9 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getOrInsertMap } from "../../../../../common/utils";
import type { ClusterId } from "../../../../../common/cluster-types";
import { ipcMainHandle } from "../../../../../common/ipc";
import { getOrInsertMap } from "../../../../common/utils";
import type { ClusterId } from "../../../../common/cluster-types";
import { ipcMainHandle } from "../../../../common/ipc";
import crypto from "crypto";
import { promisify } from "util";

View File

@ -1,8 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import logger from "../common/logger";
export default logger;

View File

@ -3,22 +3,25 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import type { PortForwardArgs } from "./port-forward";
import type { PortForwardArgs, PortForwardDependencies } from "./port-forward";
import { PortForward } from "./port-forward";
import bundledKubectlInjectable from "../../../kubectl/bundled-kubectl.injectable";
import getPortFromStreamInjectable from "../../../utils/get-port-from-stream.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
export type CreatePortForward = (pathToKubeConfig: string, args: PortForwardArgs) => PortForward;
const createPortForwardInjectable = getInjectable({
id: "create-port-forward",
instantiate: (di) => {
const bundledKubectl = di.inject(bundledKubectlInjectable);
const dependencies = {
getKubectlBinPath: bundledKubectl.getPath,
instantiate: (di): CreatePortForward => {
const dependencies: PortForwardDependencies = {
getKubectlBinPath: di.inject(bundledKubectlInjectable).getPath,
getPortFromStream: di.inject(getPortFromStreamInjectable),
logger: di.inject(loggerInjectable),
};
return (pathToKubeConfig: string, args: PortForwardArgs) =>
new PortForward(dependencies, pathToKubeConfig, args);
return (pathToKubeConfig, args) => new PortForward(dependencies, pathToKubeConfig, args);
},
});

View File

@ -2,12 +2,12 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import logger from "../../../logger";
import { getPortFrom } from "../../../utils/get-port";
import type { GetPortFromStream } from "../../../utils/get-port-from-stream.injectable";
import type { ChildProcessWithoutNullStreams } from "child_process";
import { spawn } from "child_process";
import * as tcpPortUsed from "tcp-port-used";
import { TypedRegEx } from "typed-regex";
import type { Logger } from "../../../../common/logger";
const internalPortMatcher = "^forwarding from (?<address>.+) ->";
const internalPortRegex = Object.assign(TypedRegEx(internalPortMatcher, "i"), {
@ -23,8 +23,10 @@ export interface PortForwardArgs {
forwardPort: number;
}
interface Dependencies {
export interface PortForwardDependencies {
readonly logger: Logger;
getKubectlBinPath: (bundled: boolean) => Promise<string>;
getPortFromStream: GetPortFromStream;
}
export class PortForward {
@ -48,7 +50,7 @@ export class PortForward {
public port: number;
public forwardPort: number;
constructor(private dependencies: Dependencies, public pathToKubeConfig: string, args: PortForwardArgs) {
constructor(private dependencies: PortForwardDependencies, public pathToKubeConfig: string, args: PortForwardArgs) {
this.clusterId = args.clusterId;
this.kind = args.kind;
this.namespace = args.namespace;
@ -80,10 +82,10 @@ export class PortForward {
});
this.process.stderr.on("data", (data) => {
logger.debug(`[PORT-FORWARD-ROUTE]: kubectl port-forward process stderr: ${data}`);
this.dependencies.logger.debug(`[PORT-FORWARD-ROUTE]: kubectl port-forward process stderr: ${data}`);
});
const internalPort = await getPortFrom(this.process.stdout, {
const internalPort = await this.dependencies.getPortFromStream(this.process.stdout, {
lineRegex: internalPortRegex,
});

View File

@ -0,0 +1,77 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Readable } from "stream";
import URLParse from "url-parse";
import { getInjectable } from "@ogre-tools/injectable";
import loggerInjectable from "../../common/logger.injectable";
export interface GetPortFromStreamArgs {
/**
* Should be case insensitive
* Must have a named matching group called `address`
*/
lineRegex: {
match: (line: string) => {
matched: boolean;
groups?: {
address?: string;
};
raw?: RegExpExecArray;
};
rawMatcher: string;
};
/**
* Called when the port is found
*/
onFind?: () => void;
/**
* Timeout for how long to wait for the port.
* Default: 15s
*/
timeout?: number;
}
export type GetPortFromStream = (stream: Readable, args: GetPortFromStreamArgs) => Promise<number>;
const getPortFromStreamInjectable = getInjectable({
id: "get-port-from-stream",
instantiate: (di): GetPortFromStream => {
const logger = di.inject(loggerInjectable);
return (stream, args) => {
const logLines: string[] = [];
return new Promise<number>((resolve, reject) => {
const handler = (data: unknown) => {
const logItem = String(data);
const match = args.lineRegex.match(logItem);
logLines.push(logItem);
if (match.matched) {
// use unknown protocol so that there is no default port
const addr = new URLParse(`s://${match.groups?.address?.trim()}`);
args.onFind?.();
stream.off("data", handler);
clearTimeout(timeoutID);
resolve(+addr.port);
}
};
const timeoutID = setTimeout(() => {
stream.off("data", handler);
logger.warn(`[getPortFrom]: failed to retrieve port via ${args.lineRegex.rawMatcher}`, logLines);
reject(new Error("failed to retrieve port from stream"));
}, args.timeout ?? 15000);
stream.on("data", handler);
});
};
},
});
export default getPortFromStreamInjectable;

View File

@ -1,71 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Readable } from "stream";
import URLParse from "url-parse";
import logger from "../logger";
interface GetPortArgs {
/**
* Should be case insensitive
* Must have a named matching group called `address`
*/
lineRegex: {
match: (line: string) => {
matched: boolean;
groups?: {
address?: string;
};
raw?: RegExpExecArray;
};
rawMatcher: string;
};
/**
* Called when the port is found
*/
onFind?: () => void;
/**
* Timeout for how long to wait for the port.
* Default: 15s
*/
timeout?: number;
}
/**
* Parse lines from `stream` (assumes data comes in lines) to find the port
* which the source of the stream is watching on.
* @param stream A readable stream to match lines against
* @param args The args concerning the stream
* @returns A Promise for port number
*/
export function getPortFrom(stream: Readable, args: GetPortArgs): Promise<number> {
const logLines: string[] = [];
return new Promise<number>((resolve, reject) => {
const handler = (data: unknown) => {
const logItem = String(data);
const match = args.lineRegex.match(logItem);
logLines.push(logItem);
if (match.matched) {
// use unknown protocol so that there is no default port
const addr = new URLParse(`s://${match.groups?.address?.trim()}`);
args.onFind?.();
stream.off("data", handler);
clearTimeout(timeoutID);
resolve(+addr.port);
}
};
const timeoutID = setTimeout(() => {
stream.off("data", handler);
logger.warn(`[getPortFrom]: failed to retrieve port via ${args.lineRegex.rawMatcher}`, logLines);
reject(new Error("failed to retrieve port from stream"));
}, args.timeout ?? 15000);
stream.on("data", handler);
});
}

View File

@ -4,8 +4,9 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import loggerInjectable from "../../common/logger.injectable";
import hostedClusterIdInjectable from "../cluster-frame-context/hosted-cluster-id.injectable";
import type { TerminalApiQuery } from "./terminal-api";
import type { TerminalApiDependencies, TerminalApiQuery } from "./terminal-api";
import { TerminalApi } from "./terminal-api";
export type CreateTerminalApi = (query: TerminalApiQuery) => TerminalApi;
@ -14,12 +15,16 @@ const createTerminalApiInjectable = getInjectable({
id: "create-terminal-api",
instantiate: (di): CreateTerminalApi => {
const hostedClusterId = di.inject(hostedClusterIdInjectable);
const deps: Omit<TerminalApiDependencies, "hostedClusterId"> = {
logger: di.inject(loggerInjectable),
};
return (query) => {
assert(hostedClusterId, "Can only create terminal APIs within a cluster frame");
return new TerminalApi({
hostedClusterId,
...deps,
}, query);
};
},

View File

@ -9,7 +9,7 @@ import isEqual from "lodash/isEqual";
import url from "url";
import { makeObservable, observable } from "mobx";
import { ipcRenderer } from "electron";
import logger from "../../common/logger";
import type { Logger } from "../../common/logger";
import { once } from "lodash";
import { type TerminalMessage, TerminalChannels } from "../../common/terminal/channels";
@ -38,6 +38,7 @@ export interface TerminalEvents extends WebSocketEvents {
export interface TerminalApiDependencies {
readonly hostedClusterId: string;
readonly logger: Logger;
}
export class TerminalApi extends WebSocketApi<TerminalEvents> {
@ -145,11 +146,11 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
this.emit("connected");
break;
default:
logger.warn(`[TERMINAL-API]: unknown or unhandleable message type`, message);
this.dependencies.logger.warn(`[TERMINAL-API]: unknown or unhandleable message type`, message);
break;
}
} catch (error) {
logger.error(`[TERMINAL-API]: failed to handle message`, error);
this.dependencies.logger.error(`[TERMINAL-API]: failed to handle message`, error);
}
}

View File

@ -12,6 +12,7 @@ import { KubeObject } from "../../../common/k8s-api/kube-object";
import { beforeClusterFrameStartsSecondInjectionToken } from "../tokens";
import type { KubeObjectStoreDependencies } from "../../../common/k8s-api/kube-object.store";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import loggerInjectable from "../../../common/logger.injectable";
const setupAutoRegistrationInjectable = getInjectable({
id: "setup-auto-registration",
@ -23,6 +24,7 @@ const setupAutoRegistrationInjectable = getInjectable({
const beforeApiManagerInitializationApis: KubeApi[] = [];
const deps: KubeObjectStoreDependencies = {
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
};
let initialized = false;

View File

@ -13,7 +13,7 @@ import type { DiContainer } from "@ogre-tools/injectable";
import extensionLoaderInjectable from "../extensions/extension-loader/extension-loader.injectable";
import extensionDiscoveryInjectable from "../extensions/extension-discovery/extension-discovery.injectable";
import extensionInstallationStateStoreInjectable from "../extensions/extension-installation-state-store/extension-installation-state-store.injectable";
import initRootFrameInjectable from "./frames/root-frame/init-root-frame/init-root-frame.injectable";
import initRootFrameInjectable from "./frames/root-frame/init-root-frame.injectable";
import initClusterFrameInjectable from "./frames/cluster-frame/init-cluster-frame/init-cluster-frame.injectable";
import { Router } from "react-router";
import historyInjectable from "./navigation/history.injectable";

View File

@ -14,6 +14,7 @@ import assert from "assert";
import nodeStoreInjectable from "../../+nodes/store.injectable";
import requestClusterMetricsByNodeNamesInjectable from "../../../../common/k8s-api/endpoints/metrics.api/request-cluster-metrics-by-node-names.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
const clusterOverviewStoreInjectable = getInjectable({
id: "cluster-overview-store",
@ -34,6 +35,7 @@ const clusterOverviewStoreInjectable = getInjectable({
nodeStore: di.inject(nodeStoreInjectable),
requestClusterMetricsByNodeNames: di.inject(requestClusterMetricsByNodeNamesInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, clusterApi);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -16,17 +16,19 @@ import type { HorizontalPodAutoscalerMetricSpec, HorizontalPodAutoscalerMetricTa
import { HorizontalPodAutoscaler, HpaMetricType } from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api";
import { Table, TableCell, TableHead, TableRow } from "../table";
import type { ApiManager } from "../../../common/k8s-api/api-manager";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
import { withInjectables } from "@ogre-tools/injectable-react";
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
import loggerInjectable from "../../../common/logger.injectable";
export interface HpaDetailsProps extends KubeObjectDetailsProps<HorizontalPodAutoscaler> {
}
interface Dependencies {
apiManager: ApiManager;
logger: Logger;
getDetailsUrl: GetDetailsUrl;
}
@ -104,7 +106,7 @@ class NonInjectedHpaDetails extends React.Component<HpaDetailsProps & Dependenci
}
render() {
const { object: hpa, apiManager, getDetailsUrl } = this.props;
const { object: hpa, apiManager, getDetailsUrl, logger } = this.props;
if (!hpa) {
return null;
@ -172,5 +174,6 @@ export const HpaDetails = withInjectables<Dependencies, HpaDetailsProps>(NonInje
...props,
apiManager: di.inject(apiManagerInjectable),
getDetailsUrl: di.inject(getDetailsUrlInjectable),
logger: di.inject(loggerInjectable),
}),
});

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import horizontalPodAutoscalerApiInjectable from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { HorizontalPodAutoscalerStore } from "./store";
@ -19,6 +20,7 @@ const horizontalPodAutoscalerStoreInjectable = getInjectable({
return new HorizontalPodAutoscalerStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import leaseApiInjectable from "../../../common/k8s-api/endpoints/lease.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { LeaseStore } from "./store";
@ -19,6 +20,7 @@ const leaseStoreInjectable = getInjectable({
return new LeaseStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -12,7 +12,9 @@ import type { LimitRangeItem } from "../../../common/k8s-api/endpoints/limit-ran
import { LimitPart, LimitRange, Resource } from "../../../common/k8s-api/endpoints/limit-range.api";
import { DrawerItem } from "../drawer/drawer-item";
import { Badge } from "../badge";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
export interface LimitRangeDetailsProps extends KubeObjectDetailsProps<LimitRange> {
}
@ -51,10 +53,14 @@ function renderLimitDetails(limits: LimitRangeItem[], resources: Resource[]) {
));
}
interface Dependencies {
logger: Logger;
}
@observer
export class LimitRangeDetails extends React.Component<LimitRangeDetailsProps> {
class NonInjectedLimitRangeDetails extends React.Component<LimitRangeDetailsProps & Dependencies> {
render() {
const { object: limitRange } = this.props;
const { object: limitRange, logger } = this.props;
if (!limitRange) {
return null;
@ -97,3 +103,10 @@ export class LimitRangeDetails extends React.Component<LimitRangeDetailsProps> {
);
}
}
export const LimitRangeDetails = withInjectables<Dependencies, LimitRangeDetailsProps>(NonInjectedLimitRangeDetails, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
});

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import limitRangeApiInjectable from "../../../common/k8s-api/endpoints/limit-range.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { LimitRangeStore } from "./store";
@ -19,6 +20,7 @@ const limitRangeStoreInjectable = getInjectable({
return new LimitRangeStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import configMapApiInjectable from "../../../common/k8s-api/endpoints/config-map.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { ConfigMapStore } from "./store";
@ -19,6 +20,7 @@ const configMapStoreInjectable = getInjectable({
return new ConfigMapStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -11,13 +11,19 @@ import { DrawerItem } from "../drawer";
import { Badge } from "../badge";
import type { KubeObjectDetailsProps } from "../kube-object-details";
import { PodDisruptionBudget } from "../../../common/k8s-api/endpoints";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
export interface PodDisruptionBudgetDetailsProps extends KubeObjectDetailsProps<PodDisruptionBudget> {
}
interface Dependencies {
logger: Logger;
}
@observer
export class PodDisruptionBudgetDetails extends React.Component<PodDisruptionBudgetDetailsProps> {
class NonInjectedPodDisruptionBudgetDetails extends React.Component<PodDisruptionBudgetDetailsProps & Dependencies> {
render() {
const { object: pdb } = this.props;
@ -27,7 +33,7 @@ export class PodDisruptionBudgetDetails extends React.Component<PodDisruptionBud
}
if (!(pdb instanceof PodDisruptionBudget)) {
logger.error("[PodDisruptionBudgetDetails]: passed object that is not an instanceof PodDisruptionBudget", pdb);
this.props.logger.error("[PodDisruptionBudgetDetails]: passed object that is not an instanceof PodDisruptionBudget", pdb);
return null;
}
@ -64,3 +70,10 @@ export class PodDisruptionBudgetDetails extends React.Component<PodDisruptionBud
);
}
}
export const PodDisruptionBudgetDetails = withInjectables<Dependencies, PodDisruptionBudgetDetailsProps>(NonInjectedPodDisruptionBudgetDetails, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
});

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import podDisruptionBudgetApiInjectable from "../../../common/k8s-api/endpoints/pod-disruption-budget.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { PodDisruptionBudgetStore } from "./store";
@ -19,6 +20,7 @@ const podDisruptionBudgetStoreInjectable = getInjectable({
return new PodDisruptionBudgetStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import priorityClassApiInjectable from "../../../common/k8s-api/endpoints/priority-class.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { PriorityClassStore } from "./store";
@ -19,6 +20,7 @@ const priorityClassStoreInjectable = getInjectable({
return new PriorityClassStore({
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -13,7 +13,9 @@ import type { KubeObjectDetailsProps } from "../kube-object-details";
import { ResourceQuota } from "../../../common/k8s-api/endpoints/resource-quota.api";
import { LineProgress } from "../line-progress";
import { Table, TableCell, TableHead, TableRow } from "../table";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
export interface ResourceQuotaDetailsProps extends KubeObjectDetailsProps<ResourceQuota> {
}
@ -75,8 +77,12 @@ function renderQuotas(quota: ResourceQuota): JSX.Element[] {
});
}
interface Dependencies {
logger: Logger;
}
@observer
export class ResourceQuotaDetails extends React.Component<ResourceQuotaDetailsProps> {
class NonInjectedResourceQuotaDetails extends React.Component<ResourceQuotaDetailsProps & Dependencies> {
render() {
const { object: quota } = this.props;
@ -85,7 +91,7 @@ export class ResourceQuotaDetails extends React.Component<ResourceQuotaDetailsPr
}
if (!(quota instanceof ResourceQuota)) {
logger.error("[ResourceQuotaDetails]: passed object that is not an instanceof ResourceQuota", quota);
this.props.logger.error("[ResourceQuotaDetails]: passed object that is not an instanceof ResourceQuota", quota);
return null;
}
@ -125,3 +131,10 @@ export class ResourceQuotaDetails extends React.Component<ResourceQuotaDetailsPr
);
}
}
export const ResourceQuotaDetails = withInjectables<Dependencies, ResourceQuotaDetailsProps>(NonInjectedResourceQuotaDetails, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
});

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import resourceQuotaApiInjectable from "../../../common/k8s-api/endpoints/resource-quota.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { ResourceQuotaStore } from "./store";
@ -19,6 +20,7 @@ const resourceQuotaStoreInjectable = getInjectable({
return new ResourceQuotaStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import runtimeClassApiInjectable from "../../../common/k8s-api/endpoints/runtime-class.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { RuntimeClassStore } from "./store";
@ -19,6 +20,7 @@ const runtimeClassStoreInjectable = getInjectable({
return new RuntimeClassStore({
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import secretApiInjectable from "../../../common/k8s-api/endpoints/secret.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { SecretStore } from "./store";
@ -19,6 +20,7 @@ const secretStoreInjectable = getInjectable({
return new SecretStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -15,13 +15,19 @@ import type { KubeObjectDetailsProps } from "../kube-object-details";
import { Table, TableCell, TableHead, TableRow } from "../table";
import { Input } from "../input";
import { MonacoEditor } from "../monaco-editor";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
export interface CRDDetailsProps extends KubeObjectDetailsProps<CustomResourceDefinition> {
}
interface Dependencies {
logger: Logger;
}
@observer
export class CRDDetails extends React.Component<CRDDetailsProps> {
class NonInjectedCRDDetails extends React.Component<CRDDetailsProps & Dependencies> {
render() {
const { object: crd } = this.props;
@ -30,7 +36,7 @@ export class CRDDetails extends React.Component<CRDDetailsProps> {
}
if (!(crd instanceof CustomResourceDefinition)) {
logger.error("[CRDDetails]: passed object that is not an instanceof CustomResourceDefinition", crd);
this.props.logger.error("[CRDDetails]: passed object that is not an instanceof CustomResourceDefinition", crd);
return null;
}
@ -152,3 +158,10 @@ export class CRDDetails extends React.Component<CRDDetailsProps> {
);
}
}
export const CRDDetails = withInjectables<Dependencies, CRDDetailsProps>(NonInjectedCRDDetails, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
});

View File

@ -17,7 +17,9 @@ import { CustomResourceDefinition } from "../../../common/k8s-api/endpoints/cust
import { safeJSONPathValue } from "../../utils/jsonPath";
import type { KubeObjectMetadata, KubeObjectStatus } from "../../../common/k8s-api/kube-object";
import { KubeObject } from "../../../common/k8s-api/kube-object";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
export interface CustomResourceDetailsProps extends KubeObjectDetailsProps<KubeObject> {
crd?: CustomResourceDefinition;
@ -59,8 +61,12 @@ function convertSpecValue(value: unknown): React.ReactNode {
return null;
}
interface Dependencies {
logger: Logger;
}
@observer
export class CustomResourceDetails extends React.Component<CustomResourceDetailsProps> {
class NonInjectedCustomResourceDetails extends React.Component<CustomResourceDetailsProps & Dependencies> {
renderAdditionalColumns(resource: KubeObject, columns: AdditionalPrinterColumnsV1[]) {
return columns.map(({ name, jsonPath }) => (
<DrawerItem key={name} name={name}>
@ -106,7 +112,7 @@ export class CustomResourceDetails extends React.Component<CustomResourceDetails
}
render() {
const { props: { object, crd }} = this;
const { props: { object, crd, logger }} = this;
if (!object || !crd) {
return null;
@ -134,3 +140,10 @@ export class CustomResourceDetails extends React.Component<CustomResourceDetails
);
}
}
export const CustomResourceDetails = withInjectables<Dependencies, CustomResourceDetailsProps>(NonInjectedCustomResourceDetails, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
});

View File

@ -7,6 +7,7 @@ import assert from "assert";
import autoRegistrationEmitterInjectable from "../../../common/k8s-api/api-manager/auto-registration-emitter.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import customResourceDefinitionApiInjectable from "../../../common/k8s-api/endpoints/custom-resource-definition.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { CustomResourceDefinitionStore } from "./definition.store";
@ -21,6 +22,7 @@ const customResourceDefinitionStoreInjectable = getInjectable({
return new CustomResourceDefinitionStore({
autoRegistration: di.inject(autoRegistrationEmitterInjectable),
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -14,13 +14,14 @@ import type { KubeObjectDetailsProps } from "../kube-object-details";
import { KubeEvent } from "../../../common/k8s-api/endpoints/events.api";
import { Table, TableCell, TableHead, TableRow } from "../table";
import type { ApiManager } from "../../../common/k8s-api/api-manager";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { DurationAbsoluteTimestamp } from "./duration-absolute";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
import { cssNames } from "../../utils";
import loggerInjectable from "../../../common/logger.injectable";
export interface EventDetailsProps extends KubeObjectDetailsProps<KubeEvent> {
}
@ -28,6 +29,7 @@ export interface EventDetailsProps extends KubeObjectDetailsProps<KubeEvent> {
interface Dependencies {
getDetailsUrl: GetDetailsUrl;
apiManager: ApiManager;
logger: Logger;
}
const NonInjectedEventDetails = observer(({
@ -35,6 +37,7 @@ const NonInjectedEventDetails = observer(({
getDetailsUrl,
object: event,
className,
logger,
}: Dependencies & EventDetailsProps) => {
if (!event) {
return null;
@ -101,5 +104,6 @@ export const EventDetails = withInjectables<Dependencies, EventDetailsProps>(Non
...props,
apiManager: di.inject(apiManagerInjectable),
getDetailsUrl: di.inject(getDetailsUrlInjectable),
logger: di.inject(loggerInjectable),
}),
});

View File

@ -12,12 +12,13 @@ import { DrawerItem, DrawerTitle } from "../drawer";
import { cssNames } from "../../utils";
import { LocaleDate } from "../locale-date";
import type { EventStore } from "./store";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
import eventStoreInjectable from "./store.injectable";
import loggerInjectable from "../../../common/logger.injectable";
export interface KubeEventDetailsProps {
object: KubeObject;
@ -26,6 +27,7 @@ export interface KubeEventDetailsProps {
interface Dependencies {
subscribeStores: SubscribeStores;
eventStore: EventStore;
logger: Logger;
}
@observer
@ -46,7 +48,7 @@ class NonInjectedKubeEventDetails extends React.Component<KubeEventDetailsProps
}
if (!(object instanceof KubeObject)) {
logger.error("[KubeEventDetails]: passed object that is not an instanceof KubeObject", object);
this.props.logger.error("[KubeEventDetails]: passed object that is not an instanceof KubeObject", object);
return null;
}
@ -93,6 +95,7 @@ export const KubeEventDetails = withInjectables<Dependencies, KubeEventDetailsPr
...props,
subscribeStores: di.inject(subscribeStoresInjectable),
eventStore: di.inject(eventStoreInjectable),
logger: di.inject(loggerInjectable),
}),
});

View File

@ -7,6 +7,7 @@ import assert from "assert";
import getPodByIdInjectable from "../+workloads-pods/get-pod-by-id.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import kubeEventApiInjectable from "../../../common/k8s-api/endpoints/events.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { EventStore } from "./store";
@ -21,6 +22,7 @@ const eventStoreInjectable = getInjectable({
return new EventStore({
getPodById: di.inject(getPodByIdInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import extensionLoaderInjectable from "../../../../extensions/extension-loader/extension-loader.injectable";
import uninstallExtensionInjectable from "../uninstall-extension/uninstall-extension.injectable";
import uninstallExtensionInjectable from "../uninstall-extension.injectable";
import type { UnpackExtension } from "./unpack-extension.injectable";
import unpackExtensionInjectable from "./unpack-extension.injectable";
import type { GetExtensionDestFolder } from "./get-extension-dest-folder.injectable";

View File

@ -9,7 +9,7 @@ import type { LensExtensionId } from "../../../extensions/lens-extension";
import { extensionDisplayName } from "../../../extensions/lens-extension";
import type { Confirm } from "../confirm-dialog/confirm.injectable";
import confirmInjectable from "../confirm-dialog/confirm.injectable";
import uninstallExtensionInjectable from "./uninstall-extension/uninstall-extension.injectable";
import uninstallExtensionInjectable from "./uninstall-extension.injectable";
interface Dependencies {
uninstallExtension: (id: LensExtensionId) => Promise<boolean>;

View File

@ -0,0 +1,81 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import extensionLoaderInjectable from "../../../extensions/extension-loader/extension-loader.injectable";
import extensionInstallationStateStoreInjectable from "../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable";
import extensionDiscoveryInjectable from "../../../extensions/extension-discovery/extension-discovery.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import type { LensExtensionId } from "../../../extensions/lens-extension";
import { extensionDisplayName } from "../../../extensions/lens-extension";
import { Notifications } from "../notifications";
import React from "react";
import { when } from "mobx";
import { getMessageFromError } from "./get-message-from-error/get-message-from-error";
const uninstallExtensionInjectable = getInjectable({
id: "uninstall-extension",
instantiate: (di) => {
const extensionLoader = di.inject(extensionLoaderInjectable);
const extensionDiscovery = di.inject(extensionDiscoveryInjectable);
const extensionInstallationStateStore = di.inject(extensionInstallationStateStoreInjectable);
const logger = di.inject(loggerInjectable);
return async (extensionId: LensExtensionId): Promise<boolean> => {
const ext = extensionLoader.getExtension(extensionId);
if (!ext) {
logger.debug(`[EXTENSIONS]: cannot uninstall ${extensionId}, was not installed`);
return true;
}
const { manifest } = ext;
const displayName = extensionDisplayName(manifest.name, manifest.version);
try {
logger.debug(`[EXTENSIONS]: trying to uninstall ${extensionId}`);
extensionInstallationStateStore.setUninstalling(extensionId);
await extensionDiscovery.uninstallExtension(extensionId);
// wait for the ExtensionLoader to actually uninstall the extension
await when(() => !extensionLoader.userExtensions.has(extensionId));
Notifications.ok(
<p>
{"Extension "}
<b>{displayName}</b>
{" successfully uninstalled!"}
</p>,
);
return true;
} catch (error) {
const message = getMessageFromError(error);
logger.info(
`[EXTENSION-UNINSTALL]: uninstalling ${displayName} has failed: ${error}`,
{ error },
);
Notifications.error(
<p>
{"Uninstalling extension "}
<b>{displayName}</b>
{" has failed: "}
<em>{message}</em>
</p>,
);
return false;
} finally {
// Remove uninstall state on uninstall failure
extensionInstallationStateStore.clearUninstalling(extensionId);
}
};
},
});
export default uninstallExtensionInjectable;

View File

@ -1,24 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import extensionLoaderInjectable from "../../../../extensions/extension-loader/extension-loader.injectable";
import { uninstallExtension } from "./uninstall-extension";
import extensionInstallationStateStoreInjectable
from "../../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable";
import extensionDiscoveryInjectable
from "../../../../extensions/extension-discovery/extension-discovery.injectable";
const uninstallExtensionInjectable = getInjectable({
id: "uninstall-extension",
instantiate: (di) =>
uninstallExtension({
extensionLoader: di.inject(extensionLoaderInjectable),
extensionDiscovery: di.inject(extensionDiscoveryInjectable),
extensionInstallationStateStore: di.inject(extensionInstallationStateStoreInjectable),
}),
});
export default uninstallExtensionInjectable;

View File

@ -1,79 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { ExtensionLoader } from "../../../../extensions/extension-loader";
import type { LensExtensionId } from "../../../../extensions/lens-extension";
import { extensionDisplayName } from "../../../../extensions/lens-extension";
import logger from "../../../../main/logger";
import type { ExtensionDiscovery } from "../../../../extensions/extension-discovery/extension-discovery";
import { Notifications } from "../../notifications";
import React from "react";
import { when } from "mobx";
import { getMessageFromError } from "../get-message-from-error/get-message-from-error";
import type { ExtensionInstallationStateStore } from "../../../../extensions/extension-installation-state-store/extension-installation-state-store";
interface Dependencies {
extensionLoader: ExtensionLoader;
extensionDiscovery: ExtensionDiscovery;
extensionInstallationStateStore: ExtensionInstallationStateStore;
}
export const uninstallExtension = ({
extensionLoader,
extensionDiscovery,
extensionInstallationStateStore,
}: Dependencies) => (
async (extensionId: LensExtensionId): Promise<boolean> => {
const ext = extensionLoader.getExtension(extensionId);
if (!ext) {
logger.debug(`[EXTENSIONS]: cannot uninstall ${extensionId}, was not installed`);
return true;
}
const { manifest } = ext;
const displayName = extensionDisplayName(manifest.name, manifest.version);
try {
logger.debug(`[EXTENSIONS]: trying to uninstall ${extensionId}`);
extensionInstallationStateStore.setUninstalling(extensionId);
await extensionDiscovery.uninstallExtension(extensionId);
// wait for the ExtensionLoader to actually uninstall the extension
await when(() => !extensionLoader.userExtensions.has(extensionId));
Notifications.ok(
<p>
{"Extension "}
<b>{displayName}</b>
{" successfully uninstalled!"}
</p>,
);
return true;
} catch (error) {
const message = getMessageFromError(error);
logger.info(
`[EXTENSION-UNINSTALL]: uninstalling ${displayName} has failed: ${error}`,
{ error },
);
Notifications.error(
<p>
{"Uninstalling extension "}
<b>{displayName}</b>
{" has failed: "}
<em>{message}</em>
</p>,
);
return false;
} finally {
// Remove uninstall state on uninstall failure
extensionInstallationStateStore.clearUninstalling(extensionId);
}
}
);

View File

@ -11,6 +11,7 @@ import assert from "assert";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import clusterConfiguredAccessibleNamespacesInjectable from "../../cluster/accessible-namespaces.injectable";
import loggerInjectable from "../../../common/logger.injectable";
const namespaceStoreInjectable = getInjectable({
id: "namespace-store",
@ -25,6 +26,7 @@ const namespaceStoreInjectable = getInjectable({
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
storage: createStorage<string[] | undefined>("selected_namespaces", undefined),
clusterConfiguredAccessibleNamespaces: di.inject(clusterConfiguredAccessibleNamespacesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -11,13 +11,19 @@ import { DrawerTitle } from "../drawer";
import type { KubeObjectDetailsProps } from "../kube-object-details";
import { Endpoints } from "../../../common/k8s-api/endpoints";
import { EndpointSubsetList } from "./endpoint-subset-list";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
export interface EndpointsDetailsProps extends KubeObjectDetailsProps<Endpoints> {
}
interface Dependencies {
logger: Logger;
}
@observer
export class EndpointsDetails extends React.Component<EndpointsDetailsProps> {
class NonInjectedEndpointsDetails extends React.Component<EndpointsDetailsProps & Dependencies> {
render() {
const { object: endpoint } = this.props;
@ -26,7 +32,7 @@ export class EndpointsDetails extends React.Component<EndpointsDetailsProps> {
}
if (!(endpoint instanceof Endpoints)) {
logger.error("[EndpointDetails]: passed object that is not an instanceof Endpoint", endpoint);
this.props.logger.error("[EndpointDetails]: passed object that is not an instanceof Endpoint", endpoint);
return null;
}
@ -47,3 +53,10 @@ export class EndpointsDetails extends React.Component<EndpointsDetailsProps> {
);
}
}
export const EndpointsDetails = withInjectables<Dependencies, EndpointsDetailsProps>(NonInjectedEndpointsDetails, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
});

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import endpointsApiInjectable from "../../../common/k8s-api/endpoints/endpoint.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { EndpointsStore } from "./store";
@ -19,6 +20,7 @@ const endpointsStoreInjectable = getInjectable({
return new EndpointsStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import ingressApiInjectable from "../../../common/k8s-api/endpoints/ingress.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { IngressStore } from "./ingress-store";
@ -19,6 +20,7 @@ const ingressStoreInjectable = getInjectable({
return new IngressStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -13,15 +13,21 @@ import { Badge } from "../badge";
import { SubTitle } from "../layout/sub-title";
import { observer } from "mobx-react";
import type { KubeObjectDetailsProps } from "../kube-object-details";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import type { LabelMatchExpression, LabelSelector } from "../../../common/k8s-api/kube-object";
import { isEmpty } from "lodash";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
export interface NetworkPolicyDetailsProps extends KubeObjectDetailsProps<NetworkPolicy> {
}
interface Dependencies {
logger: Logger;
}
@observer
export class NetworkPolicyDetails extends React.Component<NetworkPolicyDetailsProps> {
class NonInjectedNetworkPolicyDetails extends React.Component<NetworkPolicyDetailsProps & Dependencies> {
renderIPolicyIpBlock(ipBlock: IPolicyIpBlock | undefined) {
if (!ipBlock) {
return null;
@ -159,7 +165,7 @@ export class NetworkPolicyDetails extends React.Component<NetworkPolicyDetailsPr
}
if (!(policy instanceof NetworkPolicy)) {
logger.error("[NetworkPolicyDetails]: passed object that is not an instanceof NetworkPolicy", policy);
this.props.logger.error("[NetworkPolicyDetails]: passed object that is not an instanceof NetworkPolicy", policy);
return null;
}
@ -204,3 +210,10 @@ export class NetworkPolicyDetails extends React.Component<NetworkPolicyDetailsPr
);
}
}
export const NetworkPolicyDetails = withInjectables<Dependencies, NetworkPolicyDetailsProps>(NonInjectedNetworkPolicyDetails, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
});

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import networkPolicyApiInjectable from "../../../common/k8s-api/endpoints/network-policy.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { NetworkPolicyStore } from "./store";
@ -19,6 +20,7 @@ const networkPolicyStoreInjectable = getInjectable({
return new NetworkPolicyStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -15,12 +15,13 @@ import { ServicePortComponent } from "./service-port-component";
import type { EndpointsStore } from "../+network-endpoints/store";
import { ServiceDetailsEndpoint } from "./service-details-endpoint";
import type { PortForwardStore } from "../../port-forward";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import portForwardStoreInjectable from "../../port-forward/port-forward-store/port-forward-store.injectable";
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
import endpointsStoreInjectable from "../+network-endpoints/store.injectable";
import loggerInjectable from "../../../common/logger.injectable";
export interface ServiceDetailsProps extends KubeObjectDetailsProps<Service> {
}
@ -29,6 +30,7 @@ interface Dependencies {
subscribeStores: SubscribeStores;
portForwardStore: PortForwardStore;
endpointsStore: EndpointsStore;
logger: Logger;
}
@observer
@ -59,7 +61,7 @@ class NonInjectedServiceDetails extends React.Component<ServiceDetailsProps & De
}
if (!(service instanceof Service)) {
logger.error("[ServiceDetails]: passed object that is not an instanceof Service", service);
this.props.logger.error("[ServiceDetails]: passed object that is not an instanceof Service", service);
return null;
}
@ -155,5 +157,6 @@ export const ServiceDetails = withInjectables<Dependencies, ServiceDetailsProps>
subscribeStores: di.inject(subscribeStoresInjectable),
portForwardStore: di.inject(portForwardStoreInjectable),
endpointsStore: di.inject(endpointsStoreInjectable),
logger: di.inject(loggerInjectable),
}),
});

View File

@ -18,11 +18,12 @@ import { Spinner } from "../spinner";
import { withInjectables } from "@ogre-tools/injectable-react";
import portForwardStoreInjectable from "../../port-forward/port-forward-store/port-forward-store.injectable";
import portForwardDialogModelInjectable from "../../port-forward/port-forward-dialog-model/port-forward-dialog-model.injectable";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import aboutPortForwardingInjectable from "../../port-forward/about-port-forwarding.injectable";
import notifyErrorPortForwardingInjectable from "../../port-forward/notify-error-port-forwarding.injectable";
import type { OpenPortForward } from "../../port-forward/open-port-forward.injectable";
import openPortForwardInjectable from "../../port-forward/open-port-forward.injectable";
import loggerInjectable from "../../../common/logger.injectable";
export interface ServicePortComponentProps {
service: Service;
@ -31,6 +32,7 @@ export interface ServicePortComponentProps {
interface Dependencies {
portForwardStore: PortForwardStore;
logger: Logger;
openPortForwardDialog: (item: ForwardedPort, options: { openInBrowser: boolean; onClose: () => void }) => void;
aboutPortForwarding: () => void;
notifyErrorPortForwarding: (message: string) => void;
@ -127,7 +129,7 @@ class NonInjectedServicePortComponent extends React.Component<ServicePortCompone
this.props.notifyErrorPortForwarding(`Error occurred starting port-forward, the local port may not be available or the ${portForward.kind} ${portForward.name} may not be reachable`);
}
} catch (error) {
logger.error("[SERVICE-PORT-COMPONENT]:", error, portForward);
this.props.logger.error("[SERVICE-PORT-COMPONENT]:", error, portForward);
} finally {
this.checkExistingPortForwarding();
this.waiting = false;
@ -196,18 +198,15 @@ class NonInjectedServicePortComponent extends React.Component<ServicePortCompone
}
}
export const ServicePortComponent = withInjectables<Dependencies, ServicePortComponentProps>(
NonInjectedServicePortComponent,
{
getProps: (di, props) => ({
portForwardStore: di.inject(portForwardStoreInjectable),
openPortForwardDialog: di.inject(portForwardDialogModelInjectable).open,
aboutPortForwarding: di.inject(aboutPortForwardingInjectable),
notifyErrorPortForwarding: di.inject(notifyErrorPortForwardingInjectable),
openPortForward: di.inject(openPortForwardInjectable),
...props,
}),
},
);
export const ServicePortComponent = withInjectables<Dependencies, ServicePortComponentProps>(NonInjectedServicePortComponent, {
getProps: (di, props) => ({
...props,
portForwardStore: di.inject(portForwardStoreInjectable),
openPortForwardDialog: di.inject(portForwardDialogModelInjectable).open,
aboutPortForwarding: di.inject(aboutPortForwardingInjectable),
notifyErrorPortForwarding: di.inject(notifyErrorPortForwardingInjectable),
openPortForward: di.inject(openPortForwardInjectable),
logger: di.inject(loggerInjectable),
}),
});

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import serviceApiInjectable from "../../../common/k8s-api/endpoints/service.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { ServiceStore } from "./store";
@ -19,6 +20,7 @@ const serviceStoreInjectable = getInjectable({
return new ServiceStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import nodeApiInjectable from "../../../common/k8s-api/endpoints/node.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { NodeStore } from "./store";
@ -19,6 +20,7 @@ const nodeStoreInjectable = getInjectable({
return new NodeStore({
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -12,7 +12,9 @@ import type { KubeObjectDetailsProps } from "../kube-object-details";
import { PodSecurityPolicy } from "../../../common/k8s-api/endpoints";
import { Badge } from "../badge";
import { Table, TableCell, TableHead, TableRow } from "../table";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
export interface PodSecurityPolicyDetailsProps extends KubeObjectDetailsProps<PodSecurityPolicy> {
}
@ -25,8 +27,12 @@ interface RuleGroup {
}[];
}
interface Dependencies {
logger: Logger;
}
@observer
export class PodSecurityPolicyDetails extends React.Component<PodSecurityPolicyDetailsProps> {
class NonInjectedPodSecurityPolicyDetails extends React.Component<PodSecurityPolicyDetailsProps & Dependencies> {
renderRuleGroup(title: React.ReactNode, group: RuleGroup | undefined) {
if (!group) return null;
const { rule, ranges } = group;
@ -59,7 +65,7 @@ export class PodSecurityPolicyDetails extends React.Component<PodSecurityPolicyD
}
if (!(psp instanceof PodSecurityPolicy)) {
logger.error("[PodSecurityPolicyDetails]: passed object that is not an instanceof PodSecurityPolicy", psp);
this.props.logger.error("[PodSecurityPolicyDetails]: passed object that is not an instanceof PodSecurityPolicy", psp);
return null;
}
@ -225,3 +231,10 @@ export class PodSecurityPolicyDetails extends React.Component<PodSecurityPolicyD
);
}
}
export const PodSecurityPolicyDetails = withInjectables<Dependencies, PodSecurityPolicyDetailsProps>(NonInjectedPodSecurityPolicyDetails, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
});

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import podSecurityPolicyApiInjectable from "../../../common/k8s-api/endpoints/pod-security-policy.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { PodSecurityPolicyStore } from "./store";
@ -19,6 +20,7 @@ const podSecurityPolicyStoreInjectable = getInjectable({
return new PodSecurityPolicyStore({
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -15,12 +15,13 @@ import { StorageClass } from "../../../common/k8s-api/endpoints";
import type { StorageClassStore } from "./store";
import { VolumeDetailsList } from "../+storage-volumes/volume-details-list";
import type { PersistentVolumeStore } from "../+storage-volumes/store";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
import storageClassStoreInjectable from "./store.injectable";
import persistentVolumeStoreInjectable from "../+storage-volumes/store.injectable";
import loggerInjectable from "../../../common/logger.injectable";
export interface StorageClassDetailsProps extends KubeObjectDetailsProps<StorageClass> {
}
@ -29,6 +30,7 @@ interface Dependencies {
subscribeStores: SubscribeStores;
storageClassStore: StorageClassStore;
persistentVolumeStore: PersistentVolumeStore;
logger: Logger;
}
@observer
@ -49,7 +51,7 @@ class NonInjectedStorageClassDetails extends React.Component<StorageClassDetails
}
if (!(storageClass instanceof StorageClass)) {
logger.error("[StorageClassDetails]: passed object that is not an instanceof StorageClass", storageClass);
this.props.logger.error("[StorageClassDetails]: passed object that is not an instanceof StorageClass", storageClass);
return null;
}
@ -100,6 +102,7 @@ export const StorageClassDetails = withInjectables<Dependencies, StorageClassDet
subscribeStores: di.inject(subscribeStoresInjectable),
storageClassStore: di.inject(storageClassStoreInjectable),
persistentVolumeStore: di.inject(persistentVolumeStoreInjectable),
logger: di.inject(loggerInjectable),
}),
});

View File

@ -7,6 +7,7 @@ import assert from "assert";
import getPersistentVolumesByStorageClassInjectable from "../+storage-volumes/get-persisten-volumes-by-storage-class.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import storageClassApiInjectable from "../../../common/k8s-api/endpoints/storage-class.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { StorageClassStore } from "./store";
@ -21,6 +22,7 @@ const storageClassStoreInjectable = getInjectable({
return new StorageClassStore({
getPersistentVolumesByStorageClass: di.inject(getPersistentVolumesByStorageClassInjectable),
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import persistentVolumeClaimApiInjectable from "../../../common/k8s-api/endpoints/persistent-volume-claim.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { PersistentVolumeClaimStore } from "./store";
@ -19,6 +20,7 @@ const persistentVolumeClaimStoreInjectable = getInjectable({
return new PersistentVolumeClaimStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import persistentVolumeApiInjectable from "../../../common/k8s-api/endpoints/persistent-volume.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { PersistentVolumeStore } from "./store";
@ -19,6 +20,7 @@ const persistentVolumeStoreInjectable = getInjectable({
return new PersistentVolumeStore({
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -14,14 +14,20 @@ import { Badge } from "../badge";
import { PersistentVolume, persistentVolumeClaimApi, storageClassApi } from "../../../common/k8s-api/endpoints";
import type { KubeObjectDetailsProps } from "../kube-object-details";
import { getDetailsUrl } from "../kube-detail-params";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { stopPropagation } from "../../../renderer/utils";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
export interface PersistentVolumeDetailsProps extends KubeObjectDetailsProps<PersistentVolume> {
}
interface Dependencies {
logger: Logger;
}
@observer
export class PersistentVolumeDetails extends React.Component<PersistentVolumeDetailsProps> {
class NonInjectedPersistentVolumeDetails extends React.Component<PersistentVolumeDetailsProps & Dependencies> {
render() {
const { object: volume } = this.props;
@ -30,7 +36,7 @@ export class PersistentVolumeDetails extends React.Component<PersistentVolumeDet
}
if (!(volume instanceof PersistentVolume)) {
logger.error("[PersistentVolumeDetails]: passed object that is not an instanceof PersistentVolume", volume);
this.props.logger.error("[PersistentVolumeDetails]: passed object that is not an instanceof PersistentVolume", volume);
return null;
}
@ -121,3 +127,10 @@ export class PersistentVolumeDetails extends React.Component<PersistentVolumeDet
);
}
}
export const PersistentVolumeDetails = withInjectables<Dependencies, PersistentVolumeDetailsProps>(NonInjectedPersistentVolumeDetails, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
});

View File

@ -9,6 +9,7 @@ import clusterRoleBindingApiInjectable from "../../../../common/k8s-api/endpoint
import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable";
import { ClusterRoleBindingStore } from "./store";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
const clusterRoleBindingStoreInjectable = getInjectable({
id: "cluster-role-binding-store",
@ -19,6 +20,7 @@ const clusterRoleBindingStoreInjectable = getInjectable({
return new ClusterRoleBindingStore({
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -9,6 +9,7 @@ import clusterRoleApiInjectable from "../../../../common/k8s-api/endpoints/clust
import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable";
import { ClusterRoleStore } from "./store";
import clusterFrameContextForClusterScopedResourcesInjectable from "../../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
const clusterRoleStoreInjectable = getInjectable({
id: "cluster-role-store",
@ -19,6 +20,7 @@ const clusterRoleStoreInjectable = getInjectable({
return new ClusterRoleStore({
context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import assert from "assert";
import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable";
import roleBindingApiInjectable from "../../../../common/k8s-api/endpoints/role-binding.api.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable";
import { RoleBindingStore } from "./store";
@ -19,6 +20,7 @@ const roleBindingStoreInjectable = getInjectable({
return new RoleBindingStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -9,6 +9,7 @@ import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-cre
import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable";
import { RoleStore } from "./store";
import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
const roleStoreInjectable = getInjectable({
id: "role-store",
@ -19,6 +20,7 @@ const roleStoreInjectable = getInjectable({
return new RoleStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -9,6 +9,7 @@ import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-cre
import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable";
import { ServiceAccountStore } from "./store";
import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
const serviceAccountStoreInjectable = getInjectable({
id: "service-account-store",
@ -19,6 +20,7 @@ const serviceAccountStoreInjectable = getInjectable({
return new ServiceAccountStore({
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -17,12 +17,13 @@ import type { KubeObjectDetailsProps } from "../kube-object-details";
import { getDetailsUrl } from "../kube-detail-params";
import type { Job } from "../../../common/k8s-api/endpoints";
import { CronJob } from "../../../common/k8s-api/endpoints";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
import cronJobStoreInjectable from "./store.injectable";
import jobStoreInjectable from "../+workloads-jobs/store.injectable";
import loggerInjectable from "../../../common/logger.injectable";
export interface CronJobDetailsProps extends KubeObjectDetailsProps<CronJob> {
}
@ -31,6 +32,7 @@ interface Dependencies {
subscribeStores: SubscribeStores;
jobStore: JobStore;
cronJobStore: CronJobStore;
logger: Logger;
}
@observer
@ -51,7 +53,7 @@ class NonInjectedCronJobDetails extends React.Component<CronJobDetailsProps & De
}
if (!(cronJob instanceof CronJob)) {
logger.error("[CronJobDetails]: passed object that is not an instanceof CronJob", cronJob);
this.props.logger.error("[CronJobDetails]: passed object that is not an instanceof CronJob", cronJob);
return null;
}
@ -123,5 +125,6 @@ export const CronJobDetails = withInjectables<Dependencies, CronJobDetailsProps>
subscribeStores: di.inject(subscribeStoresInjectable),
cronJobStore: di.inject(cronJobStoreInjectable),
jobStore: di.inject(jobStoreInjectable),
logger: di.inject(loggerInjectable),
}),
});

View File

@ -7,6 +7,7 @@ import assert from "assert";
import getJobsByOwnerInjectable from "../+workloads-jobs/get-jobs-by-owner.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import cronJobApiInjectable from "../../../common/k8s-api/endpoints/cron-job.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { CronJobStore } from "./store";
@ -21,6 +22,7 @@ const cronJobStoreInjectable = getInjectable({
return new CronJobStore({
getJobsByOwner: di.inject(getJobsByOwnerInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -10,6 +10,7 @@ import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-create
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import { DaemonSetStore } from "./store";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import loggerInjectable from "../../../common/logger.injectable";
const daemonSetStoreInjectable = getInjectable({
id: "daemon-set-store",
@ -21,6 +22,7 @@ const daemonSetStoreInjectable = getInjectable({
return new DaemonSetStore({
getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -10,6 +10,7 @@ import { storesAndApisCanBeCreatedInjectionToken } from "../../../common/k8s-api
import deploymentApiInjectable from "../../../common/k8s-api/endpoints/deployment.api.injectable";
import { DeploymentStore } from "./store";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import loggerInjectable from "../../../common/logger.injectable";
const deploymentStoreInjectable = getInjectable({
id: "deployment-store",
@ -21,6 +22,7 @@ const deploymentStoreInjectable = getInjectable({
return new DeploymentStore({
podStore: di.inject(podStoreInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -7,6 +7,7 @@ import assert from "assert";
import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import jobApiInjectable from "../../../common/k8s-api/endpoints/job.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { JobStore } from "./store";
@ -21,6 +22,7 @@ const jobStoreInjectable = getInjectable({
return new JobStore({
getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -18,11 +18,12 @@ import { Spinner } from "../spinner";
import { withInjectables } from "@ogre-tools/injectable-react";
import portForwardStoreInjectable from "../../port-forward/port-forward-store/port-forward-store.injectable";
import portForwardDialogModelInjectable from "../../port-forward/port-forward-dialog-model/port-forward-dialog-model.injectable";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import aboutPortForwardingInjectable from "../../port-forward/about-port-forwarding.injectable";
import notifyErrorPortForwardingInjectable from "../../port-forward/notify-error-port-forwarding.injectable";
import type { OpenPortForward } from "../../port-forward/open-port-forward.injectable";
import openPortForwardInjectable from "../../port-forward/open-port-forward.injectable";
import loggerInjectable from "../../../common/logger.injectable";
export interface PodContainerPortProps {
pod: Pod;
@ -31,6 +32,7 @@ export interface PodContainerPortProps {
interface Dependencies {
portForwardStore: PortForwardStore;
logger: Logger;
openPortForwardDialog: (item: ForwardedPort, options: { openInBrowser: boolean; onClose: () => void }) => void;
aboutPortForwarding: () => void;
notifyErrorPortForwarding: (message: string) => void;
@ -123,7 +125,7 @@ class NonInjectedPodContainerPort extends React.Component<PodContainerPortProps
this.props.notifyErrorPortForwarding(`Error occurred starting port-forward, the local port may not be available or the ${portForward.kind} ${portForward.name} may not be reachable`);
}
} catch (error) {
logger.error("[POD-CONTAINER-PORT]:", error, portForward);
this.props.logger.error("[POD-CONTAINER-PORT]:", error, portForward);
} finally {
this.checkExistingPortForwarding();
this.waiting = false;
@ -194,17 +196,14 @@ class NonInjectedPodContainerPort extends React.Component<PodContainerPortProps
}
}
export const PodContainerPort = withInjectables<Dependencies, PodContainerPortProps>(
NonInjectedPodContainerPort,
{
getProps: (di, props) => ({
portForwardStore: di.inject(portForwardStoreInjectable),
openPortForwardDialog: di.inject(portForwardDialogModelInjectable).open,
aboutPortForwarding: di.inject(aboutPortForwardingInjectable),
notifyErrorPortForwarding: di.inject(notifyErrorPortForwardingInjectable),
openPortForward: di.inject(openPortForwardInjectable),
...props,
}),
},
);
export const PodContainerPort = withInjectables<Dependencies, PodContainerPortProps>(NonInjectedPodContainerPort, {
getProps: (di, props) => ({
...props,
portForwardStore: di.inject(portForwardStoreInjectable),
openPortForwardDialog: di.inject(portForwardDialogModelInjectable).open,
aboutPortForwarding: di.inject(aboutPortForwardingInjectable),
notifyErrorPortForwarding: di.inject(notifyErrorPortForwardingInjectable),
openPortForward: di.inject(openPortForwardInjectable),
logger: di.inject(loggerInjectable),
}),
});

View File

@ -10,6 +10,7 @@ import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manag
import { PodStore } from "./store";
import podMetricsApiInjectable from "../../../common/k8s-api/endpoints/pod-metrics.api.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import loggerInjectable from "../../../common/logger.injectable";
const podStoreInjectable = getInjectable({
id: "pod-store",
@ -21,6 +22,7 @@ const podStoreInjectable = getInjectable({
return new PodStore({
podMetricsApi: di.inject(podMetricsApiInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -10,6 +10,7 @@ import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-create
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import { ReplicaSetStore } from "./store";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import loggerInjectable from "../../../common/logger.injectable";
const replicaSetStoreInjectable = getInjectable({
id: "replica-set-store",
@ -21,6 +22,7 @@ const replicaSetStoreInjectable = getInjectable({
return new ReplicaSetStore({
getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -7,6 +7,7 @@ import assert from "assert";
import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import statefulSetApiInjectable from "../../../common/k8s-api/endpoints/stateful-set.api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { StatefulSetStore } from "./store";
@ -21,6 +22,7 @@ const statefulSetStoreInjectable = getInjectable({
return new StatefulSetStore({
getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable),
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
logger: di.inject(loggerInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,

View File

@ -13,6 +13,7 @@ import terminalCopyOnSelectInjectable from "../../../../common/user-store/termin
import isMacInjectable from "../../../../common/vars/is-mac.injectable";
import openLinkInBrowserInjectable from "../../../../common/utils/open-link-in-browser.injectable";
import xtermColorThemeInjectable from "../../../themes/terminal-colors.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
export type CreateTerminal = (tabId: TabId, api: TerminalApi) => Terminal;
@ -26,6 +27,7 @@ const createTerminalInjectable = getInjectable({
isMac: di.inject(isMacInjectable),
openLinkInBrowser: di.inject(openLinkInBrowserInjectable),
xtermColorTheme: di.inject(xtermColorThemeInjectable),
logger: di.inject(loggerInjectable),
};
return (tabId, api) => new Terminal(dependencies, { tabId, api });

View File

@ -13,7 +13,7 @@ import type { TerminalApi } from "../../../api/terminal-api";
import { disposer } from "../../../utils";
import { once } from "lodash";
import { clipboard } from "electron";
import logger from "../../../../common/logger";
import type { Logger } from "../../../../common/logger";
import type { TerminalConfig } from "../../../../common/user-store/preferences-helpers";
import assert from "assert";
import { TerminalChannels } from "../../../../common/terminal/channels";
@ -26,6 +26,7 @@ export interface TerminalDependencies {
readonly terminalCopyOnSelect: IComputedValue<boolean>;
readonly isMac: boolean;
readonly xtermColorTheme: IComputedValue<Record<string, string>>;
readonly logger: Logger;
openLinkInBrowser: OpenLinkInBrowser;
}
@ -199,14 +200,14 @@ export class Terminal {
};
setFontSize = (fontSize: number) => {
logger.info(`[TERMINAL]: set fontSize to ${fontSize}`);
this.dependencies.logger.info(`[TERMINAL]: set fontSize to ${fontSize}`);
this.xterm.options.fontSize = fontSize;
this.fit();
};
setFontFamily = (fontFamily: string) => {
logger.info(`[TERMINAL]: set fontFamily to ${fontFamily}`);
this.dependencies.logger.info(`[TERMINAL]: set fontFamily to ${fontFamily}`);
this.xterm.options.fontFamily = fontFamily;
this.fit();

View File

@ -9,7 +9,9 @@ import type { IClassName } from "../../utils";
import { autoBind, cssNames } from "../../utils";
import { observable, makeObservable } from "mobx";
import { observer } from "mobx-react";
import logger from "../../../main/logger";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
export interface DropFileInputProps<T extends HTMLElement> extends React.DOMAttributes<T> {
className?: IClassName;
@ -21,12 +23,16 @@ export interface DropFileMeta<T extends HTMLElement> {
evt: React.DragEvent<T>;
}
interface Dependencies {
logger: Logger;
}
@observer
export class DropFileInput<T extends HTMLElement> extends React.Component<DropFileInputProps<T>> {
class NonInjectedDropFileInput<T extends HTMLElement> extends React.Component<DropFileInputProps<T> & Dependencies> {
@observable dropAreaActive = false;
dragCounter = 0; // Counter preventing firing onDragLeave() too early (https://stackoverflow.com/questions/7110353/html5-dragleave-fired-when-hovering-a-child-element)
constructor(props: DropFileInputProps<T>) {
constructor(props: DropFileInputProps<T> & Dependencies) {
super(props);
makeObservable(this);
autoBind(this);
@ -92,9 +98,18 @@ export class DropFileInput<T extends HTMLElement> extends React.Component<DropFi
return null;
} catch (err) {
logger.error(`Error: <DropFileInput/> must contain only single child element`);
this.props.logger.error(`Error: <DropFileInput/> must contain only single child element`);
return this.props.children;
}
}
}
const InjectedDropFileInput = withInjectables<Dependencies, DropFileInputProps<HTMLElement>>(NonInjectedDropFileInput, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
});
export const DropFileInput = <T extends HTMLElement>(props: DropFileInputProps<T>) => <InjectedDropFileInput {...props} />;

View File

@ -11,13 +11,14 @@ import type { ApiManager } from "../../../common/k8s-api/api-manager";
import { Link } from "react-router-dom";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
import { LocaleDate } from "../locale-date";
import logger from "../../../common/logger";
import type { Logger } from "../../../common/logger";
import { KubeObjectAge } from "../kube-object/age";
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
import { observer } from "mobx-react";
import { withInjectables } from "@ogre-tools/injectable-react";
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
import loggerInjectable from "../../../common/logger.injectable";
export interface KubeObjectMetaProps {
object: KubeObject;
@ -27,6 +28,7 @@ export interface KubeObjectMetaProps {
interface Dependencies {
getDetailsUrl: GetDetailsUrl;
apiManager: ApiManager;
logger: Logger;
}
const NonInjectedKubeObjectMeta = observer(({
@ -38,6 +40,7 @@ const NonInjectedKubeObjectMeta = observer(({
"resourceVersion",
"selfLink",
],
logger,
}: Dependencies & KubeObjectMetaProps) => {
if (!object) {
return null;
@ -118,5 +121,6 @@ export const KubeObjectMeta = withInjectables<Dependencies, KubeObjectMetaProps>
...props,
getDetailsUrl: di.inject(getDetailsUrlInjectable),
apiManager: di.inject(apiManagerInjectable),
logger: di.inject(loggerInjectable),
}),
});

View File

@ -0,0 +1,69 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import ipcRendererInjectable from "../../utils/channel/ipc-renderer.injectable";
import bindProtocolAddRouteHandlersInjectable from "../../protocol-handler/bind-protocol-add-route-handlers/bind-protocol-add-route-handlers.injectable";
import lensProtocolRouterRendererInjectable from "../../protocol-handler/lens-protocol-router-renderer/lens-protocol-router-renderer.injectable";
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";
import registerIpcListenersInjectable from "../../ipc/register-ipc-listeners.injectable";
import loadExtensionsInjectable from "../load-extensions.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import { delay } from "../../../common/utils";
import { broadcastMessage } from "../../../common/ipc";
import { bundledExtensionsLoaded } from "../../../common/ipc/extension-handling";
const initRootFrameInjectable = getInjectable({
id: "init-root-frame",
instantiate: (di) => {
const loadExtensions = di.inject(loadExtensionsInjectable);
const registerIpcListeners = di.inject(registerIpcListenersInjectable);
const ipcRenderer = di.inject(ipcRendererInjectable);
const bindProtocolAddRouteHandlers = di.inject(bindProtocolAddRouteHandlersInjectable);
const lensProtocolRouterRenderer = di.inject(lensProtocolRouterRendererInjectable);
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
const logger = di.inject(loggerInjectable);
return async (unmountRoot: () => void) => {
catalogEntityRegistry.init();
try {
// maximum time to let bundled extensions finish loading
const timeout = delay(10000);
const loadingExtensions = await loadExtensions();
const loadingBundledExtensions = loadingExtensions
.filter((e) => e.isBundled)
.map((e) => e.loaded);
const bundledExtensionsFinished = Promise.all(loadingBundledExtensions);
await Promise.race([bundledExtensionsFinished, timeout]);
} finally {
ipcRenderer.send(bundledExtensionsLoaded);
}
lensProtocolRouterRenderer.init();
bindProtocolAddRouteHandlers();
window.addEventListener("offline", () =>
broadcastMessage("network:offline"),
);
window.addEventListener("online", () => broadcastMessage("network:online"));
registerIpcListeners();
window.addEventListener("beforeunload", () => {
logger.info("[ROOT-FRAME]: Unload app");
unmountRoot();
});
};
},
});
export default initRootFrameInjectable;

Some files were not shown because too many files have changed in this diff Show More