1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Refactor to use async methods

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>
This commit is contained in:
Lauri Nevala 2021-03-22 15:36:23 +02:00
parent 4e731753d2
commit 040d78eba7
7 changed files with 40 additions and 34 deletions

View File

@ -85,8 +85,8 @@ describe("kubeconfig manager tests", () => {
const kubeConfManager = await KubeconfigManager.create(cluster, contextHandler, port); const kubeConfManager = await KubeconfigManager.create(cluster, contextHandler, port);
expect(logger.error).not.toBeCalled(); expect(logger.error).not.toBeCalled();
expect(kubeConfManager.getPath()).toBe(`tmp${path.sep}kubeconfig-foo`); expect(await kubeConfManager.getPath()).toBe(`tmp${path.sep}kubeconfig-foo`);
const file = await fse.readFile(kubeConfManager.getPath()); const file = await fse.readFile(await kubeConfManager.getPath());
const yml = loadYaml<any>(file.toString()); const yml = loadYaml<any>(file.toString());
expect(yml["current-context"]).toBe("minikube"); expect(yml["current-context"]).toBe("minikube");
@ -104,12 +104,12 @@ describe("kubeconfig manager tests", () => {
const contextHandler = new ContextHandler(cluster); const contextHandler = new ContextHandler(cluster);
const port = await getFreePort(); const port = await getFreePort();
const kubeConfManager = await KubeconfigManager.create(cluster, contextHandler, port); const kubeConfManager = await KubeconfigManager.create(cluster, contextHandler, port);
const configPath = kubeConfManager.getPath(); const configPath = await kubeConfManager.getPath();
expect(await fse.pathExists(configPath)).toBe(true); expect(await fse.pathExists(configPath)).toBe(true);
await kubeConfManager.unlink(); await kubeConfManager.unlink();
expect(await fse.pathExists(configPath)).toBe(false); expect(await fse.pathExists(configPath)).toBe(false);
await kubeConfManager.unlink(); // doesn't throw await kubeConfManager.unlink(); // doesn't throw
expect(kubeConfManager.getPath()).toBeUndefined(); expect(await kubeConfManager.getPath()).toBeUndefined();
}); });
}); });

View File

@ -482,14 +482,16 @@ export class Cluster implements ClusterModel, ClusterState {
/** /**
* @internal * @internal
*/ */
getProxyKubeconfig(): KubeConfig { async getProxyKubeconfig(): Promise<KubeConfig> {
return loadConfig(this.getProxyKubeconfigPath()); const kubeconfigPath = await this.getProxyKubeconfigPath();
return loadConfig(kubeconfigPath);
} }
/** /**
* @internal * @internal
*/ */
getProxyKubeconfigPath(): string { async getProxyKubeconfigPath(): Promise<string> {
return this.kubeconfigManager.getPath(); return this.kubeconfigManager.getPath();
} }
@ -565,7 +567,7 @@ export class Cluster implements ClusterModel, ClusterState {
* @param resourceAttributes resource attributes * @param resourceAttributes resource attributes
*/ */
async canI(resourceAttributes: V1ResourceAttributes): Promise<boolean> { async canI(resourceAttributes: V1ResourceAttributes): Promise<boolean> {
const authApi = this.getProxyKubeconfig().makeApiClient(AuthorizationV1Api); const authApi = (await this.getProxyKubeconfig()).makeApiClient(AuthorizationV1Api);
try { try {
const accessReview = await authApi.createSelfSubjectAccessReview({ const accessReview = await authApi.createSelfSubjectAccessReview({
@ -680,14 +682,14 @@ export class Cluster implements ClusterModel, ClusterState {
return this.accessibleNamespaces; return this.accessibleNamespaces;
} }
const api = this.getProxyKubeconfig().makeApiClient(CoreV1Api); const api = (await this.getProxyKubeconfig()).makeApiClient(CoreV1Api);
try { try {
const namespaceList = await api.listNamespace(); const namespaceList = await api.listNamespace();
return namespaceList.body.items.map(ns => ns.metadata.name); return namespaceList.body.items.map(ns => ns.metadata.name);
} catch (error) { } catch (error) {
const ctx = this.getProxyKubeconfig().getContextObject(this.contextName); const ctx = (await this.getProxyKubeconfig()).getContextObject(this.contextName);
if (ctx.namespace) return [ctx.namespace]; if (ctx.namespace) return [ctx.namespace];

View File

@ -59,7 +59,7 @@ export class ContextHandler {
async getPrometheusService(): Promise<PrometheusService> { async getPrometheusService(): Promise<PrometheusService> {
const providers = this.prometheusProvider ? prometheusProviders.filter(provider => provider.id == this.prometheusProvider) : prometheusProviders; const providers = this.prometheusProvider ? prometheusProviders.filter(provider => provider.id == this.prometheusProvider) : prometheusProviders;
const prometheusPromises: Promise<PrometheusService>[] = providers.map(async (provider: PrometheusProvider): Promise<PrometheusService> => { const prometheusPromises: Promise<PrometheusService>[] = providers.map(async (provider: PrometheusProvider): Promise<PrometheusService> => {
const apiClient = this.cluster.getProxyKubeconfig().makeApiClient(CoreV1Api); const apiClient = (await this.cluster.getProxyKubeconfig()).makeApiClient(CoreV1Api);
return await provider.getPrometheusService(apiClient); return await provider.getPrometheusService(apiClient);
}); });

View File

@ -24,17 +24,17 @@ export class KubeconfigManager {
protected async init() { protected async init() {
try { try {
await this.contextHandler.ensurePort(); await this.contextHandler.ensurePort();
this.tempFile = this.createProxyKubeconfig(); this.tempFile = await this.createProxyKubeconfig();
} catch (err) { } catch (err) {
logger.error(`Failed to created temp config for auth-proxy`, { err }); logger.error(`Failed to created temp config for auth-proxy`, { err });
} }
} }
getPath() { async getPath() {
// create proxy kubeconfig if it is removed // create proxy kubeconfig if it is removed
if (this.tempFile && !fs.pathExistsSync(this.tempFile)) { if (this.tempFile && !(await fs.pathExists(this.tempFile))) {
try { try {
this.tempFile = this.createProxyKubeconfig(); this.tempFile = await this.createProxyKubeconfig();
} catch (err) { } catch (err) {
logger.error(`Failed to created temp config for auth-proxy`, { err }); logger.error(`Failed to created temp config for auth-proxy`, { err });
} }
@ -52,7 +52,7 @@ export class KubeconfigManager {
* Creates new "temporary" kubeconfig that point to the kubectl-proxy. * Creates new "temporary" kubeconfig that point to the kubectl-proxy.
* This way any user of the config does not need to know anything about the auth etc. details. * This way any user of the config does not need to know anything about the auth etc. details.
*/ */
protected createProxyKubeconfig(): string { protected async createProxyKubeconfig(): Promise<string> {
const { configDir, cluster } = this; const { configDir, cluster } = this;
const { contextName, kubeConfigPath, id } = cluster; const { contextName, kubeConfigPath, id } = cluster;
const tempFile = path.join(configDir, `kubeconfig-${id}`); const tempFile = path.join(configDir, `kubeconfig-${id}`);
@ -81,8 +81,8 @@ export class KubeconfigManager {
// write // write
const configYaml = dumpConfigYaml(proxyConfig); const configYaml = dumpConfigYaml(proxyConfig);
fs.ensureDirSync(path.dirname(tempFile)); await fs.ensureDir(path.dirname(tempFile));
fs.writeFileSync(tempFile, configYaml, { mode: 0o600 }); await fs.writeFile(tempFile, configYaml, { mode: 0o600 });
logger.debug(`Created temp kubeconfig "${contextName}" at "${tempFile}": \n${configYaml}`); logger.debug(`Created temp kubeconfig "${contextName}" at "${tempFile}": \n${configYaml}`);
return tempFile; return tempFile;

View File

@ -17,10 +17,10 @@ export class NodeShellSession extends ShellSession {
super(socket, cluster); super(socket, cluster);
this.nodeName = nodeName; this.nodeName = nodeName;
this.podId = `node-shell-${uuid()}`; this.podId = `node-shell-${uuid()}`;
this.kc = cluster.getProxyKubeconfig();
} }
public async open() { public async open() {
this.kc = await this.cluster.getProxyKubeconfig();
const shell = await this.kubectl.getPath(); const shell = await this.kubectl.getPath();
let args = []; let args = [];

View File

@ -23,12 +23,13 @@ export class ResourceApplier {
protected async kubectlApply(content: string): Promise<string> { protected async kubectlApply(content: string): Promise<string> {
const { kubeCtl } = this.cluster; const { kubeCtl } = this.cluster;
const kubectlPath = await kubeCtl.getPath(); const kubectlPath = await kubeCtl.getPath();
const proxyKubeconfigPath = await this.cluster.getProxyKubeconfigPath();
return new Promise<string>((resolve, reject) => { return new Promise<string>((resolve, reject) => {
const fileName = tempy.file({ name: "resource.yaml" }); const fileName = tempy.file({ name: "resource.yaml" });
fs.writeFileSync(fileName, content); fs.writeFileSync(fileName, content);
const cmd = `"${kubectlPath}" apply --kubeconfig "${this.cluster.getProxyKubeconfigPath()}" -o json -f "${fileName}"`; const cmd = `"${kubectlPath}" apply --kubeconfig "${proxyKubeconfigPath}" -o json -f "${fileName}"`;
logger.debug(`shooting manifests with: ${cmd}`); logger.debug(`shooting manifests with: ${cmd}`);
const execEnv: NodeJS.ProcessEnv = Object.assign({}, process.env); const execEnv: NodeJS.ProcessEnv = Object.assign({}, process.env);
@ -54,6 +55,7 @@ export class ResourceApplier {
public async kubectlApplyAll(resources: string[]): Promise<string> { public async kubectlApplyAll(resources: string[]): Promise<string> {
const { kubeCtl } = this.cluster; const { kubeCtl } = this.cluster;
const kubectlPath = await kubeCtl.getPath(); const kubectlPath = await kubeCtl.getPath();
const proxyKubeconfigPath = await this.cluster.getProxyKubeconfigPath();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const tmpDir = tempy.directory(); const tmpDir = tempy.directory();
@ -62,7 +64,7 @@ export class ResourceApplier {
resources.forEach((resource, index) => { resources.forEach((resource, index) => {
fs.writeFileSync(path.join(tmpDir, `${index}.yaml`), resource); fs.writeFileSync(path.join(tmpDir, `${index}.yaml`), resource);
}); });
const cmd = `"${kubectlPath}" apply --kubeconfig "${this.cluster.getProxyKubeconfigPath()}" -o json -f "${tmpDir}"`; const cmd = `"${kubectlPath}" apply --kubeconfig "${proxyKubeconfigPath}" -o json -f "${tmpDir}"`;
console.log("shooting manifests with:", cmd); console.log("shooting manifests with:", cmd);
exec(cmd, (error, stdout, stderr) => { exec(cmd, (error, stdout, stderr) => {

View File

@ -6,7 +6,6 @@ import shellEnv from "shell-env";
import { app } from "electron"; import { app } from "electron";
import { Kubectl } from "./kubectl"; import { Kubectl } from "./kubectl";
import { Cluster } from "./cluster"; import { Cluster } from "./cluster";
import { ClusterPreferences } from "../common/cluster-store";
import { helmCli } from "./helm/helm-cli"; import { helmCli } from "./helm/helm-cli";
import { isWindows } from "../common/vars"; import { isWindows } from "../common/vars";
import { appEventBus } from "../common/event-bus"; import { appEventBus } from "../common/event-bus";
@ -24,20 +23,18 @@ export class ShellSession extends EventEmitter {
protected kubectlBinDir: string; protected kubectlBinDir: string;
protected kubectlPathDir: string; protected kubectlPathDir: string;
protected helmBinDir: string; protected helmBinDir: string;
protected preferences: ClusterPreferences;
protected running = false; protected running = false;
protected clusterId: string; protected cluster: Cluster;
constructor(socket: WebSocket, cluster: Cluster) { constructor(socket: WebSocket, cluster: Cluster) {
super(); super();
this.websocket = socket; this.websocket = socket;
this.kubeconfigPath = cluster.getProxyKubeconfigPath();
this.kubectl = new Kubectl(cluster.version); this.kubectl = new Kubectl(cluster.version);
this.preferences = cluster.preferences || {}; this.cluster = cluster;
this.clusterId = cluster.id;
} }
public async open() { public async open() {
this.kubeconfigPath = await this.cluster.getProxyKubeconfigPath();
this.kubectlBinDir = await this.kubectl.binDir(); this.kubectlBinDir = await this.kubectl.binDir();
const pathFromPreferences = userStore.preferences.kubectlBinariesPath || this.kubectl.getBundledPath(); const pathFromPreferences = userStore.preferences.kubectlBinariesPath || this.kubectl.getBundledPath();
@ -65,11 +62,13 @@ export class ShellSession extends EventEmitter {
} }
protected cwd(): string { protected cwd(): string {
if(!this.preferences || !this.preferences.terminalCWD || this.preferences.terminalCWD === "") { const { preferences } = this.cluster;
if(!preferences || !preferences.terminalCWD || preferences.terminalCWD === "") {
return null; return null;
} }
return this.preferences.terminalCWD; return preferences.terminalCWD;
} }
protected async getShellArgs(shell: string): Promise<Array<string>> { protected async getShellArgs(shell: string): Promise<Array<string>> {
@ -88,15 +87,17 @@ export class ShellSession extends EventEmitter {
} }
protected async getCachedShellEnv() { protected async getCachedShellEnv() {
let env = ShellSession.shellEnvs.get(this.clusterId); const { id: clusterId } = this.cluster;
let env = ShellSession.shellEnvs.get(clusterId);
if (!env) { if (!env) {
env = await this.getShellEnv(); env = await this.getShellEnv();
ShellSession.shellEnvs.set(this.clusterId, env); ShellSession.shellEnvs.set(clusterId, env);
} else { } else {
// refresh env in the background // refresh env in the background
this.getShellEnv().then((shellEnv: any) => { this.getShellEnv().then((shellEnv: any) => {
ShellSession.shellEnvs.set(this.clusterId, shellEnv); ShellSession.shellEnvs.set(clusterId, shellEnv);
}); });
} }
@ -107,6 +108,7 @@ export class ShellSession extends EventEmitter {
const env = clearKubeconfigEnvVars(JSON.parse(JSON.stringify(await shellEnv()))); const env = clearKubeconfigEnvVars(JSON.parse(JSON.stringify(await shellEnv())));
const pathStr = [this.kubectlBinDir, this.helmBinDir, process.env.PATH].join(path.delimiter); const pathStr = [this.kubectlBinDir, this.helmBinDir, process.env.PATH].join(path.delimiter);
const shell = userStore.preferences.shell || process.env.SHELL || process.env.PTYSHELL; const shell = userStore.preferences.shell || process.env.SHELL || process.env.PTYSHELL;
const { preferences } = this.cluster;
if(isWindows) { if(isWindows) {
env["SystemRoot"] = process.env.SystemRoot; env["SystemRoot"] = process.env.SystemRoot;
@ -138,8 +140,8 @@ export class ShellSession extends EventEmitter {
env["TERM_PROGRAM"] = app.getName(); env["TERM_PROGRAM"] = app.getName();
env["TERM_PROGRAM_VERSION"] = app.getVersion(); env["TERM_PROGRAM_VERSION"] = app.getVersion();
if (this.preferences.httpsProxy) { if (preferences.httpsProxy) {
env["HTTPS_PROXY"] = this.preferences.httpsProxy; env["HTTPS_PROXY"] = preferences.httpsProxy;
} }
const no_proxy = ["localhost", "127.0.0.1", env["NO_PROXY"]]; const no_proxy = ["localhost", "127.0.0.1", env["NO_PROXY"]];