diff --git a/src/extensions/lens-main-extension.ts b/src/extensions/lens-main-extension.ts index 6d720752e6..bda6024522 100644 --- a/src/extensions/lens-main-extension.ts +++ b/src/extensions/lens-main-extension.ts @@ -16,6 +16,19 @@ export class LensMainExtension extends LensExtension { appMenus: MenuRegistration[] = []; trayMenus: TrayMenuRegistration[] = []; + /** + * implement this to modify the shell environment that Lens terminals are opened with. The ShellEnvModifier type has the signature + * + * (ctx: ShellEnvContext, env: Record) => Record + * + * @param ctx the shell environment context, specifically the relevant catalog entity for the terminal. This can be used, for example, to get + * cluster-specific information that can be made available in the shell environment by the implementation of terminalShellEnvModifier + * + * @param env the current shell environment that the terminal will be opened with. The implementation should modify this as desired. + * + * @returns the modified shell environment that the terminal will be opened with. The implementation must return env as passed in, if it + * does not modify the shell environment + */ terminalShellEnvModifier?: ShellEnvModifier; async navigate(pageId?: string, params?: Record, frameId?: number) { diff --git a/src/main/shell-session/local-shell-session/local-shell-session.injectable.ts b/src/main/shell-session/local-shell-session/local-shell-session.injectable.ts index 03a8f564e2..2578cc106d 100644 --- a/src/main/shell-session/local-shell-session/local-shell-session.injectable.ts +++ b/src/main/shell-session/local-shell-session/local-shell-session.injectable.ts @@ -7,8 +7,7 @@ import { LocalShellSession } from "./local-shell-session"; import type { Cluster } from "../../../common/cluster/cluster"; import type WebSocket from "ws"; import createKubectlInjectable from "../../kubectl/create-kubectl.injectable"; -import terminalShellEnvModifiersInjectable from "../shell-env-modifier/terminal-shell-env-modifier.injectable"; -import { catalogEntityRegistry } from "../../catalog"; +import terminalShellEnvModifiersInjectable from "../shell-env-modifier/terminal-shell-env-modify.injectable"; interface InstantiationParameter { webSocket: WebSocket; @@ -19,12 +18,11 @@ interface InstantiationParameter { const localShellSessionInjectable = getInjectable({ instantiate: (di, { cluster, tabId, webSocket }: InstantiationParameter) => { const createKubectl = di.inject(createKubectlInjectable); - const localShellEnvModifiers = di.inject(terminalShellEnvModifiersInjectable); + const localShellEnvModify = di.inject(terminalShellEnvModifiersInjectable); const kubectl = createKubectl(cluster.version); - const entity = catalogEntityRegistry.getById(cluster.id); - return new LocalShellSession(localShellEnvModifiers.get(), entity, kubectl, webSocket, cluster, tabId); + return new LocalShellSession(localShellEnvModify, kubectl, webSocket, cluster, tabId); }, lifecycle: lifecycleEnum.transient, diff --git a/src/main/shell-session/local-shell-session/local-shell-session.ts b/src/main/shell-session/local-shell-session/local-shell-session.ts index ee520e62aa..dd70aa0d24 100644 --- a/src/main/shell-session/local-shell-session/local-shell-session.ts +++ b/src/main/shell-session/local-shell-session/local-shell-session.ts @@ -8,15 +8,14 @@ import path from "path"; import { helmCli } from "../../helm/helm-cli"; import { UserStore } from "../../../common/user-store"; import type { Cluster } from "../../../common/cluster/cluster"; +import type { ClusterId } from "../../../common/cluster-types"; import { ShellSession } from "../shell-session"; import type { Kubectl } from "../../kubectl/kubectl"; -import type { ShellEnvModifier } from "../shell-env-modifier/shell-env-modifier-registration"; -import type { CatalogEntity } from "../../../common/catalog"; export class LocalShellSession extends ShellSession { ShellType = "shell"; - constructor(protected shellEnvModifiers: ShellEnvModifier[], protected entity: CatalogEntity, kubectl: Kubectl, websocket: WebSocket, cluster: Cluster, terminalId: string) { + constructor(protected shellEnvModify: (clusterId: ClusterId, env: Record) => Record, kubectl: Kubectl, websocket: WebSocket, cluster: Cluster, terminalId: string) { super(kubectl, websocket, cluster, terminalId); } @@ -30,12 +29,8 @@ export class LocalShellSession extends ShellSession { public async open() { let env = await this.getCachedShellEnv(); - - if (this.entity) { - const ctx = { catalogEntity: this.entity }; - env = JSON.parse(JSON.stringify(this.shellEnvModifiers.reduce((env, modifier) => modifier(ctx, env), env))); - } + env = this.shellEnvModify(this.cluster.id, env); const shell = env.PTYSHELL; const args = await this.getShellArgs(shell); diff --git a/src/main/shell-session/shell-env-modifier/terminal-shell-env-modifiers.ts b/src/main/shell-session/shell-env-modifier/terminal-shell-env-modifiers.ts index 1d0e0bf1a3..1486beaef9 100644 --- a/src/main/shell-session/shell-env-modifier/terminal-shell-env-modifiers.ts +++ b/src/main/shell-session/shell-env-modifier/terminal-shell-env-modifiers.ts @@ -4,16 +4,36 @@ */ import { computed, IComputedValue } from "mobx"; +import type { ClusterId } from "../../../common/cluster-types"; import type { LensMainExtension } from "../../../extensions/lens-main-extension"; +import { catalogEntityRegistry } from "../../catalog"; interface Dependencies { extensions: IComputedValue; } -export const terminalShellEnvModifiers = ({ extensions }: Dependencies) => { - return computed(() => ( - extensions.get() - .map((extension) => extension.terminalShellEnvModifier) - .filter(Boolean) - )); -}; +export const terminalShellEnvModify = ({ extensions }: Dependencies) => + (clusterId: ClusterId, env: Record) => { + const terminalShellEnvModifiers = computed(() => ( + extensions.get() + .map((extension) => extension.terminalShellEnvModifier) + .filter(Boolean) + )) + .get(); + + if (terminalShellEnvModifiers.length === 0) { + return env; + } + + const entity = catalogEntityRegistry.getById(clusterId); + + if (entity) { + const ctx = { catalogEntity: entity }; + + // clone it so the passed value is not also modified + env = JSON.parse(JSON.stringify(env)); + env = terminalShellEnvModifiers.reduce((env, modifier) => modifier(ctx, env), env); + } + + return env; + }; diff --git a/src/main/shell-session/shell-env-modifier/terminal-shell-env-modifier.injectable.ts b/src/main/shell-session/shell-env-modifier/terminal-shell-env-modify.injectable.ts similarity index 66% rename from src/main/shell-session/shell-env-modifier/terminal-shell-env-modifier.injectable.ts rename to src/main/shell-session/shell-env-modifier/terminal-shell-env-modify.injectable.ts index cba4d3ad06..a6bd842f61 100644 --- a/src/main/shell-session/shell-env-modifier/terminal-shell-env-modifier.injectable.ts +++ b/src/main/shell-session/shell-env-modifier/terminal-shell-env-modify.injectable.ts @@ -5,15 +5,15 @@ import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import mainExtensionsInjectable from "../../../extensions/main-extensions.injectable"; -import { terminalShellEnvModifiers } from "./terminal-shell-env-modifiers"; +import { terminalShellEnvModify } from "./terminal-shell-env-modifiers"; -const terminalShellEnvModifiersInjectable = getInjectable({ +const terminalShellEnvModifyInjectable = getInjectable({ instantiate: (di) => - terminalShellEnvModifiers({ + terminalShellEnvModify({ extensions: di.inject(mainExtensionsInjectable), }), lifecycle: lifecycleEnum.singleton, }); -export default terminalShellEnvModifiersInjectable; +export default terminalShellEnvModifyInjectable;