apis / clusters-menu refactoring

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman committed 2020-07-14 15:04:26 +03:00
1 parent 4e88715b8d
commit fbcb2fd281
12 files changed
+72 -50

No files matched your search

+7 -7
View File
@@ -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,
});
}
}
+7 -7
View File
@@ -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
}
}
}
+10 -13
View File
@@ -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;
}
+6 -6
View File
@@ -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);