mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
added common/ipc-helpers
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
17cd886ce6
commit
bde60b1625
@ -179,6 +179,7 @@
|
|||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
"handlebars": "^4.7.6",
|
"handlebars": "^4.7.6",
|
||||||
"http-proxy": "^1.18.1",
|
"http-proxy": "^1.18.1",
|
||||||
|
"immer": "^7.0.5",
|
||||||
"js-yaml": "^3.14.0",
|
"js-yaml": "^3.14.0",
|
||||||
"jsonpath": "^1.0.2",
|
"jsonpath": "^1.0.2",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import path from "path"
|
import path from "path"
|
||||||
import Config from "conf"
|
import Config from "conf"
|
||||||
import { Options as ConfOptions } from "conf/dist/source/types"
|
import { Options as ConfOptions } from "conf/dist/source/types"
|
||||||
|
import produce from "immer";
|
||||||
import { app, remote } from "electron"
|
import { app, remote } from "electron"
|
||||||
import { observable, reaction, toJS, when } from "mobx";
|
import { observable, reaction, toJS, when } from "mobx";
|
||||||
import Singleton from "./utils/singleton";
|
import Singleton from "./utils/singleton";
|
||||||
@ -115,6 +116,10 @@ export class BaseStore<T = any> extends Singleton {
|
|||||||
Object.assign(this.data, data);
|
Object.assign(this.data, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
merge(updater: (modelDraft: T) => void) {
|
||||||
|
this.data = produce(this.data, updater);
|
||||||
|
}
|
||||||
|
|
||||||
toJSON(): T {
|
toJSON(): T {
|
||||||
return toJS(this.data, {
|
return toJS(this.data, {
|
||||||
recurseEverything: true,
|
recurseEverything: true,
|
||||||
|
|||||||
39
src/common/ipc-helpers.ts
Normal file
39
src/common/ipc-helpers.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Inter-protocol communications (main <-> renderer)
|
||||||
|
// https://www.electronjs.org/docs/api/ipc-main
|
||||||
|
// https://www.electronjs.org/docs/api/ipc-renderer
|
||||||
|
|
||||||
|
import { ipcMain, ipcRenderer } from "electron"
|
||||||
|
import logger from "../main/logger";
|
||||||
|
|
||||||
|
export interface IpcOptions {
|
||||||
|
timeout?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function sendMessage(channel: string, ...args: any[]) {
|
||||||
|
logger.debug(`[IPC]: invoke "${channel}" with arguments`, args);
|
||||||
|
return ipcRenderer.invoke(channel, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: maybe spawn callback in separate thread/worker
|
||||||
|
export function onMessage<T = any>(channel: string, callback: (...args: any[]) => T, options: IpcOptions = {}) {
|
||||||
|
const { timeout = 0 } = options;
|
||||||
|
ipcMain.handle(channel, async (event, ...args: any[]) => {
|
||||||
|
logger.debug(`[IPC]: handle "${channel}"`, event, args);
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
let timerId;
|
||||||
|
if (timeout) {
|
||||||
|
timerId = setTimeout(() => {
|
||||||
|
const timeoutError = new Error("[IPC]: response timeout");
|
||||||
|
reject(timeoutError);
|
||||||
|
}, timeout);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const result = await callback(...args);
|
||||||
|
clearTimeout(timerId);
|
||||||
|
return result;
|
||||||
|
} catch (err) {
|
||||||
|
logger.debug(`[IPC]: handling "${channel}" error`, err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -2,6 +2,8 @@ import { app, remote } from "electron"
|
|||||||
import { ensureDirSync, writeFileSync } from "fs-extra"
|
import { ensureDirSync, writeFileSync } from "fs-extra"
|
||||||
import * as path from "path"
|
import * as path from "path"
|
||||||
|
|
||||||
|
// todo: move to main/kubeconfig-manager.ts (?)
|
||||||
|
|
||||||
// Writes kubeconfigs to "embedded" store, i.e. .../Lens/kubeconfigs/
|
// Writes kubeconfigs to "embedded" store, i.e. .../Lens/kubeconfigs/
|
||||||
export function writeEmbeddedKubeConfig(clusterId: string, kubeConfig: string): string {
|
export function writeEmbeddedKubeConfig(clusterId: string, kubeConfig: string): string {
|
||||||
// This can be called from main & renderer
|
// This can be called from main & renderer
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { AuthorizationV1Api, CoreV1Api, KubeConfig, V1ResourceAttributes } from
|
|||||||
import * as fm from "./feature-manager";
|
import * as fm from "./feature-manager";
|
||||||
import { Kubectl } from "./kubectl";
|
import { Kubectl } from "./kubectl";
|
||||||
import { KubeconfigManager } from "./kubeconfig-manager"
|
import { KubeconfigManager } from "./kubeconfig-manager"
|
||||||
import { PromiseIpc } from "electron-promise-ipc"
|
|
||||||
import request from "request-promise-native"
|
import request from "request-promise-native"
|
||||||
import { apiPrefix } from "../common/vars";
|
import { apiPrefix } from "../common/vars";
|
||||||
import type { ClusterInfo } from "../renderer/_vue/store/modules/clusters";
|
import type { ClusterInfo } from "../renderer/_vue/store/modules/clusters";
|
||||||
@ -40,12 +39,10 @@ export class Cluster implements ClusterModel {
|
|||||||
public preferences: ClusterPreferences;
|
public preferences: ClusterPreferences;
|
||||||
|
|
||||||
protected eventPoller: NodeJS.Timeout;
|
protected eventPoller: NodeJS.Timeout;
|
||||||
protected promiseIpc = new PromiseIpc({ timeout: 2000 })
|
|
||||||
|
|
||||||
protected kubeconfigManager: KubeconfigManager;
|
protected kubeconfigManager: KubeconfigManager;
|
||||||
|
|
||||||
constructor(jsonModel: ClusterModel) {
|
constructor(model: ClusterModel) {
|
||||||
if (jsonModel) Object.assign(this, jsonModel)
|
if (model) Object.assign(this, model)
|
||||||
if (!this.preferences) this.preferences = {}
|
if (!this.preferences) this.preferences = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +61,6 @@ export class Cluster implements ClusterModel {
|
|||||||
this.contextHandler = new ContextHandler(kc, this)
|
this.contextHandler = new ContextHandler(kc, this)
|
||||||
await this.contextHandler.init() // So we get the proxy port reserved
|
await this.contextHandler.init() // So we get the proxy port reserved
|
||||||
this.kubeconfigManager = new KubeconfigManager(this)
|
this.kubeconfigManager = new KubeconfigManager(this)
|
||||||
|
|
||||||
this.url = this.contextHandler.url
|
this.url = this.contextHandler.url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { CoreV1Api, KubeConfig } from "@kubernetes/client-node"
|
import { CoreV1Api, KubeConfig } from "@kubernetes/client-node"
|
||||||
import http from "http"
|
|
||||||
import { ServerOptions } from "http-proxy"
|
import { ServerOptions } from "http-proxy"
|
||||||
import * as url from "url"
|
import * as url from "url"
|
||||||
import logger from "./logger"
|
import logger from "./logger"
|
||||||
@ -7,20 +6,20 @@ import { getFreePort } from "./port"
|
|||||||
import { KubeAuthProxy } from "./kube-auth-proxy"
|
import { KubeAuthProxy } from "./kube-auth-proxy"
|
||||||
import { Cluster } from "./cluster"
|
import { Cluster } from "./cluster"
|
||||||
import { prometheusProviders } from "../common/prometheus-providers"
|
import { prometheusProviders } from "../common/prometheus-providers"
|
||||||
import type { PrometheusService, PrometheusProvider } from "./prometheus/provider-registry"
|
import type { PrometheusProvider, PrometheusService } from "./prometheus/provider-registry"
|
||||||
import type { ClusterPreferences } from "../common/cluster-store";
|
import type { ClusterPreferences } from "../common/cluster-store";
|
||||||
|
|
||||||
export class ContextHandler {
|
export class ContextHandler {
|
||||||
public contextName: string
|
|
||||||
public id: string
|
|
||||||
public url: string
|
public url: string
|
||||||
public clusterUrl: url.UrlWithStringQuery
|
|
||||||
public proxyServer: KubeAuthProxy
|
|
||||||
public proxyPort: number
|
public proxyPort: number
|
||||||
public certData: string
|
public contextName: string
|
||||||
public authCertData: string
|
|
||||||
public cluster: Cluster
|
|
||||||
|
|
||||||
|
protected id: string
|
||||||
|
protected clusterUrl: url.UrlWithStringQuery
|
||||||
|
protected proxyServer: KubeAuthProxy
|
||||||
|
protected certData: string
|
||||||
|
protected authCertData: string
|
||||||
|
protected cluster: Cluster
|
||||||
protected apiTarget: ServerOptions
|
protected apiTarget: ServerOptions
|
||||||
protected proxyTarget: ServerOptions
|
protected proxyTarget: ServerOptions
|
||||||
protected clientCert: string
|
protected clientCert: string
|
||||||
@ -34,7 +33,6 @@ export class ContextHandler {
|
|||||||
|
|
||||||
constructor(kc: KubeConfig, cluster: Cluster) {
|
constructor(kc: KubeConfig, cluster: Cluster) {
|
||||||
this.id = cluster.id
|
this.id = cluster.id
|
||||||
|
|
||||||
this.cluster = cluster
|
this.cluster = cluster
|
||||||
this.clusterUrl = url.parse(cluster.apiUrl)
|
this.clusterUrl = url.parse(cluster.apiUrl)
|
||||||
this.contextName = cluster.contextName;
|
this.contextName = cluster.contextName;
|
||||||
@ -49,26 +47,19 @@ export class ContextHandler {
|
|||||||
await this.resolveProxyPort()
|
await this.resolveProxyPort()
|
||||||
}
|
}
|
||||||
|
|
||||||
public setClusterPreferences(clusterPreferences?: ClusterPreferences) {
|
public setClusterPreferences(preferences?: ClusterPreferences) {
|
||||||
this.prometheusProvider = clusterPreferences.prometheusProvider?.type
|
this.clusterName = preferences?.clusterName || this.contextName;
|
||||||
|
this.prometheusProvider = preferences.prometheusProvider?.type;
|
||||||
|
this.prometheusPath = null;
|
||||||
|
|
||||||
if (clusterPreferences && clusterPreferences.prometheus) {
|
if (preferences?.prometheus) {
|
||||||
const prom = clusterPreferences.prometheus
|
const { namespace, service, port } = preferences.prometheus
|
||||||
this.prometheusPath = `${prom.namespace}/services/${prom.service}:${prom.port}`
|
this.prometheusPath = `${namespace}/services/${service}:${port}`
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.prometheusPath = null
|
|
||||||
}
|
|
||||||
if (clusterPreferences && clusterPreferences.clusterName) {
|
|
||||||
this.clusterName = clusterPreferences.clusterName;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.clusterName = this.contextName;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async resolvePrometheusPath(): Promise<string> {
|
protected async resolvePrometheusPath(): Promise<string> {
|
||||||
const {service, namespace, port} = await this.getPrometheusService()
|
const { service, namespace, port } = await this.getPrometheusService()
|
||||||
return `${namespace}/services/${service}:${port}`
|
return `${namespace}/services/${service}:${port}`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,8 +82,7 @@ export class ContextHandler {
|
|||||||
const service = resolvedPrometheusServices.filter(n => n)[0]
|
const service = resolvedPrometheusServices.filter(n => n)[0]
|
||||||
if (service) {
|
if (service) {
|
||||||
return service
|
return service
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return {
|
return {
|
||||||
id: "lens",
|
id: "lens",
|
||||||
namespace: "lens-metrics",
|
namespace: "lens-metrics",
|
||||||
@ -103,11 +93,10 @@ export class ContextHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async getPrometheusPath(): Promise<string> {
|
public async getPrometheusPath(): Promise<string> {
|
||||||
if (this.prometheusPath) return this.prometheusPath
|
if (!this.prometheusPath) {
|
||||||
|
this.prometheusPath = await this.resolvePrometheusPath()
|
||||||
this.prometheusPath = await this.resolvePrometheusPath()
|
}
|
||||||
|
return this.prometheusPath;
|
||||||
return this.prometheusPath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getApiTarget(isWatchRequest = false): Promise<ServerOptions> {
|
public async getApiTarget(isWatchRequest = false): Promise<ServerOptions> {
|
||||||
@ -139,18 +128,15 @@ export class ContextHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async resolveProxyPort(): Promise<number> {
|
protected async resolveProxyPort(): Promise<number> {
|
||||||
if (this.proxyPort) return this.proxyPort
|
if (!this.proxyPort) {
|
||||||
|
try {
|
||||||
let serverPort: number = null
|
this.proxyPort = await getFreePort()
|
||||||
try {
|
} catch (error) {
|
||||||
serverPort = await getFreePort()
|
logger.error(error)
|
||||||
} catch (error) {
|
throw(error)
|
||||||
logger.error(error)
|
}
|
||||||
throw(error)
|
|
||||||
}
|
}
|
||||||
this.proxyPort = serverPort
|
return this.proxyPort
|
||||||
|
|
||||||
return serverPort
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async withTemporaryKubeconfig(callback: (kubeconfig: string) => Promise<any>) {
|
public async withTemporaryKubeconfig(callback: (kubeconfig: string) => Promise<any>) {
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ClustersMixin from "@/_vue/mixins/ClustersMixin";
|
import ClustersMixin from "@/_vue/mixins/ClustersMixin";
|
||||||
import { newContexts } from '@kubernetes/client-node/dist/config_types';
|
|
||||||
export default {
|
export default {
|
||||||
name: "AddClusterMenuItem",
|
name: "AddClusterMenuItem",
|
||||||
mixins: [ClustersMixin],
|
mixins: [ClustersMixin],
|
||||||
@ -43,7 +42,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
console.log(this.newContexts.length)
|
|
||||||
this.$store.dispatch("reloadAvailableKubeContexts");
|
this.$store.dispatch("reloadAvailableKubeContexts");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6186,6 +6186,11 @@ ignore@^4.0.6:
|
|||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
||||||
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
|
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
|
||||||
|
|
||||||
|
immer@^7.0.5:
|
||||||
|
version "7.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/immer/-/immer-7.0.5.tgz#8af347db5b60b40af8ae7baf1784ea4d35b5208e"
|
||||||
|
integrity sha512-TtRAKZyuqld2eYjvWgXISLJ0ZlOl1OOTzRmrmiY8SlB0dnAhZ1OiykIDL5KDFNaPHDXiLfGQFNJGtet8z8AEmg==
|
||||||
|
|
||||||
import-fresh@^3.0.0, import-fresh@^3.1.0:
|
import-fresh@^3.0.0, import-fresh@^3.1.0:
|
||||||
version "3.2.1"
|
version "3.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
|
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user