1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/main/helm/helm-repo-manager.ts
pashevskii b7e5fb78d9
Add posibility to add custom repository (#1368)
Signed-off-by: Pavel Ashevskii <pashevskii@mirantis.com>
2020-12-08 15:54:49 +03:00

165 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import yaml from "js-yaml";
import { readFile } from "fs-extra";
import { promiseExec } from "../promise-exec";
import { helmCli } from "./helm-cli";
import { Singleton } from "../../common/utils/singleton";
import { customRequestPromise } from "../../common/request";
import orderBy from "lodash/orderBy";
import logger from "../logger";
export type HelmEnv = Record<string, string> & {
HELM_REPOSITORY_CACHE?: string;
HELM_REPOSITORY_CONFIG?: string;
};
export interface HelmRepoConfig {
repositories: HelmRepo[]
}
export interface HelmRepo {
name: string;
url: string;
cacheFilePath?: string
caFile?: string,
certFile?: string,
insecureSkipTlsVerify?: boolean,
keyFile?: string,
username?: string,
password?: string,
}
export class HelmRepoManager extends Singleton {
static cache = {}; // todo: remove implicit updates in helm-chart-manager.ts
protected repos: HelmRepo[];
protected helmEnv: HelmEnv;
protected initialized: boolean;
async loadAvailableRepos(): Promise<HelmRepo[]> {
const res = await customRequestPromise({
uri: "https://github.com/lensapp/artifact-hub-repositories/releases/download/latest/repositories.json",
json: true,
resolveWithFullResponse: true,
timeout: 10000,
});
return orderBy<HelmRepo>(res.body, repo => repo.name);
}
async init() {
helmCli.setLogger(logger);
await helmCli.ensureBinary();
if (!this.initialized) {
this.helmEnv = await this.parseHelmEnv();
await this.update();
this.initialized = true;
}
}
protected async parseHelmEnv() {
const helm = await helmCli.binaryPath();
const { stdout } = await promiseExec(`"${helm}" env`).catch((error) => {
throw(error.stderr);
});
const lines = stdout.split(/\r?\n/); // split by new line feed
const env: HelmEnv = {};
lines.forEach((line: string) => {
const [key, value] = line.split("=");
if (key && value) {
env[key] = value.replace(/"/g, ""); // strip quotas
}
});
return env;
}
public async repositories(): Promise<HelmRepo[]> {
if (!this.initialized) {
await this.init();
}
try {
const repoConfigFile = this.helmEnv.HELM_REPOSITORY_CONFIG;
const { repositories }: HelmRepoConfig = await readFile(repoConfigFile, "utf8")
.then((yamlContent: string) => yaml.safeLoad(yamlContent))
.catch(() => ({
repositories: []
}));
if (!repositories.length) {
await this.addRepo({ name: "bitnami", url: "https://charts.bitnami.com/bitnami" });
return await this.repositories();
}
return repositories.map(repo => ({
...repo,
cacheFilePath: `${this.helmEnv.HELM_REPOSITORY_CACHE}/${repo.name}-index.yaml`
}));
} catch (error) {
logger.error(`[HELM]: repositories listing error "${error}"`);
return [];
}
}
public async repository(name: string) {
const repositories = await this.repositories();
return repositories.find(repo => repo.name == name);
}
public async update() {
const helm = await helmCli.binaryPath();
const { stdout } = await promiseExec(`"${helm}" repo update`).catch((error) => {
return { stdout: error.stdout };
});
return stdout;
}
public async addRepo({ name, url }: HelmRepo) {
logger.info(`[HELM]: adding repo "${name}" from ${url}`);
const helm = await helmCli.binaryPath();
const { stdout } = await promiseExec(`"${helm}" repo add ${name} ${url}`).catch((error) => {
throw(error.stderr);
});
return stdout;
}
public async addСustomRepo(repoAttributes : HelmRepo) {
logger.info(`[HELM]: adding repo "${repoAttributes.name}" from ${repoAttributes.url}`);
const helm = await helmCli.binaryPath();
const insecureSkipTlsVerify = repoAttributes.insecureSkipTlsVerify ? " --insecure-skip-tls-verify" : "";
const username = repoAttributes.username ? ` --username "${repoAttributes.username}"` : "";
const password = repoAttributes.password ? ` --password "${repoAttributes.password}"` : "";
const caFile = repoAttributes.caFile ? ` --ca-file "${repoAttributes.caFile}"` : "";
const keyFile = repoAttributes.keyFile ? ` --key-file "${repoAttributes.keyFile}"` : "";
const certFile = repoAttributes.certFile ? ` --cert-file "${repoAttributes.certFile}"` : "";
const addRepoCommand = `"${helm}" repo add ${repoAttributes.name} ${repoAttributes.url}${insecureSkipTlsVerify}${username}${password}${caFile}${keyFile}${certFile}`;
const { stdout } = await promiseExec(addRepoCommand).catch((error) => {
throw(error.stderr);
});
return stdout;
}
public async removeRepo({ name, url }: HelmRepo): Promise<string> {
logger.info(`[HELM]: removing repo "${name}" from ${url}`);
const helm = await helmCli.binaryPath();
const { stdout } = await promiseExec(`"${helm}" repo remove ${name}`).catch((error) => {
throw(error.stderr);
});
return stdout;
}
}
export const repoManager = HelmRepoManager.getInstance<HelmRepoManager>();