mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Convert to injectable IPC
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
853573afcb
commit
0a7c214767
@ -10,8 +10,10 @@ import { broadcastMessage } from "../ipc";
|
|||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
import type { CatalogEntityConstructor, CatalogEntitySpec } from "../catalog/catalog-entity";
|
import type { CatalogEntityConstructor, CatalogEntitySpec } from "../catalog/catalog-entity";
|
||||||
import { IpcRendererNavigationEvents } from "../../renderer/navigation/events";
|
import { IpcRendererNavigationEvents } from "../../renderer/navigation/events";
|
||||||
import { requestClusterActivation, requestClusterDisconnection } from "../../renderer/ipc";
|
import { requestClusterDisconnection } from "../../renderer/ipc";
|
||||||
import KubeClusterCategoryIcon from "./icons/kubernetes.svg";
|
import KubeClusterCategoryIcon from "./icons/kubernetes.svg";
|
||||||
|
import { asLegacyGlobalFunctionForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
|
||||||
|
import requestClusterActivationInjectable from "../../renderer/cluster/request-activation.injectable";
|
||||||
|
|
||||||
export interface KubernetesClusterPrometheusMetrics {
|
export interface KubernetesClusterPrometheusMetrics {
|
||||||
address?: {
|
address?: {
|
||||||
@ -63,6 +65,8 @@ export function isKubernetesCluster(item: unknown): item is KubernetesCluster {
|
|||||||
return item instanceof KubernetesCluster;
|
return item instanceof KubernetesCluster;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const requestClusterActivation = asLegacyGlobalFunctionForExtensionApi(requestClusterActivationInjectable);
|
||||||
|
|
||||||
export class KubernetesCluster<
|
export class KubernetesCluster<
|
||||||
Metadata extends KubernetesClusterMetadata = KubernetesClusterMetadata,
|
Metadata extends KubernetesClusterMetadata = KubernetesClusterMetadata,
|
||||||
Status extends KubernetesClusterStatus = KubernetesClusterStatus,
|
Status extends KubernetesClusterStatus = KubernetesClusterStatus,
|
||||||
@ -78,7 +82,10 @@ export class KubernetesCluster<
|
|||||||
if (app) {
|
if (app) {
|
||||||
await ClusterStore.getInstance().getById(this.getId())?.activate();
|
await ClusterStore.getInstance().getById(this.getId())?.activate();
|
||||||
} else {
|
} else {
|
||||||
await requestClusterActivation(this.getId(), false);
|
await requestClusterActivation({
|
||||||
|
clusterId: this.getId(),
|
||||||
|
force: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
18
src/common/cluster-store/clusters.injectable.ts
Normal file
18
src/common/cluster-store/clusters.injectable.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* 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 { computed } from "mobx";
|
||||||
|
import clusterStoreInjectable from "./cluster-store.injectable";
|
||||||
|
|
||||||
|
const clustersInjectable = getInjectable({
|
||||||
|
id: "clusters",
|
||||||
|
instantiate: (di) => {
|
||||||
|
const store = di.inject(clusterStoreInjectable);
|
||||||
|
|
||||||
|
return computed(() => [...store.clusters.values()]);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default clustersInjectable;
|
||||||
@ -25,6 +25,8 @@ import type { CanI } from "./authorization-review.injectable";
|
|||||||
import type { ListNamespaces } from "./list-namespaces.injectable";
|
import type { ListNamespaces } from "./list-namespaces.injectable";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import type { Logger } from "../logger";
|
import type { Logger } from "../logger";
|
||||||
|
import type { ReadFileSync } from "../fs/read-file-sync.injectable";
|
||||||
|
import type { EmitClusterConnectionUpdate } from "../../main/cluster/emit-connection-update.injectable";
|
||||||
|
|
||||||
export interface ClusterDependencies {
|
export interface ClusterDependencies {
|
||||||
readonly directoryForKubeConfigs: string;
|
readonly directoryForKubeConfigs: string;
|
||||||
@ -36,6 +38,10 @@ export interface ClusterDependencies {
|
|||||||
createAuthorizationReview: (config: KubeConfig) => CanI;
|
createAuthorizationReview: (config: KubeConfig) => CanI;
|
||||||
createListNamespaces: (config: KubeConfig) => ListNamespaces;
|
createListNamespaces: (config: KubeConfig) => ListNamespaces;
|
||||||
createVersionDetector: (cluster: Cluster) => VersionDetector;
|
createVersionDetector: (cluster: Cluster) => VersionDetector;
|
||||||
|
emitClusterConnectionUpdate: EmitClusterConnectionUpdate;
|
||||||
|
|
||||||
|
// TODO: creating a Cluster should not have such wild side effects
|
||||||
|
readFileSync: ReadFileSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -625,7 +631,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
|||||||
const update: KubeAuthUpdate = { message, isError };
|
const update: KubeAuthUpdate = { message, isError };
|
||||||
|
|
||||||
this.dependencies.logger.debug(`[CLUSTER]: broadcasting connection update`, { ...update, meta: this.getMeta() });
|
this.dependencies.logger.debug(`[CLUSTER]: broadcasting connection update`, { ...update, meta: this.getMeta() });
|
||||||
broadcastMessage(`cluster:connection-update`, this.id, update);
|
this.dependencies.emitClusterConnectionUpdate({ clusterId: this.id, update });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async getAllowedNamespaces(proxyConfig: KubeConfig) {
|
protected async getAllowedNamespaces(proxyConfig: KubeConfig) {
|
||||||
|
|||||||
26
src/common/cluster/connection-update-channel.injectable.ts
Normal file
26
src/common/cluster/connection-update-channel.injectable.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ClusterId, KubeAuthUpdate } from "../cluster-types";
|
||||||
|
import type { MessageChannel } from "../utils/channel/message-channel-injection-token";
|
||||||
|
import { messageChannelInjectionToken } from "../utils/channel/message-channel-injection-token";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
|
||||||
|
export interface ClusterConnectionUpdateMessage {
|
||||||
|
clusterId: ClusterId;
|
||||||
|
update: KubeAuthUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ClusterConnectionUpdateChannel = MessageChannel<ClusterConnectionUpdateMessage>;
|
||||||
|
|
||||||
|
const clusterConnectionUpdateChannelInjectable = getInjectable({
|
||||||
|
id: "cluster-connection-update-channel",
|
||||||
|
instantiate: (): ClusterConnectionUpdateChannel => ({
|
||||||
|
id: "cluster:connection-update",
|
||||||
|
}),
|
||||||
|
injectionToken: messageChannelInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default clusterConnectionUpdateChannelInjectable;
|
||||||
23
src/common/cluster/request-activation.injectable.ts
Normal file
23
src/common/cluster/request-activation.injectable.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { ClusterId } from "../cluster-types";
|
||||||
|
import type { RequestChannel } from "../utils/channel/request-channel-injection-token";
|
||||||
|
|
||||||
|
export interface ClusterActivationRequest {
|
||||||
|
clusterId: ClusterId;
|
||||||
|
force: boolean;
|
||||||
|
}
|
||||||
|
export type ClusterActivationRequestChannel = RequestChannel<ClusterActivationRequest, void>;
|
||||||
|
|
||||||
|
const clusterActivationRequestChannelInjectable = getInjectable({
|
||||||
|
id: "cluster-activation-request-channel",
|
||||||
|
instantiate: (): ClusterActivationRequestChannel => ({
|
||||||
|
id: "cluster-request-activation",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default clusterActivationRequestChannelInjectable;
|
||||||
@ -3,7 +3,6 @@
|
|||||||
* 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 const clusterActivateHandler = "cluster:activate";
|
|
||||||
export const clusterSetFrameIdHandler = "cluster:set-frame-id";
|
export const clusterSetFrameIdHandler = "cluster:set-frame-id";
|
||||||
export const clusterVisibilityHandler = "cluster:visibility";
|
export const clusterVisibilityHandler = "cluster:visibility";
|
||||||
export const clusterRefreshHandler = "cluster:refresh";
|
export const clusterRefreshHandler = "cluster:refresh";
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
export interface Channel<MessageTemplate = void, ReturnTemplate = void> {
|
|
||||||
id: string;
|
|
||||||
_messageTemplate?: MessageTemplate;
|
|
||||||
_returnTemplate?: ReturnTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -4,9 +4,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { JsonValue } from "type-fest";
|
|
||||||
|
|
||||||
export interface MessageChannel<Message extends JsonValue | void = void> {
|
export interface MessageChannel<Message = void> {
|
||||||
id: string;
|
id: string;
|
||||||
_messageSignature?: Message;
|
_messageSignature?: Message;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,10 @@ import { getInjectionToken } from "@ogre-tools/injectable";
|
|||||||
import type { SetRequired } from "type-fest";
|
import type { SetRequired } from "type-fest";
|
||||||
import type { MessageChannel } from "./message-channel-injection-token";
|
import type { MessageChannel } from "./message-channel-injection-token";
|
||||||
|
|
||||||
|
export type EmitChannelMessage<Channel> = Channel extends MessageChannel<infer Message>
|
||||||
|
? (message: Message) => void
|
||||||
|
: never;
|
||||||
|
|
||||||
export interface MessageToChannel {
|
export interface MessageToChannel {
|
||||||
<TChannel extends MessageChannel<TMessage>, TMessage extends void>(
|
<TChannel extends MessageChannel<TMessage>, TMessage extends void>(
|
||||||
channel: TChannel,
|
channel: TChannel,
|
||||||
|
|||||||
@ -4,11 +4,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { JsonValue } from "type-fest";
|
|
||||||
|
|
||||||
export interface RequestChannel<
|
export interface RequestChannel<
|
||||||
Request extends JsonValue | void = void,
|
Request = void,
|
||||||
Response extends JsonValue | void = void,
|
Response = void,
|
||||||
> {
|
> {
|
||||||
id: string;
|
id: string;
|
||||||
_requestSignature?: Request;
|
_requestSignature?: Request;
|
||||||
|
|||||||
@ -6,6 +6,12 @@ import { getInjectionToken } from "@ogre-tools/injectable";
|
|||||||
import type { SetRequired } from "type-fest";
|
import type { SetRequired } from "type-fest";
|
||||||
import type { RequestChannel } from "./request-channel-injection-token";
|
import type { RequestChannel } from "./request-channel-injection-token";
|
||||||
|
|
||||||
|
export type RequestFromChannelImpl<Channel> = Channel extends RequestChannel<infer Request, infer Response>
|
||||||
|
? Request extends void
|
||||||
|
? () => Promise<Response>
|
||||||
|
: (req: Request) => Promise<Response>
|
||||||
|
: never;
|
||||||
|
|
||||||
export type RequestFromChannel = <
|
export type RequestFromChannel = <
|
||||||
TChannel extends RequestChannel<any, any>,
|
TChannel extends RequestChannel<any, any>,
|
||||||
>(
|
>(
|
||||||
|
|||||||
84
src/features/cluster/connection-status.test.tsx
Normal file
84
src/features/cluster/connection-status.test.tsx
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ClusterStore } from "../../common/cluster-store/cluster-store";
|
||||||
|
import clusterStoreInjectable from "../../common/cluster-store/cluster-store.injectable";
|
||||||
|
import type { ClusterId } from "../../common/cluster-types";
|
||||||
|
import type { Cluster } from "../../common/cluster/cluster";
|
||||||
|
import navigateToClusterViewInjectable from "../../common/front-end-routing/routes/cluster-view/navigate-to-cluster-view.injectable";
|
||||||
|
import type { ReadFileSync } from "../../common/fs/read-file-sync.injectable";
|
||||||
|
import readFileSyncInjectable from "../../common/fs/read-file-sync.injectable";
|
||||||
|
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import createClusterInjectable from "../../renderer/create-cluster/create-cluster.injectable";
|
||||||
|
|
||||||
|
describe("cluster connection status", () => {
|
||||||
|
let clusterStore: ClusterStore;
|
||||||
|
let clusters: Map<ClusterId, Cluster>;
|
||||||
|
let cluster: Cluster;
|
||||||
|
let applicationBuilder: ApplicationBuilder;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
applicationBuilder = getApplicationBuilder();
|
||||||
|
|
||||||
|
const readFileSyncMock: ReadFileSync = (filePath) => {
|
||||||
|
expect(filePath).toBe("/some/file/path");
|
||||||
|
|
||||||
|
return JSON.stringify({
|
||||||
|
apiVersion: "v1",
|
||||||
|
clusters: [{
|
||||||
|
name: "minikube",
|
||||||
|
cluster: {
|
||||||
|
server: "https://192.168.64.3:8443",
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
contexts: [{
|
||||||
|
context: {
|
||||||
|
cluster: "minikube",
|
||||||
|
user: "minikube",
|
||||||
|
},
|
||||||
|
name: "minikube",
|
||||||
|
}],
|
||||||
|
users: [{
|
||||||
|
name: "minikube",
|
||||||
|
}],
|
||||||
|
kind: "Config",
|
||||||
|
preferences: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
applicationBuilder.dis.rendererDi.override(readFileSyncInjectable, () => readFileSyncMock);
|
||||||
|
|
||||||
|
const navigateToClusterView = applicationBuilder.dis.rendererDi.inject(navigateToClusterViewInjectable);
|
||||||
|
const createCluster = applicationBuilder.dis.rendererDi.inject(createClusterInjectable);
|
||||||
|
|
||||||
|
cluster = createCluster({
|
||||||
|
contextName: "minikube",
|
||||||
|
id: "some-cluster-id",
|
||||||
|
kubeConfigPath: "/some/file/path",
|
||||||
|
}, {
|
||||||
|
clusterServerUrl: "https://localhost:1234",
|
||||||
|
});
|
||||||
|
|
||||||
|
clusters = new Map();
|
||||||
|
|
||||||
|
clusters.set(cluster.id, cluster);
|
||||||
|
|
||||||
|
clusterStore = ({
|
||||||
|
clusters,
|
||||||
|
get clustersList() {
|
||||||
|
return [...clusters.values()];
|
||||||
|
},
|
||||||
|
getById: (id) => clusters.get(id),
|
||||||
|
}) as ClusterStore;
|
||||||
|
|
||||||
|
applicationBuilder.dis.mainDi.override(clusterStoreInjectable, () => clusterStore);
|
||||||
|
applicationBuilder.dis.rendererDi.override(clusterStoreInjectable, () => clusterStore);
|
||||||
|
|
||||||
|
await applicationBuilder.render();
|
||||||
|
|
||||||
|
navigateToClusterView(cluster.id);
|
||||||
|
});
|
||||||
|
});
|
||||||
23
src/main/cluster/emit-connection-update.injectable.ts
Normal file
23
src/main/cluster/emit-connection-update.injectable.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { ClusterConnectionUpdateChannel } from "../../common/cluster/connection-update-channel.injectable";
|
||||||
|
import clusterConnectionUpdateChannelInjectable from "../../common/cluster/connection-update-channel.injectable";
|
||||||
|
import type { EmitChannelMessage } from "../../common/utils/channel/message-to-channel-injection-token";
|
||||||
|
import messageToChannelInjectable from "../utils/channel/message-to-channel.injectable";
|
||||||
|
|
||||||
|
export type EmitClusterConnectionUpdate = EmitChannelMessage<ClusterConnectionUpdateChannel>;
|
||||||
|
|
||||||
|
const emitClusterConnectionUpdateInjectable = getInjectable({
|
||||||
|
id: "emit-cluster-connection-update",
|
||||||
|
instantiate: (di): EmitClusterConnectionUpdate => {
|
||||||
|
const channel = di.inject(clusterConnectionUpdateChannelInjectable);
|
||||||
|
const messageToChannel = di.inject(messageToChannelInjectable);
|
||||||
|
|
||||||
|
return (message) => messageToChannel(channel, message);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default emitClusterConnectionUpdateInjectable;
|
||||||
28
src/main/cluster/request-activation-handler.injectable.ts
Normal file
28
src/main/cluster/request-activation-handler.injectable.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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 clusterStoreInjectable from "../../common/cluster-store/cluster-store.injectable";
|
||||||
|
import type { ClusterActivationRequestChannel } from "../../common/cluster/request-activation.injectable";
|
||||||
|
import clusterActivationRequestChannelInjectable from "../../common/cluster/request-activation.injectable";
|
||||||
|
import type { RequestChannelListener } from "../../common/utils/channel/request-channel-listener-injection-token";
|
||||||
|
import { requestChannelListenerInjectionToken } from "../../common/utils/channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
|
const requestClusterActivationHandlerInjectable = getInjectable({
|
||||||
|
id: "request-cluster-activation-handler",
|
||||||
|
instantiate: (di) => {
|
||||||
|
const channel = di.inject(clusterActivationRequestChannelInjectable);
|
||||||
|
const store = di.inject(clusterStoreInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
channel,
|
||||||
|
handler: ({ clusterId, force }) => {
|
||||||
|
store.getById(clusterId)?.activate(force);
|
||||||
|
},
|
||||||
|
} as RequestChannelListener<ClusterActivationRequestChannel>;
|
||||||
|
},
|
||||||
|
injectionToken: requestChannelListenerInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default requestClusterActivationHandlerInjectable;
|
||||||
@ -15,6 +15,8 @@ import listNamespacesInjectable from "../../common/cluster/list-namespaces.injec
|
|||||||
import loggerInjectable from "../../common/logger.injectable";
|
import loggerInjectable from "../../common/logger.injectable";
|
||||||
import detectorRegistryInjectable from "../cluster-detectors/detector-registry.injectable";
|
import detectorRegistryInjectable from "../cluster-detectors/detector-registry.injectable";
|
||||||
import createVersionDetectorInjectable from "../cluster-detectors/create-version-detector.injectable";
|
import createVersionDetectorInjectable from "../cluster-detectors/create-version-detector.injectable";
|
||||||
|
import readFileSyncInjectable from "../../common/fs/read-file-sync.injectable";
|
||||||
|
import emitClusterConnectionUpdateInjectable from "../cluster/emit-connection-update.injectable";
|
||||||
|
|
||||||
const createClusterInjectable = getInjectable({
|
const createClusterInjectable = getInjectable({
|
||||||
id: "create-cluster",
|
id: "create-cluster",
|
||||||
@ -30,6 +32,8 @@ const createClusterInjectable = getInjectable({
|
|||||||
logger: di.inject(loggerInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
detectorRegistry: di.inject(detectorRegistryInjectable),
|
detectorRegistry: di.inject(detectorRegistryInjectable),
|
||||||
createVersionDetector: di.inject(createVersionDetectorInjectable),
|
createVersionDetector: di.inject(createVersionDetectorInjectable),
|
||||||
|
readFileSync: di.inject(readFileSyncInjectable),
|
||||||
|
emitClusterConnectionUpdate: di.inject(emitClusterConnectionUpdateInjectable),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (model, configData) => new Cluster(dependencies, model, configData);
|
return (model, configData) => new Cluster(dependencies, model, configData);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import type { IpcMainInvokeEvent } from "electron";
|
import type { IpcMainInvokeEvent } from "electron";
|
||||||
import { BrowserWindow, Menu } from "electron";
|
import { BrowserWindow, Menu } from "electron";
|
||||||
import { clusterFrameMap } from "../../../../common/cluster-frames";
|
import { clusterFrameMap } from "../../../../common/cluster-frames";
|
||||||
import { clusterActivateHandler, clusterSetFrameIdHandler, clusterVisibilityHandler, clusterRefreshHandler, clusterDisconnectHandler, clusterKubectlApplyAllHandler, clusterKubectlDeleteAllHandler, clusterDeleteHandler, clusterSetDeletingHandler, clusterClearDeletingHandler } from "../../../../common/ipc/cluster";
|
import { clusterSetFrameIdHandler, clusterVisibilityHandler, clusterRefreshHandler, clusterDisconnectHandler, clusterKubectlApplyAllHandler, clusterKubectlDeleteAllHandler, clusterDeleteHandler, clusterSetDeletingHandler, clusterClearDeletingHandler } 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 { appEventBus } from "../../../../common/app-event-bus/event-bus";
|
||||||
@ -37,12 +37,6 @@ interface Dependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const setupIpcMainHandlers = ({ applicationMenuItems, directoryForLensLocalStorage, getAbsolutePath, clusterManager, catalogEntityRegistry, clusterStore, operatingSystemTheme, askUserForFilePaths }: Dependencies) => {
|
export const setupIpcMainHandlers = ({ applicationMenuItems, directoryForLensLocalStorage, getAbsolutePath, clusterManager, catalogEntityRegistry, clusterStore, operatingSystemTheme, askUserForFilePaths }: Dependencies) => {
|
||||||
ipcMainHandle(clusterActivateHandler, (event, clusterId: ClusterId, force = false) => {
|
|
||||||
return ClusterStore.getInstance()
|
|
||||||
.getById(clusterId)
|
|
||||||
?.activate(force);
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMainHandle(clusterSetFrameIdHandler, (event: IpcMainInvokeEvent, clusterId: ClusterId) => {
|
ipcMainHandle(clusterSetFrameIdHandler, (event: IpcMainInvokeEvent, clusterId: ClusterId) => {
|
||||||
const cluster = ClusterStore.getInstance().getById(clusterId);
|
const cluster = ClusterStore.getInstance().getById(clusterId);
|
||||||
|
|
||||||
|
|||||||
@ -95,6 +95,7 @@ import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
|
|||||||
import electronInjectable from "./utils/resolve-system-proxy/electron.injectable";
|
import electronInjectable from "./utils/resolve-system-proxy/electron.injectable";
|
||||||
import type { HotbarStore } from "../common/hotbars/store";
|
import type { HotbarStore } from "../common/hotbars/store";
|
||||||
import focusApplicationInjectable from "./electron-app/features/focus-application.injectable";
|
import focusApplicationInjectable from "./electron-app/features/focus-application.injectable";
|
||||||
|
import readFileSyncInjectable from "../common/fs/read-file-sync.injectable";
|
||||||
import type { GlobalOverride } from "../common/test-utils/get-global-override";
|
import type { GlobalOverride } from "../common/test-utils/get-global-override";
|
||||||
|
|
||||||
export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) {
|
export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) {
|
||||||
@ -177,6 +178,7 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {})
|
|||||||
readJsonFileInjectable,
|
readJsonFileInjectable,
|
||||||
readFileInjectable,
|
readFileInjectable,
|
||||||
execFileInjectable,
|
execFileInjectable,
|
||||||
|
readFileSyncInjectable,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// TODO: Remove usages of globally exported appEventBus to get rid of this
|
// TODO: Remove usages of globally exported appEventBus to get rid of this
|
||||||
|
|||||||
@ -3,8 +3,8 @@
|
|||||||
* 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 { MessageToChannel } from "../../../common/utils/channel/message-to-channel-injection-token";
|
||||||
import { messageToChannelInjectionToken } from "../../../common/utils/channel/message-to-channel-injection-token";
|
import { messageToChannelInjectionToken } from "../../../common/utils/channel/message-to-channel-injection-token";
|
||||||
import type { MessageChannel } from "../../../common/utils/channel/message-channel-injection-token";
|
|
||||||
import { tentativeStringifyJson } from "../../../common/utils/tentative-stringify-json";
|
import { tentativeStringifyJson } from "../../../common/utils/tentative-stringify-json";
|
||||||
import getVisibleWindowsInjectable from "../../start-main-application/lens-window/get-visible-windows.injectable";
|
import getVisibleWindowsInjectable from "../../start-main-application/lens-window/get-visible-windows.injectable";
|
||||||
|
|
||||||
@ -14,15 +14,13 @@ const messageToChannelInjectable = getInjectable({
|
|||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const getVisibleWindows = di.inject(getVisibleWindowsInjectable);
|
const getVisibleWindows = di.inject(getVisibleWindowsInjectable);
|
||||||
|
|
||||||
// TODO: Figure out way to improve typing in internals
|
return ((channel, message) => {
|
||||||
// Notice that this should be injected using "messageToChannelInjectionToken" which is typed correctly.
|
|
||||||
return (channel: MessageChannel<any>, message?: unknown) => {
|
|
||||||
const stringifiedMessage = tentativeStringifyJson(message);
|
const stringifiedMessage = tentativeStringifyJson(message);
|
||||||
|
|
||||||
getVisibleWindows().forEach((lensWindow) =>
|
getVisibleWindows().forEach((lensWindow) =>
|
||||||
lensWindow.send({ channel: channel.id, data: stringifiedMessage ? [stringifiedMessage] : [] }),
|
lensWindow.send({ channel: channel.id, data: stringifiedMessage ? [stringifiedMessage] : [] }),
|
||||||
);
|
);
|
||||||
};
|
}) as MessageToChannel;
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: messageToChannelInjectionToken,
|
injectionToken: messageToChannelInjectionToken,
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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 clusterConnectionStatusStateInjectable from "../components/cluster-manager/cluster-status.state.injectable";
|
||||||
|
import type { MessageChannelListener } from "../../common/utils/channel/message-channel-listener-injection-token";
|
||||||
|
import { messageChannelListenerInjectionToken } from "../../common/utils/channel/message-channel-listener-injection-token";
|
||||||
|
import type { ClusterConnectionUpdateChannel } from "../../common/cluster/connection-update-channel.injectable";
|
||||||
|
import clusterConnectionUpdateChannelInjectable from "../../common/cluster/connection-update-channel.injectable";
|
||||||
|
|
||||||
|
const clusterConnectionChannelListenerInjectable = getInjectable({
|
||||||
|
id: "cluster-connection-channel-listener",
|
||||||
|
instantiate: (di): MessageChannelListener<ClusterConnectionUpdateChannel> => {
|
||||||
|
const clusterConnectionUpdateChannel = di.inject(clusterConnectionUpdateChannelInjectable);
|
||||||
|
const state = di.inject(clusterConnectionStatusStateInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
channel: clusterConnectionUpdateChannel,
|
||||||
|
handler: ({ clusterId, update }) => {
|
||||||
|
const status = state.forCluster(clusterId);
|
||||||
|
|
||||||
|
status.appendAuthUpdate(update);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
injectionToken: messageChannelListenerInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default clusterConnectionChannelListenerInjectable;
|
||||||
23
src/renderer/cluster/request-activation.injectable.ts
Normal file
23
src/renderer/cluster/request-activation.injectable.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { ClusterActivationRequestChannel } from "../../common/cluster/request-activation.injectable";
|
||||||
|
import clusterActivationRequestChannelInjectable from "../../common/cluster/request-activation.injectable";
|
||||||
|
import type { RequestFromChannelImpl } from "../../common/utils/channel/request-from-channel-injection-token";
|
||||||
|
import requestFromChannelInjectable from "../utils/channel/request-from-channel.injectable";
|
||||||
|
|
||||||
|
export type RequestClusterActivation = RequestFromChannelImpl<ClusterActivationRequestChannel>;
|
||||||
|
|
||||||
|
const requestClusterActivationInjectable = getInjectable({
|
||||||
|
id: "request-cluster-activation",
|
||||||
|
instantiate: (di): RequestClusterActivation => {
|
||||||
|
const channel = di.inject(clusterActivationRequestChannelInjectable);
|
||||||
|
const requestFromChannel = di.inject(requestFromChannelInjectable);
|
||||||
|
|
||||||
|
return (clusterId) => requestFromChannel(channel, clusterId);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default requestClusterActivationInjectable;
|
||||||
@ -3,55 +3,53 @@
|
|||||||
* 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 { action, reaction } from "mobx";
|
import { action, computed, reaction } from "mobx";
|
||||||
import type { ClusterStore } from "../../../common/cluster-store/cluster-store";
|
import clustersInjectable from "../../../common/cluster-store/clusters.injectable";
|
||||||
import clusterStoreInjectable from "../../../common/cluster-store/cluster-store.injectable";
|
import type { ClusterId } from "../../../common/cluster-types";
|
||||||
import type { ClusterId, KubeAuthUpdate } from "../../../common/cluster-types";
|
import setupAppPathsInjectable from "../../app-paths/setup-app-paths.injectable";
|
||||||
import ipcRendererInjectable from "../../app-paths/get-value-from-registered-channel/ipc-renderer/ipc-renderer.injectable";
|
import { beforeFrameStartsInjectionToken } from "../../before-frame-starts/before-frame-starts-injection-token";
|
||||||
import type { ClusterConnectionStatusState } from "./cluster-status.state.injectable";
|
import clusterConnectionStatusStateInjectable from "./cluster-status.state.injectable";
|
||||||
|
|
||||||
function computeRisingEdgeForClusterDisconnect(store: ClusterStore, onNewlyDisconnected: (clusterId: ClusterId) => void) {
|
const startClusterStatusClearingInjectable = getInjectable({
|
||||||
const disconnectedStateComputer = () => store.clustersList.map(cluster => [cluster.id, cluster.disconnected] as const);
|
|
||||||
const state = new Map(disconnectedStateComputer());
|
|
||||||
|
|
||||||
reaction(
|
|
||||||
disconnectedStateComputer,
|
|
||||||
(disconnectedStates) => {
|
|
||||||
for (const [clusterId, isDisconnected] of disconnectedStates) {
|
|
||||||
if (state.get(clusterId) === isDisconnected) {
|
|
||||||
// do nothing
|
|
||||||
} else {
|
|
||||||
state.set(clusterId, isDisconnected); // save the new state
|
|
||||||
|
|
||||||
if (isDisconnected) {
|
|
||||||
// If the new value is `true` then the previous value was falsy and this is the rising edge.
|
|
||||||
onNewlyDisconnected(clusterId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This needs to be an `init` function to bypass a bug in the setup -> injectable -> setup path
|
|
||||||
const initClusterStatusWatcherInjectable = getInjectable({
|
|
||||||
id: "cluster-status-watcher",
|
id: "cluster-status-watcher",
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const ipcRenderer = di.inject(ipcRendererInjectable);
|
const statusState = di.inject(clusterConnectionStatusStateInjectable);
|
||||||
const clusterStore = di.inject(clusterStoreInjectable);
|
const state = new Map<string, boolean>();
|
||||||
|
const onNewlyDisconnected = action((clusterId: ClusterId) => {
|
||||||
|
const status = statusState.forCluster(clusterId);
|
||||||
|
|
||||||
return (state: ClusterConnectionStatusState) => {
|
status.clearReconnectingState();
|
||||||
ipcRenderer.on("cluster:connection-update", (evt, clusterId: ClusterId, update: KubeAuthUpdate) => {
|
status.resetAuthOutput();
|
||||||
state.forCluster(clusterId).appendAuthUpdate(update);
|
});
|
||||||
});
|
|
||||||
computeRisingEdgeForClusterDisconnect(clusterStore, action((clusterId) => {
|
|
||||||
const forCluster = state.forCluster(clusterId);
|
|
||||||
|
|
||||||
forCluster.clearReconnectingState();
|
return {
|
||||||
forCluster.resetAuthOutput();
|
run: () => {
|
||||||
}));
|
const clusters = di.inject(clustersInjectable); // This has to be in here so that it happens after the `setupAppPaths`
|
||||||
|
const disconnectedStates = computed(() => clusters.get().map(cluster => [cluster.id, cluster.disconnected] as const));
|
||||||
|
|
||||||
|
reaction(
|
||||||
|
() => disconnectedStates.get(),
|
||||||
|
states => {
|
||||||
|
for (const [clusterId, isDisconnected] of states) {
|
||||||
|
if (state.get(clusterId) !== isDisconnected) {
|
||||||
|
state.set(clusterId, isDisconnected); // save the new state
|
||||||
|
|
||||||
|
if (isDisconnected) {
|
||||||
|
// If the new value is `true` then the previous value was falsy and this is the rising edge.
|
||||||
|
onNewlyDisconnected(clusterId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fireImmediately: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
runAfter: di.inject(setupAppPathsInjectable),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
injectionToken: beforeFrameStartsInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default initClusterStatusWatcherInjectable;
|
export default startClusterStatusClearingInjectable;
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import { action, computed, observable } from "mobx";
|
|||||||
import type { ClusterId, KubeAuthUpdate } from "../../../common/cluster-types";
|
import type { ClusterId, KubeAuthUpdate } from "../../../common/cluster-types";
|
||||||
import loggerInjectable from "../../../common/logger.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
import { getOrInsert, hasTypedProperty, isBoolean, isObject, isString } from "../../utils";
|
import { getOrInsert, hasTypedProperty, isBoolean, isObject, isString } from "../../utils";
|
||||||
import initClusterStatusWatcherInjectable from "./cluster-status-watcher.injectable";
|
|
||||||
|
|
||||||
export interface ClusterConnectionStatus {
|
export interface ClusterConnectionStatus {
|
||||||
readonly authOutput: IComputedValue<KubeAuthUpdate[]>;
|
readonly authOutput: IComputedValue<KubeAuthUpdate[]>;
|
||||||
@ -21,18 +20,17 @@ export interface ClusterConnectionStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ClusterConnectionStatusState {
|
export interface ClusterConnectionStatusState {
|
||||||
forCluster(clusterId: ClusterId): Readonly<ClusterConnectionStatus>;
|
forCluster(clusterId: ClusterId): ClusterConnectionStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
const clusterConnectionStatusStateInjectable = getInjectable({
|
const clusterConnectionStatusStateInjectable = getInjectable({
|
||||||
id: "cluster-connection-status-state",
|
id: "cluster-connection-status-state",
|
||||||
instantiate: (di) => {
|
instantiate: (di): ClusterConnectionStatusState => {
|
||||||
const authOutputs = observable.map<ClusterId, KubeAuthUpdate[]>();
|
const authOutputs = observable.map<ClusterId, KubeAuthUpdate[]>();
|
||||||
const reconnecting = observable.set<ClusterId>();
|
const reconnecting = observable.set<ClusterId>();
|
||||||
const initWatcher = di.inject(initClusterStatusWatcherInjectable);
|
|
||||||
const logger = di.inject(loggerInjectable);
|
const logger = di.inject(loggerInjectable);
|
||||||
|
|
||||||
const state: ClusterConnectionStatusState = {
|
return {
|
||||||
forCluster: (clusterId) => {
|
forCluster: (clusterId) => {
|
||||||
const authOutput = computed(() => authOutputs.get(clusterId) ?? []);
|
const authOutput = computed(() => authOutputs.get(clusterId) ?? []);
|
||||||
|
|
||||||
@ -63,10 +61,6 @@ const clusterConnectionStatusStateInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
initWatcher(state);
|
|
||||||
|
|
||||||
return state;
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -15,13 +15,14 @@ import { Button } from "../button";
|
|||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { Spinner } from "../spinner";
|
import { Spinner } from "../spinner";
|
||||||
import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry";
|
import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry";
|
||||||
import { requestClusterActivation } from "../../ipc";
|
|
||||||
import type { NavigateToEntitySettings } from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
|
import type { NavigateToEntitySettings } from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import navigateToEntitySettingsInjectable from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
|
import navigateToEntitySettingsInjectable from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
|
||||||
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";
|
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";
|
||||||
import type { ClusterConnectionStatus } from "./cluster-status.state.injectable";
|
import type { ClusterConnectionStatus } from "./cluster-status.state.injectable";
|
||||||
import clusterConnectionStatusStateInjectable from "./cluster-status.state.injectable";
|
import clusterConnectionStatusStateInjectable from "./cluster-status.state.injectable";
|
||||||
|
import type { RequestClusterActivation } from "../../cluster/request-activation.injectable";
|
||||||
|
import requestClusterActivationInjectable from "../../cluster/request-activation.injectable";
|
||||||
|
|
||||||
export interface ClusterStatusProps {
|
export interface ClusterStatusProps {
|
||||||
className?: IClassName;
|
className?: IClassName;
|
||||||
@ -32,6 +33,7 @@ interface Dependencies {
|
|||||||
navigateToEntitySettings: NavigateToEntitySettings;
|
navigateToEntitySettings: NavigateToEntitySettings;
|
||||||
entityRegistry: CatalogEntityRegistry;
|
entityRegistry: CatalogEntityRegistry;
|
||||||
state: ClusterConnectionStatus;
|
state: ClusterConnectionStatus;
|
||||||
|
requestClusterActivation: RequestClusterActivation;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NonInjectedClusterStatus = observer((props: ClusterStatusProps & Dependencies) => {
|
const NonInjectedClusterStatus = observer((props: ClusterStatusProps & Dependencies) => {
|
||||||
@ -41,6 +43,7 @@ const NonInjectedClusterStatus = observer((props: ClusterStatusProps & Dependenc
|
|||||||
state,
|
state,
|
||||||
className,
|
className,
|
||||||
entityRegistry,
|
entityRegistry,
|
||||||
|
requestClusterActivation,
|
||||||
} = props;
|
} = props;
|
||||||
const entity = entityRegistry.getById(cluster.id);
|
const entity = entityRegistry.getById(cluster.id);
|
||||||
const clusterName = entity?.getName() ?? cluster.name;
|
const clusterName = entity?.getName() ?? cluster.name;
|
||||||
@ -52,7 +55,10 @@ const NonInjectedClusterStatus = observer((props: ClusterStatusProps & Dependenc
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await requestClusterActivation(cluster.id, true);
|
await requestClusterActivation({
|
||||||
|
clusterId: cluster.id,
|
||||||
|
force: true,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
state.appendAuthUpdate({
|
state.appendAuthUpdate({
|
||||||
message: String(error),
|
message: String(error),
|
||||||
@ -141,5 +147,6 @@ export const ClusterStatus = withInjectables<Dependencies, ClusterStatusProps>(N
|
|||||||
navigateToEntitySettings: di.inject(navigateToEntitySettingsInjectable),
|
navigateToEntitySettings: di.inject(navigateToEntitySettingsInjectable),
|
||||||
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||||
state: di.inject(clusterConnectionStatusStateInjectable).forCluster(props.cluster.id),
|
state: di.inject(clusterConnectionStatusStateInjectable).forCluster(props.cluster.id),
|
||||||
|
requestClusterActivation: di.inject(requestClusterActivationInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import { ClusterStatus } from "./cluster-status";
|
|||||||
import type { ClusterFrameHandler } from "./cluster-frame-handler";
|
import type { ClusterFrameHandler } from "./cluster-frame-handler";
|
||||||
import type { Cluster } from "../../../common/cluster/cluster";
|
import type { Cluster } from "../../../common/cluster/cluster";
|
||||||
import type { ClusterStore } from "../../../common/cluster-store/cluster-store";
|
import type { ClusterStore } from "../../../common/cluster-store/cluster-store";
|
||||||
import { requestClusterActivation } from "../../ipc";
|
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
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";
|
||||||
@ -25,6 +24,8 @@ import clusterConnectionStatusStateInjectable from "./cluster-status.state.injec
|
|||||||
import clusterStoreInjectable from "../../../common/cluster-store/cluster-store.injectable";
|
import clusterStoreInjectable from "../../../common/cluster-store/cluster-store.injectable";
|
||||||
import type { Disposer } from "../../utils";
|
import type { Disposer } from "../../utils";
|
||||||
import { disposer } from "../../utils";
|
import { disposer } from "../../utils";
|
||||||
|
import type { RequestClusterActivation } from "../../cluster/request-activation.injectable";
|
||||||
|
import requestClusterActivationInjectable from "../../cluster/request-activation.injectable";
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
clusterId: IComputedValue<string | undefined>;
|
clusterId: IComputedValue<string | undefined>;
|
||||||
@ -33,6 +34,7 @@ interface Dependencies {
|
|||||||
entityRegistry: CatalogEntityRegistry;
|
entityRegistry: CatalogEntityRegistry;
|
||||||
clusterConnectionStatusState: ClusterConnectionStatusState;
|
clusterConnectionStatusState: ClusterConnectionStatusState;
|
||||||
clusterStore: ClusterStore;
|
clusterStore: ClusterStore;
|
||||||
|
requestClusterActivation: RequestClusterActivation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
@ -104,7 +106,10 @@ class NonInjectedClusterView extends React.Component<Dependencies> {
|
|||||||
|
|
||||||
this.props.clusterFrames.setVisibleCluster(clusterId);
|
this.props.clusterFrames.setVisibleCluster(clusterId);
|
||||||
this.props.clusterFrames.initView(clusterId);
|
this.props.clusterFrames.initView(clusterId);
|
||||||
requestClusterActivation(clusterId, false); // activate and fetch cluster's state from main
|
this.props.requestClusterActivation({
|
||||||
|
clusterId,
|
||||||
|
force: false,
|
||||||
|
});
|
||||||
this.props.entityRegistry.activeEntity = clusterId;
|
this.props.entityRegistry.activeEntity = clusterId;
|
||||||
|
|
||||||
const navigateToClusterDisposer = disposer(
|
const navigateToClusterDisposer = disposer(
|
||||||
@ -160,6 +165,7 @@ export const ClusterView = withInjectables<Dependencies>(NonInjectedClusterView,
|
|||||||
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||||
clusterConnectionStatusState: di.inject(clusterConnectionStatusStateInjectable),
|
clusterConnectionStatusState: di.inject(clusterConnectionStatusStateInjectable),
|
||||||
clusterStore: di.inject(clusterStoreInjectable),
|
clusterStore: di.inject(clusterStoreInjectable),
|
||||||
|
requestClusterActivation: di.inject(requestClusterActivationInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -143,8 +143,6 @@ export const getApplicationBuilder = () => {
|
|||||||
doGeneralOverrides: true,
|
doGeneralOverrides: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
mainDi.register(mainExtensionsStateInjectable);
|
|
||||||
|
|
||||||
const overrideChannelsForWindow = overrideChannels(mainDi);
|
const overrideChannelsForWindow = overrideChannels(mainDi);
|
||||||
|
|
||||||
const beforeApplicationStartCallbacks: Callback[] = [];
|
const beforeApplicationStartCallbacks: Callback[] = [];
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { Cluster } from "../../common/cluster/cluster";
|
|||||||
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 { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
|
import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
|
||||||
import loggerInjectable from "../../common/logger.injectable";
|
import loggerInjectable from "../../common/logger.injectable";
|
||||||
|
import readFileSyncInjectable from "../../common/fs/read-file-sync.injectable";
|
||||||
|
|
||||||
const createClusterInjectable = getInjectable({
|
const createClusterInjectable = getInjectable({
|
||||||
id: "create-cluster",
|
id: "create-cluster",
|
||||||
@ -16,6 +17,7 @@ const createClusterInjectable = getInjectable({
|
|||||||
const dependencies: ClusterDependencies = {
|
const dependencies: ClusterDependencies = {
|
||||||
directoryForKubeConfigs: di.inject(directoryForKubeConfigsInjectable),
|
directoryForKubeConfigs: di.inject(directoryForKubeConfigsInjectable),
|
||||||
logger: di.inject(loggerInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
|
readFileSync: di.inject(readFileSyncInjectable),
|
||||||
|
|
||||||
// TODO: Dismantle wrong abstraction
|
// TODO: Dismantle wrong abstraction
|
||||||
// Note: "as never" to get around strictness in unnatural scenario
|
// Note: "as never" to get around strictness in unnatural scenario
|
||||||
@ -26,6 +28,7 @@ const createClusterInjectable = getInjectable({
|
|||||||
createListNamespaces: () => { throw new Error("Tried to access back-end feature in front-end."); },
|
createListNamespaces: () => { throw new Error("Tried to access back-end feature in front-end."); },
|
||||||
detectorRegistry: undefined as never,
|
detectorRegistry: undefined as never,
|
||||||
createVersionDetector: () => { throw new Error("Tried to access back-end feature in front-end."); },
|
createVersionDetector: () => { throw new Error("Tried to access back-end feature in front-end."); },
|
||||||
|
emitClusterConnectionUpdate: () => { throw new Error("Tried to access back-end feature in front-end."); },
|
||||||
};
|
};
|
||||||
|
|
||||||
return (model, configData) => new Cluster(dependencies, model, configData);
|
return (model, configData) => new Cluster(dependencies, model, configData);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import type { OpenDialogOptions } from "electron";
|
import type { OpenDialogOptions } from "electron";
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron";
|
||||||
import { clusterActivateHandler, clusterClearDeletingHandler, clusterDeleteHandler, clusterDisconnectHandler, clusterKubectlApplyAllHandler, clusterKubectlDeleteAllHandler, clusterSetDeletingHandler, clusterSetFrameIdHandler, clusterStates } from "../../common/ipc/cluster";
|
import { clusterClearDeletingHandler, clusterDeleteHandler, clusterDisconnectHandler, clusterKubectlApplyAllHandler, clusterKubectlDeleteAllHandler, clusterSetDeletingHandler, clusterSetFrameIdHandler, clusterStates } from "../../common/ipc/cluster";
|
||||||
import type { ClusterId, ClusterState } from "../../common/cluster-types";
|
import type { ClusterId, ClusterState } from "../../common/cluster-types";
|
||||||
import { windowActionHandleChannel, windowLocationChangedChannel, windowOpenAppMenuAsContextMenuChannel, type WindowAction } from "../../common/ipc/window";
|
import { windowActionHandleChannel, windowLocationChangedChannel, windowOpenAppMenuAsContextMenuChannel, type WindowAction } from "../../common/ipc/window";
|
||||||
import { openFilePickingDialogChannel } from "../../common/ipc/dialog";
|
import { openFilePickingDialogChannel } from "../../common/ipc/dialog";
|
||||||
@ -43,10 +43,6 @@ export function requestSetClusterFrameId(clusterId: ClusterId): Promise<void> {
|
|||||||
return requestMain(clusterSetFrameIdHandler, clusterId);
|
return requestMain(clusterSetFrameIdHandler, clusterId);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestClusterActivation(clusterId: ClusterId, force?: boolean): Promise<void> {
|
|
||||||
return requestMain(clusterActivateHandler, clusterId, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function requestClusterDisconnection(clusterId: ClusterId, force?: boolean): Promise<void> {
|
export function requestClusterDisconnection(clusterId: ClusterId, force?: boolean): Promise<void> {
|
||||||
return requestMain(clusterDisconnectHandler, clusterId, force);
|
return requestMain(clusterDisconnectHandler, clusterId, force);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,9 +24,11 @@ const enlistMessageChannelListenerInjectable = getInjectable({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.debug(`[IPC]: listening on ${channel.id}`);
|
||||||
ipcRenderer.on(channel.id, nativeCallback);
|
ipcRenderer.on(channel.id, nativeCallback);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
console.debug(`[IPC]: listenering off ${channel.id}`);
|
||||||
ipcRenderer.off(channel.id, nativeCallback);
|
ipcRenderer.off(channel.id, nativeCallback);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user