mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Remove global version of appEventBus (#6096)
* Remove global version of appEventBus Signed-off-by: Sebastian Malton <sebastian@malton.name> * Introduce a temporary but better shape of ExecFileInjectable error Signed-off-by: Sebastian Malton <sebastian@malton.name> Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
ba349e8b8d
commit
900f02fd8c
@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { AppEvent } from "../app-event-bus/event-bus";
|
|
||||||
import { appEventBus } from "../app-event-bus/event-bus";
|
|
||||||
import { assert, Console } from "console";
|
|
||||||
import { stdout, stderr } from "process";
|
|
||||||
|
|
||||||
console = new Console(stdout, stderr);
|
|
||||||
|
|
||||||
describe("event bus tests", () => {
|
|
||||||
describe("emit", () => {
|
|
||||||
it("emits an event", () => {
|
|
||||||
let event: AppEvent | undefined;
|
|
||||||
|
|
||||||
appEventBus.addListener((data) => {
|
|
||||||
event = data;
|
|
||||||
});
|
|
||||||
|
|
||||||
appEventBus.emit({ name: "foo", action: "bar" });
|
|
||||||
assert(event);
|
|
||||||
expect(event?.name).toBe("foo");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 emitEventInjectable from "./emit-event.injectable";
|
|
||||||
|
|
||||||
export default getGlobalOverride(emitEventInjectable, () => () => {});
|
|
||||||
@ -3,12 +3,12 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { appEventBus } from "./event-bus";
|
import { EventEmitter } from "../event-emitter";
|
||||||
|
import type { AppEvent } from "./event-bus";
|
||||||
|
|
||||||
const appEventBusInjectable = getInjectable({
|
const appEventBusInjectable = getInjectable({
|
||||||
id: "app-event-bus",
|
id: "app-event-bus",
|
||||||
instantiate: () => appEventBus,
|
instantiate: () => new EventEmitter<[AppEvent]>,
|
||||||
causesSideEffects: true,
|
|
||||||
decorable: false,
|
decorable: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -4,11 +4,18 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import appEventBusInjectable from "./app-event-bus.injectable";
|
import appEventBusInjectable from "./app-event-bus.injectable";
|
||||||
|
import type { AppEvent } from "./event-bus";
|
||||||
|
|
||||||
const emitEventInjectable = getInjectable({
|
export type EmitAppEvent = (event: AppEvent) => void;
|
||||||
id: "emit-event",
|
|
||||||
instantiate: (di) => di.inject(appEventBusInjectable).emit,
|
const emitAppEventInjectable = getInjectable({
|
||||||
|
id: "emit-app-event",
|
||||||
|
instantiate: (di): EmitAppEvent => {
|
||||||
|
const bus = di.inject(appEventBusInjectable);
|
||||||
|
|
||||||
|
return (event) => bus.emit(event);
|
||||||
|
},
|
||||||
decorable: false,
|
decorable: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default emitEventInjectable;
|
export default emitAppEventInjectable;
|
||||||
|
|||||||
@ -3,13 +3,12 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EventEmitter } from "../event-emitter";
|
/**
|
||||||
|
* Data for telemetry
|
||||||
|
*/
|
||||||
export interface AppEvent {
|
export interface AppEvent {
|
||||||
name: string;
|
name: string;
|
||||||
action: string;
|
action: string;
|
||||||
destination?: string;
|
destination?: string;
|
||||||
params?: Record<string, any>;
|
params?: Record<string, any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const appEventBus = new EventEmitter<[AppEvent]>();
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import { ClusterStore } from "./cluster-store";
|
import { ClusterStore } from "./cluster-store";
|
||||||
import { createClusterInjectionToken } from "../cluster/create-cluster-injection-token";
|
import { createClusterInjectionToken } from "../cluster/create-cluster-injection-token";
|
||||||
import readClusterConfigSyncInjectable from "./read-cluster-config.injectable";
|
import readClusterConfigSyncInjectable from "./read-cluster-config.injectable";
|
||||||
|
import emitAppEventInjectable from "../app-event-bus/emit-event.injectable";
|
||||||
|
|
||||||
const clusterStoreInjectable = getInjectable({
|
const clusterStoreInjectable = getInjectable({
|
||||||
id: "cluster-store",
|
id: "cluster-store",
|
||||||
@ -16,6 +17,7 @@ const clusterStoreInjectable = getInjectable({
|
|||||||
return ClusterStore.createInstance({
|
return ClusterStore.createInstance({
|
||||||
createCluster: di.inject(createClusterInjectionToken),
|
createCluster: di.inject(createClusterInjectionToken),
|
||||||
readClusterConfigSync: di.inject(readClusterConfigSyncInjectable),
|
readClusterConfigSync: di.inject(readClusterConfigSyncInjectable),
|
||||||
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { BaseStore } from "../base-store";
|
|||||||
import { Cluster } from "../cluster/cluster";
|
import { Cluster } from "../cluster/cluster";
|
||||||
import migrations from "../../migrations/cluster-store";
|
import migrations from "../../migrations/cluster-store";
|
||||||
import logger from "../../main/logger";
|
import logger from "../../main/logger";
|
||||||
import { appEventBus } from "../app-event-bus/event-bus";
|
|
||||||
import { ipcMainHandle } from "../ipc";
|
import { ipcMainHandle } from "../ipc";
|
||||||
import { disposer, toJS } from "../utils";
|
import { disposer, toJS } from "../utils";
|
||||||
import type { ClusterModel, ClusterId, ClusterState } from "../cluster-types";
|
import type { ClusterModel, ClusterId, ClusterState } from "../cluster-types";
|
||||||
@ -18,6 +17,7 @@ import { requestInitialClusterStates } from "../../renderer/ipc";
|
|||||||
import { clusterStates } from "../ipc/cluster";
|
import { clusterStates } from "../ipc/cluster";
|
||||||
import type { CreateCluster } from "../cluster/create-cluster-injection-token";
|
import type { CreateCluster } from "../cluster/create-cluster-injection-token";
|
||||||
import type { ReadClusterConfigSync } from "./read-cluster-config.injectable";
|
import type { ReadClusterConfigSync } from "./read-cluster-config.injectable";
|
||||||
|
import type { EmitAppEvent } from "../app-event-bus/emit-event.injectable";
|
||||||
|
|
||||||
export interface ClusterStoreModel {
|
export interface ClusterStoreModel {
|
||||||
clusters?: ClusterModel[];
|
clusters?: ClusterModel[];
|
||||||
@ -26,6 +26,7 @@ export interface ClusterStoreModel {
|
|||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
createCluster: CreateCluster;
|
createCluster: CreateCluster;
|
||||||
readClusterConfigSync: ReadClusterConfigSync;
|
readClusterConfigSync: ReadClusterConfigSync;
|
||||||
|
emitAppEvent: EmitAppEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||||
@ -34,7 +35,7 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
|||||||
|
|
||||||
protected disposer = disposer();
|
protected disposer = disposer();
|
||||||
|
|
||||||
constructor(private dependencies: Dependencies) {
|
constructor(private readonly dependencies: Dependencies) {
|
||||||
super({
|
super({
|
||||||
configName: "lens-cluster-store",
|
configName: "lens-cluster-store",
|
||||||
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
||||||
@ -115,7 +116,7 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addCluster(clusterOrModel: ClusterModel | Cluster): Cluster {
|
addCluster(clusterOrModel: ClusterModel | Cluster): Cluster {
|
||||||
appEventBus.emit({ name: "cluster", action: "add" });
|
this.dependencies.emitAppEvent({ name: "cluster", action: "add" });
|
||||||
|
|
||||||
const cluster = clusterOrModel instanceof Cluster
|
const cluster = clusterOrModel instanceof Cluster
|
||||||
? clusterOrModel
|
? clusterOrModel
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export class EventEmitter<D extends [...any[]]> {
|
|||||||
this.listeners.length = 0;
|
this.listeners.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit = (...data: D) => {
|
emit(...data: D) {
|
||||||
for (const [callback, { once }] of this.listeners) {
|
for (const [callback, { once }] of this.listeners) {
|
||||||
if (once) {
|
if (once) {
|
||||||
this.removeListener(callback);
|
this.removeListener(callback);
|
||||||
@ -39,5 +39,5 @@ export class EventEmitter<D extends [...any[]]> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,26 +3,23 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { ExecFileOptions } from "child_process";
|
import type { ExecFileException, ExecFileOptions } from "child_process";
|
||||||
import { execFile } from "child_process";
|
import { execFile } from "child_process";
|
||||||
import type { AsyncResult } from "../utils/async-result";
|
import type { AsyncResult } from "../utils/async-result";
|
||||||
|
|
||||||
export interface ExecFile {
|
export interface ExecFile {
|
||||||
(filePath: string, args: string[], options: ExecFileOptions): Promise<AsyncResult<string, { stderr: string; error: Error }>>;
|
(filePath: string, args: string[], options?: ExecFileOptions): Promise<AsyncResult<string, ExecFileException & { stderr: string }>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const execFileInjectable = getInjectable({
|
const execFileInjectable = getInjectable({
|
||||||
id: "exec-file",
|
id: "exec-file",
|
||||||
|
|
||||||
instantiate: (): ExecFile => (filePath, args, options) => new Promise((resolve) => {
|
instantiate: (): ExecFile => (filePath, args, options) => new Promise((resolve) => {
|
||||||
execFile(filePath, args, options, (error, stdout, stderr) => {
|
execFile(filePath, args, options ?? {}, (error, stdout, stderr) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
resolve({
|
resolve({
|
||||||
callWasSuccessful: false,
|
callWasSuccessful: false,
|
||||||
error: {
|
error: Object.assign(error, { stderr }),
|
||||||
error,
|
|
||||||
stderr,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
resolve({
|
resolve({
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import type { HelmRepo } from "./helm-repo";
|
|||||||
import type { AsyncResult } from "../utils/async-result";
|
import type { AsyncResult } from "../utils/async-result";
|
||||||
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
export type AddHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<string>>;
|
export type AddHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<void, string>>;
|
||||||
|
|
||||||
export const addHelmRepositoryChannel: AddHelmRepositoryChannel = {
|
export const addHelmRepositoryChannel: AddHelmRepositoryChannel = {
|
||||||
id: "add-helm-repository-channel",
|
id: "add-helm-repository-channel",
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import type { AsyncResult } from "../utils/async-result";
|
|||||||
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||||
import type { HelmRepo } from "./helm-repo";
|
import type { HelmRepo } from "./helm-repo";
|
||||||
|
|
||||||
export type RemoveHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<string, string>>;
|
export type RemoveHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<void, string>>;
|
||||||
|
|
||||||
export const removeHelmRepositoryChannel: RemoveHelmRepositoryChannel = {
|
export const removeHelmRepositoryChannel: RemoveHelmRepositoryChannel = {
|
||||||
id: "remove-helm-repository-channel",
|
id: "remove-helm-repository-channel",
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
import fse from "fs-extra";
|
import fse from "fs-extra";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import hb from "handlebars";
|
import hb from "handlebars";
|
||||||
import { ResourceApplier } from "../../main/resource-applier";
|
|
||||||
import type { KubernetesCluster } from "../catalog-entities";
|
import type { KubernetesCluster } from "../catalog-entities";
|
||||||
import logger from "../../main/logger";
|
import logger from "../../main/logger";
|
||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
@ -14,6 +13,8 @@ import yaml from "js-yaml";
|
|||||||
import { requestKubectlApplyAll, requestKubectlDeleteAll } from "../../renderer/ipc";
|
import { requestKubectlApplyAll, requestKubectlDeleteAll } from "../../renderer/ipc";
|
||||||
import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||||
import productNameInjectable from "../vars/product-name.injectable";
|
import productNameInjectable from "../vars/product-name.injectable";
|
||||||
|
import { asLegacyGlobalFunctionForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
|
||||||
|
import createResourceApplierInjectable from "../../main/resource-applier/create-resource-applier.injectable";
|
||||||
|
|
||||||
export class ResourceStack {
|
export class ResourceStack {
|
||||||
constructor(protected cluster: KubernetesCluster, protected name: string) {}
|
constructor(protected cluster: KubernetesCluster, protected name: string) {}
|
||||||
@ -52,7 +53,9 @@ export class ResourceStack {
|
|||||||
kubectlArgs = this.appendKubectlArgs(kubectlArgs);
|
kubectlArgs = this.appendKubectlArgs(kubectlArgs);
|
||||||
|
|
||||||
if (app) {
|
if (app) {
|
||||||
return await new ResourceApplier(clusterModel).kubectlApplyAll(resources, kubectlArgs);
|
const createResourceApplier = asLegacyGlobalFunctionForExtensionApi(createResourceApplierInjectable);
|
||||||
|
|
||||||
|
return await createResourceApplier(clusterModel).kubectlApplyAll(resources, kubectlArgs);
|
||||||
} else {
|
} else {
|
||||||
const response = await requestKubectlApplyAll(this.cluster.getId(), resources, kubectlArgs);
|
const response = await requestKubectlApplyAll(this.cluster.getId(), resources, kubectlArgs);
|
||||||
|
|
||||||
@ -76,7 +79,9 @@ export class ResourceStack {
|
|||||||
kubectlArgs = this.appendKubectlArgs(kubectlArgs);
|
kubectlArgs = this.appendKubectlArgs(kubectlArgs);
|
||||||
|
|
||||||
if (app) {
|
if (app) {
|
||||||
return await new ResourceApplier(clusterModel).kubectlDeleteAll(resources, kubectlArgs);
|
const createResourceApplier = asLegacyGlobalFunctionForExtensionApi(createResourceApplierInjectable);
|
||||||
|
|
||||||
|
return await createResourceApplier(clusterModel).kubectlDeleteAll(resources, kubectlArgs);
|
||||||
} else {
|
} else {
|
||||||
const response = await requestKubectlDeleteAll(this.cluster.getId(), resources, kubectlArgs);
|
const response = await requestKubectlDeleteAll(this.cluster.getId(), resources, kubectlArgs);
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { UserStore } from "./user-store";
|
import { UserStore } from "./user-store";
|
||||||
import selectedUpdateChannelInjectable from "../../features/application-update/common/selected-update-channel/selected-update-channel.injectable";
|
import selectedUpdateChannelInjectable from "../../features/application-update/common/selected-update-channel/selected-update-channel.injectable";
|
||||||
|
import emitAppEventInjectable from "../app-event-bus/emit-event.injectable";
|
||||||
|
|
||||||
const userStoreInjectable = getInjectable({
|
const userStoreInjectable = getInjectable({
|
||||||
id: "user-store",
|
id: "user-store",
|
||||||
@ -14,6 +15,7 @@ const userStoreInjectable = getInjectable({
|
|||||||
|
|
||||||
return UserStore.createInstance({
|
return UserStore.createInstance({
|
||||||
selectedUpdateChannel: di.inject(selectedUpdateChannelInjectable),
|
selectedUpdateChannel: di.inject(selectedUpdateChannelInjectable),
|
||||||
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import { getOrInsertSet, toggle, toJS, object } from "../../renderer/utils";
|
|||||||
import { DESCRIPTORS } from "./preferences-helpers";
|
import { DESCRIPTORS } from "./preferences-helpers";
|
||||||
import type { UserPreferencesModel, StoreType } from "./preferences-helpers";
|
import type { UserPreferencesModel, StoreType } from "./preferences-helpers";
|
||||||
import logger from "../../main/logger";
|
import logger from "../../main/logger";
|
||||||
|
import type { EmitAppEvent } from "../app-event-bus/emit-event.injectable";
|
||||||
|
|
||||||
// TODO: Remove coupling with Feature
|
// TODO: Remove coupling with Feature
|
||||||
import type { SelectedUpdateChannel } from "../../features/application-update/common/selected-update-channel/selected-update-channel.injectable";
|
import type { SelectedUpdateChannel } from "../../features/application-update/common/selected-update-channel/selected-update-channel.injectable";
|
||||||
@ -23,6 +24,7 @@ export interface UserStoreModel {
|
|||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
readonly selectedUpdateChannel: SelectedUpdateChannel;
|
readonly selectedUpdateChannel: SelectedUpdateChannel;
|
||||||
|
emitAppEvent: EmitAppEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UserStore extends BaseStore<UserStoreModel> /* implements UserStoreFlatModel (when strict null is enabled) */ {
|
export class UserStore extends BaseStore<UserStoreModel> /* implements UserStoreFlatModel (when strict null is enabled) */ {
|
||||||
|
|||||||
@ -3,5 +3,9 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
export type AsyncResult<Response, Error = string> =
|
export type AsyncResult<Response, Error = string> =
|
||||||
| { callWasSuccessful: true; response: Response }
|
| (
|
||||||
|
Response extends void
|
||||||
|
? { callWasSuccessful: true; response?: undefined }
|
||||||
|
: { callWasSuccessful: true; response: Response }
|
||||||
|
)
|
||||||
| { callWasSuccessful: false; error: Error };
|
| { callWasSuccessful: false; error: Error };
|
||||||
|
|||||||
@ -3,5 +3,9 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { appEventBus } from "../../common/app-event-bus/event-bus";
|
import appEventBusInjectable from "../../common/app-event-bus/app-event-bus.injectable";
|
||||||
|
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
|
||||||
|
|
||||||
export type { AppEvent } from "../../common/app-event-bus/event-bus";
|
export type { AppEvent } from "../../common/app-event-bus/event-bus";
|
||||||
|
|
||||||
|
export const appEventBus = asLegacyGlobalForExtensionApi(appEventBusInjectable);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"name": "@k8slens/extensions",
|
"name": "@k8slens/extensions",
|
||||||
"productName": "OpenLens extensions",
|
"productName": "OpenLens extensions",
|
||||||
"description": "OpenLens - Open Source Kubernetes IDE: extensions",
|
"description": "OpenLens - Open Source Kubernetes IDE: extensions",
|
||||||
"version": "0.0.1",
|
"version": "6.0.0",
|
||||||
"copyright": "© 2022 OpenLens Authors",
|
"copyright": "© 2022 OpenLens Authors",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "dist/src/extensions/extension-api.js",
|
"main": "dist/src/extensions/extension-api.js",
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsLoadedInjectionToken } from "../../../main/start-main-application/runnable-tokens/after-application-is-loaded-injection-token";
|
import { afterApplicationIsLoadedInjectionToken } from "../../../main/start-main-application/runnable-tokens/after-application-is-loaded-injection-token";
|
||||||
import emitEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
import { getCurrentDateTime } from "../../../common/utils/date/get-current-date-time";
|
import { getCurrentDateTime } from "../../../common/utils/date/get-current-date-time";
|
||||||
import buildVersionInjectable from "../../../main/vars/build-version/build-version.injectable";
|
import buildVersionInjectable from "../../../main/vars/build-version/build-version.injectable";
|
||||||
|
|
||||||
@ -12,13 +12,13 @@ const emitCurrentVersionToAnalyticsInjectable = getInjectable({
|
|||||||
id: "emit-current-version-to-analytics",
|
id: "emit-current-version-to-analytics",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const emitEvent = di.inject(emitEventInjectable);
|
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||||
const buildVersion = di.inject(buildVersionInjectable);
|
const buildVersion = di.inject(buildVersionInjectable);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "emit-current-version-to-analytics",
|
id: "emit-current-version-to-analytics",
|
||||||
run: () => {
|
run: () => {
|
||||||
emitEvent({
|
emitAppEvent({
|
||||||
name: "app",
|
name: "app",
|
||||||
action: "current-version",
|
action: "current-version",
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import discoveredUpdateVersionInjectable from "../common/discovered-update-versi
|
|||||||
import { runInAction } from "mobx";
|
import { runInAction } from "mobx";
|
||||||
import downloadUpdateInjectable from "./download-update/download-update.injectable";
|
import downloadUpdateInjectable from "./download-update/download-update.injectable";
|
||||||
import checkForUpdatesStartingFromChannelInjectable from "./check-for-updates/check-for-updates-starting-from-channel.injectable";
|
import checkForUpdatesStartingFromChannelInjectable from "./check-for-updates/check-for-updates-starting-from-channel.injectable";
|
||||||
import emitEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
import { getCurrentDateTime } from "../../../common/utils/date/get-current-date-time";
|
import { getCurrentDateTime } from "../../../common/utils/date/get-current-date-time";
|
||||||
|
|
||||||
const processCheckingForUpdatesInjectable = getInjectable({
|
const processCheckingForUpdatesInjectable = getInjectable({
|
||||||
@ -21,7 +21,7 @@ const processCheckingForUpdatesInjectable = getInjectable({
|
|||||||
const checkingForUpdatesState = di.inject(updatesAreBeingDiscoveredInjectable);
|
const checkingForUpdatesState = di.inject(updatesAreBeingDiscoveredInjectable);
|
||||||
const discoveredVersionState = di.inject(discoveredUpdateVersionInjectable);
|
const discoveredVersionState = di.inject(discoveredUpdateVersionInjectable);
|
||||||
const checkForUpdatesStartingFromChannel = di.inject(checkForUpdatesStartingFromChannelInjectable);
|
const checkForUpdatesStartingFromChannel = di.inject(checkForUpdatesStartingFromChannelInjectable);
|
||||||
const emitEvent = di.inject(emitEventInjectable);
|
const emitEvent = di.inject(emitAppEventInjectable);
|
||||||
|
|
||||||
return async (source: string) => {
|
return async (source: string) => {
|
||||||
emitEvent({
|
emitEvent({
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import electronQuitAndInstallUpdateInjectable from "../../../main/electron-app/features/electron-quit-and-install-update.injectable";
|
import electronQuitAndInstallUpdateInjectable from "../../../main/electron-app/features/electron-quit-and-install-update.injectable";
|
||||||
import { getCurrentDateTime } from "../../../common/utils/date/get-current-date-time";
|
import { getCurrentDateTime } from "../../../common/utils/date/get-current-date-time";
|
||||||
import emitEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
import discoveredUpdateVersionInjectable from "../common/discovered-update-version/discovered-update-version.injectable";
|
import discoveredUpdateVersionInjectable from "../common/discovered-update-version/discovered-update-version.injectable";
|
||||||
|
|
||||||
const quitAndInstallUpdateInjectable = getInjectable({
|
const quitAndInstallUpdateInjectable = getInjectable({
|
||||||
@ -16,7 +16,7 @@ const quitAndInstallUpdateInjectable = getInjectable({
|
|||||||
electronQuitAndInstallUpdateInjectable,
|
electronQuitAndInstallUpdateInjectable,
|
||||||
);
|
);
|
||||||
|
|
||||||
const emitEvent = di.inject(emitEventInjectable);
|
const emitEvent = di.inject(emitAppEventInjectable);
|
||||||
const discoveredUpdateVersion = di.inject(discoveredUpdateVersionInjectable);
|
const discoveredUpdateVersion = di.inject(discoveredUpdateVersionInjectable);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import { type ApplicationBuilder, getApplicationBuilder } from "../../../rendere
|
|||||||
import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
|
import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
|
||||||
import type { Cluster } from "../../../common/cluster/cluster";
|
import type { Cluster } from "../../../common/cluster/cluster";
|
||||||
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||||
import appEventBusInjectable from "../../../common/app-event-bus/app-event-bus.injectable";
|
|
||||||
import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
||||||
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
||||||
|
|
||||||
@ -93,9 +92,6 @@ describe("Deleting a cluster", () => {
|
|||||||
builder.beforeWindowStart((windowDi) => {
|
builder.beforeWindowStart((windowDi) => {
|
||||||
windowDi.override(storesAndApisCanBeCreatedInjectable, () => true);
|
windowDi.override(storesAndApisCanBeCreatedInjectable, () => true);
|
||||||
openDeleteClusterDialog = windowDi.inject(openDeleteClusterDialogInjectable);
|
openDeleteClusterDialog = windowDi.inject(openDeleteClusterDialogInjectable);
|
||||||
|
|
||||||
// TODO: remove this line when all global uses of appEventBus are removed
|
|
||||||
windowDi.permitSideEffects(appEventBusInjectable);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.afterWindowStart(windowDi => {
|
builder.afterWindowStart(windowDi => {
|
||||||
|
|||||||
@ -2,19 +2,20 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable";
|
import emitAppEventInjectable from "../../../../common/app-event-bus/emit-event.injectable";
|
||||||
import clusterFramesInjectable from "../../../../common/cluster-frames.injectable";
|
import clusterFramesInjectable from "../../../../common/cluster-frames.injectable";
|
||||||
import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable";
|
import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable";
|
||||||
import directoryForLensLocalStorageInjectable from "../../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable";
|
import directoryForLensLocalStorageInjectable from "../../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable";
|
||||||
import deleteFileInjectable from "../../../../common/fs/delete-file.injectable";
|
import deleteFileInjectable from "../../../../common/fs/delete-file.injectable";
|
||||||
import joinPathsInjectable from "../../../../common/path/join-paths.injectable";
|
import joinPathsInjectable from "../../../../common/path/join-paths.injectable";
|
||||||
|
import { noop } from "../../../../common/utils";
|
||||||
import { getRequestChannelListenerInjectable } from "../../../../main/utils/channel/channel-listeners/listener-tokens";
|
import { getRequestChannelListenerInjectable } from "../../../../main/utils/channel/channel-listeners/listener-tokens";
|
||||||
import { deleteClusterChannel } from "../common/delete-channel";
|
import { deleteClusterChannel } from "../common/delete-channel";
|
||||||
|
|
||||||
const deleteClusterChannelListenerInjectable = getRequestChannelListenerInjectable({
|
const deleteClusterChannelListenerInjectable = getRequestChannelListenerInjectable({
|
||||||
channel: deleteClusterChannel,
|
channel: deleteClusterChannel,
|
||||||
handler: (di) => {
|
handler: (di) => {
|
||||||
const appEventBus = di.inject(appEventBusInjectable);
|
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||||
const clusterStore = di.inject(clusterStoreInjectable);
|
const clusterStore = di.inject(clusterStoreInjectable);
|
||||||
const clusterFrames = di.inject(clusterFramesInjectable);
|
const clusterFrames = di.inject(clusterFramesInjectable);
|
||||||
const joinPaths = di.inject(joinPathsInjectable);
|
const joinPaths = di.inject(joinPathsInjectable);
|
||||||
@ -22,7 +23,7 @@ const deleteClusterChannelListenerInjectable = getRequestChannelListenerInjectab
|
|||||||
const deleteFile = di.inject(deleteFileInjectable);
|
const deleteFile = di.inject(deleteFileInjectable);
|
||||||
|
|
||||||
return async (clusterId) => {
|
return async (clusterId) => {
|
||||||
appEventBus.emit({ name: "cluster", action: "remove" });
|
emitAppEvent({ name: "cluster", action: "remove" });
|
||||||
|
|
||||||
const cluster = clusterStore.getById(clusterId);
|
const cluster = clusterStore.getById(clusterId);
|
||||||
|
|
||||||
@ -36,14 +37,10 @@ const deleteClusterChannelListenerInjectable = getRequestChannelListenerInjectab
|
|||||||
// Remove from the cluster store as well, this should clear any old settings
|
// Remove from the cluster store as well, this should clear any old settings
|
||||||
clusterStore.clusters.delete(cluster.id);
|
clusterStore.clusters.delete(cluster.id);
|
||||||
|
|
||||||
try {
|
// remove the local storage file
|
||||||
// remove the local storage file
|
const localStorageFilePath = joinPaths(directoryForLensLocalStorage, `${cluster.id}.json`);
|
||||||
const localStorageFilePath = joinPaths(directoryForLensLocalStorage, `${cluster.id}.json`);
|
|
||||||
|
|
||||||
await deleteFile(localStorageFilePath);
|
await deleteFile(localStorageFilePath).catch(noop);
|
||||||
} catch {
|
|
||||||
// ignore error
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -185,10 +185,9 @@ describe("add custom helm repository in preferences", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await execFileMock.resolve({
|
await execFileMock.resolve({
|
||||||
callWasSuccessful: false,
|
callWasSuccessful: false,
|
||||||
error: {
|
error: Object.assign(new Error("Some error"), {
|
||||||
error: new Error("Some error"),
|
|
||||||
stderr: "",
|
stderr: "",
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -130,10 +130,9 @@ describe("add helm repository from list in preferences", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await execFileMock.resolve({
|
await execFileMock.resolve({
|
||||||
callWasSuccessful: false,
|
callWasSuccessful: false,
|
||||||
error: {
|
error: Object.assign(new Error("Some error"), {
|
||||||
error: new Error("Some error"),
|
|
||||||
stderr: "",
|
stderr: "",
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -85,10 +85,9 @@ describe("listing active helm repositories in preferences", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await execFileMock.resolve({
|
await execFileMock.resolve({
|
||||||
callWasSuccessful: false,
|
callWasSuccessful: false,
|
||||||
error: {
|
error: Object.assign(new Error("Some error"), {
|
||||||
error: new Error("some error"),
|
|
||||||
stderr: "some-error",
|
stderr: "some-error",
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -235,10 +234,9 @@ describe("listing active helm repositories in preferences", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await execFileMock.resolve({
|
await execFileMock.resolve({
|
||||||
callWasSuccessful: false,
|
callWasSuccessful: false,
|
||||||
error: {
|
error: Object.assign(new Error("Some error"), {
|
||||||
error: new Error("Some error"),
|
|
||||||
stderr: "Some error",
|
stderr: "Some error",
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -271,10 +269,9 @@ describe("listing active helm repositories in preferences", () => {
|
|||||||
|
|
||||||
await execFileMock.resolve({
|
await execFileMock.resolve({
|
||||||
callWasSuccessful: false,
|
callWasSuccessful: false,
|
||||||
error: {
|
error: Object.assign(new Error("no repositories found. You must add one before updating"), {
|
||||||
error: new Error("no repositories found. You must add one before updating"),
|
|
||||||
stderr: "no repositories found. You must add one before updating",
|
stderr: "no repositories found. You must add one before updating",
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -300,10 +297,9 @@ describe("listing active helm repositories in preferences", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await execFileMock.resolve({
|
await execFileMock.resolve({
|
||||||
callWasSuccessful: false,
|
callWasSuccessful: false,
|
||||||
error: {
|
error: Object.assign(new Error("Some error"), {
|
||||||
error: new Error("Some error"),
|
|
||||||
stderr: "Some error",
|
stderr: "Some error",
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,8 @@ import operatingSystemThemeInjectable from "../../../theme/operating-system-them
|
|||||||
import catalogEntityRegistryInjectable from "../../../catalog/entity-registry.injectable";
|
import catalogEntityRegistryInjectable from "../../../catalog/entity-registry.injectable";
|
||||||
import askUserForFilePathsInjectable from "../../../ipc/ask-user-for-file-paths.injectable";
|
import askUserForFilePathsInjectable from "../../../ipc/ask-user-for-file-paths.injectable";
|
||||||
import applicationMenuItemCompositeInjectable from "../../../../features/application-menu/main/application-menu-item-composite.injectable";
|
import applicationMenuItemCompositeInjectable from "../../../../features/application-menu/main/application-menu-item-composite.injectable";
|
||||||
|
import emitAppEventInjectable from "../../../../common/app-event-bus/emit-event.injectable";
|
||||||
|
import createResourceApplierInjectable from "../../../resource-applier/create-resource-applier.injectable";
|
||||||
|
|
||||||
const setupIpcMainHandlersInjectable = getInjectable({
|
const setupIpcMainHandlersInjectable = getInjectable({
|
||||||
id: "setup-ipc-main-handlers",
|
id: "setup-ipc-main-handlers",
|
||||||
@ -24,6 +26,8 @@ const setupIpcMainHandlersInjectable = getInjectable({
|
|||||||
const clusterStore = di.inject(clusterStoreInjectable);
|
const clusterStore = di.inject(clusterStoreInjectable);
|
||||||
const operatingSystemTheme = di.inject(operatingSystemThemeInjectable);
|
const operatingSystemTheme = di.inject(operatingSystemThemeInjectable);
|
||||||
const askUserForFilePaths = di.inject(askUserForFilePathsInjectable);
|
const askUserForFilePaths = di.inject(askUserForFilePathsInjectable);
|
||||||
|
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||||
|
const createResourceApplier = di.inject(createResourceApplierInjectable);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "setup-ipc-main-handlers",
|
id: "setup-ipc-main-handlers",
|
||||||
@ -37,6 +41,8 @@ const setupIpcMainHandlersInjectable = getInjectable({
|
|||||||
clusterStore,
|
clusterStore,
|
||||||
operatingSystemTheme,
|
operatingSystemTheme,
|
||||||
askUserForFilePaths,
|
askUserForFilePaths,
|
||||||
|
emitAppEvent,
|
||||||
|
createResourceApplier,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -8,12 +8,10 @@ import { clusterFrameMap } from "../../../../common/cluster-frames";
|
|||||||
import { clusterActivateHandler, clusterSetFrameIdHandler, clusterVisibilityHandler, clusterRefreshHandler, clusterDisconnectHandler, clusterKubectlApplyAllHandler, clusterKubectlDeleteAllHandler } from "../../../../common/ipc/cluster";
|
import { clusterActivateHandler, clusterSetFrameIdHandler, clusterVisibilityHandler, clusterRefreshHandler, clusterDisconnectHandler, clusterKubectlApplyAllHandler, clusterKubectlDeleteAllHandler } from "../../../../common/ipc/cluster";
|
||||||
import type { ClusterId } from "../../../../common/cluster-types";
|
import type { ClusterId } from "../../../../common/cluster-types";
|
||||||
import { ClusterStore } from "../../../../common/cluster-store/cluster-store";
|
import { ClusterStore } from "../../../../common/cluster-store/cluster-store";
|
||||||
import { appEventBus } from "../../../../common/app-event-bus/event-bus";
|
|
||||||
import { broadcastMainChannel, broadcastMessage, ipcMainHandle, ipcMainOn } from "../../../../common/ipc";
|
import { broadcastMainChannel, broadcastMessage, ipcMainHandle, ipcMainOn } from "../../../../common/ipc";
|
||||||
import type { CatalogEntityRegistry } from "../../../catalog";
|
import type { CatalogEntityRegistry } from "../../../catalog";
|
||||||
import { pushCatalogToRenderer } from "../../../catalog-pusher";
|
import { pushCatalogToRenderer } from "../../../catalog-pusher";
|
||||||
import type { ClusterManager } from "../../../cluster/manager";
|
import type { ClusterManager } from "../../../cluster/manager";
|
||||||
import { ResourceApplier } from "../../../resource-applier";
|
|
||||||
import type { IComputedValue } from "mobx";
|
import type { IComputedValue } from "mobx";
|
||||||
import { windowActionHandleChannel, windowLocationChangedChannel, windowOpenAppMenuAsContextMenuChannel } from "../../../../common/ipc/window";
|
import { windowActionHandleChannel, windowLocationChangedChannel, windowOpenAppMenuAsContextMenuChannel } from "../../../../common/ipc/window";
|
||||||
import { handleWindowAction, onLocationChange } from "../../../ipc/window";
|
import { handleWindowAction, onLocationChange } from "../../../ipc/window";
|
||||||
@ -25,6 +23,8 @@ import type { ApplicationMenuItemTypes } from "../../../../features/application-
|
|||||||
import type { Composite } from "../../../../common/utils/composite/get-composite/get-composite";
|
import type { Composite } from "../../../../common/utils/composite/get-composite/get-composite";
|
||||||
import { getApplicationMenuTemplate } from "../../../../features/application-menu/main/populate-application-menu.injectable";
|
import { getApplicationMenuTemplate } from "../../../../features/application-menu/main/populate-application-menu.injectable";
|
||||||
import type { MenuItemRoot } from "../../../../features/application-menu/main/application-menu-item-composite.injectable";
|
import type { MenuItemRoot } from "../../../../features/application-menu/main/application-menu-item-composite.injectable";
|
||||||
|
import type { EmitAppEvent } from "../../../../common/app-event-bus/emit-event.injectable";
|
||||||
|
import type { CreateResourceApplier } from "../../../resource-applier/create-resource-applier.injectable";
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
applicationMenuItemComposite: IComputedValue<Composite<ApplicationMenuItemTypes | MenuItemRoot>>;
|
applicationMenuItemComposite: IComputedValue<Composite<ApplicationMenuItemTypes | MenuItemRoot>>;
|
||||||
@ -33,6 +33,8 @@ interface Dependencies {
|
|||||||
clusterStore: ClusterStore;
|
clusterStore: ClusterStore;
|
||||||
operatingSystemTheme: IComputedValue<Theme>;
|
operatingSystemTheme: IComputedValue<Theme>;
|
||||||
askUserForFilePaths: AskUserForFilePaths;
|
askUserForFilePaths: AskUserForFilePaths;
|
||||||
|
emitAppEvent: EmitAppEvent;
|
||||||
|
createResourceApplier: CreateResourceApplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setupIpcMainHandlers = ({
|
export const setupIpcMainHandlers = ({
|
||||||
@ -42,6 +44,8 @@ export const setupIpcMainHandlers = ({
|
|||||||
clusterStore,
|
clusterStore,
|
||||||
operatingSystemTheme,
|
operatingSystemTheme,
|
||||||
askUserForFilePaths,
|
askUserForFilePaths,
|
||||||
|
emitAppEvent,
|
||||||
|
createResourceApplier,
|
||||||
}: Dependencies) => {
|
}: Dependencies) => {
|
||||||
ipcMainHandle(clusterActivateHandler, (event, clusterId: ClusterId, force = false) => {
|
ipcMainHandle(clusterActivateHandler, (event, clusterId: ClusterId, force = false) => {
|
||||||
return ClusterStore.getInstance()
|
return ClusterStore.getInstance()
|
||||||
@ -71,7 +75,7 @@ export const setupIpcMainHandlers = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMainHandle(clusterDisconnectHandler, (event, clusterId: ClusterId) => {
|
ipcMainHandle(clusterDisconnectHandler, (event, clusterId: ClusterId) => {
|
||||||
appEventBus.emit({ name: "cluster", action: "stop" });
|
emitAppEvent({ name: "cluster", action: "stop" });
|
||||||
const cluster = ClusterStore.getInstance().getById(clusterId);
|
const cluster = ClusterStore.getInstance().getById(clusterId);
|
||||||
|
|
||||||
if (cluster) {
|
if (cluster) {
|
||||||
@ -81,11 +85,11 @@ export const setupIpcMainHandlers = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMainHandle(clusterKubectlApplyAllHandler, async (event, clusterId: ClusterId, resources: string[], extraArgs: string[]) => {
|
ipcMainHandle(clusterKubectlApplyAllHandler, async (event, clusterId: ClusterId, resources: string[], extraArgs: string[]) => {
|
||||||
appEventBus.emit({ name: "cluster", action: "kubectl-apply-all" });
|
emitAppEvent({ name: "cluster", action: "kubectl-apply-all" });
|
||||||
const cluster = ClusterStore.getInstance().getById(clusterId);
|
const cluster = ClusterStore.getInstance().getById(clusterId);
|
||||||
|
|
||||||
if (cluster) {
|
if (cluster) {
|
||||||
const applier = new ResourceApplier(cluster);
|
const applier = createResourceApplier(cluster);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const stdout = await applier.kubectlApplyAll(resources, extraArgs);
|
const stdout = await applier.kubectlApplyAll(resources, extraArgs);
|
||||||
@ -100,11 +104,11 @@ export const setupIpcMainHandlers = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMainHandle(clusterKubectlDeleteAllHandler, async (event, clusterId: ClusterId, resources: string[], extraArgs: string[]) => {
|
ipcMainHandle(clusterKubectlDeleteAllHandler, async (event, clusterId: ClusterId, resources: string[], extraArgs: string[]) => {
|
||||||
appEventBus.emit({ name: "cluster", action: "kubectl-delete-all" });
|
emitAppEvent({ name: "cluster", action: "kubectl-delete-all" });
|
||||||
const cluster = ClusterStore.getInstance().getById(clusterId);
|
const cluster = ClusterStore.getInstance().getById(clusterId);
|
||||||
|
|
||||||
if (cluster) {
|
if (cluster) {
|
||||||
const applier = new ResourceApplier(cluster);
|
const applier = createResourceApplier(cluster);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const stdout = await applier.kubectlDeleteAll(resources, extraArgs);
|
const stdout = await applier.kubectlDeleteAll(resources, extraArgs);
|
||||||
|
|||||||
@ -19,9 +19,6 @@ import type { FileSystemProvisionerStore } from "../extensions/extension-loader/
|
|||||||
import userStoreInjectable from "../common/user-store/user-store.injectable";
|
import userStoreInjectable from "../common/user-store/user-store.injectable";
|
||||||
import type { UserStore } from "../common/user-store";
|
import type { UserStore } from "../common/user-store";
|
||||||
import hotbarStoreInjectable from "../common/hotbars/store.injectable";
|
import hotbarStoreInjectable from "../common/hotbars/store.injectable";
|
||||||
import appEventBusInjectable from "../common/app-event-bus/app-event-bus.injectable";
|
|
||||||
import { EventEmitter } from "../common/event-emitter";
|
|
||||||
import type { AppEvent } from "../common/app-event-bus/event-bus";
|
|
||||||
import commandLineArgumentsInjectable from "./utils/command-line-arguments.injectable";
|
import commandLineArgumentsInjectable from "./utils/command-line-arguments.injectable";
|
||||||
import initializeExtensionsInjectable from "./start-main-application/runnables/initialize-extensions.injectable";
|
import initializeExtensionsInjectable from "./start-main-application/runnables/initialize-extensions.injectable";
|
||||||
import lensResourcesDirInjectable from "../common/vars/lens-resources-dir.injectable";
|
import lensResourcesDirInjectable from "../common/vars/lens-resources-dir.injectable";
|
||||||
@ -167,9 +164,6 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {})
|
|||||||
execFileInjectable,
|
execFileInjectable,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// TODO: Remove usages of globally exported appEventBus to get rid of this
|
|
||||||
di.override(appEventBusInjectable, () => new EventEmitter<[AppEvent]>());
|
|
||||||
|
|
||||||
di.override(broadcastMessageInjectable, () => (channel) => {
|
di.override(broadcastMessageInjectable, () => (channel) => {
|
||||||
throw new Error(`Tried to broadcast message to channel "${channel}" over IPC without explicit override.`);
|
throw new Error(`Tried to broadcast message to channel "${channel}" over IPC without explicit override.`);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,11 +3,12 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { ExecFileException } from "child_process";
|
||||||
import execFileInjectable from "../../../common/fs/exec-file.injectable";
|
import execFileInjectable from "../../../common/fs/exec-file.injectable";
|
||||||
import helmBinaryPathInjectable from "../helm-binary-path.injectable";
|
|
||||||
import type { AsyncResult } from "../../../common/utils/async-result";
|
import type { AsyncResult } from "../../../common/utils/async-result";
|
||||||
|
import helmBinaryPathInjectable from "../helm-binary-path.injectable";
|
||||||
|
|
||||||
export type ExecHelm = (args: string[]) => Promise<AsyncResult<string, string>>;
|
export type ExecHelm = (args: string[]) => Promise<AsyncResult<string, ExecFileException & { stderr: string }>>;
|
||||||
|
|
||||||
const execHelmInjectable = getInjectable({
|
const execHelmInjectable = getInjectable({
|
||||||
id: "exec-helm",
|
id: "exec-helm",
|
||||||
@ -16,20 +17,9 @@ const execHelmInjectable = getInjectable({
|
|||||||
const execFile = di.inject(execFileInjectable);
|
const execFile = di.inject(execFileInjectable);
|
||||||
const helmBinaryPath = di.inject(helmBinaryPathInjectable);
|
const helmBinaryPath = di.inject(helmBinaryPathInjectable);
|
||||||
|
|
||||||
return async (args) => {
|
return async (args) => execFile(helmBinaryPath, args, {
|
||||||
const response = await execFile(helmBinaryPath, args, {
|
maxBuffer: 32 * 1024 * 1024 * 1024, // 32 MiB
|
||||||
maxBuffer: 32 * 1024 * 1024 * 1024, // 32 MiB
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if (response.callWasSuccessful) {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
callWasSuccessful: false,
|
|
||||||
error: response.error.stderr || response.error.error.message,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ const getHelmEnvInjectable = getInjectable({
|
|||||||
const result = await execHelm(["env"]);
|
const result = await execHelm(["env"]);
|
||||||
|
|
||||||
if (!result.callWasSuccessful) {
|
if (!result.callWasSuccessful) {
|
||||||
return { callWasSuccessful: false, error: result.error };
|
return { callWasSuccessful: false, error: result.error.stderr };
|
||||||
}
|
}
|
||||||
|
|
||||||
const lines = result.response.split(/\r?\n/); // split by new line feed
|
const lines = result.response.split(/\r?\n/); // split by new line feed
|
||||||
|
|||||||
@ -30,7 +30,7 @@ const callForHelmManifestInjectable = getInjectable({
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
if (!result.callWasSuccessful) {
|
if (!result.callWasSuccessful) {
|
||||||
return { callWasSuccessful: false, error: result.error };
|
return { callWasSuccessful: false, error: result.error.message };
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -4,17 +4,18 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import execHelmInjectable from "../../exec-helm/exec-helm.injectable";
|
import execHelmInjectable from "../../exec-helm/exec-helm.injectable";
|
||||||
import type { HelmRepo } from "../../../../common/helm/helm-repo";
|
|
||||||
import loggerInjectable from "../../../../common/logger.injectable";
|
import loggerInjectable from "../../../../common/logger.injectable";
|
||||||
|
import type { AddHelmRepositoryChannel } from "../../../../common/helm/add-helm-repository-channel";
|
||||||
|
import type { RequestChannelHandler } from "../../../utils/channel/channel-listeners/listener-tokens";
|
||||||
|
|
||||||
const addHelmRepositoryInjectable = getInjectable({
|
const addHelmRepositoryInjectable = getInjectable({
|
||||||
id: "add-helm-repository",
|
id: "add-helm-repository",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di): RequestChannelHandler<AddHelmRepositoryChannel> => {
|
||||||
const execHelm = di.inject(execHelmInjectable);
|
const execHelm = di.inject(execHelmInjectable);
|
||||||
const logger = di.inject(loggerInjectable);
|
const logger = di.inject(loggerInjectable);
|
||||||
|
|
||||||
return async (repo: HelmRepo) => {
|
return async (repo) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
url,
|
url,
|
||||||
@ -54,7 +55,18 @@ const addHelmRepositoryInjectable = getInjectable({
|
|||||||
args.push("--cert-file", certFile);
|
args.push("--cert-file", certFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await execHelm(args);
|
const result = await execHelm(args);
|
||||||
|
|
||||||
|
if (result.callWasSuccessful) {
|
||||||
|
return {
|
||||||
|
callWasSuccessful: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
callWasSuccessful: false,
|
||||||
|
error: result.error.stderr || result.error.message,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -78,10 +78,10 @@ const getActiveHelmRepositoriesInjectable = getInjectable({
|
|||||||
const updateResult = await execHelm(["repo", "update"]);
|
const updateResult = await execHelm(["repo", "update"]);
|
||||||
|
|
||||||
if (!updateResult.callWasSuccessful) {
|
if (!updateResult.callWasSuccessful) {
|
||||||
if (!updateResult.error.includes(internalHelmErrorForNoRepositoriesFound)) {
|
if (!updateResult.error.stderr.includes(internalHelmErrorForNoRepositoriesFound)) {
|
||||||
return {
|
return {
|
||||||
callWasSuccessful: false,
|
callWasSuccessful: false,
|
||||||
error: `Error updating Helm repositories: ${updateResult.error}`,
|
error: `Error updating Helm repositories: ${updateResult.error.stderr}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const resultOfAddingDefaultRepository = await execHelm(["repo", "add", "bitnami", "https://charts.bitnami.com/bitnami"]);
|
const resultOfAddingDefaultRepository = await execHelm(["repo", "add", "bitnami", "https://charts.bitnami.com/bitnami"]);
|
||||||
@ -89,7 +89,7 @@ const getActiveHelmRepositoriesInjectable = getInjectable({
|
|||||||
if (!resultOfAddingDefaultRepository.callWasSuccessful) {
|
if (!resultOfAddingDefaultRepository.callWasSuccessful) {
|
||||||
return {
|
return {
|
||||||
callWasSuccessful: false,
|
callWasSuccessful: false,
|
||||||
error: `Error when adding default Helm repository: ${resultOfAddingDefaultRepository.error}`,
|
error: `Error when adding default Helm repository: ${resultOfAddingDefaultRepository.error.stderr}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import execHelmInjectable from "../../exec-helm/exec-helm.injectable";
|
import execHelmInjectable from "../../exec-helm/exec-helm.injectable";
|
||||||
import type { HelmRepo } from "../../../../common/helm/helm-repo";
|
import type { HelmRepo } from "../../../../common/helm/helm-repo";
|
||||||
import loggerInjectable from "../../../../common/logger.injectable";
|
import loggerInjectable from "../../../../common/logger.injectable";
|
||||||
|
import type { AsyncResult } from "../../../../common/utils/async-result";
|
||||||
|
|
||||||
const removeHelmRepositoryInjectable = getInjectable({
|
const removeHelmRepositoryInjectable = getInjectable({
|
||||||
id: "remove-helm-repository",
|
id: "remove-helm-repository",
|
||||||
@ -14,14 +15,25 @@ const removeHelmRepositoryInjectable = getInjectable({
|
|||||||
const execHelm = di.inject(execHelmInjectable);
|
const execHelm = di.inject(execHelmInjectable);
|
||||||
const logger = di.inject(loggerInjectable);
|
const logger = di.inject(loggerInjectable);
|
||||||
|
|
||||||
return async (repo: HelmRepo) => {
|
return async (repo: HelmRepo): Promise<AsyncResult<void, string>> => {
|
||||||
logger.info(`[HELM]: removing repo ${repo.name} (${repo.url})`);
|
logger.info(`[HELM]: removing repo ${repo.name} (${repo.url})`);
|
||||||
|
|
||||||
return execHelm([
|
const result = await execHelm([
|
||||||
"repo",
|
"repo",
|
||||||
"remove",
|
"remove",
|
||||||
repo.name,
|
repo.name,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if (result.callWasSuccessful) {
|
||||||
|
return {
|
||||||
|
callWasSuccessful: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
callWasSuccessful: false,
|
||||||
|
error: result.error.stderr,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -11,6 +11,8 @@ 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/shell-api-request.injectable";
|
||||||
import lensProxyPortInjectable from "./lens-proxy-port.injectable";
|
import lensProxyPortInjectable from "./lens-proxy-port.injectable";
|
||||||
import contentSecurityPolicyInjectable from "../../common/vars/content-security-policy.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";
|
||||||
|
|
||||||
const lensProxyInjectable = getInjectable({
|
const lensProxyInjectable = getInjectable({
|
||||||
id: "lens-proxy",
|
id: "lens-proxy",
|
||||||
@ -23,6 +25,8 @@ const lensProxyInjectable = getInjectable({
|
|||||||
getClusterForRequest: di.inject(clusterManagerInjectable).getClusterForRequest,
|
getClusterForRequest: di.inject(clusterManagerInjectable).getClusterForRequest,
|
||||||
lensProxyPort: di.inject(lensProxyPortInjectable),
|
lensProxyPort: di.inject(lensProxyPortInjectable),
|
||||||
contentSecurityPolicy: di.inject(contentSecurityPolicyInjectable),
|
contentSecurityPolicy: di.inject(contentSecurityPolicyInjectable),
|
||||||
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -10,13 +10,13 @@ import type httpProxy from "http-proxy";
|
|||||||
import { apiPrefix, apiKubePrefix } from "../../common/vars";
|
import { apiPrefix, apiKubePrefix } from "../../common/vars";
|
||||||
import type { Router } from "../router/router";
|
import type { Router } from "../router/router";
|
||||||
import type { ClusterContextHandler } from "../context-handler/context-handler";
|
import type { ClusterContextHandler } from "../context-handler/context-handler";
|
||||||
import logger from "../logger";
|
|
||||||
import type { Cluster } from "../../common/cluster/cluster";
|
import type { Cluster } from "../../common/cluster/cluster";
|
||||||
import type { ProxyApiRequestArgs } from "./proxy-functions";
|
import type { ProxyApiRequestArgs } from "./proxy-functions";
|
||||||
import { appEventBus } from "../../common/app-event-bus/event-bus";
|
|
||||||
import { getBoolean } from "../utils/parse-query";
|
import { getBoolean } from "../utils/parse-query";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import type { SetRequired } from "type-fest";
|
import type { SetRequired } from "type-fest";
|
||||||
|
import type { EmitAppEvent } from "../../common/app-event-bus/emit-event.injectable";
|
||||||
|
import type { Logger } from "../../common/logger";
|
||||||
|
|
||||||
type GetClusterForRequest = (req: http.IncomingMessage) => Cluster | undefined;
|
type GetClusterForRequest = (req: http.IncomingMessage) => Cluster | undefined;
|
||||||
|
|
||||||
@ -26,10 +26,12 @@ interface Dependencies {
|
|||||||
getClusterForRequest: GetClusterForRequest;
|
getClusterForRequest: GetClusterForRequest;
|
||||||
shellApiRequest: (args: ProxyApiRequestArgs) => void | Promise<void>;
|
shellApiRequest: (args: ProxyApiRequestArgs) => void | Promise<void>;
|
||||||
kubeApiUpgradeRequest: (args: ProxyApiRequestArgs) => void | Promise<void>;
|
kubeApiUpgradeRequest: (args: ProxyApiRequestArgs) => void | Promise<void>;
|
||||||
|
emitAppEvent: EmitAppEvent;
|
||||||
readonly router: Router;
|
readonly router: Router;
|
||||||
readonly proxy: httpProxy;
|
readonly proxy: httpProxy;
|
||||||
readonly lensProxyPort: { set: (portNumber: number) => void };
|
readonly lensProxyPort: { set: (portNumber: number) => void };
|
||||||
readonly contentSecurityPolicy: string;
|
readonly contentSecurityPolicy: string;
|
||||||
|
readonly logger: Logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
const watchParam = "watch";
|
const watchParam = "watch";
|
||||||
@ -81,14 +83,14 @@ export class LensProxy {
|
|||||||
const cluster = dependencies.getClusterForRequest(req);
|
const cluster = dependencies.getClusterForRequest(req);
|
||||||
|
|
||||||
if (!cluster) {
|
if (!cluster) {
|
||||||
logger.error(`[LENS-PROXY]: Could not find cluster for upgrade request from url=${req.url}`);
|
this.dependencies.logger.error(`[LENS-PROXY]: Could not find cluster for upgrade request from url=${req.url}`);
|
||||||
socket.destroy();
|
socket.destroy();
|
||||||
} else {
|
} else {
|
||||||
const isInternal = req.url.startsWith(`${apiPrefix}?`);
|
const isInternal = req.url.startsWith(`${apiPrefix}?`);
|
||||||
const reqHandler = isInternal ? dependencies.shellApiRequest : dependencies.kubeApiUpgradeRequest;
|
const reqHandler = isInternal ? dependencies.shellApiRequest : dependencies.kubeApiUpgradeRequest;
|
||||||
|
|
||||||
(async () => reqHandler({ req, socket, head, cluster }))()
|
(async () => reqHandler({ req, socket, head, cluster }))()
|
||||||
.catch(error => logger.error("[LENS-PROXY]: failed to handle proxy upgrade", error));
|
.catch(error => this.dependencies.logger.error("[LENS-PROXY]: failed to handle proxy upgrade", error));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -111,17 +113,17 @@ export class LensProxy {
|
|||||||
|
|
||||||
this.dependencies.lensProxyPort.set(port);
|
this.dependencies.lensProxyPort.set(port);
|
||||||
|
|
||||||
logger.info(`[LENS-PROXY]: Proxy server has started at ${address}:${port}`);
|
this.dependencies.logger.info(`[LENS-PROXY]: Proxy server has started at ${address}:${port}`);
|
||||||
|
|
||||||
this.proxyServer.on("error", (error) => {
|
this.proxyServer.on("error", (error) => {
|
||||||
logger.info(`[LENS-PROXY]: Subsequent error: ${error}`);
|
this.dependencies.logger.info(`[LENS-PROXY]: Subsequent error: ${error}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
appEventBus.emit({ name: "lens-proxy", action: "listen", params: { port }});
|
this.dependencies.emitAppEvent({ name: "lens-proxy", action: "listen", params: { port }});
|
||||||
resolve(port);
|
resolve(port);
|
||||||
})
|
})
|
||||||
.once("error", (error) => {
|
.once("error", (error) => {
|
||||||
logger.info(`[LENS-PROXY]: Proxy server failed to start: ${error}`);
|
this.dependencies.logger.info(`[LENS-PROXY]: Proxy server failed to start: ${error}`);
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -144,7 +146,7 @@ export class LensProxy {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warn(`[LENS-PROXY]: Proxy server has with port known to be considered unsafe to connect to by chrome, restarting...`);
|
this.dependencies.logger.warn(`[LENS-PROXY]: Proxy server has with port known to be considered unsafe to connect to by chrome, restarting...`);
|
||||||
|
|
||||||
if (seenPorts.has(port)) {
|
if (seenPorts.has(port)) {
|
||||||
/**
|
/**
|
||||||
@ -160,7 +162,7 @@ export class LensProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
logger.info("[LENS-PROXY]: Closing server");
|
this.dependencies.logger.info("[LENS-PROXY]: Closing server");
|
||||||
this.proxyServer.close();
|
this.proxyServer.close();
|
||||||
this.closed = true;
|
this.closed = true;
|
||||||
}
|
}
|
||||||
@ -183,10 +185,10 @@ export class LensProxy {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.error(`[LENS-PROXY]: http proxy errored for cluster: ${error}`, { url: req.url });
|
this.dependencies.logger.error(`[LENS-PROXY]: http proxy errored for cluster: ${error}`, { url: req.url });
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
logger.debug(`Failed proxy to target: ${JSON.stringify(target, null, 2)}`);
|
this.dependencies.logger.debug(`Failed proxy to target: ${JSON.stringify(target, null, 2)}`);
|
||||||
|
|
||||||
if (req.method === "GET" && (!res.statusCode || res.statusCode >= 500)) {
|
if (req.method === "GET" && (!res.statusCode || res.statusCode >= 500)) {
|
||||||
const reqId = this.getRequestId(req);
|
const reqId = this.getRequestId(req);
|
||||||
@ -194,11 +196,11 @@ export class LensProxy {
|
|||||||
const timeoutMs = retryCount * 250;
|
const timeoutMs = retryCount * 250;
|
||||||
|
|
||||||
if (retryCount < 20) {
|
if (retryCount < 20) {
|
||||||
logger.debug(`Retrying proxy request to url: ${reqId}`);
|
this.dependencies.logger.debug(`Retrying proxy request to url: ${reqId}`);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.retryCounters.set(reqId, retryCount + 1);
|
this.retryCounters.set(reqId, retryCount + 1);
|
||||||
this.handleRequest(req as ServerIncomingMessage, res)
|
this.handleRequest(req as ServerIncomingMessage, res)
|
||||||
.catch(error => logger.error(`[LENS-PROXY]: failed to handle request on proxy error: ${error}`));
|
.catch(error => this.dependencies.logger.error(`[LENS-PROXY]: failed to handle request on proxy error: ${error}`));
|
||||||
}, timeoutMs);
|
}, timeoutMs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,7 +209,7 @@ export class LensProxy {
|
|||||||
try {
|
try {
|
||||||
res.writeHead(500).end(`Oops, something went wrong.\n${error}`);
|
res.writeHead(500).end(`Oops, something went wrong.\n${error}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(`[LENS-PROXY]: Failed to write headers: `, e);
|
this.dependencies.logger.error(`[LENS-PROXY]: Failed to write headers: `, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* 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 emitAppEventInjectable from "../../common/app-event-bus/emit-event.injectable";
|
||||||
|
import type { Cluster } from "../../common/cluster/cluster";
|
||||||
|
import deleteFileInjectable from "../../common/fs/delete-file.injectable";
|
||||||
|
import execFileInjectable from "../../common/fs/exec-file.injectable";
|
||||||
|
import writeFileInjectable from "../../common/fs/write-file.injectable";
|
||||||
|
import loggerInjectable from "../../common/logger.injectable";
|
||||||
|
import joinPathsInjectable from "../../common/path/join-paths.injectable";
|
||||||
|
import type { ResourceApplierDependencies } from "./resource-applier";
|
||||||
|
import { ResourceApplier } from "./resource-applier";
|
||||||
|
|
||||||
|
export type CreateResourceApplier = (cluster: Cluster) => ResourceApplier;
|
||||||
|
|
||||||
|
const createResourceApplierInjectable = getInjectable({
|
||||||
|
id: "create-resource-applier",
|
||||||
|
instantiate: (di): CreateResourceApplier => {
|
||||||
|
const deps: ResourceApplierDependencies = {
|
||||||
|
deleteFile: di.inject(deleteFileInjectable),
|
||||||
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
|
execFile: di.inject(execFileInjectable),
|
||||||
|
joinPaths: di.inject(joinPathsInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
writeFile: di.inject(writeFileInjectable),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (cluster) => new ResourceApplier(deps, cluster);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default createResourceApplierInjectable;
|
||||||
@ -3,21 +3,29 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Cluster } from "../common/cluster/cluster";
|
import type { Cluster } from "../../common/cluster/cluster";
|
||||||
import { exec } from "child_process";
|
|
||||||
import fs from "fs-extra";
|
|
||||||
import * as yaml from "js-yaml";
|
import * as yaml from "js-yaml";
|
||||||
import path from "path";
|
|
||||||
import tempy from "tempy";
|
import tempy from "tempy";
|
||||||
import logger from "./logger";
|
|
||||||
import { appEventBus } from "../common/app-event-bus/event-bus";
|
|
||||||
import { isChildProcessError } from "../common/utils";
|
|
||||||
import type { Patch } from "rfc6902";
|
import type { Patch } from "rfc6902";
|
||||||
import { promiseExecFile } from "../common/utils/promise-exec";
|
|
||||||
import type { KubernetesObject } from "@kubernetes/client-node";
|
import type { KubernetesObject } from "@kubernetes/client-node";
|
||||||
|
import type { EmitAppEvent } from "../../common/app-event-bus/emit-event.injectable";
|
||||||
|
import type { Logger } from "../../common/logger";
|
||||||
|
import type { WriteFile } from "../../common/fs/write-file.injectable";
|
||||||
|
import type { DeleteFile } from "../../common/fs/delete-file.injectable";
|
||||||
|
import type { ExecFile } from "../../common/fs/exec-file.injectable";
|
||||||
|
import type { JoinPaths } from "../../common/path/join-paths.injectable";
|
||||||
|
|
||||||
|
export interface ResourceApplierDependencies {
|
||||||
|
emitAppEvent: EmitAppEvent;
|
||||||
|
writeFile: WriteFile;
|
||||||
|
deleteFile: DeleteFile;
|
||||||
|
execFile: ExecFile;
|
||||||
|
joinPaths: JoinPaths;
|
||||||
|
readonly logger: Logger;
|
||||||
|
}
|
||||||
|
|
||||||
export class ResourceApplier {
|
export class ResourceApplier {
|
||||||
constructor(protected cluster: Cluster) {}
|
constructor(protected readonly dependencies: ResourceApplierDependencies, protected readonly cluster: Cluster) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Patch a kube resource's manifest, throwing any error that occurs.
|
* Patch a kube resource's manifest, throwing any error that occurs.
|
||||||
@ -27,7 +35,7 @@ export class ResourceApplier {
|
|||||||
* @param ns The optional namespace of the kube resource
|
* @param ns The optional namespace of the kube resource
|
||||||
*/
|
*/
|
||||||
async patch(name: string, kind: string, patch: Patch, ns?: string): Promise<string> {
|
async patch(name: string, kind: string, patch: Patch, ns?: string): Promise<string> {
|
||||||
appEventBus.emit({ name: "resource", action: "patch" });
|
this.dependencies.emitAppEvent({ name: "resource", action: "patch" });
|
||||||
|
|
||||||
const kubectl = await this.cluster.ensureKubectl();
|
const kubectl = await this.cluster.ensureKubectl();
|
||||||
const kubectlPath = await kubectl.getPath();
|
const kubectlPath = await kubectl.getPath();
|
||||||
@ -49,23 +57,17 @@ export class ResourceApplier {
|
|||||||
"-o", "json",
|
"-o", "json",
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
const result = await this.dependencies.execFile(kubectlPath, args);
|
||||||
const { stdout } = await promiseExecFile(kubectlPath, args);
|
|
||||||
|
|
||||||
return stdout;
|
if (result.callWasSuccessful) {
|
||||||
} catch (error) {
|
return result.response;
|
||||||
if (isChildProcessError(error)) {
|
|
||||||
throw error.stderr ?? error;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw result.error.stderr || result.error.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(resource: string): Promise<string> {
|
async create(resource: string): Promise<string> {
|
||||||
appEventBus.emit({ name: "resource", action: "apply" });
|
this.dependencies.emitAppEvent({ name: "resource", action: "apply" });
|
||||||
|
|
||||||
console.log({ resource });
|
|
||||||
|
|
||||||
return this.kubectlApply(this.sanitizeObject(resource));
|
return this.kubectlApply(this.sanitizeObject(resource));
|
||||||
}
|
}
|
||||||
@ -82,7 +84,7 @@ export class ResourceApplier {
|
|||||||
"-f", fileName,
|
"-f", fileName,
|
||||||
];
|
];
|
||||||
|
|
||||||
logger.debug(`shooting manifests with ${kubectlPath}`, { args });
|
this.dependencies.logger.debug(`shooting manifests with ${kubectlPath}`, { args });
|
||||||
|
|
||||||
const execEnv = { ...process.env };
|
const execEnv = { ...process.env };
|
||||||
const httpsProxy = this.cluster.preferences?.httpsProxy;
|
const httpsProxy = this.cluster.preferences?.httpsProxy;
|
||||||
@ -92,18 +94,17 @@ export class ResourceApplier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fs.writeFile(fileName, content);
|
await this.dependencies.writeFile(fileName, content);
|
||||||
const { stdout } = await promiseExecFile(kubectlPath, args);
|
|
||||||
|
|
||||||
return stdout;
|
const result = await this.dependencies.execFile(kubectlPath, args);
|
||||||
} catch (error) {
|
|
||||||
if (isChildProcessError(error)) {
|
if (result.callWasSuccessful) {
|
||||||
throw error.stderr ?? error;
|
return result.response;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error;
|
throw result.error.stderr || result.error.message;
|
||||||
} finally {
|
} finally {
|
||||||
await fs.unlink(fileName);
|
await this.dependencies.deleteFile(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,39 +116,36 @@ export class ResourceApplier {
|
|||||||
return this.kubectlCmdAll("delete", resources, extraArgs);
|
return this.kubectlCmdAll("delete", resources, extraArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async kubectlCmdAll(subCmd: string, resources: string[], args: string[] = []): Promise<string> {
|
protected async kubectlCmdAll(subCmd: string, resources: string[], parentArgs: string[] = []): Promise<string> {
|
||||||
const kubectl = await this.cluster.ensureKubectl();
|
const kubectl = await this.cluster.ensureKubectl();
|
||||||
const kubectlPath = await kubectl.getPath();
|
const kubectlPath = await kubectl.getPath();
|
||||||
const proxyKubeconfigPath = await this.cluster.getProxyKubeconfigPath();
|
const proxyKubeconfigPath = await this.cluster.getProxyKubeconfigPath();
|
||||||
|
const tmpDir = tempy.directory();
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
await Promise.all(resources.map((resource, index) => this.dependencies.writeFile(
|
||||||
const tmpDir = tempy.directory();
|
this.dependencies.joinPaths(tmpDir, `${index}.yaml`),
|
||||||
|
resource,
|
||||||
|
)));
|
||||||
|
|
||||||
// Dump each resource into tmpDir
|
const args = [
|
||||||
resources.forEach((resource, index) => {
|
subCmd,
|
||||||
fs.writeFileSync(path.join(tmpDir, `${index}.yaml`), resource);
|
"--kubeconfig", `"${proxyKubeconfigPath}"`,
|
||||||
});
|
...parentArgs,
|
||||||
args.push("-f", `"${tmpDir}"`);
|
"-f", `"${tmpDir}"`,
|
||||||
const cmd = `"${kubectlPath}" ${subCmd} --kubeconfig "${proxyKubeconfigPath}" ${args.join(" ")}`;
|
];
|
||||||
|
|
||||||
logger.info(`[RESOURCE-APPLIER] running cmd ${cmd}`);
|
this.dependencies.logger.info(`[RESOURCE-APPLIER] running kubectl`, { args });
|
||||||
exec(cmd, (error, stdout) => {
|
const result = await this.dependencies.execFile(kubectlPath, args);
|
||||||
if (error) {
|
|
||||||
logger.error(`[RESOURCE-APPLIER] cmd errored: ${error}`);
|
|
||||||
const splitError = error.toString().split(`.yaml": `);
|
|
||||||
|
|
||||||
if (splitError[1]) {
|
if (result.callWasSuccessful) {
|
||||||
reject(splitError[1]);
|
return result.response;
|
||||||
} else {
|
}
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
this.dependencies.logger.error(`[RESOURCE-APPLIER] kubectl errored: ${result.error.message}`);
|
||||||
}
|
|
||||||
|
|
||||||
resolve(stdout);
|
const splitError = result.error.stderr.split(`.yaml": `);
|
||||||
});
|
|
||||||
});
|
throw splitError[1] || result.error.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected sanitizeObject(resource: string) {
|
protected sanitizeObject(resource: string) {
|
||||||
@ -20,6 +20,7 @@ import type { SetRequired } from "type-fest";
|
|||||||
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
|
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
|
||||||
import kubectlBinaryNameInjectable from "../kubectl/binary-name.injectable";
|
import kubectlBinaryNameInjectable from "../kubectl/binary-name.injectable";
|
||||||
import kubectlDownloadingNormalizedArchInjectable from "../kubectl/normalized-arch.injectable";
|
import kubectlDownloadingNormalizedArchInjectable from "../kubectl/normalized-arch.injectable";
|
||||||
|
import fsInjectable from "../../common/fs/fs.injectable";
|
||||||
import { runInAction } from "mobx";
|
import { runInAction } from "mobx";
|
||||||
|
|
||||||
describe("router", () => {
|
describe("router", () => {
|
||||||
@ -32,6 +33,7 @@ describe("router", () => {
|
|||||||
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||||
|
|
||||||
mockFs();
|
mockFs();
|
||||||
|
di.permitSideEffects(fsInjectable);
|
||||||
|
|
||||||
di.override(parseRequestInjectable, () => () => Promise.resolve({
|
di.override(parseRequestInjectable, () => () => Promise.resolve({
|
||||||
payload: "some-payload",
|
payload: "some-payload",
|
||||||
|
|||||||
@ -4,20 +4,24 @@
|
|||||||
*/
|
*/
|
||||||
import { getRouteInjectable } from "../../router/router.injectable";
|
import { getRouteInjectable } from "../../router/router.injectable";
|
||||||
import { apiPrefix } from "../../../common/vars";
|
import { apiPrefix } from "../../../common/vars";
|
||||||
import { ResourceApplier } from "../../resource-applier";
|
|
||||||
import { payloadValidatedClusterRoute } from "../../router/route";
|
import { payloadValidatedClusterRoute } from "../../router/route";
|
||||||
import Joi from "joi";
|
import Joi from "joi";
|
||||||
|
import createResourceApplierInjectable from "../../resource-applier/create-resource-applier.injectable";
|
||||||
|
|
||||||
const createResourceRouteInjectable = getRouteInjectable({
|
const createResourceRouteInjectable = getRouteInjectable({
|
||||||
id: "create-resource-route",
|
id: "create-resource-route",
|
||||||
|
|
||||||
instantiate: () => payloadValidatedClusterRoute({
|
instantiate: (di) => {
|
||||||
method: "post",
|
const createResourceApplier = di.inject(createResourceApplierInjectable);
|
||||||
path: `${apiPrefix}/stack`,
|
|
||||||
payloadValidator: Joi.string(),
|
return payloadValidatedClusterRoute({
|
||||||
})(async ({ cluster, payload }) => ({
|
method: "post",
|
||||||
response: await new ResourceApplier(cluster).create(payload),
|
path: `${apiPrefix}/stack`,
|
||||||
})),
|
payloadValidator: Joi.string(),
|
||||||
|
})(async ({ cluster, payload }) => ({
|
||||||
|
response: await createResourceApplier(cluster).create(payload),
|
||||||
|
}));
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default createResourceRouteInjectable;
|
export default createResourceRouteInjectable;
|
||||||
|
|||||||
@ -4,10 +4,10 @@
|
|||||||
*/
|
*/
|
||||||
import { getRouteInjectable } from "../../router/router.injectable";
|
import { getRouteInjectable } from "../../router/router.injectable";
|
||||||
import { apiPrefix } from "../../../common/vars";
|
import { apiPrefix } from "../../../common/vars";
|
||||||
import { ResourceApplier } from "../../resource-applier";
|
|
||||||
import { payloadValidatedClusterRoute } from "../../router/route";
|
import { payloadValidatedClusterRoute } from "../../router/route";
|
||||||
import Joi from "joi";
|
import Joi from "joi";
|
||||||
import type { Patch } from "rfc6902";
|
import type { Patch } from "rfc6902";
|
||||||
|
import createResourceApplierInjectable from "../../resource-applier/create-resource-applier.injectable";
|
||||||
|
|
||||||
interface PatchResourcePayload {
|
interface PatchResourcePayload {
|
||||||
name: string;
|
name: string;
|
||||||
@ -40,18 +40,22 @@ const patchResourcePayloadValidator = Joi.object<PatchResourcePayload, true, Pat
|
|||||||
const patchResourceRouteInjectable = getRouteInjectable({
|
const patchResourceRouteInjectable = getRouteInjectable({
|
||||||
id: "patch-resource-route",
|
id: "patch-resource-route",
|
||||||
|
|
||||||
instantiate: () => payloadValidatedClusterRoute({
|
instantiate: (di) => {
|
||||||
method: "patch",
|
const createResourceApplier = di.inject(createResourceApplierInjectable);
|
||||||
path: `${apiPrefix}/stack`,
|
|
||||||
payloadValidator: patchResourcePayloadValidator,
|
return payloadValidatedClusterRoute({
|
||||||
})(async ({ cluster, payload }) => ({
|
method: "patch",
|
||||||
response: await new ResourceApplier(cluster).patch(
|
path: `${apiPrefix}/stack`,
|
||||||
payload.name,
|
payloadValidator: patchResourcePayloadValidator,
|
||||||
payload.kind,
|
})(async ({ cluster, payload }) => ({
|
||||||
payload.patch,
|
response: await createResourceApplier(cluster).patch(
|
||||||
payload.ns,
|
payload.name,
|
||||||
),
|
payload.kind,
|
||||||
})),
|
payload.patch,
|
||||||
|
payload.ns,
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default patchResourceRouteInjectable;
|
export default patchResourceRouteInjectable;
|
||||||
|
|||||||
@ -22,6 +22,8 @@ import spawnPtyInjectable from "../spawn-pty.injectable";
|
|||||||
import resolvedShellInjectable from "../../../common/user-store/resolved-shell.injectable";
|
import resolvedShellInjectable from "../../../common/user-store/resolved-shell.injectable";
|
||||||
import appNameInjectable from "../../../common/vars/app-name.injectable";
|
import appNameInjectable from "../../../common/vars/app-name.injectable";
|
||||||
import buildVersionInjectable from "../../vars/build-version/build-version.injectable";
|
import buildVersionInjectable from "../../vars/build-version/build-version.injectable";
|
||||||
|
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
|
import statInjectable from "../../../common/fs/stat/stat.injectable";
|
||||||
|
|
||||||
export interface OpenLocalShellSessionArgs {
|
export interface OpenLocalShellSessionArgs {
|
||||||
websocket: WebSocket;
|
websocket: WebSocket;
|
||||||
@ -46,11 +48,13 @@ const openLocalShellSessionInjectable = getInjectable({
|
|||||||
appName: di.inject(appNameInjectable),
|
appName: di.inject(appNameInjectable),
|
||||||
buildVersion: di.inject(buildVersionInjectable),
|
buildVersion: di.inject(buildVersionInjectable),
|
||||||
modifyTerminalShellEnv: di.inject(modifyTerminalShellEnvInjectable),
|
modifyTerminalShellEnv: di.inject(modifyTerminalShellEnvInjectable),
|
||||||
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
getDirnameOfPath: di.inject(getDirnameOfPathInjectable),
|
getDirnameOfPath: di.inject(getDirnameOfPathInjectable),
|
||||||
joinPaths: di.inject(joinPathsInjectable),
|
joinPaths: di.inject(joinPathsInjectable),
|
||||||
getBasenameOfPath: di.inject(getBasenameOfPathInjectable),
|
getBasenameOfPath: di.inject(getBasenameOfPathInjectable),
|
||||||
computeShellEnvironment: di.inject(computeShellEnvironmentInjectable),
|
computeShellEnvironment: di.inject(computeShellEnvironmentInjectable),
|
||||||
spawnPty: di.inject(spawnPtyInjectable),
|
spawnPty: di.inject(spawnPtyInjectable),
|
||||||
|
stat: di.inject(statInjectable),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (args) => {
|
return (args) => {
|
||||||
|
|||||||
@ -17,6 +17,8 @@ import spawnPtyInjectable from "../spawn-pty.injectable";
|
|||||||
import resolvedShellInjectable from "../../../common/user-store/resolved-shell.injectable";
|
import resolvedShellInjectable from "../../../common/user-store/resolved-shell.injectable";
|
||||||
import appNameInjectable from "../../../common/vars/app-name.injectable";
|
import appNameInjectable from "../../../common/vars/app-name.injectable";
|
||||||
import buildVersionInjectable from "../../vars/build-version/build-version.injectable";
|
import buildVersionInjectable from "../../vars/build-version/build-version.injectable";
|
||||||
|
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
|
import statInjectable from "../../../common/fs/stat/stat.injectable";
|
||||||
|
|
||||||
export interface NodeShellSessionArgs {
|
export interface NodeShellSessionArgs {
|
||||||
websocket: WebSocket;
|
websocket: WebSocket;
|
||||||
@ -39,6 +41,8 @@ const openNodeShellSessionInjectable = getInjectable({
|
|||||||
createKubeJsonApiForCluster: di.inject(createKubeJsonApiForClusterInjectable),
|
createKubeJsonApiForCluster: di.inject(createKubeJsonApiForClusterInjectable),
|
||||||
computeShellEnvironment: di.inject(computeShellEnvironmentInjectable),
|
computeShellEnvironment: di.inject(computeShellEnvironmentInjectable),
|
||||||
spawnPty: di.inject(spawnPtyInjectable),
|
spawnPty: di.inject(spawnPtyInjectable),
|
||||||
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
|
stat: di.inject(statInjectable),
|
||||||
};
|
};
|
||||||
const kubectl = createKubectl(params.cluster.version);
|
const kubectl = createKubectl(params.cluster.version);
|
||||||
const session = new NodeShellSession(dependencies, { kubectl, ...params });
|
const session = new NodeShellSession(dependencies, { kubectl, ...params });
|
||||||
|
|||||||
@ -10,14 +10,14 @@ import { clearKubeconfigEnvVars } from "../utils/clear-kube-env-vars";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import os, { userInfo } from "os";
|
import os, { userInfo } from "os";
|
||||||
import type * as pty from "node-pty";
|
import type * as pty from "node-pty";
|
||||||
import { appEventBus } from "../../common/app-event-bus/event-bus";
|
|
||||||
import { stat } from "fs/promises";
|
|
||||||
import { getOrInsertWith } from "../../common/utils";
|
import { getOrInsertWith } from "../../common/utils";
|
||||||
import { type TerminalMessage, TerminalChannels } from "../../common/terminal/channels";
|
import { type TerminalMessage, TerminalChannels } from "../../common/terminal/channels";
|
||||||
import type { Logger } from "../../common/logger";
|
import type { Logger } from "../../common/logger";
|
||||||
import type { ComputeShellEnvironment } from "../utils/shell-env/compute-shell-environment.injectable";
|
import type { ComputeShellEnvironment } from "../utils/shell-env/compute-shell-environment.injectable";
|
||||||
import type { SpawnPty } from "./spawn-pty.injectable";
|
import type { SpawnPty } from "./spawn-pty.injectable";
|
||||||
import type { InitializableState } from "../../common/initializable-state/create";
|
import type { InitializableState } from "../../common/initializable-state/create";
|
||||||
|
import type { EmitAppEvent } from "../../common/app-event-bus/emit-event.injectable";
|
||||||
|
import type { Stat } from "../../common/fs/stat/stat.injectable";
|
||||||
|
|
||||||
export class ShellOpenError extends Error {
|
export class ShellOpenError extends Error {
|
||||||
constructor(message: string, options?: ErrorOptions) {
|
constructor(message: string, options?: ErrorOptions) {
|
||||||
@ -112,6 +112,8 @@ export interface ShellSessionDependencies {
|
|||||||
readonly buildVersion: InitializableState<string>;
|
readonly buildVersion: InitializableState<string>;
|
||||||
computeShellEnvironment: ComputeShellEnvironment;
|
computeShellEnvironment: ComputeShellEnvironment;
|
||||||
spawnPty: SpawnPty;
|
spawnPty: SpawnPty;
|
||||||
|
emitAppEvent: EmitAppEvent;
|
||||||
|
stat: Stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShellSessionArgs {
|
export interface ShellSessionArgs {
|
||||||
@ -213,7 +215,7 @@ export abstract class ShellSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const stats = await stat(potentialCwd);
|
const stats = await this.dependencies.stat(potentialCwd);
|
||||||
|
|
||||||
if (stats.isDirectory()) {
|
if (stats.isDirectory()) {
|
||||||
return potentialCwd;
|
return potentialCwd;
|
||||||
@ -310,7 +312,7 @@ export abstract class ShellSession {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
appEventBus.emit({ name: this.ShellType, action: "open" });
|
this.dependencies.emitAppEvent({ name: this.ShellType, action: "open" });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getPathEntries(): string[] {
|
protected getPathEntries(): string[] {
|
||||||
|
|||||||
@ -6,9 +6,9 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import createLensWindowInjectable from "./create-lens-window.injectable";
|
import createLensWindowInjectable from "./create-lens-window.injectable";
|
||||||
import lensProxyPortInjectable from "../../../lens-proxy/lens-proxy-port.injectable";
|
import lensProxyPortInjectable from "../../../lens-proxy/lens-proxy-port.injectable";
|
||||||
import isMacInjectable from "../../../../common/vars/is-mac.injectable";
|
import isMacInjectable from "../../../../common/vars/is-mac.injectable";
|
||||||
import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable";
|
|
||||||
import waitUntilBundledExtensionsAreLoadedInjectable from "./wait-until-bundled-extensions-are-loaded.injectable";
|
import waitUntilBundledExtensionsAreLoadedInjectable from "./wait-until-bundled-extensions-are-loaded.injectable";
|
||||||
import { applicationWindowInjectionToken } from "./application-window-injection-token";
|
import { applicationWindowInjectionToken } from "./application-window-injection-token";
|
||||||
|
import emitAppEventInjectable from "../../../../common/app-event-bus/emit-event.injectable";
|
||||||
import { runInAction } from "mobx";
|
import { runInAction } from "mobx";
|
||||||
import appNameInjectable from "../../../../common/vars/app-name.injectable";
|
import appNameInjectable from "../../../../common/vars/app-name.injectable";
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ const createApplicationWindowInjectable = getInjectable({
|
|||||||
const createLensWindow = di.inject(createLensWindowInjectable);
|
const createLensWindow = di.inject(createLensWindowInjectable);
|
||||||
const isMac = di.inject(isMacInjectable);
|
const isMac = di.inject(isMacInjectable);
|
||||||
const applicationName = di.inject(appNameInjectable);
|
const applicationName = di.inject(appNameInjectable);
|
||||||
const appEventBus = di.inject(appEventBusInjectable);
|
|
||||||
const waitUntilBundledExtensionsAreLoaded = di.inject(waitUntilBundledExtensionsAreLoadedInjectable);
|
const waitUntilBundledExtensionsAreLoaded = di.inject(waitUntilBundledExtensionsAreLoadedInjectable);
|
||||||
const lensProxyPort = di.inject(lensProxyPortInjectable);
|
const lensProxyPort = di.inject(lensProxyPortInjectable);
|
||||||
|
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||||
|
|
||||||
return createLensWindow({
|
return createLensWindow({
|
||||||
id,
|
id,
|
||||||
@ -40,13 +40,13 @@ const createApplicationWindowInjectable = getInjectable({
|
|||||||
titleBarStyle: isMac ? "hiddenInset" : "hidden",
|
titleBarStyle: isMac ? "hiddenInset" : "hidden",
|
||||||
centered: false,
|
centered: false,
|
||||||
onFocus: () => {
|
onFocus: () => {
|
||||||
appEventBus.emit({ name: "app", action: "focus" });
|
emitAppEvent({ name: "app", action: "focus" });
|
||||||
},
|
},
|
||||||
onBlur: () => {
|
onBlur: () => {
|
||||||
appEventBus.emit({ name: "app", action: "blur" });
|
emitAppEvent({ name: "app", action: "blur" });
|
||||||
},
|
},
|
||||||
onDomReady: () => {
|
onDomReady: () => {
|
||||||
appEventBus.emit({ name: "app", action: "dom-ready" });
|
emitAppEvent({ name: "app", action: "dom-ready" });
|
||||||
},
|
},
|
||||||
|
|
||||||
onClose: () => {
|
onClose: () => {
|
||||||
|
|||||||
@ -3,19 +3,19 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import appEventBusInjectable from "../../../common/app-event-bus/app-event-bus.injectable";
|
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
import { beforeQuitOfFrontEndInjectionToken } from "../runnable-tokens/before-quit-of-front-end-injection-token";
|
import { beforeQuitOfFrontEndInjectionToken } from "../runnable-tokens/before-quit-of-front-end-injection-token";
|
||||||
|
|
||||||
const emitCloseToEventBusInjectable = getInjectable({
|
const emitCloseToEventBusInjectable = getInjectable({
|
||||||
id: "emit-close-to-event-bus",
|
id: "emit-close-to-event-bus",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const appEventBus = di.inject(appEventBusInjectable);
|
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "emit-close-to-event-bus",
|
id: "emit-close-to-event-bus",
|
||||||
run: () => {
|
run: () => {
|
||||||
appEventBus.emit({ name: "app", action: "close" });
|
emitAppEvent({ name: "app", action: "close" });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -3,19 +3,19 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import appEventBusInjectable from "../../../common/app-event-bus/app-event-bus.injectable";
|
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
import { afterApplicationIsLoadedInjectionToken } from "../runnable-tokens/after-application-is-loaded-injection-token";
|
import { afterApplicationIsLoadedInjectionToken } from "../runnable-tokens/after-application-is-loaded-injection-token";
|
||||||
|
|
||||||
const emitServiceStartToEventBusInjectable = getInjectable({
|
const emitServiceStartToEventBusInjectable = getInjectable({
|
||||||
id: "emit-service-start-to-event-bus",
|
id: "emit-service-start-to-event-bus",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const appEventBus = di.inject(appEventBusInjectable);
|
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "emit-service-start-to-event-bus",
|
id: "emit-service-start-to-event-bus",
|
||||||
run: () => {
|
run: () => {
|
||||||
appEventBus.emit({ name: "service", action: "start" });
|
emitAppEvent({ name: "service", action: "start" });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -5,9 +5,9 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import exitAppInjectable from "./electron-app/features/exit-app.injectable";
|
import exitAppInjectable from "./electron-app/features/exit-app.injectable";
|
||||||
import clusterManagerInjectable from "./cluster/manager.injectable";
|
import clusterManagerInjectable from "./cluster/manager.injectable";
|
||||||
import appEventBusInjectable from "../common/app-event-bus/app-event-bus.injectable";
|
|
||||||
import loggerInjectable from "../common/logger.injectable";
|
import loggerInjectable from "../common/logger.injectable";
|
||||||
import closeAllWindowsInjectable from "./start-main-application/lens-window/hide-all-windows/close-all-windows.injectable";
|
import closeAllWindowsInjectable from "./start-main-application/lens-window/hide-all-windows/close-all-windows.injectable";
|
||||||
|
import emitAppEventInjectable from "../common/app-event-bus/emit-event.injectable";
|
||||||
|
|
||||||
const stopServicesAndExitAppInjectable = getInjectable({
|
const stopServicesAndExitAppInjectable = getInjectable({
|
||||||
id: "stop-services-and-exit-app",
|
id: "stop-services-and-exit-app",
|
||||||
@ -15,12 +15,12 @@ const stopServicesAndExitAppInjectable = getInjectable({
|
|||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const exitApp = di.inject(exitAppInjectable);
|
const exitApp = di.inject(exitAppInjectable);
|
||||||
const clusterManager = di.inject(clusterManagerInjectable);
|
const clusterManager = di.inject(clusterManagerInjectable);
|
||||||
const appEventBus = di.inject(appEventBusInjectable);
|
|
||||||
const logger = di.inject(loggerInjectable);
|
const logger = di.inject(loggerInjectable);
|
||||||
const closeAllWindows = di.inject(closeAllWindowsInjectable);
|
const closeAllWindows = di.inject(closeAllWindowsInjectable);
|
||||||
|
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
appEventBus.emit({ name: "service", action: "close" });
|
emitAppEvent({ name: "service", action: "close" });
|
||||||
closeAllWindows();
|
closeAllWindows();
|
||||||
clusterManager.stop();
|
clusterManager.stop();
|
||||||
logger.info("SERVICE:QUIT");
|
logger.info("SERVICE:QUIT");
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import { action, computed, makeObservable, observable } from "mobx";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import * as uuid from "uuid";
|
import * as uuid from "uuid";
|
||||||
import { appEventBus } from "../../../common/app-event-bus/event-bus";
|
|
||||||
import { loadConfigFromString, splitConfig } from "../../../common/kube-helpers";
|
import { loadConfigFromString, splitConfig } from "../../../common/kube-helpers";
|
||||||
import { docsUrl } from "../../../common/vars";
|
import { docsUrl } from "../../../common/vars";
|
||||||
import { isDefined, iter } from "../../utils";
|
import { isDefined, iter } from "../../utils";
|
||||||
@ -24,6 +23,8 @@ import { withInjectables } from "@ogre-tools/injectable-react";
|
|||||||
import getCustomKubeConfigDirectoryInjectable from "../../../common/app-paths/get-custom-kube-config-directory/get-custom-kube-config-directory.injectable";
|
import getCustomKubeConfigDirectoryInjectable from "../../../common/app-paths/get-custom-kube-config-directory/get-custom-kube-config-directory.injectable";
|
||||||
import type { NavigateToCatalog } from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
import type { NavigateToCatalog } from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||||
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||||
|
import type { EmitAppEvent } from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
|
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
import type { GetDirnameOfPath } from "../../../common/path/get-dirname.injectable";
|
import type { GetDirnameOfPath } from "../../../common/path/get-dirname.injectable";
|
||||||
import getDirnameOfPathInjectable from "../../../common/path/get-dirname.injectable";
|
import getDirnameOfPathInjectable from "../../../common/path/get-dirname.injectable";
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ interface Dependencies {
|
|||||||
getCustomKubeConfigDirectory: (directoryName: string) => string;
|
getCustomKubeConfigDirectory: (directoryName: string) => string;
|
||||||
navigateToCatalog: NavigateToCatalog;
|
navigateToCatalog: NavigateToCatalog;
|
||||||
getDirnameOfPath: GetDirnameOfPath;
|
getDirnameOfPath: GetDirnameOfPath;
|
||||||
|
emitAppEvent: EmitAppEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getContexts(config: KubeConfig): Map<string, Option> {
|
function getContexts(config: KubeConfig): Map<string, Option> {
|
||||||
@ -55,13 +57,13 @@ class NonInjectedAddCluster extends React.Component<Dependencies> {
|
|||||||
@observable isWaiting = false;
|
@observable isWaiting = false;
|
||||||
@observable errors: string[] = [];
|
@observable errors: string[] = [];
|
||||||
|
|
||||||
constructor(dependencies: Dependencies) {
|
constructor(props: Dependencies) {
|
||||||
super(dependencies);
|
super(props);
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
appEventBus.emit({ name: "cluster-add", action: "start" });
|
this.props.emitAppEvent({ name: "cluster-add", action: "start" });
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed get allErrors(): string[] {
|
@computed get allErrors(): string[] {
|
||||||
@ -87,7 +89,7 @@ class NonInjectedAddCluster extends React.Component<Dependencies> {
|
|||||||
|
|
||||||
addClusters = action(async () => {
|
addClusters = action(async () => {
|
||||||
this.isWaiting = true;
|
this.isWaiting = true;
|
||||||
appEventBus.emit({ name: "cluster-add", action: "click" });
|
this.props.emitAppEvent({ name: "cluster-add", action: "click" });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const absPath = this.props.getCustomKubeConfigDirectory(uuid.v4());
|
const absPath = this.props.getCustomKubeConfigDirectory(uuid.v4());
|
||||||
@ -160,5 +162,6 @@ export const AddCluster = withInjectables<Dependencies>(NonInjectedAddCluster, {
|
|||||||
getCustomKubeConfigDirectory: di.inject(getCustomKubeConfigDirectoryInjectable),
|
getCustomKubeConfigDirectory: di.inject(getCustomKubeConfigDirectoryInjectable),
|
||||||
navigateToCatalog: di.inject(navigateToCatalogInjectable),
|
navigateToCatalog: di.inject(navigateToCatalogInjectable),
|
||||||
getDirnameOfPath: di.inject(getDirnameOfPathInjectable),
|
getDirnameOfPath: di.inject(getDirnameOfPathInjectable),
|
||||||
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -57,7 +57,7 @@ describe("<Catalog />", () => {
|
|||||||
let di: DiContainer;
|
let di: DiContainer;
|
||||||
let catalogEntityStore: CatalogEntityStore;
|
let catalogEntityStore: CatalogEntityStore;
|
||||||
let catalogEntityRegistry: CatalogEntityRegistry;
|
let catalogEntityRegistry: CatalogEntityRegistry;
|
||||||
let emitEvent: (event: AppEvent) => void;
|
let appEventListener: jest.MockedFunction<(event: AppEvent) => void>;
|
||||||
let onRun: jest.MockedFunction<(context: CatalogEntityActionContext) => void | Promise<void>>;
|
let onRun: jest.MockedFunction<(context: CatalogEntityActionContext) => void | Promise<void>>;
|
||||||
let catalogEntityItem: MockCatalogEntity;
|
let catalogEntityItem: MockCatalogEntity;
|
||||||
let render: DiRender;
|
let render: DiRender;
|
||||||
@ -78,11 +78,8 @@ describe("<Catalog />", () => {
|
|||||||
catalogEntityItem = createMockCatalogEntity(onRun);
|
catalogEntityItem = createMockCatalogEntity(onRun);
|
||||||
catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
|
catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
|
||||||
|
|
||||||
emitEvent = jest.fn();
|
appEventListener = jest.fn();
|
||||||
|
di.inject(appEventBusInjectable).addListener(appEventListener);
|
||||||
di.override(appEventBusInjectable, () => ({
|
|
||||||
emit: emitEvent,
|
|
||||||
}));
|
|
||||||
|
|
||||||
catalogEntityStore = di.inject(catalogEntityStoreInjectable);
|
catalogEntityStore = di.inject(catalogEntityStoreInjectable);
|
||||||
Object.assign(catalogEntityStore, {
|
Object.assign(catalogEntityStore, {
|
||||||
@ -204,24 +201,20 @@ describe("<Catalog />", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("emits catalog open AppEvent", () => {
|
it("emits catalog open AppEvent", () => {
|
||||||
render(
|
render(<Catalog />);
|
||||||
<Catalog />,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(emitEvent).toHaveBeenCalledWith( {
|
expect(appEventListener).toHaveBeenCalledWith( {
|
||||||
action: "open",
|
action: "open",
|
||||||
name: "catalog",
|
name: "catalog",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("emits catalog change AppEvent when changing the category", () => {
|
it("emits catalog change AppEvent when changing the category", () => {
|
||||||
render(
|
render(<Catalog />);
|
||||||
<Catalog />,
|
|
||||||
);
|
|
||||||
|
|
||||||
userEvent.click(screen.getByText("Web Links"));
|
userEvent.click(screen.getByText("Web Links"));
|
||||||
|
|
||||||
expect(emitEvent).toHaveBeenLastCalledWith({
|
expect(appEventListener).toHaveBeenCalledWith({
|
||||||
action: "change-category",
|
action: "change-category",
|
||||||
name: "catalog",
|
name: "catalog",
|
||||||
params: {
|
params: {
|
||||||
|
|||||||
@ -37,8 +37,6 @@ import type { NavigateToCatalog } from "../../../common/front-end-routing/routes
|
|||||||
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||||
import catalogRouteParametersInjectable from "./catalog-route-parameters.injectable";
|
import catalogRouteParametersInjectable from "./catalog-route-parameters.injectable";
|
||||||
import { browseCatalogTab } from "./catalog-browse-tab";
|
import { browseCatalogTab } from "./catalog-browse-tab";
|
||||||
import type { AppEvent } from "../../../common/app-event-bus/event-bus";
|
|
||||||
import appEventBusInjectable from "../../../common/app-event-bus/app-event-bus.injectable";
|
|
||||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||||
import type { VisitEntityContextMenu } from "../../../common/catalog/visit-entity-context-menu.injectable";
|
import type { VisitEntityContextMenu } from "../../../common/catalog/visit-entity-context-menu.injectable";
|
||||||
@ -48,13 +46,15 @@ import type { Navigate } from "../../navigation/navigate.injectable";
|
|||||||
import navigateInjectable from "../../navigation/navigate.injectable";
|
import navigateInjectable from "../../navigation/navigate.injectable";
|
||||||
import type { NormalizeCatalogEntityContextMenu } from "../../catalog/normalize-menu-item.injectable";
|
import type { NormalizeCatalogEntityContextMenu } from "../../catalog/normalize-menu-item.injectable";
|
||||||
import normalizeCatalogEntityContextMenuInjectable from "../../catalog/normalize-menu-item.injectable";
|
import normalizeCatalogEntityContextMenuInjectable from "../../catalog/normalize-menu-item.injectable";
|
||||||
|
import type { EmitAppEvent } from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
|
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
catalogPreviousActiveTabStorage: StorageLayer<string | null>;
|
catalogPreviousActiveTabStorage: StorageLayer<string | null>;
|
||||||
catalogEntityStore: CatalogEntityStore;
|
catalogEntityStore: CatalogEntityStore;
|
||||||
getCategoryColumns: (params: GetCategoryColumnsParams) => CategoryColumns;
|
getCategoryColumns: (params: GetCategoryColumnsParams) => CategoryColumns;
|
||||||
customCategoryViews: IComputedValue<Map<string, Map<string, RegisteredCustomCategoryViewDecl>>>;
|
customCategoryViews: IComputedValue<Map<string, Map<string, RegisteredCustomCategoryViewDecl>>>;
|
||||||
emitEvent: (event: AppEvent) => void;
|
emitEvent: EmitAppEvent;
|
||||||
routeParameters: {
|
routeParameters: {
|
||||||
group: IComputedValue<string>;
|
group: IComputedValue<string>;
|
||||||
kind: IComputedValue<string>;
|
kind: IComputedValue<string>;
|
||||||
@ -356,7 +356,7 @@ export const Catalog = withInjectables<Dependencies>(NonInjectedCatalog, {
|
|||||||
customCategoryViews: di.inject(customCategoryViewsInjectable),
|
customCategoryViews: di.inject(customCategoryViewsInjectable),
|
||||||
routeParameters: di.inject(catalogRouteParametersInjectable),
|
routeParameters: di.inject(catalogRouteParametersInjectable),
|
||||||
navigateToCatalog: di.inject(navigateToCatalogInjectable),
|
navigateToCatalog: di.inject(navigateToCatalogInjectable),
|
||||||
emitEvent: di.inject(appEventBusInjectable).emit,
|
emitEvent: di.inject(emitAppEventInjectable),
|
||||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||||
catalogCategoryRegistry: di.inject(catalogCategoryRegistryInjectable),
|
catalogCategoryRegistry: di.inject(catalogCategoryRegistryInjectable),
|
||||||
visitEntityContextMenu: di.inject(visitEntityContextMenuInjectable),
|
visitEntityContextMenu: di.inject(visitEntityContextMenuInjectable),
|
||||||
|
|||||||
@ -8,9 +8,9 @@ import extensionLoaderInjectable from "../../../../extensions/extension-loader/e
|
|||||||
import catalogEntityRegistryInjectable from "../../../api/catalog/entity/registry.injectable";
|
import catalogEntityRegistryInjectable from "../../../api/catalog/entity/registry.injectable";
|
||||||
import frameRoutingIdInjectable from "./frame-routing-id/frame-routing-id.injectable";
|
import frameRoutingIdInjectable from "./frame-routing-id/frame-routing-id.injectable";
|
||||||
import hostedClusterInjectable from "../../../cluster-frame-context/hosted-cluster.injectable";
|
import hostedClusterInjectable from "../../../cluster-frame-context/hosted-cluster.injectable";
|
||||||
import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable";
|
|
||||||
import clusterFrameContextInjectable from "../../../cluster-frame-context/cluster-frame-context.injectable";
|
import clusterFrameContextInjectable from "../../../cluster-frame-context/cluster-frame-context.injectable";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
|
import emitAppEventInjectable from "../../../../common/app-event-bus/emit-event.injectable";
|
||||||
|
|
||||||
const initClusterFrameInjectable = getInjectable({
|
const initClusterFrameInjectable = getInjectable({
|
||||||
id: "init-cluster-frame",
|
id: "init-cluster-frame",
|
||||||
@ -25,7 +25,7 @@ const initClusterFrameInjectable = getInjectable({
|
|||||||
loadExtensions: di.inject(extensionLoaderInjectable).loadOnClusterRenderer,
|
loadExtensions: di.inject(extensionLoaderInjectable).loadOnClusterRenderer,
|
||||||
catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable),
|
catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||||
frameRoutingId: di.inject(frameRoutingIdInjectable),
|
frameRoutingId: di.inject(frameRoutingIdInjectable),
|
||||||
emitEvent: di.inject(appEventBusInjectable).emit,
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
clusterFrameContext: di.inject(clusterFrameContextInjectable),
|
clusterFrameContext: di.inject(clusterFrameContextInjectable),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@ -7,19 +7,19 @@ import type { CatalogEntityRegistry } from "../../../api/catalog/entity/registry
|
|||||||
import logger from "../../../../main/logger";
|
import logger from "../../../../main/logger";
|
||||||
import type { KubernetesCluster } from "../../../../common/catalog-entities";
|
import type { KubernetesCluster } from "../../../../common/catalog-entities";
|
||||||
import { Notifications } from "../../../components/notifications";
|
import { Notifications } from "../../../components/notifications";
|
||||||
import type { AppEvent } from "../../../../common/app-event-bus/event-bus";
|
|
||||||
import type { CatalogEntity } from "../../../../common/catalog";
|
import type { CatalogEntity } from "../../../../common/catalog";
|
||||||
import { when } from "mobx";
|
import { when } from "mobx";
|
||||||
import type { ClusterFrameContext } from "../../../cluster-frame-context/cluster-frame-context";
|
import type { ClusterFrameContext } from "../../../cluster-frame-context/cluster-frame-context";
|
||||||
import { KubeObjectStore } from "../../../../common/k8s-api/kube-object.store";
|
import { KubeObjectStore } from "../../../../common/k8s-api/kube-object.store";
|
||||||
import { requestSetClusterFrameId } from "../../../ipc";
|
import { requestSetClusterFrameId } from "../../../ipc";
|
||||||
|
import type { EmitAppEvent } from "../../../../common/app-event-bus/emit-event.injectable";
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
hostedCluster: Cluster;
|
hostedCluster: Cluster;
|
||||||
loadExtensions: (getCluster: () => CatalogEntity) => void;
|
loadExtensions: (getCluster: () => CatalogEntity) => void;
|
||||||
catalogEntityRegistry: CatalogEntityRegistry;
|
catalogEntityRegistry: CatalogEntityRegistry;
|
||||||
frameRoutingId: number;
|
frameRoutingId: number;
|
||||||
emitEvent: (event: AppEvent) => void;
|
emitAppEvent: EmitAppEvent;
|
||||||
|
|
||||||
// TODO: This dependency belongs to KubeObjectStore
|
// TODO: This dependency belongs to KubeObjectStore
|
||||||
clusterFrameContext: ClusterFrameContext;
|
clusterFrameContext: ClusterFrameContext;
|
||||||
@ -32,7 +32,7 @@ export const initClusterFrame = ({
|
|||||||
loadExtensions,
|
loadExtensions,
|
||||||
catalogEntityRegistry,
|
catalogEntityRegistry,
|
||||||
frameRoutingId,
|
frameRoutingId,
|
||||||
emitEvent,
|
emitAppEvent,
|
||||||
clusterFrameContext,
|
clusterFrameContext,
|
||||||
}: Dependencies) =>
|
}: Dependencies) =>
|
||||||
async (unmountRoot: () => void) => {
|
async (unmountRoot: () => void) => {
|
||||||
@ -70,7 +70,7 @@ export const initClusterFrame = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
emitEvent({
|
emitAppEvent({
|
||||||
name: "cluster",
|
name: "cluster",
|
||||||
action: "open",
|
action: "open",
|
||||||
params: {
|
params: {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user