From 25e904d2d5ca49b6641a052ae879fba6f3ad08da Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 10 Jul 2020 02:22:53 +0300 Subject: [PATCH] night insomnia clean-up, part 2 Signed-off-by: Roman --- src/common/ipc-messages.ts | 1 - src/main/cluster-manager.ts | 8 +++----- src/main/cluster.ts | 21 ++++++++++++--------- src/main/context-handler.ts | 22 +++++++++------------- src/main/kubeconfig-manager.ts | 16 +++++++--------- src/main/routes/metrics-route.ts | 2 +- 6 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/common/ipc-messages.ts b/src/common/ipc-messages.ts index e4e1cf78be..856a4539bb 100644 --- a/src/common/ipc-messages.ts +++ b/src/common/ipc-messages.ts @@ -3,7 +3,6 @@ export enum ClusterIpcMessage { CLUSTER_ADD = "cluster-add", CLUSTER_STOP = "cluster-stop", - CLUSTER_REFRESH = "cluster-refresh", CLUSTER_REMOVE = "cluster-remove", CLUSTER_REMOVE_WORKSPACE = "cluster-remove-all-from-workspace", CLUSTER_EVENTS = "cluster-events-count", diff --git a/src/main/cluster-manager.ts b/src/main/cluster-manager.ts index 9871201a58..b49715714e 100644 --- a/src/main/cluster-manager.ts +++ b/src/main/cluster-manager.ts @@ -26,6 +26,7 @@ export class ClusterManager { } constructor(protected port: number) { + // init clusters reaction(() => clusterStore.clusters.toJS(), clusters => { clusters.forEach(cluster => { if (!cluster.initialized) { @@ -33,12 +34,14 @@ export class ClusterManager { } }) }); + // destroy clusters reaction(() => clusterStore.removedClusters.toJS(), removedClusters => { if (removedClusters.size > 0) { removedClusters.forEach(cluster => cluster.stopServer()); clusterStore.removedClusters.clear(); } }); + // listen ipc-events ClusterManager.ipcListen(this); } @@ -148,10 +151,6 @@ export class ClusterManager { return this.getCluster(clusterId)?.uninstallFeature(name); } - protected async refreshCluster(clusterId: ClusterId) { - await this.getCluster(clusterId)?.refreshCluster(); - } - protected async getEventsCount(clusterId: ClusterId): Promise { return await this.getCluster(clusterId)?.getEventCount() || 0; } @@ -162,7 +161,6 @@ export class ClusterManager { [ClusterIpcMessage.CLUSTER_STOP]: clusterManager.stopCluster, [ClusterIpcMessage.CLUSTER_REMOVE]: clusterManager.removeCluster, [ClusterIpcMessage.CLUSTER_REMOVE_WORKSPACE]: clusterManager.removeAllByWorkspace, - [ClusterIpcMessage.CLUSTER_REFRESH]: clusterManager.refreshCluster, [ClusterIpcMessage.CLUSTER_EVENTS]: clusterManager.getEventsCount, [ClusterIpcMessage.FEATURE_INSTALL]: clusterManager.installFeature, [ClusterIpcMessage.FEATURE_UPGRADE]: clusterManager.upgradeFeature, diff --git a/src/main/cluster.ts b/src/main/cluster.ts index 9bfaf51ce6..8368e2fd31 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -1,4 +1,4 @@ -import url from "url" +import url, { UrlWithStringQuery } from "url" import type { ClusterId, ClusterModel, ClusterPreferences } from "../common/cluster-store" import type { FeatureStatusMap } from "./feature" import { computed, observable, toJS } from "mobx"; @@ -33,8 +33,8 @@ export interface ClusterState extends ClusterModel { } export class Cluster implements ClusterModel { - public contextHandler: ContextHandler; public kubeCtl: Kubectl + public contextHandler: ContextHandler; protected kubeconfigManager: KubeconfigManager; @observable initialized = false; @@ -63,20 +63,21 @@ export class Cluster implements ClusterModel { Object.assign(this, model) } - @computed get apiUrl() { - return url.parse(`http://${this.id}.localhost:${this.port}`) + // todo: use only api proxy url? + @computed get apiUrl(): UrlWithStringQuery { + return url.parse(`http://${this.id}.localhost:${this.port}`); } - @computed get apiServerUrl() { - return url.parse(`http://127.0.0.1:${this.port}${apiPrefix.KUBE_BASE}`) + @computed get apiProxyUrl(): string { + return `http://127.0.0.1:${this.port}${apiPrefix.KUBE_BASE}`; } async init(port: number) { try { this.port = port; this.contextHandler = new ContextHandler(this); - await this.contextHandler.init() // So we get the proxy port reserved - this.kubeconfigManager = new KubeconfigManager(this) + const proxyPort = await this.contextHandler.resolveProxyPort(); + this.kubeconfigManager = new KubeconfigManager(this, proxyPort); this.url = this.contextHandler.url this.initialized = true; logger.debug(`[CLUSTER]: init done (id="${this.id}", context="${this.contextName}")`); @@ -88,6 +89,7 @@ export class Cluster implements ClusterModel { } } + // todo: auto-refresh when preferences changed? async refreshCluster() { this.contextHandler.setClusterPreferences(this.preferences) @@ -140,7 +142,7 @@ export class Cluster implements ClusterModel { } k8sRequest(path: string, options: RequestPromiseOptions = {}) { - return request(this.apiServerUrl + path, { + return request(this.apiProxyUrl + path, { json: true, timeout: 10000, headers: { @@ -272,6 +274,7 @@ export class Cluster implements ClusterModel { }) } + // todo: use for push-updates to lens view getState(): ClusterState { const storeModel = this.toJSON(); return toJS({ diff --git a/src/main/context-handler.ts b/src/main/context-handler.ts index f4c14cf125..d34b314060 100644 --- a/src/main/context-handler.ts +++ b/src/main/context-handler.ts @@ -1,12 +1,12 @@ +import type { PrometheusProvider, PrometheusService } from "./prometheus/provider-registry" +import type { ClusterPreferences } from "../common/cluster-store"; +import type { ServerOptions } from "http-proxy" +import type { Cluster } from "./cluster" import { CoreV1Api } from "@kubernetes/client-node" -import { ServerOptions } from "http-proxy" +import { prometheusProviders } from "../common/prometheus-providers" import logger from "./logger" import { getFreePort } from "./port" import { KubeAuthProxy } from "./kube-auth-proxy" -import { Cluster } from "./cluster" -import { prometheusProviders } from "../common/prometheus-providers" -import type { PrometheusProvider, PrometheusService } from "./prometheus/provider-registry" -import type { ClusterPreferences } from "../common/cluster-store"; export class ContextHandler { public url: string @@ -32,16 +32,12 @@ export class ContextHandler { this.setClusterPreferences(cluster.preferences) } - public async init() { - await this.resolveProxyPort() - } - - public setClusterPreferences(preferences?: ClusterPreferences) { - this.clusterName = preferences?.clusterName || this.contextName; + public setClusterPreferences(preferences: ClusterPreferences = {}) { + this.clusterName = preferences.clusterName || this.contextName; this.prometheusProvider = preferences.prometheusProvider?.type; this.prometheusPath = null; - if (preferences?.prometheus) { + if (preferences.prometheus) { const { namespace, service, port } = preferences.prometheus this.prometheusPath = `${namespace}/services/${service}:${port}` } @@ -113,7 +109,7 @@ export class ContextHandler { } } - protected async resolveProxyPort(): Promise { + async resolveProxyPort(): Promise { if (!this.proxyPort) { try { this.proxyPort = await getFreePort() diff --git a/src/main/kubeconfig-manager.ts b/src/main/kubeconfig-manager.ts index dfb7645b1f..fd8430cebe 100644 --- a/src/main/kubeconfig-manager.ts +++ b/src/main/kubeconfig-manager.ts @@ -1,18 +1,16 @@ +import type { Cluster } from "./cluster" import { app } from "electron" import fs from "fs" -import { ensureDir, randomFileName } from "./file-helpers" -import logger from "./logger" -import { Cluster } from "./cluster" -import { dumpConfigYaml } from "./k8s" import { KubeConfig } from "@kubernetes/client-node" +import { ensureDir, randomFileName } from "./file-helpers" +import { dumpConfigYaml } from "./k8s" +import logger from "./logger" export class KubeconfigManager { protected configDir = app.getPath("temp") protected tempFile: string - protected cluster: Cluster - constructor(cluster: Cluster) { - this.cluster = cluster + constructor(protected cluster: Cluster, protected proxyPort: number) { this.tempFile = this.createTemporaryKubeconfig() } @@ -27,13 +25,13 @@ export class KubeconfigManager { protected createTemporaryKubeconfig(): string { ensureDir(this.configDir); const path = `${this.configDir}/${randomFileName("kubeconfig")}` - const { contextName, contextHandler, kubeConfigPath } = this.cluster; + const { contextName, kubeConfigPath } = this.cluster; const kubeConfig = new KubeConfig() kubeConfig.loadFromFile(kubeConfigPath) kubeConfig.clusters = [ { name: contextName, - server: `http://127.0.0.1:${contextHandler.proxyPort}`, + server: `http://127.0.0.1:${this.proxyPort}`, skipTLSVerify: true, } ]; diff --git a/src/main/routes/metrics-route.ts b/src/main/routes/metrics-route.ts index abe36f3b23..8bda7511d8 100644 --- a/src/main/routes/metrics-route.ts +++ b/src/main/routes/metrics-route.ts @@ -25,7 +25,7 @@ class MetricsRoute extends LensApi { let prometheusProvider: PrometheusProvider try { const prometheusPath = await cluster.contextHandler.getPrometheusPath() - metricsUrl = `${cluster.apiServerUrl}/api/v1/namespaces/${prometheusPath}/proxy${cluster.getPrometheusApiPrefix()}/api/v1/query_range` + metricsUrl = `${cluster.apiProxyUrl}/api/v1/namespaces/${prometheusPath}/proxy${cluster.getPrometheusApiPrefix()}/api/v1/query_range` prometheusProvider = await cluster.contextHandler.getPrometheusProvider() } catch { this.respondJson(response, {})