From c69eb16248cf9192835186720d2c00a3cd5c3017 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Thu, 22 Dec 2022 12:53:04 -0500 Subject: [PATCH] Make installHelmChart injectable Signed-off-by: Sebastian Malton --- src/main/getDiForUnitTesting.ts | 2 - src/main/helm/helm-release-manager.ts | 48 ---------- .../install-helm-chart.injectable.ts | 23 +++-- .../helm/install-helm-chart.injectable.ts | 93 +++++++++++++++++++ .../install-chart-route.injectable.ts | 4 +- 5 files changed, 109 insertions(+), 61 deletions(-) create mode 100644 src/main/helm/install-helm-chart.injectable.ts diff --git a/src/main/getDiForUnitTesting.ts b/src/main/getDiForUnitTesting.ts index a3fc8e7696..b7043e8945 100644 --- a/src/main/getDiForUnitTesting.ts +++ b/src/main/getDiForUnitTesting.ts @@ -60,7 +60,6 @@ import listHelmChartsInjectable from "./helm/helm-service/list-helm-charts.injec import deleteHelmReleaseInjectable from "./helm/helm-service/delete-helm-release.injectable"; import getHelmReleaseHistoryInjectable from "./helm/helm-service/get-helm-release-history.injectable"; import getHelmReleaseValuesInjectable from "./helm/helm-service/get-helm-release-values.injectable"; -import installHelmChartInjectable from "./helm/helm-service/install-helm-chart.injectable"; import rollbackHelmReleaseInjectable from "./helm/helm-service/rollback-helm-release.injectable"; import waitUntilBundledExtensionsAreLoadedInjectable from "./start-main-application/lens-window/application-window/wait-until-bundled-extensions-are-loaded.injectable"; import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx"; @@ -141,7 +140,6 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) deleteHelmReleaseInjectable, getHelmReleaseHistoryInjectable, getHelmReleaseValuesInjectable, - installHelmChartInjectable, rollbackHelmReleaseInjectable, writeJsonFileInjectable, readJsonFileInjectable, diff --git a/src/main/helm/helm-release-manager.ts b/src/main/helm/helm-release-manager.ts index db8dc0896a..e67f1551ee 100644 --- a/src/main/helm/helm-release-manager.ts +++ b/src/main/helm/helm-release-manager.ts @@ -3,9 +3,6 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import tempy from "tempy"; -import fse from "fs-extra"; -import * as yaml from "js-yaml"; import type { JsonValue } from "type-fest"; import { json } from "../../common/utils"; import { asLegacyGlobalFunctionForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api"; @@ -13,51 +10,6 @@ import execHelmInjectable from "./exec-helm/exec-helm.injectable"; const execHelm = asLegacyGlobalFunctionForExtensionApi(execHelmInjectable); -export async function installChart(chart: string, values: JsonValue, name: string | undefined = "", namespace: string, version: string, kubeconfigPath: string) { - const valuesFilePath = tempy.file({ name: "values.yaml" }); - - await fse.writeFile(valuesFilePath, yaml.dump(values)); - - const args = ["install"]; - - if (name) { - args.push(name); - } - - args.push( - chart, - "--version", version, - "--values", valuesFilePath, - "--namespace", namespace, - "--kubeconfig", kubeconfigPath, - ); - - if (!name) { - args.push("--generate-name"); - } - - try { - const result = await execHelm(args); - - if (!result.callWasSuccessful) { - throw result.error; - } - - const output = result.response; - const releaseName = output.split("\n")[0].split(" ")[1].trim(); - - return { - log: output, - release: { - name: releaseName, - namespace, - }, - }; - } finally { - await fse.unlink(valuesFilePath); - } -} - export async function deleteRelease(name: string, namespace: string, kubeconfigPath: string): Promise { const result = await execHelm([ "delete", diff --git a/src/main/helm/helm-service/install-helm-chart.injectable.ts b/src/main/helm/helm-service/install-helm-chart.injectable.ts index 9ddb4fa599..b81b48cfa6 100644 --- a/src/main/helm/helm-service/install-helm-chart.injectable.ts +++ b/src/main/helm/helm-service/install-helm-chart.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import type { JsonObject } from "type-fest"; import type { Cluster } from "../../../common/cluster/cluster"; -import { installChart } from "../helm-release-manager"; +import installHelmChartInjectable from "../install-helm-chart.injectable"; export interface InstallChartArgs { chart: string; @@ -15,16 +15,21 @@ export interface InstallChartArgs { version: string; } -const installHelmChartInjectable = getInjectable({ - id: "install-helm-chart", +const installClusterHelmChartInjectable = getInjectable({ + id: "install-cluster-helm-chart", - instantiate: () => async (cluster: Cluster, data: InstallChartArgs) => { - const proxyKubeconfig = await cluster.getProxyKubeconfigPath(); + instantiate: (di) => { + const installHelmChart = di.inject(installHelmChartInjectable); - return installChart(data.chart, data.values, data.name, data.namespace, data.version, proxyKubeconfig); + return async (cluster: Cluster, data: InstallChartArgs) => { + const proxyKubeconfig = await cluster.getProxyKubeconfigPath(); + + return installHelmChart({ + ...data, + kubeconfigPath: proxyKubeconfig, + }); + }; }, - - causesSideEffects: true, }); -export default installHelmChartInjectable; +export default installClusterHelmChartInjectable; diff --git a/src/main/helm/install-helm-chart.injectable.ts b/src/main/helm/install-helm-chart.injectable.ts new file mode 100644 index 0000000000..f566c6a6f1 --- /dev/null +++ b/src/main/helm/install-helm-chart.injectable.ts @@ -0,0 +1,93 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { dump } from "js-yaml"; +import tempy from "tempy"; +import type { JsonValue } from "type-fest"; +import removePathInjectable from "../../common/fs/remove.injectable"; +import writeFileInjectable from "../../common/fs/write-file.injectable"; +import execHelmInjectable from "./exec-helm/exec-helm.injectable"; + +export interface InstallHelmChartData { + chart: string; + values: JsonValue; + name: string; + namespace: string; + version: string; + kubeconfigPath: string; +} + +export interface InstallHelmChartResult { + log: string; + release: { + name: string; + namespace: string; + }; +} + +export type InstallHelmChart = (data: InstallHelmChartData) => Promise; + +const installHelmChartInjectable = getInjectable({ + id: "install-helm-chart", + instantiate: (di): InstallHelmChart => { + const writeFile = di.inject(writeFileInjectable); + const removePath = di.inject(removePathInjectable); + const execHelm = di.inject(execHelmInjectable); + + return async ({ + chart, + kubeconfigPath, + name, + namespace, + values, + version, + }) => { + const valuesFilePath = tempy.file({ name: "values.yaml" }); + + await writeFile(valuesFilePath, dump(values)); + + const args = ["install"]; + + if (name) { + args.push(name); + } + + args.push( + chart, + "--version", version, + "--values", valuesFilePath, + "--namespace", namespace, + "--kubeconfig", kubeconfigPath, + ); + + if (!name) { + args.push("--generate-name"); + } + + try { + const result = await execHelm(args); + + if (!result.callWasSuccessful) { + throw result.error; + } + + const output = result.response; + const releaseName = output.split("\n")[0].split(" ")[1].trim(); + + return { + log: output, + release: { + name: releaseName, + namespace, + }, + }; + } finally { + await removePath(valuesFilePath); + } + }; + }, +}); + +export default installHelmChartInjectable; diff --git a/src/main/routes/helm/releases/install-chart-route.injectable.ts b/src/main/routes/helm/releases/install-chart-route.injectable.ts index 75969c4a2f..e34d54db23 100644 --- a/src/main/routes/helm/releases/install-chart-route.injectable.ts +++ b/src/main/routes/helm/releases/install-chart-route.injectable.ts @@ -7,7 +7,7 @@ import { getRouteInjectable } from "../../../router/router.injectable"; import Joi from "joi"; import { payloadValidatedClusterRoute } from "../../../router/route"; import type { InstallChartArgs } from "../../../helm/helm-service/install-helm-chart.injectable"; -import installHelmChartInjectable from "../../../helm/helm-service/install-helm-chart.injectable"; +import installClusterHelmChartInjectable from "../../../helm/helm-service/install-helm-chart.injectable"; const installChartArgsValidator = Joi.object({ chart: Joi @@ -31,7 +31,7 @@ const installChartRouteInjectable = getRouteInjectable({ id: "install-chart-route", instantiate: (di) => { - const installHelmChart = di.inject(installHelmChartInjectable); + const installHelmChart = di.inject(installClusterHelmChartInjectable); return payloadValidatedClusterRoute({ method: "post",