mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
night insomnia clean-up, part 2
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
e1acf7e3d0
commit
25e904d2d5
@ -3,7 +3,6 @@
|
|||||||
export enum ClusterIpcMessage {
|
export enum ClusterIpcMessage {
|
||||||
CLUSTER_ADD = "cluster-add",
|
CLUSTER_ADD = "cluster-add",
|
||||||
CLUSTER_STOP = "cluster-stop",
|
CLUSTER_STOP = "cluster-stop",
|
||||||
CLUSTER_REFRESH = "cluster-refresh",
|
|
||||||
CLUSTER_REMOVE = "cluster-remove",
|
CLUSTER_REMOVE = "cluster-remove",
|
||||||
CLUSTER_REMOVE_WORKSPACE = "cluster-remove-all-from-workspace",
|
CLUSTER_REMOVE_WORKSPACE = "cluster-remove-all-from-workspace",
|
||||||
CLUSTER_EVENTS = "cluster-events-count",
|
CLUSTER_EVENTS = "cluster-events-count",
|
||||||
|
|||||||
@ -26,6 +26,7 @@ export class ClusterManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(protected port: number) {
|
constructor(protected port: number) {
|
||||||
|
// init clusters
|
||||||
reaction(() => clusterStore.clusters.toJS(), clusters => {
|
reaction(() => clusterStore.clusters.toJS(), clusters => {
|
||||||
clusters.forEach(cluster => {
|
clusters.forEach(cluster => {
|
||||||
if (!cluster.initialized) {
|
if (!cluster.initialized) {
|
||||||
@ -33,12 +34,14 @@ export class ClusterManager {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
// destroy clusters
|
||||||
reaction(() => clusterStore.removedClusters.toJS(), removedClusters => {
|
reaction(() => clusterStore.removedClusters.toJS(), removedClusters => {
|
||||||
if (removedClusters.size > 0) {
|
if (removedClusters.size > 0) {
|
||||||
removedClusters.forEach(cluster => cluster.stopServer());
|
removedClusters.forEach(cluster => cluster.stopServer());
|
||||||
clusterStore.removedClusters.clear();
|
clusterStore.removedClusters.clear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// listen ipc-events
|
||||||
ClusterManager.ipcListen(this);
|
ClusterManager.ipcListen(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,10 +151,6 @@ export class ClusterManager {
|
|||||||
return this.getCluster(clusterId)?.uninstallFeature(name);
|
return this.getCluster(clusterId)?.uninstallFeature(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async refreshCluster(clusterId: ClusterId) {
|
|
||||||
await this.getCluster(clusterId)?.refreshCluster();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async getEventsCount(clusterId: ClusterId): Promise<number> {
|
protected async getEventsCount(clusterId: ClusterId): Promise<number> {
|
||||||
return await this.getCluster(clusterId)?.getEventCount() || 0;
|
return await this.getCluster(clusterId)?.getEventCount() || 0;
|
||||||
}
|
}
|
||||||
@ -162,7 +161,6 @@ export class ClusterManager {
|
|||||||
[ClusterIpcMessage.CLUSTER_STOP]: clusterManager.stopCluster,
|
[ClusterIpcMessage.CLUSTER_STOP]: clusterManager.stopCluster,
|
||||||
[ClusterIpcMessage.CLUSTER_REMOVE]: clusterManager.removeCluster,
|
[ClusterIpcMessage.CLUSTER_REMOVE]: clusterManager.removeCluster,
|
||||||
[ClusterIpcMessage.CLUSTER_REMOVE_WORKSPACE]: clusterManager.removeAllByWorkspace,
|
[ClusterIpcMessage.CLUSTER_REMOVE_WORKSPACE]: clusterManager.removeAllByWorkspace,
|
||||||
[ClusterIpcMessage.CLUSTER_REFRESH]: clusterManager.refreshCluster,
|
|
||||||
[ClusterIpcMessage.CLUSTER_EVENTS]: clusterManager.getEventsCount,
|
[ClusterIpcMessage.CLUSTER_EVENTS]: clusterManager.getEventsCount,
|
||||||
[ClusterIpcMessage.FEATURE_INSTALL]: clusterManager.installFeature,
|
[ClusterIpcMessage.FEATURE_INSTALL]: clusterManager.installFeature,
|
||||||
[ClusterIpcMessage.FEATURE_UPGRADE]: clusterManager.upgradeFeature,
|
[ClusterIpcMessage.FEATURE_UPGRADE]: clusterManager.upgradeFeature,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import url from "url"
|
import url, { UrlWithStringQuery } from "url"
|
||||||
import type { ClusterId, ClusterModel, ClusterPreferences } from "../common/cluster-store"
|
import type { ClusterId, ClusterModel, ClusterPreferences } from "../common/cluster-store"
|
||||||
import type { FeatureStatusMap } from "./feature"
|
import type { FeatureStatusMap } from "./feature"
|
||||||
import { computed, observable, toJS } from "mobx";
|
import { computed, observable, toJS } from "mobx";
|
||||||
@ -33,8 +33,8 @@ export interface ClusterState extends ClusterModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Cluster implements ClusterModel {
|
export class Cluster implements ClusterModel {
|
||||||
public contextHandler: ContextHandler;
|
|
||||||
public kubeCtl: Kubectl
|
public kubeCtl: Kubectl
|
||||||
|
public contextHandler: ContextHandler;
|
||||||
protected kubeconfigManager: KubeconfigManager;
|
protected kubeconfigManager: KubeconfigManager;
|
||||||
|
|
||||||
@observable initialized = false;
|
@observable initialized = false;
|
||||||
@ -63,20 +63,21 @@ export class Cluster implements ClusterModel {
|
|||||||
Object.assign(this, model)
|
Object.assign(this, model)
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed get apiUrl() {
|
// todo: use only api proxy url?
|
||||||
return url.parse(`http://${this.id}.localhost:${this.port}`)
|
@computed get apiUrl(): UrlWithStringQuery {
|
||||||
|
return url.parse(`http://${this.id}.localhost:${this.port}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed get apiServerUrl() {
|
@computed get apiProxyUrl(): string {
|
||||||
return url.parse(`http://127.0.0.1:${this.port}${apiPrefix.KUBE_BASE}`)
|
return `http://127.0.0.1:${this.port}${apiPrefix.KUBE_BASE}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(port: number) {
|
async init(port: number) {
|
||||||
try {
|
try {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.contextHandler = new ContextHandler(this);
|
this.contextHandler = new ContextHandler(this);
|
||||||
await this.contextHandler.init() // So we get the proxy port reserved
|
const proxyPort = await this.contextHandler.resolveProxyPort();
|
||||||
this.kubeconfigManager = new KubeconfigManager(this)
|
this.kubeconfigManager = new KubeconfigManager(this, proxyPort);
|
||||||
this.url = this.contextHandler.url
|
this.url = this.contextHandler.url
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
logger.debug(`[CLUSTER]: init done (id="${this.id}", context="${this.contextName}")`);
|
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() {
|
async refreshCluster() {
|
||||||
this.contextHandler.setClusterPreferences(this.preferences)
|
this.contextHandler.setClusterPreferences(this.preferences)
|
||||||
|
|
||||||
@ -140,7 +142,7 @@ export class Cluster implements ClusterModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
k8sRequest(path: string, options: RequestPromiseOptions = {}) {
|
k8sRequest(path: string, options: RequestPromiseOptions = {}) {
|
||||||
return request(this.apiServerUrl + path, {
|
return request(this.apiProxyUrl + path, {
|
||||||
json: true,
|
json: true,
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
headers: {
|
headers: {
|
||||||
@ -272,6 +274,7 @@ export class Cluster implements ClusterModel {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: use for push-updates to lens view
|
||||||
getState(): ClusterState {
|
getState(): ClusterState {
|
||||||
const storeModel = this.toJSON();
|
const storeModel = this.toJSON();
|
||||||
return toJS({
|
return toJS({
|
||||||
|
|||||||
@ -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 { CoreV1Api } from "@kubernetes/client-node"
|
||||||
import { ServerOptions } from "http-proxy"
|
import { prometheusProviders } from "../common/prometheus-providers"
|
||||||
import logger from "./logger"
|
import logger from "./logger"
|
||||||
import { getFreePort } from "./port"
|
import { getFreePort } from "./port"
|
||||||
import { KubeAuthProxy } from "./kube-auth-proxy"
|
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 {
|
export class ContextHandler {
|
||||||
public url: string
|
public url: string
|
||||||
@ -32,16 +32,12 @@ export class ContextHandler {
|
|||||||
this.setClusterPreferences(cluster.preferences)
|
this.setClusterPreferences(cluster.preferences)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async init() {
|
public setClusterPreferences(preferences: ClusterPreferences = {}) {
|
||||||
await this.resolveProxyPort()
|
this.clusterName = preferences.clusterName || this.contextName;
|
||||||
}
|
|
||||||
|
|
||||||
public setClusterPreferences(preferences?: ClusterPreferences) {
|
|
||||||
this.clusterName = preferences?.clusterName || this.contextName;
|
|
||||||
this.prometheusProvider = preferences.prometheusProvider?.type;
|
this.prometheusProvider = preferences.prometheusProvider?.type;
|
||||||
this.prometheusPath = null;
|
this.prometheusPath = null;
|
||||||
|
|
||||||
if (preferences?.prometheus) {
|
if (preferences.prometheus) {
|
||||||
const { namespace, service, port } = preferences.prometheus
|
const { namespace, service, port } = preferences.prometheus
|
||||||
this.prometheusPath = `${namespace}/services/${service}:${port}`
|
this.prometheusPath = `${namespace}/services/${service}:${port}`
|
||||||
}
|
}
|
||||||
@ -113,7 +109,7 @@ export class ContextHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async resolveProxyPort(): Promise<number> {
|
async resolveProxyPort(): Promise<number> {
|
||||||
if (!this.proxyPort) {
|
if (!this.proxyPort) {
|
||||||
try {
|
try {
|
||||||
this.proxyPort = await getFreePort()
|
this.proxyPort = await getFreePort()
|
||||||
|
|||||||
@ -1,18 +1,16 @@
|
|||||||
|
import type { Cluster } from "./cluster"
|
||||||
import { app } from "electron"
|
import { app } from "electron"
|
||||||
import fs from "fs"
|
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 { KubeConfig } from "@kubernetes/client-node"
|
||||||
|
import { ensureDir, randomFileName } from "./file-helpers"
|
||||||
|
import { dumpConfigYaml } from "./k8s"
|
||||||
|
import logger from "./logger"
|
||||||
|
|
||||||
export class KubeconfigManager {
|
export class KubeconfigManager {
|
||||||
protected configDir = app.getPath("temp")
|
protected configDir = app.getPath("temp")
|
||||||
protected tempFile: string
|
protected tempFile: string
|
||||||
protected cluster: Cluster
|
|
||||||
|
|
||||||
constructor(cluster: Cluster) {
|
constructor(protected cluster: Cluster, protected proxyPort: number) {
|
||||||
this.cluster = cluster
|
|
||||||
this.tempFile = this.createTemporaryKubeconfig()
|
this.tempFile = this.createTemporaryKubeconfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,13 +25,13 @@ export class KubeconfigManager {
|
|||||||
protected createTemporaryKubeconfig(): string {
|
protected createTemporaryKubeconfig(): string {
|
||||||
ensureDir(this.configDir);
|
ensureDir(this.configDir);
|
||||||
const path = `${this.configDir}/${randomFileName("kubeconfig")}`
|
const path = `${this.configDir}/${randomFileName("kubeconfig")}`
|
||||||
const { contextName, contextHandler, kubeConfigPath } = this.cluster;
|
const { contextName, kubeConfigPath } = this.cluster;
|
||||||
const kubeConfig = new KubeConfig()
|
const kubeConfig = new KubeConfig()
|
||||||
kubeConfig.loadFromFile(kubeConfigPath)
|
kubeConfig.loadFromFile(kubeConfigPath)
|
||||||
kubeConfig.clusters = [
|
kubeConfig.clusters = [
|
||||||
{
|
{
|
||||||
name: contextName,
|
name: contextName,
|
||||||
server: `http://127.0.0.1:${contextHandler.proxyPort}`,
|
server: `http://127.0.0.1:${this.proxyPort}`,
|
||||||
skipTLSVerify: true,
|
skipTLSVerify: true,
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@ -25,7 +25,7 @@ class MetricsRoute extends LensApi {
|
|||||||
let prometheusProvider: PrometheusProvider
|
let prometheusProvider: PrometheusProvider
|
||||||
try {
|
try {
|
||||||
const prometheusPath = await cluster.contextHandler.getPrometheusPath()
|
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()
|
prometheusProvider = await cluster.contextHandler.getPrometheusProvider()
|
||||||
} catch {
|
} catch {
|
||||||
this.respondJson(response, {})
|
this.respondJson(response, {})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user