mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Stop using HelmCli from Renderer (#4861)
* Introduce way for execute file Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make typing of HelmRepo shared Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce way to get Helm environment values Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce function to read YAML file Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for listing active helm repositories in preferences Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make sense in name of injectable Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce helper for opening and selecting values of select Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for activating, deactivating public helm repositories in preferences Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for deactivating helm repository from list of active repositories Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add missing global overrides Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make some tests more deterministic by mocking tooltips Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for activating custom helm repository in preferences Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update snapshots Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove old implementation made redundant with competition for preferences of helm repositories Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add success notification for activating custom helm repository Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce way to get single active helm repository Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Extract responsibilities from god-class and switch to getting helm repositories using competition instead of another god class Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove dead code Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add TODO Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Tweak position of spinner Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Start handling errors when accessing helm repositories Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Handle error about no helm repositories when updating repositories Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove unwarranted function configuration Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add missing global overrides Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove duplication how to acquire binary path for helm Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove redundant comment Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Consolidate naming to match Helm's internal Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Relocate file closer to it's relatives Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
1 parent
5420780ae0
commit
1393cc303d
99 files changed
+21409
-1039
No files matched your search
@@ -5,7 +5,7 @@
|
||||
|
||||
import glob from "glob";
|
||||
import { kebabCase, memoize, noop } from "lodash/fp";
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import type { DiContainer, Injectable } from "@ogre-tools/injectable";
|
||||
import { createContainer } from "@ogre-tools/injectable";
|
||||
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import appNameInjectable from "./app-paths/app-name/app-name.injectable";
|
||||
@@ -76,7 +76,7 @@ import quitAndInstallUpdateInjectable from "./electron-app/features/quit-and-ins
|
||||
import electronUpdaterIsActiveInjectable from "./electron-app/features/electron-updater-is-active.injectable";
|
||||
import publishIsConfiguredInjectable from "./application-update/publish-is-configured.injectable";
|
||||
import checkForPlatformUpdatesInjectable from "./application-update/check-for-platform-updates/check-for-platform-updates.injectable";
|
||||
import baseBundeledBinariesDirectoryInjectable from "../common/vars/base-bundled-binaries-dir.injectable";
|
||||
import baseBundledBinariesDirectoryInjectable from "../common/vars/base-bundled-binaries-dir.injectable";
|
||||
import setUpdateOnQuitInjectable from "./electron-app/features/set-update-on-quit.injectable";
|
||||
import downloadPlatformUpdateInjectable from "./application-update/download-platform-update/download-platform-update.injectable";
|
||||
import startCatalogSyncInjectable from "./catalog-sync-to-renderer/start-catalog-sync.injectable";
|
||||
@@ -84,6 +84,19 @@ import startKubeConfigSyncInjectable from "./start-main-application/runnables/ku
|
||||
import appVersionInjectable from "../common/get-configuration-file-model/app-version/app-version.injectable";
|
||||
import getRandomIdInjectable from "../common/utils/get-random-id.injectable";
|
||||
import periodicalCheckForUpdatesInjectable from "./application-update/periodical-check-for-updates/periodical-check-for-updates.injectable";
|
||||
import execFileInjectable from "../common/fs/exec-file.injectable";
|
||||
import normalizedPlatformArchitectureInjectable from "../common/vars/normalized-platform-architecture.injectable";
|
||||
import getHelmChartInjectable from "./helm/helm-service/get-helm-chart.injectable";
|
||||
import getHelmChartValuesInjectable from "./helm/helm-service/get-helm-chart-values.injectable";
|
||||
import listHelmChartsInjectable from "./helm/helm-service/list-helm-charts.injectable";
|
||||
import deleteHelmReleaseInjectable from "./helm/helm-service/delete-helm-release.injectable";
|
||||
import getHelmReleaseHistoryInjectable from "./helm/helm-service/get-helm-release-history.injectable";
|
||||
import getHelmReleaseInjectable from "./helm/helm-service/get-helm-release.injectable";
|
||||
import getHelmReleaseValuesInjectable from "./helm/helm-service/get-helm-release-values.injectable";
|
||||
import installHelmChartInjectable from "./helm/helm-service/install-helm-chart.injectable";
|
||||
import listHelmReleasesInjectable from "./helm/helm-service/list-helm-releases.injectable";
|
||||
import rollbackHelmReleaseInjectable from "./helm/helm-service/rollback-helm-release.injectable";
|
||||
import updateHelmReleaseInjectable from "./helm/helm-service/update-helm-release.injectable";
|
||||
|
||||
export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) {
|
||||
const {
|
||||
@@ -134,6 +147,24 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {})
|
||||
|
||||
di.override(periodicalCheckForUpdatesInjectable, () => ({ start: () => {}, stop: () => {}, started: false }));
|
||||
|
||||
overrideFunctionalInjectables(di, [
|
||||
getHelmChartInjectable,
|
||||
getHelmChartValuesInjectable,
|
||||
listHelmChartsInjectable,
|
||||
deleteHelmReleaseInjectable,
|
||||
getHelmReleaseHistoryInjectable,
|
||||
getHelmReleaseInjectable,
|
||||
getHelmReleaseValuesInjectable,
|
||||
installHelmChartInjectable,
|
||||
listHelmReleasesInjectable,
|
||||
rollbackHelmReleaseInjectable,
|
||||
updateHelmReleaseInjectable,
|
||||
writeJsonFileInjectable,
|
||||
readJsonFileInjectable,
|
||||
readFileInjectable,
|
||||
execFileInjectable,
|
||||
]);
|
||||
|
||||
// TODO: Remove usages of globally exported appEventBus to get rid of this
|
||||
di.override(appEventBusInjectable, () => new EventEmitter<[AppEvent]>());
|
||||
|
||||
@@ -141,7 +172,7 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {})
|
||||
di.override(broadcastMessageInjectable, () => (channel) => {
|
||||
throw new Error(`Tried to broadcast message to channel "${channel}" over IPC without explicit override.`);
|
||||
});
|
||||
di.override(baseBundeledBinariesDirectoryInjectable, () => "some-bin-directory");
|
||||
di.override(baseBundledBinariesDirectoryInjectable, () => "some-bin-directory");
|
||||
di.override(spawnInjectable, () => () => {
|
||||
return {
|
||||
stderr: { on: jest.fn(), removeAllListeners: jest.fn() },
|
||||
@@ -150,18 +181,6 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {})
|
||||
} as never;
|
||||
});
|
||||
|
||||
di.override(writeJsonFileInjectable, () => () => {
|
||||
throw new Error("Tried to write JSON file to file system without specifying explicit override.");
|
||||
});
|
||||
|
||||
di.override(readJsonFileInjectable, () => () => {
|
||||
throw new Error("Tried to read JSON file from file system without specifying explicit override.");
|
||||
});
|
||||
|
||||
di.override(readFileInjectable, () => () => {
|
||||
throw new Error("Tried to read file from file system without specifying explicit override.");
|
||||
});
|
||||
|
||||
di.override(loggerInjectable, () => ({
|
||||
warn: noop,
|
||||
debug: noop,
|
||||
@@ -204,6 +223,7 @@ const overrideOperatingSystem = (di: DiContainer) => {
|
||||
di.override(platformInjectable, () => "darwin");
|
||||
di.override(getAbsolutePathInjectable, () => getAbsolutePathFake);
|
||||
di.override(joinPathsInjectable, () => joinPathsFake);
|
||||
di.override(normalizedPlatformArchitectureInjectable, () => "arm64");
|
||||
};
|
||||
|
||||
const overrideElectronFeatures = (di: DiContainer) => {
|
||||
@@ -257,3 +277,11 @@ const overrideElectronFeatures = (di: DiContainer) => {
|
||||
di.override(publishIsConfiguredInjectable, () => false);
|
||||
di.override(electronUpdaterIsActiveInjectable, () => false);
|
||||
};
|
||||
|
||||
const overrideFunctionalInjectables = (di: DiContainer, injectables: Injectable<any, any, any>[]) => {
|
||||
injectables.forEach(injectable => {
|
||||
di.override(injectable, () => () => {
|
||||
throw new Error(`Tried to run "${injectable.id}" without explicit override.`);
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { sortCharts } from "../../../common/utils";
|
||||
import type { HelmRepo } from "../helm-repo-manager";
|
||||
import type { HelmRepo } from "../../../common/helm/helm-repo";
|
||||
|
||||
const charts = new Map([
|
||||
["stable", {
|
||||
|
||||
@@ -3,27 +3,48 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { helmService } from "../helm-service";
|
||||
import { HelmRepoManager } from "../helm-repo-manager";
|
||||
|
||||
const mockHelmRepoManager = jest.spyOn(HelmRepoManager, "getInstance").mockImplementation();
|
||||
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
|
||||
import listHelmChartsInjectable from "../helm-service/list-helm-charts.injectable";
|
||||
import getActiveHelmRepositoriesInjectable from "../repositories/get-active-helm-repositories/get-active-helm-repositories.injectable";
|
||||
import type { AsyncResult } from "../../../common/utils/async-result";
|
||||
import type { HelmRepo } from "../../../common/helm/helm-repo";
|
||||
|
||||
jest.mock("../helm-chart-manager");
|
||||
|
||||
describe("Helm Service tests", () => {
|
||||
let listHelmCharts: () => Promise<any>;
|
||||
let getActiveHelmRepositoriesMock: jest.Mock<Promise<AsyncResult<HelmRepo[]>>>;
|
||||
|
||||
beforeEach(() => {
|
||||
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||
|
||||
getActiveHelmRepositoriesMock = jest.fn();
|
||||
|
||||
di.override(getActiveHelmRepositoriesInjectable, () => getActiveHelmRepositoriesMock);
|
||||
|
||||
di.unoverride(listHelmChartsInjectable);
|
||||
di.permitSideEffects(listHelmChartsInjectable);
|
||||
|
||||
listHelmCharts = di.inject(listHelmChartsInjectable);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it("list charts with deprecated entries", async () => {
|
||||
mockHelmRepoManager.mockReturnValue({
|
||||
repositories: jest.fn().mockImplementation(async () => [
|
||||
{ name: "stable", url: "stableurl" },
|
||||
{ name: "experiment", url: "experimenturl" },
|
||||
]),
|
||||
} as any);
|
||||
getActiveHelmRepositoriesMock.mockReturnValue(
|
||||
Promise.resolve({
|
||||
callWasSuccessful: true,
|
||||
|
||||
const charts = await helmService.listCharts();
|
||||
response: [
|
||||
{ name: "stable", url: "stableurl" },
|
||||
{ name: "experiment", url: "experimenturl" },
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
const charts = await listHelmCharts();
|
||||
|
||||
expect(charts).toEqual({
|
||||
stable: {
|
||||
@@ -123,15 +144,14 @@ describe("Helm Service tests", () => {
|
||||
});
|
||||
|
||||
it("list charts sorted by version in descending order", async () => {
|
||||
mockHelmRepoManager.mockReturnValue({
|
||||
repositories: jest.fn().mockImplementation(async () => {
|
||||
return [
|
||||
{ name: "bitnami", url: "bitnamiurl" },
|
||||
];
|
||||
getActiveHelmRepositoriesMock.mockReturnValue(
|
||||
Promise.resolve({
|
||||
callWasSuccessful: true,
|
||||
response: [{ name: "bitnami", url: "bitnamiurl" }],
|
||||
}),
|
||||
} as any);
|
||||
);
|
||||
|
||||
const charts = await helmService.listCharts();
|
||||
const charts = await listHelmCharts();
|
||||
|
||||
expect(charts).toEqual({
|
||||
bitnami: {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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 execFileInjectable from "../../../common/fs/exec-file.injectable";
|
||||
import helmBinaryPathInjectable from "../helm-binary-path.injectable";
|
||||
import type { AsyncResult } from "../../../common/utils/async-result";
|
||||
import { getErrorMessage } from "../../../common/utils/get-error-message";
|
||||
|
||||
const execHelmInjectable = getInjectable({
|
||||
id: "exec-helm",
|
||||
|
||||
instantiate: (di) => {
|
||||
const execFile = di.inject(execFileInjectable);
|
||||
const helmBinaryPath = di.inject(helmBinaryPathInjectable);
|
||||
|
||||
return async (...args: string[]): Promise<AsyncResult<string>> => {
|
||||
try {
|
||||
const response = await execFile(helmBinaryPath, args);
|
||||
|
||||
return { callWasSuccessful: true, response };
|
||||
} catch (error) {
|
||||
return { callWasSuccessful: false, error: getErrorMessage(error) };
|
||||
}
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
export default execHelmInjectable;
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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 execHelmInjectable from "../exec-helm/exec-helm.injectable";
|
||||
import type { AsyncResult } from "../../../common/utils/async-result";
|
||||
|
||||
export type HelmEnv = Record<string, string> & {
|
||||
HELM_REPOSITORY_CACHE?: string;
|
||||
HELM_REPOSITORY_CONFIG?: string;
|
||||
};
|
||||
|
||||
const getHelmEnvInjectable = getInjectable({
|
||||
id: "get-helm-env",
|
||||
|
||||
instantiate: (di) => {
|
||||
const execHelm = di.inject(execHelmInjectable);
|
||||
|
||||
return async (): Promise<AsyncResult<HelmEnv>> => {
|
||||
const result = await execHelm("env");
|
||||
|
||||
if (!result.callWasSuccessful) {
|
||||
return { callWasSuccessful: false, error: result.error };
|
||||
}
|
||||
|
||||
const lines = result.response.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 { callWasSuccessful: true, response: env };
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default getHelmEnvInjectable;
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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 { getBinaryName } from "../../common/vars";
|
||||
import getAbsolutePathInjectable from "../../common/path/get-absolute-path.injectable";
|
||||
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
|
||||
import baseBundledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||
|
||||
const helmBinaryPathInjectable = getInjectable({
|
||||
id: "helm-binary-path",
|
||||
|
||||
instantiate: (di) => {
|
||||
const getAbsolutePath = di.inject(getAbsolutePathInjectable);
|
||||
const normalizedPlatform = di.inject(normalizedPlatformInjectable);
|
||||
const baseBundledBinariesDirectory = di.inject(baseBundledBinariesDirectoryInjectable);
|
||||
|
||||
const helmBinaryName = getBinaryName("helm", { forPlatform: normalizedPlatform });
|
||||
|
||||
return getAbsolutePath(baseBundledBinariesDirectory, helmBinaryName);
|
||||
},
|
||||
});
|
||||
|
||||
export default helmBinaryPathInjectable;
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
import fs from "fs";
|
||||
import * as yaml from "js-yaml";
|
||||
import type { HelmRepo } from "./helm-repo-manager";
|
||||
import logger from "../logger";
|
||||
import type { RepoHelmChartList } from "../../common/k8s-api/endpoints/helm-charts.api";
|
||||
import { iter, put, sortCharts } from "../../common/utils";
|
||||
import { execHelm } from "./exec";
|
||||
import type { SetRequired } from "type-fest";
|
||||
import { assert } from "console";
|
||||
import type { HelmRepo } from "../../common/helm/helm-repo";
|
||||
|
||||
interface ChartCacheEntry {
|
||||
data: string; // serialized JSON
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
/**
|
||||
* 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 yaml from "js-yaml";
|
||||
import { readFile } from "fs-extra";
|
||||
import { customRequestPromise } from "../../common/request";
|
||||
import orderBy from "lodash/orderBy";
|
||||
import logger from "../logger";
|
||||
import { execHelm } from "./exec";
|
||||
import type { HelmEnv, HelmRepo, HelmRepoConfig } from "./helm-repo-manager";
|
||||
|
||||
interface EnsuredHelmRepoManagerData {
|
||||
helmEnv: HelmEnv;
|
||||
didUpdateOnce: boolean;
|
||||
}
|
||||
|
||||
export class HelmRepoManager {
|
||||
protected helmEnv?: HelmEnv;
|
||||
protected didUpdateOnce?: boolean;
|
||||
|
||||
public 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(res.body as HelmRepo[], repo => repo.name);
|
||||
}
|
||||
|
||||
private async ensureInitialized(): Promise<EnsuredHelmRepoManagerData> {
|
||||
this.helmEnv ??= await this.parseHelmEnv();
|
||||
|
||||
const repos = await this.list(this.helmEnv);
|
||||
|
||||
if (repos.length === 0) {
|
||||
await this.addRepo({
|
||||
name: "bitnami",
|
||||
url: "https://charts.bitnami.com/bitnami",
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.didUpdateOnce) {
|
||||
await this.update();
|
||||
this.didUpdateOnce = true;
|
||||
}
|
||||
|
||||
return {
|
||||
didUpdateOnce: this.didUpdateOnce,
|
||||
helmEnv: this.helmEnv,
|
||||
};
|
||||
}
|
||||
|
||||
protected async parseHelmEnv() {
|
||||
const output = await execHelm(["env"]);
|
||||
const lines = output.split(/\r?\n/); // split by new line feed
|
||||
const env: Partial<Record<string, string>> = {};
|
||||
|
||||
lines.forEach((line: string) => {
|
||||
const [key, value] = line.split("=");
|
||||
|
||||
if (key && value) {
|
||||
env[key] = value.replace(/"/g, ""); // strip quotas
|
||||
}
|
||||
});
|
||||
|
||||
return env as HelmEnv;
|
||||
}
|
||||
|
||||
public async repo(name: string): Promise<HelmRepo | undefined> {
|
||||
const repos = await this.repositories();
|
||||
|
||||
return repos.find(repo => repo.name === name);
|
||||
}
|
||||
|
||||
private async list(helmEnv: HelmEnv): Promise<HelmRepo[]> {
|
||||
try {
|
||||
const rawConfig = await readFile(helmEnv.HELM_REPOSITORY_CONFIG, "utf8");
|
||||
const parsedConfig = yaml.load(rawConfig) as HelmRepoConfig;
|
||||
|
||||
if (typeof parsedConfig === "object" && parsedConfig) {
|
||||
return parsedConfig.repositories;
|
||||
}
|
||||
} catch {
|
||||
// ignore error
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public async repositories(): Promise<HelmRepo[]> {
|
||||
try {
|
||||
const { helmEnv } = await this.ensureInitialized();
|
||||
|
||||
const repos = await this.list(helmEnv);
|
||||
|
||||
return repos.map(repo => ({
|
||||
...repo,
|
||||
cacheFilePath: `${helmEnv.HELM_REPOSITORY_CACHE}/${repo.name}-index.yaml`,
|
||||
}));
|
||||
} catch (error) {
|
||||
logger.error(`[HELM]: repositories listing error`, error);
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public async update() {
|
||||
return execHelm([
|
||||
"repo",
|
||||
"update",
|
||||
]);
|
||||
}
|
||||
|
||||
public async addRepo({ name, url, insecureSkipTlsVerify, username, password, caFile, keyFile, certFile }: HelmRepo) {
|
||||
logger.info(`[HELM]: adding repo ${name} from ${url}`);
|
||||
const args = [
|
||||
"repo",
|
||||
"add",
|
||||
name,
|
||||
url,
|
||||
];
|
||||
|
||||
if (insecureSkipTlsVerify) {
|
||||
args.push("--insecure-skip-tls-verify");
|
||||
}
|
||||
|
||||
if (username) {
|
||||
args.push("--username", username);
|
||||
}
|
||||
|
||||
if (password) {
|
||||
args.push("--password", password);
|
||||
}
|
||||
|
||||
if (caFile) {
|
||||
args.push("--ca-file", caFile);
|
||||
}
|
||||
|
||||
if (keyFile) {
|
||||
args.push("--key-file", keyFile);
|
||||
}
|
||||
|
||||
if (certFile) {
|
||||
args.push("--cert-file", certFile);
|
||||
}
|
||||
|
||||
return execHelm(args);
|
||||
}
|
||||
|
||||
public async removeRepo({ name, url }: HelmRepo): Promise<string> {
|
||||
logger.info(`[HELM]: removing repo ${name} (${url})`);
|
||||
|
||||
return execHelm([
|
||||
"repo",
|
||||
"remove",
|
||||
name,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
const helmRepoManagerInjectable = getInjectable({
|
||||
id: "helm-repo-manager",
|
||||
|
||||
instantiate: () => new HelmRepoManager(),
|
||||
});
|
||||
|
||||
export default helmRepoManagerInjectable;
|
||||
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import {
|
||||
asLegacyGlobalSingletonForExtensionApi,
|
||||
} from "../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-singleton-object-for-extension-api";
|
||||
|
||||
import helmRepoManagerInjectable from "./helm-repo-manager.injectable";
|
||||
|
||||
export type HelmEnv = Partial<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 const HelmRepoManager = asLegacyGlobalSingletonForExtensionApi(helmRepoManagerInjectable);
|
||||
@@ -1,134 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { Cluster } from "../../common/cluster/cluster";
|
||||
import logger from "../logger";
|
||||
import { HelmRepoManager } from "./helm-repo-manager";
|
||||
import { HelmChartManager } from "./helm-chart-manager";
|
||||
import { deleteRelease, getHistory, getRelease, getValues, installChart, listReleases, rollback, upgradeRelease } from "./helm-release-manager";
|
||||
import type { JsonObject } from "type-fest";
|
||||
import { object } from "../../common/utils";
|
||||
|
||||
interface GetReleaseValuesArgs {
|
||||
cluster: Cluster;
|
||||
namespace: string;
|
||||
all: boolean;
|
||||
}
|
||||
|
||||
export interface InstallChartArgs {
|
||||
chart: string;
|
||||
values: JsonObject;
|
||||
name: string;
|
||||
namespace: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
export interface UpdateChartArgs {
|
||||
chart: string;
|
||||
values: JsonObject;
|
||||
version: string;
|
||||
}
|
||||
|
||||
class HelmService {
|
||||
public async installChart(cluster: Cluster, data: InstallChartArgs) {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
return installChart(data.chart, data.values, data.name, data.namespace, data.version, proxyKubeconfig);
|
||||
}
|
||||
|
||||
public async listCharts() {
|
||||
const repositories = await HelmRepoManager.getInstance().repositories();
|
||||
|
||||
return object.fromEntries(
|
||||
await Promise.all(repositories.map(async repo => [repo.name, await HelmChartManager.forRepo(repo).charts()] as const)),
|
||||
);
|
||||
}
|
||||
|
||||
public async getChart(repoName: string, chartName: string, version = "") {
|
||||
const repo = await HelmRepoManager.getInstance().repo(repoName);
|
||||
|
||||
if (!repo) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const chartManager = HelmChartManager.forRepo(repo);
|
||||
|
||||
return {
|
||||
readme: await chartManager.getReadme(chartName, version),
|
||||
versions: await chartManager.chartVersions(chartName),
|
||||
};
|
||||
}
|
||||
|
||||
public async getChartValues(repoName: string, chartName: string, version = "") {
|
||||
const repo = await HelmRepoManager.getInstance().repo(repoName);
|
||||
|
||||
if (!repo) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return HelmChartManager.forRepo(repo).getValues(chartName, version);
|
||||
}
|
||||
|
||||
public async listReleases(cluster: Cluster, namespace?: string) {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
logger.debug("list releases");
|
||||
|
||||
return listReleases(proxyKubeconfig, namespace);
|
||||
}
|
||||
|
||||
public async getRelease(cluster: Cluster, releaseName: string, namespace: string) {
|
||||
const kubeconfigPath = await cluster.getProxyKubeconfigPath();
|
||||
const kubectl = await cluster.ensureKubectl();
|
||||
const kubectlPath = await kubectl.getPath();
|
||||
|
||||
logger.debug("Fetch release");
|
||||
|
||||
return getRelease(releaseName, namespace, kubeconfigPath, kubectlPath);
|
||||
}
|
||||
|
||||
public async getReleaseValues(releaseName: string, { cluster, namespace, all }: GetReleaseValuesArgs) {
|
||||
const pathToKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
logger.debug("Fetch release values");
|
||||
|
||||
return getValues(releaseName, { namespace, all, kubeconfigPath: pathToKubeconfig });
|
||||
}
|
||||
|
||||
public async getReleaseHistory(cluster: Cluster, releaseName: string, namespace: string) {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
logger.debug("Fetch release history");
|
||||
|
||||
return getHistory(releaseName, namespace, proxyKubeconfig);
|
||||
}
|
||||
|
||||
public async deleteRelease(cluster: Cluster, releaseName: string, namespace: string) {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
logger.debug("Delete release");
|
||||
|
||||
return deleteRelease(releaseName, namespace, proxyKubeconfig);
|
||||
}
|
||||
|
||||
public async updateRelease(cluster: Cluster, releaseName: string, namespace: string, data: UpdateChartArgs) {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
const kubectl = await cluster.ensureKubectl();
|
||||
const kubectlPath = await kubectl.getPath();
|
||||
|
||||
logger.debug("Upgrade release");
|
||||
|
||||
return upgradeRelease(releaseName, data.chart, data.values, namespace, data.version, proxyKubeconfig, kubectlPath);
|
||||
}
|
||||
|
||||
public async rollback(cluster: Cluster, releaseName: string, namespace: string, revision: number) {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
logger.debug("Rollback release");
|
||||
await rollback(releaseName, namespace, revision, proxyKubeconfig);
|
||||
}
|
||||
}
|
||||
|
||||
export const helmService = new HelmService();
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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 type { Cluster } from "../../../common/cluster/cluster";
|
||||
import { deleteRelease } from "../helm-release-manager";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
|
||||
const deleteHelmReleaseInjectable = getInjectable({
|
||||
id: "delete-helm-release",
|
||||
|
||||
instantiate: (di) => {
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return async (cluster: Cluster, releaseName: string, namespace: string) => {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
logger.debug("Delete release");
|
||||
|
||||
return deleteRelease(releaseName, namespace, proxyKubeconfig);
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default deleteHelmReleaseInjectable;
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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 { HelmChartManager } from "../helm-chart-manager";
|
||||
import getActiveHelmRepositoryInjectable from "../repositories/get-active-helm-repository.injectable";
|
||||
|
||||
const getHelmChartValuesInjectable = getInjectable({
|
||||
id: "get-helm-chart-values",
|
||||
|
||||
instantiate: (di) => {
|
||||
const getActiveHelmRepository = di.inject(getActiveHelmRepositoryInjectable);
|
||||
|
||||
return async (repoName: string, chartName: string, version = "") => {
|
||||
const repo = await getActiveHelmRepository(repoName);
|
||||
|
||||
if (!repo) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return HelmChartManager.forRepo(repo).getValues(chartName, version);
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default getHelmChartValuesInjectable;
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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 { HelmChartManager } from "../helm-chart-manager";
|
||||
import getActiveHelmRepositoryInjectable from "../repositories/get-active-helm-repository.injectable";
|
||||
|
||||
const getHelmChartInjectable = getInjectable({
|
||||
id: "get-helm-chart",
|
||||
|
||||
instantiate: (di) => {
|
||||
const getActiveHelmRepository = di.inject(getActiveHelmRepositoryInjectable);
|
||||
|
||||
return async (repoName: string, chartName: string, version = "") => {
|
||||
const repo = await getActiveHelmRepository(repoName);
|
||||
|
||||
if (!repo) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const chartManager = HelmChartManager.forRepo(repo);
|
||||
|
||||
return {
|
||||
readme: await chartManager.getReadme(chartName, version),
|
||||
versions: await chartManager.chartVersions(chartName),
|
||||
};
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default getHelmChartInjectable;
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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 type { Cluster } from "../../../common/cluster/cluster";
|
||||
import { getHistory } from "../helm-release-manager";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
|
||||
const getHelmReleaseHistoryInjectable = getInjectable({
|
||||
id: "get-helm-release-history",
|
||||
|
||||
instantiate: (di) => {
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return async (cluster: Cluster, releaseName: string, namespace: string) => {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
logger.debug("Fetch release history");
|
||||
|
||||
return getHistory(releaseName, namespace, proxyKubeconfig);
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default getHelmReleaseHistoryInjectable;
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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 { getValues } from "../helm-release-manager";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import type { Cluster } from "../../../common/cluster/cluster";
|
||||
|
||||
interface GetReleaseValuesArgs {
|
||||
cluster: Cluster;
|
||||
namespace: string;
|
||||
all: boolean;
|
||||
}
|
||||
|
||||
const getHelmReleaseValuesInjectable = getInjectable({
|
||||
id: "get-helm-release-values",
|
||||
|
||||
instantiate: (di) => {
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return async (
|
||||
releaseName: string,
|
||||
{ cluster, namespace, all }: GetReleaseValuesArgs,
|
||||
) => {
|
||||
const pathToKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
logger.debug("Fetch release values");
|
||||
|
||||
return getValues(releaseName, {
|
||||
namespace,
|
||||
all,
|
||||
kubeconfigPath: pathToKubeconfig,
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default getHelmReleaseValuesInjectable;
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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 type { Cluster } from "../../../common/cluster/cluster";
|
||||
import { getRelease } from "../helm-release-manager";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
|
||||
const getHelmReleaseInjectable = getInjectable({
|
||||
id: "get-helm-release",
|
||||
|
||||
instantiate: (di) => {
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return async (cluster: Cluster, releaseName: string, namespace: string) => {
|
||||
const kubeconfigPath = await cluster.getProxyKubeconfigPath();
|
||||
const kubectl = await cluster.ensureKubectl();
|
||||
const kubectlPath = await kubectl.getPath();
|
||||
|
||||
logger.debug("Fetch release");
|
||||
|
||||
return getRelease(releaseName, namespace, kubeconfigPath, kubectlPath);
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default getHelmReleaseInjectable;
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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 type { JsonObject } from "type-fest";
|
||||
import type { Cluster } from "../../../common/cluster/cluster";
|
||||
import { installChart } from "../helm-release-manager";
|
||||
|
||||
export interface InstallChartArgs {
|
||||
chart: string;
|
||||
values: JsonObject;
|
||||
name: string;
|
||||
namespace: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
const installHelmChartInjectable = getInjectable({
|
||||
id: "install-helm-chart",
|
||||
|
||||
instantiate: () => async (cluster: Cluster, data: InstallChartArgs) => {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
return installChart(data.chart, data.values, data.name, data.namespace, data.version, proxyKubeconfig);
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default installHelmChartInjectable;
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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 assert from "assert";
|
||||
import { object } from "../../../common/utils";
|
||||
import { HelmChartManager } from "../helm-chart-manager";
|
||||
import getActiveHelmRepositoriesInjectable from "../repositories/get-active-helm-repositories/get-active-helm-repositories.injectable";
|
||||
|
||||
const listHelmChartsInjectable = getInjectable({
|
||||
id: "list-helm-charts",
|
||||
|
||||
instantiate: (di) => {
|
||||
const getActiveHelmRepositories = di.inject(getActiveHelmRepositoriesInjectable);
|
||||
|
||||
return async () => {
|
||||
const result = await getActiveHelmRepositories();
|
||||
|
||||
assert(result.callWasSuccessful);
|
||||
|
||||
const repositories = result.response;
|
||||
|
||||
return object.fromEntries(
|
||||
await Promise.all(
|
||||
repositories.map(
|
||||
async (repo) =>
|
||||
[
|
||||
repo.name,
|
||||
await HelmChartManager.forRepo(repo).charts(),
|
||||
] as const,
|
||||
),
|
||||
),
|
||||
);
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default listHelmChartsInjectable;
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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 type { Cluster } from "../../../common/cluster/cluster";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import { listReleases } from "../helm-release-manager";
|
||||
|
||||
const listHelmReleasesInjectable = getInjectable({
|
||||
id: "list-helm-releases",
|
||||
|
||||
instantiate: (di) => {
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return async (cluster: Cluster, namespace?: string) => {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
logger.debug("list releases");
|
||||
|
||||
return listReleases(proxyKubeconfig, namespace);
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default listHelmReleasesInjectable;
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 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 type { Cluster } from "../../../common/cluster/cluster";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import { rollback } from "../helm-release-manager";
|
||||
|
||||
const rollbackHelmReleaseInjectable = getInjectable({
|
||||
id: "rollback-helm-release",
|
||||
|
||||
instantiate: (di) => {
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return async (
|
||||
cluster: Cluster,
|
||||
releaseName: string,
|
||||
namespace: string,
|
||||
revision: number,
|
||||
) => {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
|
||||
logger.debug("Rollback release");
|
||||
await rollback(releaseName, namespace, revision, proxyKubeconfig);
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default rollbackHelmReleaseInjectable;
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 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 type { Cluster } from "../../../common/cluster/cluster";
|
||||
import { upgradeRelease } from "../helm-release-manager";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import type { JsonObject } from "type-fest";
|
||||
|
||||
export interface UpdateChartArgs {
|
||||
chart: string;
|
||||
values: JsonObject;
|
||||
version: string;
|
||||
}
|
||||
|
||||
const updateHelmReleaseInjectable = getInjectable({
|
||||
id: "update-helm-release",
|
||||
|
||||
instantiate: (di) => {
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return async (cluster: Cluster, releaseName: string, namespace: string, data: UpdateChartArgs) => {
|
||||
const proxyKubeconfig = await cluster.getProxyKubeconfigPath();
|
||||
const kubectl = await cluster.ensureKubectl();
|
||||
const kubectlPath = await kubectl.getPath();
|
||||
|
||||
logger.debug("Upgrade release");
|
||||
|
||||
return upgradeRelease(
|
||||
releaseName,
|
||||
data.chart,
|
||||
data.values,
|
||||
namespace,
|
||||
data.version,
|
||||
proxyKubeconfig,
|
||||
kubectlPath,
|
||||
);
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default updateHelmReleaseInjectable;
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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 addHelmRepositoryChannelInjectable from "../../../../common/helm/add-helm-repository-channel.injectable";
|
||||
import addHelmRepositoryInjectable from "./add-helm-repository.injectable";
|
||||
import { requestChannelListenerInjectionToken } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
|
||||
const addHelmRepositoryChannelListenerInjectable = getInjectable({
|
||||
id: "add-helm-repository-channel-listener",
|
||||
|
||||
instantiate: (di) => {
|
||||
const addHelmRepository = di.inject(addHelmRepositoryInjectable);
|
||||
const channel = di.inject(addHelmRepositoryChannelInjectable);
|
||||
|
||||
return {
|
||||
channel,
|
||||
handler: addHelmRepository,
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: requestChannelListenerInjectionToken,
|
||||
});
|
||||
|
||||
export default addHelmRepositoryChannelListenerInjectable;
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* 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 execHelmInjectable from "../../exec-helm/exec-helm.injectable";
|
||||
import type { HelmRepo } from "../../../../common/helm/helm-repo";
|
||||
import loggerInjectable from "../../../../common/logger.injectable";
|
||||
|
||||
const addHelmRepositoryInjectable = getInjectable({
|
||||
id: "add-helm-repository",
|
||||
|
||||
instantiate: (di) => {
|
||||
const execHelm = di.inject(execHelmInjectable);
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return async (repo: HelmRepo) => {
|
||||
const {
|
||||
name,
|
||||
url,
|
||||
insecureSkipTlsVerify,
|
||||
username,
|
||||
password,
|
||||
caFile,
|
||||
keyFile,
|
||||
certFile,
|
||||
} = repo;
|
||||
|
||||
logger.info(`[HELM]: adding repo ${name} from ${url}`);
|
||||
|
||||
const args = ["repo", "add", name, url];
|
||||
|
||||
if (insecureSkipTlsVerify) {
|
||||
args.push("--insecure-skip-tls-verify");
|
||||
}
|
||||
|
||||
if (username) {
|
||||
args.push("--username", username);
|
||||
}
|
||||
|
||||
if (password) {
|
||||
args.push("--password", password);
|
||||
}
|
||||
|
||||
if (caFile) {
|
||||
args.push("--ca-file", caFile);
|
||||
}
|
||||
|
||||
if (keyFile) {
|
||||
args.push("--key-file", keyFile);
|
||||
}
|
||||
|
||||
if (certFile) {
|
||||
args.push("--cert-file", certFile);
|
||||
}
|
||||
|
||||
return await execHelm(...args);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default addHelmRepositoryInjectable;
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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 { requestChannelListenerInjectionToken } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import getActiveHelmRepositoriesChannelInjectable from "../../../../common/helm/get-active-helm-repositories-channel.injectable";
|
||||
import getActiveHelmRepositoriesInjectable from "./get-active-helm-repositories.injectable";
|
||||
|
||||
const getActiveHelmRepositoriesChannelListenerInjectable = getInjectable({
|
||||
id: "get-active-helm-repositories-channel-listener",
|
||||
|
||||
instantiate: (di) => {
|
||||
const getActiveHelmRepositories = di.inject(getActiveHelmRepositoriesInjectable);
|
||||
|
||||
return {
|
||||
channel: di.inject(getActiveHelmRepositoriesChannelInjectable),
|
||||
|
||||
handler: getActiveHelmRepositories,
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: requestChannelListenerInjectionToken,
|
||||
});
|
||||
|
||||
export default getActiveHelmRepositoriesChannelListenerInjectable;
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* 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 type { HelmRepo } from "../../../../common/helm/helm-repo";
|
||||
import type { ReadYamlFile } from "../../../../common/fs/read-yaml-file.injectable";
|
||||
import readYamlFileInjectable from "../../../../common/fs/read-yaml-file.injectable";
|
||||
import getHelmEnvInjectable from "../../get-helm-env/get-helm-env.injectable";
|
||||
import execHelmInjectable from "../../exec-helm/exec-helm.injectable";
|
||||
import loggerInjectable from "../../../../common/logger.injectable";
|
||||
import type { AsyncResult } from "../../../../common/utils/async-result";
|
||||
|
||||
interface HelmRepositoryFromYaml {
|
||||
name: string;
|
||||
url: string;
|
||||
caFile: string;
|
||||
certFile: string;
|
||||
insecure_skip_tls_verify: boolean;
|
||||
keyFile: string;
|
||||
pass_credentials_all: boolean;
|
||||
password: string;
|
||||
username: string;
|
||||
}
|
||||
|
||||
export interface HelmRepositoriesFromYaml {
|
||||
repositories: HelmRepositoryFromYaml[];
|
||||
}
|
||||
|
||||
const getActiveHelmRepositoriesInjectable = getInjectable({
|
||||
id: "get-helm-repositories",
|
||||
|
||||
instantiate: (di) => {
|
||||
const readYamlFile = di.inject(readYamlFileInjectable);
|
||||
const execHelm = di.inject(execHelmInjectable);
|
||||
const getHelmEnv = di.inject(getHelmEnvInjectable);
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
const getRepositories = getRepositoriesFor(readYamlFile);
|
||||
|
||||
return async (): Promise<AsyncResult<HelmRepo[]>> => {
|
||||
const envResult = await getHelmEnv();
|
||||
|
||||
if (!envResult.callWasSuccessful) {
|
||||
return {
|
||||
callWasSuccessful: false,
|
||||
error: `Error getting Helm configuration: ${envResult.error}`,
|
||||
};
|
||||
}
|
||||
|
||||
const {
|
||||
HELM_REPOSITORY_CONFIG: repositoryConfigFilePath,
|
||||
HELM_REPOSITORY_CACHE: helmRepositoryCacheDirPath,
|
||||
} = envResult.response;
|
||||
|
||||
if (!repositoryConfigFilePath) {
|
||||
const errorMessage = "Tried to get Helm repositories, but HELM_REPOSITORY_CONFIG was not present in `$ helm env`.";
|
||||
|
||||
logger.error(errorMessage);
|
||||
|
||||
return {
|
||||
callWasSuccessful: false,
|
||||
error: `Error getting Helm configuration: ${errorMessage}`,
|
||||
};
|
||||
}
|
||||
|
||||
if (!helmRepositoryCacheDirPath) {
|
||||
const errorMessage = "Tried to get Helm repositories, but HELM_REPOSITORY_CACHE was not present in `$ helm env`.";
|
||||
|
||||
logger.error(errorMessage);
|
||||
|
||||
return {
|
||||
callWasSuccessful: false,
|
||||
error: `Error getting Helm configuration: ${errorMessage}`,
|
||||
};
|
||||
}
|
||||
|
||||
const updateResult = await execHelm("repo", "update");
|
||||
|
||||
if (!updateResult.callWasSuccessful) {
|
||||
if (!updateResult.error.includes(internalHelmErrorForNoRepositoriesFound)) {
|
||||
return {
|
||||
callWasSuccessful: false,
|
||||
error: `Error updating Helm repositories: ${updateResult.error}`,
|
||||
};
|
||||
}
|
||||
const resultOfAddingDefaultRepository = await execHelm("repo", "add", "bitnami", "https://charts.bitnami.com/bitnami");
|
||||
|
||||
if (!resultOfAddingDefaultRepository.callWasSuccessful) {
|
||||
return {
|
||||
callWasSuccessful: false,
|
||||
error: `Error when adding default Helm repository: ${resultOfAddingDefaultRepository.error}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
callWasSuccessful: true,
|
||||
|
||||
response: await getRepositories(
|
||||
repositoryConfigFilePath,
|
||||
helmRepositoryCacheDirPath,
|
||||
),
|
||||
};
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default getActiveHelmRepositoriesInjectable;
|
||||
|
||||
const getRepositoriesFor =
|
||||
(readYamlFile: ReadYamlFile) =>
|
||||
async (repositoryConfigFilePath: string, helmRepositoryCacheDirPath: string): Promise<HelmRepo[]> => {
|
||||
const { repositories } = (await readYamlFile(
|
||||
repositoryConfigFilePath,
|
||||
)) as HelmRepositoriesFromYaml;
|
||||
|
||||
return repositories.map((repository) => ({
|
||||
name: repository.name,
|
||||
url: repository.url,
|
||||
caFile: repository.caFile,
|
||||
certFile: repository.certFile,
|
||||
insecureSkipTlsVerify: repository.insecure_skip_tls_verify,
|
||||
keyFile: repository.keyFile,
|
||||
username: repository.username,
|
||||
password: repository.password,
|
||||
cacheFilePath: `${helmRepositoryCacheDirPath}/${repository.name}-index.yaml`,
|
||||
}));
|
||||
};
|
||||
|
||||
const internalHelmErrorForNoRepositoriesFound = "no repositories found. You must add one before updating";
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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 assert from "assert";
|
||||
import getActiveHelmRepositoriesInjectable from "./get-active-helm-repositories/get-active-helm-repositories.injectable";
|
||||
|
||||
const getActiveHelmRepositoryInjectable = getInjectable({
|
||||
id: "get-active-helm-repository",
|
||||
|
||||
instantiate: (di) => {
|
||||
const getActiveHelmRepositories = di.inject(getActiveHelmRepositoriesInjectable);
|
||||
|
||||
return async (name: string) => {
|
||||
const activeHelmRepositories = await getActiveHelmRepositories();
|
||||
|
||||
assert(activeHelmRepositories.callWasSuccessful);
|
||||
|
||||
return activeHelmRepositories.response.find(
|
||||
(repository) => repository.name === name,
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default getActiveHelmRepositoryInjectable;
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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 { requestChannelListenerInjectionToken } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import removeHelmRepositoryInjectable from "./remove-helm-repository.injectable";
|
||||
import removeHelmRepositoryChannelInjectable from "../../../../common/helm/remove-helm-repository-channel.injectable";
|
||||
|
||||
const removeHelmRepositoryChannelListenerInjectable = getInjectable({
|
||||
id: "remove-helm-repository-channel-listener",
|
||||
|
||||
instantiate: (di) => {
|
||||
const removeHelmRepository = di.inject(removeHelmRepositoryInjectable);
|
||||
const channel = di.inject(removeHelmRepositoryChannelInjectable);
|
||||
|
||||
return {
|
||||
channel,
|
||||
handler: removeHelmRepository,
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: requestChannelListenerInjectionToken,
|
||||
});
|
||||
|
||||
export default removeHelmRepositoryChannelListenerInjectable;
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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 execHelmInjectable from "../../exec-helm/exec-helm.injectable";
|
||||
import type { HelmRepo } from "../../../../common/helm/helm-repo";
|
||||
import loggerInjectable from "../../../../common/logger.injectable";
|
||||
|
||||
const removeHelmRepositoryInjectable = getInjectable({
|
||||
id: "remove-helm-repository",
|
||||
|
||||
instantiate: (di) => {
|
||||
const execHelm = di.inject(execHelmInjectable);
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return async (repo: HelmRepo) => {
|
||||
logger.info(`[HELM]: removing repo ${repo.name} (${repo.url})`);
|
||||
|
||||
return execHelm(
|
||||
"repo",
|
||||
"remove",
|
||||
repo.name,
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default removeHelmRepositoryInjectable;
|
||||
@@ -12,7 +12,7 @@ import { getBinaryName } from "../../common/vars";
|
||||
import spawnInjectable from "../child-process/spawn.injectable";
|
||||
import { getKubeAuthProxyCertificate } from "./get-kube-auth-proxy-certificate";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import baseBundeledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||
import baseBundledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||
|
||||
export type CreateKubeAuthProxy = (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => KubeAuthProxy;
|
||||
|
||||
@@ -25,7 +25,7 @@ const createKubeAuthProxyInjectable = getInjectable({
|
||||
return (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => {
|
||||
const clusterUrl = new URL(cluster.apiUrl);
|
||||
const dependencies: KubeAuthProxyDependencies = {
|
||||
proxyBinPath: path.join(di.inject(baseBundeledBinariesDirectoryInjectable), binaryName),
|
||||
proxyBinPath: path.join(di.inject(baseBundledBinariesDirectoryInjectable), binaryName),
|
||||
proxyCert: getKubeAuthProxyCertificate(clusterUrl.hostname, selfsigned.generate),
|
||||
spawn: di.inject(spawnInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import path from "path";
|
||||
import baseBundeledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||
import baseBundledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||
import kubectlBinaryNameInjectable from "./binary-name.injectable";
|
||||
|
||||
const bundledKubectlBinaryPathInjectable = getInjectable({
|
||||
id: "bundled-kubectl-binary-path",
|
||||
instantiate: (di) => path.join(
|
||||
di.inject(baseBundeledBinariesDirectoryInjectable),
|
||||
di.inject(baseBundledBinariesDirectoryInjectable),
|
||||
di.inject(kubectlBinaryNameInjectable),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ import kubectlDownloadingNormalizedArchInjectable from "./normalized-arch.inject
|
||||
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
|
||||
import kubectlBinaryNameInjectable from "./binary-name.injectable";
|
||||
import bundledKubectlBinaryPathInjectable from "./bundled-binary-path.injectable";
|
||||
import baseBundeledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||
import baseBundledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||
|
||||
const createKubectlInjectable = getInjectable({
|
||||
id: "create-kubectl",
|
||||
@@ -24,7 +24,7 @@ const createKubectlInjectable = getInjectable({
|
||||
normalizedDownloadPlatform: di.inject(normalizedPlatformInjectable),
|
||||
kubectlBinaryName: di.inject(kubectlBinaryNameInjectable),
|
||||
bundledKubectlBinaryPath: di.inject(bundledKubectlBinaryPathInjectable),
|
||||
baseBundeledBinariesDirectory: di.inject(baseBundeledBinariesDirectoryInjectable),
|
||||
baseBundeledBinariesDirectory: di.inject(baseBundledBinariesDirectoryInjectable),
|
||||
};
|
||||
|
||||
return (clusterVersion: string) => new Kubectl(dependencies, clusterVersion);
|
||||
|
||||
@@ -5,25 +5,29 @@
|
||||
import { getRouteInjectable } from "../../../router/router.injectable";
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import { route } from "../../../router/route";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
import getHelmChartInjectable from "../../../helm/helm-service/get-helm-chart.injectable";
|
||||
|
||||
const getChartRouteInjectable = getRouteInjectable({
|
||||
id: "get-chart-route",
|
||||
|
||||
instantiate: () => route({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/charts/{repo}/{chart}`,
|
||||
})(async ({ params, query }) => {
|
||||
const { repo, chart } = params;
|
||||
instantiate: (di) => {
|
||||
const getHelmChart = di.inject(getHelmChartInjectable);
|
||||
|
||||
return {
|
||||
response: await helmService.getChart(
|
||||
repo,
|
||||
chart,
|
||||
query.get("version") ?? undefined,
|
||||
),
|
||||
};
|
||||
}),
|
||||
return route({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/charts/{repo}/{chart}`,
|
||||
})(async ({ params, query }) => {
|
||||
const { repo, chart } = params;
|
||||
|
||||
return {
|
||||
response: await getHelmChart(
|
||||
repo,
|
||||
chart,
|
||||
query.get("version") ?? undefined,
|
||||
),
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default getChartRouteInjectable;
|
||||
@@ -3,23 +3,27 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getRouteInjectable } from "../../../router/router.injectable";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import { route } from "../../../router/route";
|
||||
import getHelmChartValuesInjectable from "../../../helm/helm-service/get-helm-chart-values.injectable";
|
||||
|
||||
const getChartRouteValuesInjectable = getRouteInjectable({
|
||||
id: "get-chart-route-values",
|
||||
|
||||
instantiate: () => route({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/charts/{repo}/{chart}/values`,
|
||||
})(async ({ params, query }) => ({
|
||||
response: await helmService.getChartValues(
|
||||
params.repo,
|
||||
params.chart,
|
||||
query.get("version") ?? undefined,
|
||||
),
|
||||
})),
|
||||
instantiate: (di) => {
|
||||
const getHelmChartValues = di.inject(getHelmChartValuesInjectable);
|
||||
|
||||
return route({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/charts/{repo}/{chart}/values`,
|
||||
})(async ({ params, query }) => ({
|
||||
response: await getHelmChartValues(
|
||||
params.repo,
|
||||
params.chart,
|
||||
query.get("version") ?? undefined,
|
||||
),
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export default getChartRouteValuesInjectable;
|
||||
@@ -3,19 +3,23 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getRouteInjectable } from "../../../router/router.injectable";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import { route } from "../../../router/route";
|
||||
import listHelmChartsInjectable from "../../../helm/helm-service/list-helm-charts.injectable";
|
||||
|
||||
const listChartsRouteInjectable = getRouteInjectable({
|
||||
id: "list-charts-route",
|
||||
|
||||
instantiate: () => route({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/charts`,
|
||||
})(async () => ({
|
||||
response: await helmService.listCharts(),
|
||||
})),
|
||||
instantiate: (di) => {
|
||||
const listHelmCharts = di.inject(listHelmChartsInjectable);
|
||||
|
||||
return route({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/charts`,
|
||||
})(async () => ({
|
||||
response: await listHelmCharts(),
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export default listChartsRouteInjectable;
|
||||
@@ -3,23 +3,23 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
import { getRouteInjectable } from "../../../router/router.injectable";
|
||||
import { clusterRoute } from "../../../router/route";
|
||||
import deleteHelmReleaseInjectable from "../../../helm/helm-service/delete-helm-release.injectable";
|
||||
|
||||
const deleteReleaseRouteInjectable = getRouteInjectable({
|
||||
id: "delete-release-route",
|
||||
|
||||
instantiate: () => clusterRoute({
|
||||
method: "delete",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}`,
|
||||
})(async ({ cluster, params: { release, namespace }}) => ({
|
||||
response: await helmService.deleteRelease(
|
||||
cluster,
|
||||
release,
|
||||
namespace,
|
||||
),
|
||||
})),
|
||||
instantiate: (di) => {
|
||||
const deleteHelmRelease = di.inject(deleteHelmReleaseInjectable);
|
||||
|
||||
return clusterRoute({
|
||||
method: "delete",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}`,
|
||||
})(async ({ cluster, params: { release, namespace }}) => ({
|
||||
response: await deleteHelmRelease(cluster, release, namespace),
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export default deleteReleaseRouteInjectable;
|
||||
@@ -3,23 +3,27 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
import { getRouteInjectable } from "../../../router/router.injectable";
|
||||
import { clusterRoute } from "../../../router/route";
|
||||
import getHelmReleaseHistoryInjectable from "../../../helm/helm-service/get-helm-release-history.injectable";
|
||||
|
||||
const getReleaseRouteHistoryInjectable = getRouteInjectable({
|
||||
id: "get-release-history-route",
|
||||
|
||||
instantiate: () => clusterRoute({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}/history`,
|
||||
})(async ({ cluster, params }) => ({
|
||||
response: await helmService.getReleaseHistory(
|
||||
cluster,
|
||||
params.release,
|
||||
params.namespace,
|
||||
),
|
||||
})),
|
||||
instantiate: (di) => {
|
||||
const getHelmReleaseHistory = di.inject(getHelmReleaseHistoryInjectable);
|
||||
|
||||
return clusterRoute({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}/history`,
|
||||
})(async ({ cluster, params }) => ({
|
||||
response: await getHelmReleaseHistory(
|
||||
cluster,
|
||||
params.release,
|
||||
params.namespace,
|
||||
),
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export default getReleaseRouteHistoryInjectable;
|
||||
@@ -3,23 +3,27 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
import { getRouteInjectable } from "../../../router/router.injectable";
|
||||
import { clusterRoute } from "../../../router/route";
|
||||
import getHelmReleaseInjectable from "../../../helm/helm-service/get-helm-release.injectable";
|
||||
|
||||
const getReleaseRouteInjectable = getRouteInjectable({
|
||||
id: "get-release-route",
|
||||
|
||||
instantiate: () => clusterRoute({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}`,
|
||||
})(async ({ cluster, params }) => ({
|
||||
response: await helmService.getRelease(
|
||||
cluster,
|
||||
params.release,
|
||||
params.namespace,
|
||||
),
|
||||
})),
|
||||
instantiate: (di) => {
|
||||
const getHelmRelease = di.inject(getHelmReleaseInjectable);
|
||||
|
||||
return clusterRoute({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}`,
|
||||
})(async ({ cluster, params }) => ({
|
||||
response: await getHelmRelease(
|
||||
cluster,
|
||||
params.release,
|
||||
params.namespace,
|
||||
),
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export default getReleaseRouteInjectable;
|
||||
@@ -3,27 +3,31 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
import { getRouteInjectable } from "../../../router/router.injectable";
|
||||
import { getBoolean } from "../../../utils/parse-query";
|
||||
import { contentTypes } from "../../../router/router-content-types";
|
||||
import { clusterRoute } from "../../../router/route";
|
||||
import getHelmReleaseValuesInjectable from "../../../helm/helm-service/get-helm-release-values.injectable";
|
||||
|
||||
const getReleaseRouteValuesInjectable = getRouteInjectable({
|
||||
id: "get-release-values-route",
|
||||
|
||||
instantiate: () => clusterRoute({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}/values`,
|
||||
})(async ({ cluster, params: { namespace, release }, query }) => ({
|
||||
response: await helmService.getReleaseValues(release, {
|
||||
cluster,
|
||||
namespace,
|
||||
all: getBoolean(query, "all"),
|
||||
}),
|
||||
instantiate: (di) => {
|
||||
const getHelmReleaseValues = di.inject(getHelmReleaseValuesInjectable);
|
||||
|
||||
contentType: contentTypes.txt,
|
||||
})),
|
||||
return clusterRoute({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}/values`,
|
||||
})(async ({ cluster, params: { namespace, release }, query }) => ({
|
||||
response: await getHelmReleaseValues(release, {
|
||||
cluster,
|
||||
namespace,
|
||||
all: getBoolean(query, "all"),
|
||||
}),
|
||||
|
||||
contentType: contentTypes.txt,
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export default getReleaseRouteValuesInjectable;
|
||||
@@ -3,11 +3,11 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import type { InstallChartArgs } from "../../../helm/helm-service";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
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";
|
||||
|
||||
const installChartArgsValidator = Joi.object<InstallChartArgs, true, InstallChartArgs>({
|
||||
chart: Joi
|
||||
@@ -31,14 +31,18 @@ const installChartArgsValidator = Joi.object<InstallChartArgs, true, InstallChar
|
||||
const installChartRouteInjectable = getRouteInjectable({
|
||||
id: "install-chart-route",
|
||||
|
||||
instantiate: () => payloadValidatedClusterRoute({
|
||||
method: "post",
|
||||
path: `${apiPrefix}/v2/releases`,
|
||||
payloadValidator: installChartArgsValidator,
|
||||
})(async ({ payload, cluster }) => ({
|
||||
response: await helmService.installChart(cluster, payload),
|
||||
statusCode: 201,
|
||||
})),
|
||||
instantiate: (di) => {
|
||||
const installHelmChart = di.inject(installHelmChartInjectable);
|
||||
|
||||
return payloadValidatedClusterRoute({
|
||||
method: "post",
|
||||
path: `${apiPrefix}/v2/releases`,
|
||||
payloadValidator: installChartArgsValidator,
|
||||
})(async ({ payload, cluster }) => ({
|
||||
response: await installHelmChart(cluster, payload),
|
||||
statusCode: 201,
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export default installChartRouteInjectable;
|
||||
@@ -3,19 +3,23 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
import { getRouteInjectable } from "../../../router/router.injectable";
|
||||
import { clusterRoute } from "../../../router/route";
|
||||
import listHelmReleasesInjectable from "../../../helm/helm-service/list-helm-releases.injectable";
|
||||
|
||||
const listReleasesRouteInjectable = getRouteInjectable({
|
||||
id: "list-releases-route",
|
||||
|
||||
instantiate: () => clusterRoute({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/releases/{namespace?}`,
|
||||
})(async ({ cluster, params }) => ({
|
||||
response: await helmService.listReleases(cluster, params.namespace),
|
||||
})),
|
||||
instantiate: (di) => {
|
||||
const listHelmReleases = di.inject(listHelmReleasesInjectable);
|
||||
|
||||
return clusterRoute({
|
||||
method: "get",
|
||||
path: `${apiPrefix}/v2/releases/{namespace?}`,
|
||||
})(async ({ cluster, params }) => ({
|
||||
response: await listHelmReleases(cluster, params.namespace),
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export default listReleasesRouteInjectable;
|
||||
@@ -3,10 +3,10 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
import { getRouteInjectable } from "../../../router/router.injectable";
|
||||
import Joi from "joi";
|
||||
import { payloadValidatedClusterRoute } from "../../../router/route";
|
||||
import rollbackHelmReleaseInjectable from "../../../helm/helm-service/rollback-helm-release.injectable";
|
||||
|
||||
interface RollbackReleasePayload {
|
||||
revision: number;
|
||||
@@ -21,13 +21,17 @@ const rollbackReleasePayloadValidator = Joi.object<RollbackReleasePayload, true,
|
||||
const rollbackReleaseRouteInjectable = getRouteInjectable({
|
||||
id: "rollback-release-route",
|
||||
|
||||
instantiate: () => payloadValidatedClusterRoute({
|
||||
method: "put",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}/rollback`,
|
||||
payloadValidator: rollbackReleasePayloadValidator,
|
||||
})(async ({ cluster, params: { release, namespace }, payload }) => {
|
||||
await helmService.rollback(cluster, release, namespace, payload.revision);
|
||||
}),
|
||||
instantiate: (di) => {
|
||||
const rollbackRelease = di.inject(rollbackHelmReleaseInjectable);
|
||||
|
||||
return payloadValidatedClusterRoute({
|
||||
method: "put",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}/rollback`,
|
||||
payloadValidator: rollbackReleasePayloadValidator,
|
||||
})(async ({ cluster, params: { release, namespace }, payload }) => {
|
||||
await rollbackRelease(cluster, release, namespace, payload.revision);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default rollbackReleaseRouteInjectable;
|
||||
@@ -3,11 +3,11 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { apiPrefix } from "../../../../common/vars";
|
||||
import type { UpdateChartArgs } from "../../../helm/helm-service";
|
||||
import { helmService } from "../../../helm/helm-service";
|
||||
import { getRouteInjectable } from "../../../router/router.injectable";
|
||||
import { payloadValidatedClusterRoute } from "../../../router/route";
|
||||
import Joi from "joi";
|
||||
import type { UpdateChartArgs } from "../../../helm/helm-service/update-helm-release.injectable";
|
||||
import updateHelmReleaseInjectable from "../../../helm/helm-service/update-helm-release.injectable";
|
||||
|
||||
const updateChartArgsValidator = Joi.object<UpdateChartArgs, true, UpdateChartArgs>({
|
||||
chart: Joi
|
||||
@@ -24,18 +24,22 @@ const updateChartArgsValidator = Joi.object<UpdateChartArgs, true, UpdateChartAr
|
||||
const updateReleaseRouteInjectable = getRouteInjectable({
|
||||
id: "update-release-route",
|
||||
|
||||
instantiate: () => payloadValidatedClusterRoute({
|
||||
method: "put",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}`,
|
||||
payloadValidator: updateChartArgsValidator,
|
||||
})(async ({ cluster, params, payload }) => ({
|
||||
response: await helmService.updateRelease(
|
||||
cluster,
|
||||
params.release,
|
||||
params.namespace,
|
||||
payload,
|
||||
),
|
||||
})),
|
||||
instantiate: (di) => {
|
||||
const updateRelease = di.inject(updateHelmReleaseInjectable);
|
||||
|
||||
return payloadValidatedClusterRoute({
|
||||
method: "put",
|
||||
path: `${apiPrefix}/v2/releases/{namespace}/{release}`,
|
||||
payloadValidator: updateChartArgsValidator,
|
||||
})(async ({ cluster, params, payload }) => ({
|
||||
response: await updateRelease(
|
||||
cluster,
|
||||
params.release,
|
||||
params.namespace,
|
||||
payload,
|
||||
),
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export default updateReleaseRouteInjectable;
|
||||
Reference in new issue
Block a user