mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
apis / clusters-menu refactoring
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
1 parent
4e88715b8d
commit
fbcb2fd281
12 files changed
+72
-50
No files matched your search
+7
-7
@@ -31,7 +31,6 @@ export class Cluster implements ClusterModel {
|
||||
@observable kubeConfigPath: string;
|
||||
@observable apiUrl: string; // cluster server url
|
||||
@observable kubeProxyUrl: string; // lens-proxy to kube-api url
|
||||
@observable kubeAuthProxyUrl: string; // auth-proxy to temp kube-config
|
||||
@observable webContentUrl: string; // page content url for loading in renderer
|
||||
@observable online: boolean;
|
||||
@observable accessible: boolean;
|
||||
@@ -59,20 +58,21 @@ export class Cluster implements ClusterModel {
|
||||
async init(port: number) {
|
||||
try {
|
||||
this.contextHandler = new ContextHandler(this);
|
||||
const contextPort = await this.contextHandler.ensurePort();
|
||||
this.kubeAuthProxyUrl = `http://127.0.0.1:${contextPort}`;
|
||||
this.kubeconfigManager = new KubeconfigManager(this, this.contextHandler);
|
||||
this.kubeProxyUrl = `http://localhost:${port}${apiKubePrefix}`;
|
||||
this.webContentUrl = `http://${this.id}.localhost:${port}`;
|
||||
this.kubeconfigManager = new KubeconfigManager(this);
|
||||
this.initialized = true;
|
||||
logger.info(`✅ ️Cluster(${this.id}) init success`, {
|
||||
logger.info(`✅ ️Cluster init success`, {
|
||||
id: this.id,
|
||||
serverUrl: this.apiUrl,
|
||||
webContentUrl: this.webContentUrl,
|
||||
kubeProxyUrl: this.kubeProxyUrl,
|
||||
kubeAuthProxyUrl: this.kubeAuthProxyUrl,
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error(`💣 Cluster(${this.id}) init failed: ${err}`);
|
||||
logger.error(`💣 Cluster init failed: ${err}`, {
|
||||
id: this.id,
|
||||
error: err,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,11 @@ export class ContextHandler {
|
||||
return this.prometheusPath;
|
||||
}
|
||||
|
||||
public async resolveAuthProxyUrl() {
|
||||
const proxyPort = await this.ensurePort();
|
||||
return `http://127.0.0.1:${proxyPort}`;
|
||||
}
|
||||
|
||||
public async getApiTarget(isWatchRequest = false): Promise<httpProxy.ServerOptions> {
|
||||
if (this.apiTarget && !isWatchRequest) {
|
||||
return this.apiTarget
|
||||
@@ -81,19 +86,14 @@ export class ContextHandler {
|
||||
}
|
||||
|
||||
protected async newApiTarget(timeout: number): Promise<httpProxy.ServerOptions> {
|
||||
await this.ensurePort();
|
||||
const proxyUrl = await this.resolveAuthProxyUrl();
|
||||
return {
|
||||
target: proxyUrl + this.clusterUrl.path,
|
||||
changeOrigin: true,
|
||||
timeout: timeout,
|
||||
headers: {
|
||||
"Host": this.clusterUrl.hostname,
|
||||
},
|
||||
target: {
|
||||
protocol: "http://",
|
||||
host: "127.0.0.1",
|
||||
port: this.proxyPort,
|
||||
path: this.clusterUrl.path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { KubeConfig } from "@kubernetes/client-node";
|
||||
import type { Cluster } from "./cluster"
|
||||
import type { ContextHandler } from "./context-handler";
|
||||
import { app } from "electron"
|
||||
import path from "path"
|
||||
import fs from "fs-extra"
|
||||
@@ -10,18 +11,13 @@ export class KubeconfigManager {
|
||||
protected configDir = app.getPath("temp")
|
||||
protected tempFile: string;
|
||||
|
||||
constructor(protected cluster: Cluster) {
|
||||
if(!cluster.kubeAuthProxyUrl) {
|
||||
throw new Error(`Cluster's auth proxy url must be initialized`)
|
||||
}
|
||||
if (!cluster.contextHandler.proxyPort) {
|
||||
throw new Error("Context-handler proxy port must be resolved")
|
||||
}
|
||||
constructor(protected cluster: Cluster, protected contextHandler: ContextHandler) {
|
||||
this.init();
|
||||
}
|
||||
|
||||
protected async init() {
|
||||
try {
|
||||
await this.contextHandler.ensurePort();
|
||||
await this.createProxyKubeconfig();
|
||||
} catch (err) {
|
||||
logger.error(`Failed to created temp config for auth-proxy`, { err })
|
||||
@@ -37,37 +33,38 @@ export class KubeconfigManager {
|
||||
* This way any user of the config does not need to know anything about the auth etc. details.
|
||||
*/
|
||||
protected async createProxyKubeconfig(): Promise<string> {
|
||||
const { configDir, cluster } = this;
|
||||
const { configDir, cluster, contextHandler } = this;
|
||||
const { contextName, kubeConfigPath, id } = cluster;
|
||||
const tempFile = path.join(configDir, `kubeconfig-${id}`);
|
||||
const kubeConfig = loadConfig(kubeConfigPath);
|
||||
const proxyUser = "proxy";
|
||||
const proxyConfig: Partial<KubeConfig> = {
|
||||
currentContext: contextName,
|
||||
clusters: [
|
||||
{
|
||||
name: contextName,
|
||||
server: cluster.kubeAuthProxyUrl,
|
||||
server: await contextHandler.resolveAuthProxyUrl(),
|
||||
skipTLSVerify: undefined,
|
||||
}
|
||||
],
|
||||
users: [
|
||||
{ name: proxyUser },
|
||||
{ name: "proxy" },
|
||||
],
|
||||
contexts: [
|
||||
{
|
||||
user: proxyUser,
|
||||
user: "proxy",
|
||||
name: contextName,
|
||||
cluster: contextName,
|
||||
namespace: kubeConfig.getContextObject(contextName).namespace,
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// write
|
||||
const configYaml = dumpConfigYaml(proxyConfig);
|
||||
fs.ensureDir(path.dirname(tempFile));
|
||||
fs.writeFileSync(tempFile, configYaml);
|
||||
logger.debug(`Created temp kubeconfig "${contextName}" at "${tempFile}": \n${configYaml}`);
|
||||
this.tempFile = tempFile;
|
||||
logger.debug(`Created temp kubeconfig "${contextName}" at "${tempFile}": \n${configYaml}`);
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,13 @@ export class WindowManager {
|
||||
});
|
||||
}),
|
||||
// auto-show active cluster view
|
||||
reaction(() => clusterStore.activeClusterId, clusterId => {
|
||||
this.activateView(clusterId);
|
||||
reaction(() => clusterStore.activeCluster, activeCluster => {
|
||||
if (activeCluster) {
|
||||
this.activateView(activeCluster.id);
|
||||
}
|
||||
}, {
|
||||
fireImmediately: true,
|
||||
delay: 250,
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -65,10 +68,7 @@ export class WindowManager {
|
||||
|
||||
async activateView(clusterId: ClusterId) {
|
||||
const cluster = clusterStore.getById(clusterId);
|
||||
if (!cluster) {
|
||||
logger.error(`Can't show a view for non-existing cluster(${clusterId})`);
|
||||
return;
|
||||
}
|
||||
if (!cluster) return;
|
||||
try {
|
||||
const activeView = this.activeView;
|
||||
const isFresh = !this.getView(clusterId);
|
||||
|
||||
Reference in new issue
Block a user