From 83970fb5a45dfb61c80c4186efec498ecde69dad Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Tue, 9 Aug 2022 10:17:13 -0400 Subject: [PATCH] Convert all of Helm functions to be DI Signed-off-by: Sebastian Malton --- .../k8s-api/endpoints/helm-charts.api.ts | 65 +- .../helm-charts.api/get-readme.injectable.ts | 24 + .../helm-charts.api/get-values.injectable.ts | 24 + .../get-versions.injectable.ts | 31 + .../helm-charts.api/list.injectable.ts | 34 + .../k8s-api/endpoints/helm-releases.api.ts | 53 +- .../helm-releases.api/create.injectable.ts | 42 + .../helm-releases.api/delete.injectable.ts | 22 + .../get-configuration.injectable.ts | 31 + .../get-details.injectable.ts | 41 + .../get-history.injectable.ts | 31 + .../get-values.injectable.ts | 22 + .../helm-releases.api/list.injectable.ts | 24 + .../helm-releases.api/rollback.injectable.ts | 27 + .../helm-releases.api/update.injectable.ts | 49 + src/common/utils/buildUrl.ts | 21 + ...installing-helm-chart-from-new-tab.test.ts | 1251 +++++++++-------- ...m-chart-from-previously-opened-tab.test.ts | 57 +- ...dock-tab-for-installing-helm-chart.test.ts | 91 +- .../showing-details-for-helm-release.test.ts | 134 +- src/main/getDiForUnitTesting.ts | 4 +- ...ts => get-helm-chart-readme.injectable.ts} | 13 +- .../get-helm-chart-versions.injectable.ts | 29 + ...able.ts => get-readme-route.injectable.ts} | 14 +- ...able.ts => get-values-route.injectable.ts} | 6 +- .../charts/get-versions-route.injectable.ts | 25 + ...injectable.ts => list-route.injectable.ts} | 6 +- ...eadme-of-selected-helm-chart.injectable.ts | 6 +- .../call-for-helm-chart-readme.injectable.ts | 29 - ...sions-of-selected-helm-chart.injectable.ts | 6 +- ...call-for-helm-chart-versions.injectable.ts | 28 - .../get-char-details.injectable.ts | 17 - .../helm-chart-store.injectable.ts | 13 - .../components/+helm-charts/helm-charts.tsx | 28 +- .../call-for-helm-charts.injectable.ts | 17 - .../helm-charts/helm-charts.injectable.ts | 6 +- .../+helm-charts/store.injectable.ts | 18 + .../{helm-chart.store.ts => store.ts} | 16 +- ...releases.global-override-for-injectable.ts | 15 - .../call-for-helm-releases.injectable.ts | 24 - ...call-for-create-helm-release.injectable.ts | 44 - .../create-release.injectable.ts | 8 +- .../delete-release.injectable.ts | 10 +- .../+helm-releases/dialog/dialog.tsx | 28 +- ...guration.global-override-for-injectable.ts | 15 - ...r-helm-release-configuration.injectable.ts | 29 - ...-details.global-override-for-injectable.ts | 15 - ...all-for-helm-release-details.injectable.ts | 45 - .../call-for-helm-release.injectable.ts | 51 - .../release-details-model.injectable.tsx | 60 +- .../request-helm-release.injectable.ts | 51 + .../+helm-releases/releases.injectable.ts | 81 +- .../rollback-release.injectable.ts | 11 +- .../to-helm-release.injectable.ts | 87 ++ ...e-update.global-override-for-injectable.ts | 15 - ...call-for-helm-release-update.injectable.ts | 50 - .../update-release.injectable.ts | 8 +- .../call-for-helm-chart-values.injectable.ts | 20 - .../install-chart-model.injectable.tsx | 41 +- .../dock/upgrade-chart/store.injectable.ts | 2 + .../components/dock/upgrade-chart/store.ts | 5 +- .../components/dock/upgrade-chart/view.tsx | 13 +- 62 files changed, 1513 insertions(+), 1570 deletions(-) create mode 100644 src/common/k8s-api/endpoints/helm-charts.api/get-readme.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-charts.api/get-values.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-charts.api/get-versions.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-charts.api/list.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-releases.api/create.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-releases.api/delete.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-releases.api/get-configuration.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-releases.api/get-details.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-releases.api/get-history.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-releases.api/get-values.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-releases.api/list.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-releases.api/rollback.injectable.ts create mode 100644 src/common/k8s-api/endpoints/helm-releases.api/update.injectable.ts rename src/main/helm/helm-service/{get-helm-chart.injectable.ts => get-helm-chart-readme.injectable.ts} (73%) create mode 100644 src/main/helm/helm-service/get-helm-chart-versions.injectable.ts rename src/main/routes/helm/charts/{get-chart-route.injectable.ts => get-readme-route.injectable.ts} (58%) rename src/main/routes/helm/charts/{get-chart-values-route.injectable.ts => get-values-route.injectable.ts} (84%) create mode 100644 src/main/routes/helm/charts/get-versions-route.injectable.ts rename src/main/routes/helm/charts/{list-charts-route.injectable.ts => list-route.injectable.ts} (82%) delete mode 100644 src/renderer/components/+helm-charts/details/readme/call-for-helm-chart-readme.injectable.ts delete mode 100644 src/renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable.ts delete mode 100644 src/renderer/components/+helm-charts/get-char-details.injectable.ts delete mode 100644 src/renderer/components/+helm-charts/helm-chart-store.injectable.ts delete mode 100644 src/renderer/components/+helm-charts/helm-charts/call-for-helm-charts.injectable.ts create mode 100644 src/renderer/components/+helm-charts/store.injectable.ts rename src/renderer/components/+helm-charts/{helm-chart.store.ts => store.ts} (81%) delete mode 100644 src/renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.global-override-for-injectable.ts delete mode 100644 src/renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.injectable.ts delete mode 100644 src/renderer/components/+helm-releases/create-release/call-for-create-helm-release.injectable.ts delete mode 100644 src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release-configuration/call-for-helm-release-configuration.global-override-for-injectable.ts delete mode 100644 src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release-configuration/call-for-helm-release-configuration.injectable.ts delete mode 100644 src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release-details/call-for-helm-release-details.global-override-for-injectable.ts delete mode 100644 src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release-details/call-for-helm-release-details.injectable.ts delete mode 100644 src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release.injectable.ts create mode 100644 src/renderer/components/+helm-releases/release-details/release-details-model/request-helm-release.injectable.ts create mode 100644 src/renderer/components/+helm-releases/to-helm-release.injectable.ts delete mode 100644 src/renderer/components/+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.global-override-for-injectable.ts delete mode 100644 src/renderer/components/+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.injectable.ts delete mode 100644 src/renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable.ts diff --git a/src/common/k8s-api/endpoints/helm-charts.api.ts b/src/common/k8s-api/endpoints/helm-charts.api.ts index f4ba0cf45f..26da740830 100644 --- a/src/common/k8s-api/endpoints/helm-charts.api.ts +++ b/src/common/k8s-api/endpoints/helm-charts.api.ts @@ -3,72 +3,9 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { compile } from "path-to-regexp"; -import { apiBase } from "../index"; -import { stringify } from "querystring"; -import type { RequestInit } from "node-fetch"; -import { autoBind, bifurcateArray, isDefined } from "../../utils"; +import { autoBind, bifurcateArray } from "../../utils"; import Joi from "joi"; -export type RepoHelmChartList = Record; - -export interface IHelmChartDetails { - readme: string; - versions: HelmChart[]; -} - -const endpoint = compile(`/v2/charts/:repo?/:name?`) as (params?: { - repo?: string; - name?: string; -}) => string; - -/** - * Get a list of all helm charts from all saved helm repos - */ -export async function listCharts(): Promise { - const data = await apiBase.get>(endpoint()); - - return Object - .values(data) - .reduce((allCharts, repoCharts) => allCharts.concat(Object.values(repoCharts)), new Array()) - .map(([chart]) => HelmChart.create(chart, { onError: "log" })) - .filter(isDefined); -} - -export interface GetChartDetailsOptions { - version?: string; - reqInit?: RequestInit; -} - -/** - * Get the readme and all versions of a chart - * @param repo The repo to get from - * @param name The name of the chart to request the data of - * @param options.version The version of the chart's readme to get, default latest - * @param options.reqInit A way for passing in an abort controller or other browser request options - */ -export async function getChartDetails(repo: string, name: string, { version, reqInit }: GetChartDetailsOptions = {}): Promise { - const path = endpoint({ repo, name }); - - const { readme, ...data } = await apiBase.get(`${path}?${stringify({ version })}`, undefined, reqInit); - const versions = data.versions.map(version => HelmChart.create(version, { onError: "log" })).filter(isDefined); - - return { - readme, - versions, - }; -} - -/** - * Get chart values related to a specific repos' version of a chart - * @param repo The repo to get from - * @param name The name of the chart to request the data of - * @param version The version to get the values from - */ -export async function getChartValues(repo: string, name: string, version: string): Promise { - return apiBase.get(`/v2/charts/${repo}/${name}/values?${stringify({ version })}`); -} - export interface RawHelmChart { apiVersion: string; name: string; diff --git a/src/common/k8s-api/endpoints/helm-charts.api/get-readme.injectable.ts b/src/common/k8s-api/endpoints/helm-charts.api/get-readme.injectable.ts new file mode 100644 index 0000000000..c6815c4b93 --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-charts.api/get-readme.injectable.ts @@ -0,0 +1,24 @@ +/** + * 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 { urlBuilderFor } from "../../../utils/buildUrl"; +import { apiBaseInjectionToken } from "../../api-base"; + +const requestReadmeEndpoint = urlBuilderFor("/v2/charts/:repo/:name/readme"); + +export type RequestHelmChartReadme = (repo: string, name: string, version?: string) => Promise; + +const requestHelmChartReadmeInjectable = getInjectable({ + id: "request-helm-chart-readme", + instantiate: (di): RequestHelmChartReadme => { + const apiBase = di.inject(apiBaseInjectionToken); + + return (repo, name, version) => ( + apiBase.get(requestReadmeEndpoint.compile({ name, repo }, { version })) + ); + }, +}); + +export default requestHelmChartReadmeInjectable; diff --git a/src/common/k8s-api/endpoints/helm-charts.api/get-values.injectable.ts b/src/common/k8s-api/endpoints/helm-charts.api/get-values.injectable.ts new file mode 100644 index 0000000000..ec927fc37a --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-charts.api/get-values.injectable.ts @@ -0,0 +1,24 @@ +/** + * 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 { urlBuilderFor } from "../../../utils/buildUrl"; +import { apiBaseInjectionToken } from "../../api-base"; + +const requestValuesEndpoint = urlBuilderFor("/v2/charts/:repo/:name/values"); + +export type RequestHelmChartValues = (repo: string, name: string, version: string) => Promise; + +const requestHelmChartValuesInjectable = getInjectable({ + id: "request-helm-chart-values", + instantiate: (di): RequestHelmChartValues => { + const apiBase = di.inject(apiBaseInjectionToken); + + return (repo, name, version) => ( + apiBase.get(requestValuesEndpoint.compile({ repo, name }, { version })) + ); + }, +}); + +export default requestHelmChartValuesInjectable; diff --git a/src/common/k8s-api/endpoints/helm-charts.api/get-versions.injectable.ts b/src/common/k8s-api/endpoints/helm-charts.api/get-versions.injectable.ts new file mode 100644 index 0000000000..ad5da0ea4f --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-charts.api/get-versions.injectable.ts @@ -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 { urlBuilderFor } from "../../../utils/buildUrl"; +import { apiBaseInjectionToken } from "../../api-base"; +import { HelmChart } from "../helm-charts.api"; +import type { RawHelmChart } from "../helm-charts.api"; +import { isDefined } from "../../../utils"; + +const requestVersionsEndpoint = urlBuilderFor("/v2/charts/:repo/:name/versions"); + +export type RequestHelmChartVersions = (repo: string, name: string) => Promise; + +const requestHelmChartVersionsInjectable = getInjectable({ + id: "request-helm-chart-versions", + instantiate: (di): RequestHelmChartVersions => { + const apiBase = di.inject(apiBaseInjectionToken); + + return async (repo, name) => { + const rawVersions = await apiBase.get(requestVersionsEndpoint.compile({ name, repo })) as RawHelmChart[]; + + return rawVersions + .map(version => HelmChart.create(version, { onError: "log" })) + .filter(isDefined); + }; + }, +}); + +export default requestHelmChartVersionsInjectable; diff --git a/src/common/k8s-api/endpoints/helm-charts.api/list.injectable.ts b/src/common/k8s-api/endpoints/helm-charts.api/list.injectable.ts new file mode 100644 index 0000000000..89de5f9d17 --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-charts.api/list.injectable.ts @@ -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 { apiBaseInjectionToken } from "../../api-base"; +import type { RawHelmChart } from "../helm-charts.api"; +import { HelmChart } from "../helm-charts.api"; +import { isDefined } from "../../../utils"; + +export type RequestHelmCharts = () => Promise; +export type RepoHelmChartList = Record; + +/** + * Get a list of all helm charts from all saved helm repos + */ +const requestHelmChartsInjectable = getInjectable({ + id: "request-helm-charts", + instantiate: (di) => { + const apiBase = di.inject(apiBaseInjectionToken); + + return async () => { + const data = await apiBase.get>("/v2/charts"); + + return Object + .values(data) + .reduce((allCharts, repoCharts) => allCharts.concat(Object.values(repoCharts)), new Array()) + .map(([chart]) => HelmChart.create(chart, { onError: "log" })) + .filter(isDefined); + }; + }, +}); + +export default requestHelmChartsInjectable; diff --git a/src/common/k8s-api/endpoints/helm-releases.api.ts b/src/common/k8s-api/endpoints/helm-releases.api.ts index f9e11073c0..3806a81534 100644 --- a/src/common/k8s-api/endpoints/helm-releases.api.ts +++ b/src/common/k8s-api/endpoints/helm-releases.api.ts @@ -3,65 +3,14 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { apiBase } from "../index"; import type { ItemObject } from "../../item.store"; -import type { JsonApiData } from "../json-api"; -import { buildURLPositional } from "../../utils/buildUrl"; -import type { HelmReleaseDetails } from "../../../renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release-details/call-for-helm-release-details.injectable"; +import type { HelmReleaseDetails } from "./helm-releases.api/get-details.injectable"; export interface HelmReleaseUpdateDetails { log: string; release: HelmReleaseDetails; } -export interface HelmReleaseRevision { - revision: number; - updated: string; - status: string; - chart: string; - app_version: string; - description: string; -} - -type EndpointParams = {} - | { namespace: string } - | { namespace: string; name: string } - | { namespace: string; name: string; route: string }; - -interface EndpointQuery { - all?: boolean; -} - -export const endpoint = buildURLPositional("/v2/releases/:namespace?/:name?/:route?"); - -export async function deleteRelease(name: string, namespace: string): Promise { - const path = endpoint({ name, namespace }); - - return apiBase.del(path); -} - -export async function getReleaseValues(name: string, namespace: string, all?: boolean): Promise { - const route = "values"; - const path = endpoint({ name, namespace, route }, { all }); - - return apiBase.get(path); -} - -export async function getReleaseHistory(name: string, namespace: string): Promise { - const route = "history"; - const path = endpoint({ name, namespace, route }); - - return apiBase.get(path); -} - -export async function rollbackRelease(name: string, namespace: string, revision: number): Promise { - const route = "rollback"; - const path = endpoint({ name, namespace, route }); - const data = { revision }; - - return apiBase.put(path, { data }); -} - export interface HelmReleaseDto { appVersion: string; name: string; diff --git a/src/common/k8s-api/endpoints/helm-releases.api/create.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/create.injectable.ts new file mode 100644 index 0000000000..bad802d3cc --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-releases.api/create.injectable.ts @@ -0,0 +1,42 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import yaml from "js-yaml"; +import { getInjectable } from "@ogre-tools/injectable"; +import type { HelmReleaseUpdateDetails } from "../helm-releases.api"; +import { apiBaseInjectionToken } from "../../api-base"; +import { urlBuilderFor } from "../../../utils/buildUrl"; + +interface HelmReleaseCreatePayload { + name?: string; + repo: string; + chart: string; + namespace: string; + version: string; + values: string; +} + +export type RequestCreateHelmRelease = (payload: HelmReleaseCreatePayload) => Promise; + +const requestCreateEndpoint = urlBuilderFor("/v2/releases"); + +const requestCreateHelmReleaseInjectable = getInjectable({ + id: "request-create-helm-release", + + instantiate: (di): RequestCreateHelmRelease => { + const apiBase = di.inject(apiBaseInjectionToken); + + return ({ repo, chart, values, ...data }) => { + return apiBase.post(requestCreateEndpoint.compile({}), { + data: { + chart: `${repo}/${chart}`, + values: yaml.load(values), + ...data, + }, + }); + }; + }, +}); + +export default requestCreateHelmReleaseInjectable; diff --git a/src/common/k8s-api/endpoints/helm-releases.api/delete.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/delete.injectable.ts new file mode 100644 index 0000000000..66b2013770 --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-releases.api/delete.injectable.ts @@ -0,0 +1,22 @@ +/** + * 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 { urlBuilderFor } from "../../../utils/buildUrl"; +import { apiBaseInjectionToken } from "../../api-base"; + +export type RequestDeleteHelmRelease = (name: string, namespace: string) => Promise; + +const requestDeleteEndpoint = urlBuilderFor("/v2/releases/:namespace/:name"); + +const requestDeleteHelmReleaseInjectable = getInjectable({ + id: "request-delete-helm-release", + instantiate: (di): RequestDeleteHelmRelease => { + const apiBase = di.inject(apiBaseInjectionToken); + + return (name, namespace) => apiBase.del(requestDeleteEndpoint.compile({ name, namespace })); + }, +}); + +export default requestDeleteHelmReleaseInjectable; diff --git a/src/common/k8s-api/endpoints/helm-releases.api/get-configuration.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/get-configuration.injectable.ts new file mode 100644 index 0000000000..af01b4bb46 --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-releases.api/get-configuration.injectable.ts @@ -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 { urlBuilderFor } from "../../../utils/buildUrl"; +import { apiBaseInjectionToken } from "../../api-base"; + +export type RequestHelmReleaseConfiguration = ( + name: string, + namespace: string, + all: boolean +) => Promise; + +const requestConfigurationEnpoint = urlBuilderFor("/v2/releases/:namespace/:name/values"); + +const requestHelmReleaseConfigurationInjectable = getInjectable({ + id: "call-for-helm-release-configuration", + + instantiate: (di): RequestHelmReleaseConfiguration => { + const apiBase = di.inject(apiBaseInjectionToken); + + return (name, namespace, all: boolean) => ( + apiBase.get(requestConfigurationEnpoint.compile({ name, namespace }, { all })) + ); + }, + + causesSideEffects: true, +}); + +export default requestHelmReleaseConfigurationInjectable; diff --git a/src/common/k8s-api/endpoints/helm-releases.api/get-details.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/get-details.injectable.ts new file mode 100644 index 0000000000..0b712cd78e --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-releases.api/get-details.injectable.ts @@ -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 type { KubeJsonApiData } from "../../kube-json-api"; +import { apiBaseInjectionToken } from "../../api-base"; +import { urlBuilderFor } from "../../../utils/buildUrl"; + +export interface HelmReleaseDetails { + resources: KubeJsonApiData[]; + name: string; + namespace: string; + version: string; + config: string; // release values + manifest: string; + info: { + deleted: string; + description: string; + first_deployed: string; + last_deployed: string; + notes: string; + status: string; + }; +} + +export type CallForHelmReleaseDetails = (name: string, namespace: string) => Promise; + +const requestDetailsEnpoint = urlBuilderFor("/v2/releases/:namespace/:name"); + +const requestHelmReleaseDetailsInjectable = getInjectable({ + id: "call-for-helm-release-details", + + instantiate: (di): CallForHelmReleaseDetails => { + const apiBase = di.inject(apiBaseInjectionToken); + + return (name, namespace) => apiBase.get(requestDetailsEnpoint.compile({ name, namespace })); + }, +}); + +export default requestHelmReleaseDetailsInjectable; diff --git a/src/common/k8s-api/endpoints/helm-releases.api/get-history.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/get-history.injectable.ts new file mode 100644 index 0000000000..b6e9794fe7 --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-releases.api/get-history.injectable.ts @@ -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 { urlBuilderFor } from "../../../utils/buildUrl"; +import { apiBaseInjectionToken } from "../../api-base"; + +export interface HelmReleaseRevision { + revision: number; + updated: string; + status: string; + chart: string; + app_version: string; + description: string; +} + +export type RequestHelmReleaseHistory = (name: string, namespace: string) => Promise; + +const requestHistoryEnpoint = urlBuilderFor("/v2/releases/:namespace/:name/history"); + +const requestHelmReleaseHistoryInjectable = getInjectable({ + id: "request-helm-release-history", + instantiate: (di): RequestHelmReleaseHistory => { + const apiBase = di.inject(apiBaseInjectionToken); + + return (name, namespace) => apiBase.get(requestHistoryEnpoint.compile({ name, namespace })); + }, +}); + +export default requestHelmReleaseHistoryInjectable; diff --git a/src/common/k8s-api/endpoints/helm-releases.api/get-values.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/get-values.injectable.ts new file mode 100644 index 0000000000..d30f9973c4 --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-releases.api/get-values.injectable.ts @@ -0,0 +1,22 @@ +/** + * 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 { urlBuilderFor } from "../../../utils/buildUrl"; +import { apiBaseInjectionToken } from "../../api-base"; + +export type RequestHelmReleaseValues = (name: string, namespace: string, all?: boolean) => Promise; + +const requestValuesEndpoint = urlBuilderFor("/v2/release/:namespace/:name/values"); + +const requestHelmReleaseValuesInjectable = getInjectable({ + id: "request-helm-release-values", + instantiate: (di): RequestHelmReleaseValues => { + const apiBase = di.inject(apiBaseInjectionToken); + + return (name, namespace, all) => apiBase.get(requestValuesEndpoint.compile({ name, namespace }, { all })); + }, +}); + +export default requestHelmReleaseValuesInjectable; diff --git a/src/common/k8s-api/endpoints/helm-releases.api/list.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/list.injectable.ts new file mode 100644 index 0000000000..2619e289c6 --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-releases.api/list.injectable.ts @@ -0,0 +1,24 @@ +/** + * 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 { urlBuilderFor } from "../../../utils/buildUrl"; +import { apiBaseInjectionToken } from "../../api-base"; +import type { HelmReleaseDto } from "../helm-releases.api"; + +export type RequestHelmReleases = (namespace?: string) => Promise; + +const requestHelmReleasesEndpoint = urlBuilderFor("/v2/releases/:namespace?"); + +const requestHelmReleasesInjectable = getInjectable({ + id: "request-helm-releases", + + instantiate: (di): RequestHelmReleases => { + const apiBase = di.inject(apiBaseInjectionToken); + + return (namespace) => apiBase.get(requestHelmReleasesEndpoint.compile({ namespace })); + }, +}); + +export default requestHelmReleasesInjectable; diff --git a/src/common/k8s-api/endpoints/helm-releases.api/rollback.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/rollback.injectable.ts new file mode 100644 index 0000000000..1a9229b73a --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-releases.api/rollback.injectable.ts @@ -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 { urlBuilderFor } from "../../../utils/buildUrl"; +import { apiBaseInjectionToken } from "../../api-base"; + +export type RequestHelmReleaseRollback = (name: string, namespace: string, revision: number) => Promise; + +const requestRollbackEndpoint = urlBuilderFor("/v2/releases/:namespace/:name"); + +const requestHelmReleaseRollbackInjectable = getInjectable({ + id: "request-helm-release-rollback", + instantiate: (di): RequestHelmReleaseRollback => { + const apiBase = di.inject(apiBaseInjectionToken); + + return async (name, namespace, revision) => { + await apiBase.put( + requestRollbackEndpoint.compile({ name, namespace }), + { data: { revision }}, + ); + }; + }, +}); + +export default requestHelmReleaseRollbackInjectable; diff --git a/src/common/k8s-api/endpoints/helm-releases.api/update.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/update.injectable.ts new file mode 100644 index 0000000000..2703ea2c56 --- /dev/null +++ b/src/common/k8s-api/endpoints/helm-releases.api/update.injectable.ts @@ -0,0 +1,49 @@ +/** + * 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 { apiBaseInjectionToken } from "../../api-base"; +import { urlBuilderFor } from "../../../utils/buildUrl"; + +interface HelmReleaseUpdatePayload { + repo: string; + chart: string; + version: string; + values: string; +} + +export type RequestHelmReleaseUpdate = ( + name: string, + namespace: string, + payload: HelmReleaseUpdatePayload +) => Promise<{ updateWasSuccessful: true } | { updateWasSuccessful: false; error: unknown }>; + +const requestUpdateEndpoint = urlBuilderFor("/v2/releases/:namespace/:name"); + +const requestHelmReleaseUpdateInjectable = getInjectable({ + id: "request-helm-release-update", + + instantiate: (di): RequestHelmReleaseUpdate => { + const apiBase = di.inject(apiBaseInjectionToken); + + return async (name, namespace, { repo, chart, values, ...data }) => { + try { + await apiBase.put(requestUpdateEndpoint.compile({ name, namespace }), { + data: { + chart: `${repo}/${chart}`, + values: yaml.load(values), + ...data, + }, + }); + } catch (e) { + return { updateWasSuccessful: false, error: e }; + } + + return { updateWasSuccessful: true }; + }; + }, +}); + +export default requestHelmReleaseUpdateInjectable; diff --git a/src/common/utils/buildUrl.ts b/src/common/utils/buildUrl.ts index 61639cea4d..82d114cd08 100644 --- a/src/common/utils/buildUrl.ts +++ b/src/common/utils/buildUrl.ts @@ -35,3 +35,24 @@ export function buildURLPositional

return buildURL(path, { params, query, fragment }); }; } + +export type UrlParamsFor = + Pathname extends `${string}/:${infer A}?/${infer Tail}` + ? Partial> & UrlParamsFor<`/${Tail}`> + : Pathname extends `${string}/:${infer A}/${infer Tail}` + ? Record & UrlParamsFor<`/${Tail}`> + : Pathname extends `${string}/:${infer A}?` + ? Partial> + : Pathname extends `${string}/:${infer A}` + ? Record + : {}; + +export interface UrlBuilder { + compile(params: UrlParamsFor, query?: object, fragment?: string): string; +} + +export function urlBuilderFor(pathname: Pathname): UrlBuilder { + return { + compile: buildURLPositional(pathname), + }; +} diff --git a/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts b/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts index f86471e897..4adf0a65bf 100644 --- a/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts +++ b/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts @@ -8,84 +8,55 @@ import type { RenderResult } from "@testing-library/react"; import { fireEvent } from "@testing-library/react"; import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder"; import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder"; -import type { CallForHelmCharts } from "../../../renderer/components/+helm-charts/helm-charts/call-for-helm-charts.injectable"; -import callForHelmChartsInjectable from "../../../renderer/components/+helm-charts/helm-charts/call-for-helm-charts.injectable"; import { HelmChart } from "../../../common/k8s-api/endpoints/helm-charts.api"; import getRandomInstallChartTabIdInjectable from "../../../renderer/components/dock/install-chart/get-random-install-chart-tab-id.injectable"; -import type { CallForHelmChartValues } from "../../../renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable"; -import callForHelmChartValuesInjectable from "../../../renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable"; -import type { CallForCreateHelmRelease } from "../../../renderer/components/+helm-releases/create-release/call-for-create-helm-release.injectable"; -import callForCreateHelmReleaseInjectable from "../../../renderer/components/+helm-releases/create-release/call-for-create-helm-release.injectable"; +import type { RequestCreateHelmRelease } from "../../../common/k8s-api/endpoints/helm-releases.api/create.injectable"; +import requestCreateHelmReleaseInjectable from "../../../common/k8s-api/endpoints/helm-releases.api/create.injectable"; import currentPathInjectable from "../../../renderer/routes/current-path.injectable"; import namespaceStoreInjectable from "../../../renderer/components/+namespaces/store.injectable"; import type { NamespaceStore } from "../../../renderer/components/+namespaces/store"; -import type { CallForHelmChartReadme } from "../../../renderer/components/+helm-charts/details/readme/call-for-helm-chart-readme.injectable"; -import callForHelmChartReadmeInjectable from "../../../renderer/components/+helm-charts/details/readme/call-for-helm-chart-readme.injectable"; -import type { CallForHelmChartVersions } from "../../../renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable"; -import callForHelmChartVersionsInjectable from "../../../renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable"; import writeJsonFileInjectable from "../../../common/fs/write-json-file.injectable"; import directoryForLensLocalStorageInjectable from "../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable"; import hostedClusterIdInjectable from "../../../renderer/cluster-frame-context/hosted-cluster-id.injectable"; import dockStoreInjectable from "../../../renderer/components/dock/dock/store.injectable"; import readJsonFileInjectable from "../../../common/fs/read-json-file.injectable"; import type { DiContainer } from "@ogre-tools/injectable"; -import callForHelmReleasesInjectable from "../../../renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.injectable"; -import callForHelmReleaseDetailsInjectable from "../../../renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release-details/call-for-helm-release-details.injectable"; +import type { RequestHelmCharts } from "../../../common/k8s-api/endpoints/helm-charts.api/list.injectable"; +import type { RequestHelmChartVersions } from "../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; +import type { RequestHelmChartReadme } from "../../../common/k8s-api/endpoints/helm-charts.api/get-readme.injectable"; +import type { RequestHelmChartValues } from "../../../common/k8s-api/endpoints/helm-charts.api/get-values.injectable"; +import requestHelmChartsInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/list.injectable"; +import requestHelmChartVersionsInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; +import requestHelmChartReadmeInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/get-readme.injectable"; +import requestHelmChartValuesInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/get-values.injectable"; describe("installing helm chart from new tab", () => { let builder: ApplicationBuilder; - let callForHelmChartsMock: AsyncFnMock; - let callForHelmChartVersionsMock: AsyncFnMock; - let callForHelmChartReadmeMock: AsyncFnMock; - let callForHelmChartValuesMock: AsyncFnMock; - let callForCreateHelmReleaseMock: AsyncFnMock; + let requestHelmChartsMock: AsyncFnMock; + let requestHelmChartVersionsMock: AsyncFnMock; + let requestHelmChartReadmeMock: AsyncFnMock; + let requestHelmChartValuesMock: AsyncFnMock; + let requestCreateHelmReleaseMock: AsyncFnMock; beforeEach(() => { builder = getApplicationBuilder(); builder.setEnvironmentToClusterFrame(); - callForHelmChartsMock = asyncFn(); - callForHelmChartVersionsMock = asyncFn(); - callForHelmChartReadmeMock = asyncFn(); - callForHelmChartValuesMock = asyncFn(); - callForCreateHelmReleaseMock = asyncFn(); + requestHelmChartsMock = asyncFn(); + requestHelmChartVersionsMock = asyncFn(); + requestHelmChartReadmeMock = asyncFn(); + requestHelmChartValuesMock = asyncFn(); + requestCreateHelmReleaseMock = asyncFn(); builder.beforeWindowStart((windowDi) => { - windowDi.override(callForHelmReleasesInjectable, () => async () => []); - windowDi.override(callForHelmReleaseDetailsInjectable, () => () => new Promise(() => {})); - - windowDi.override( - directoryForLensLocalStorageInjectable, - () => "/some-directory-for-lens-local-storage", - ); - + windowDi.override(directoryForLensLocalStorageInjectable, () => "/some-directory-for-lens-local-storage"); windowDi.override(hostedClusterIdInjectable, () => "some-cluster-id"); - - windowDi.override( - callForHelmChartsInjectable, - () => callForHelmChartsMock, - ); - - windowDi.override( - callForHelmChartVersionsInjectable, - () => callForHelmChartVersionsMock, - ); - - windowDi.override( - callForHelmChartReadmeInjectable, - () => callForHelmChartReadmeMock, - ); - - windowDi.override( - callForHelmChartValuesInjectable, - () => callForHelmChartValuesMock, - ); - - windowDi.override( - callForCreateHelmReleaseInjectable, - () => callForCreateHelmReleaseMock, - ); + windowDi.override(requestHelmChartsInjectable, () => requestHelmChartsMock); + windowDi.override(requestHelmChartVersionsInjectable, () => requestHelmChartVersionsMock); + windowDi.override(requestHelmChartReadmeInjectable, () => requestHelmChartReadmeMock); + windowDi.override(requestHelmChartValuesInjectable, () => requestHelmChartValuesMock); + windowDi.override(requestCreateHelmReleaseInjectable, () => requestCreateHelmReleaseMock); // TODO: Replace store mocking with mock for the actual side-effect (where the namespaces are coming from) windowDi.override( @@ -136,7 +107,6 @@ describe("installing helm chart from new tab", () => { // TODO: Make TerminalWindow unit testable to allow realistic behaviour dockStore.closeTab("terminal"); - }); it("renders", () => { @@ -144,14 +114,13 @@ describe("installing helm chart from new tab", () => { }); describe("when navigating to helm charts", () => { - beforeEach(async () => { builder.helmCharts.navigate({ chartName: "some-name", repo: "some-repository", }); - await callForHelmChartsMock.resolve([ + await requestHelmChartsMock.resolve([ HelmChart.create({ apiVersion: "some-api-version", name: "some-name", @@ -185,7 +154,7 @@ describe("installing helm chart from new tab", () => { }), ]); - await callForHelmChartVersionsMock.resolve([ + await requestHelmChartVersionsMock.resolve([ HelmChart.create({ apiVersion: "some-api-version", name: "some-name", @@ -219,7 +188,7 @@ describe("installing helm chart from new tab", () => { }), ]); - await callForHelmChartReadmeMock.resolve("some-readme"); + await requestHelmChartReadmeMock.resolve("some-readme"); }); it("renders", () => { @@ -228,7 +197,7 @@ describe("installing helm chart from new tab", () => { describe("when selecting to install the chart", () => { beforeEach(() => { - callForHelmChartVersionsMock.mockClear(); + requestHelmChartVersionsMock.mockClear(); const installButton = rendered.getByTestId( "install-chart-for-some-repository-some-name", @@ -248,7 +217,7 @@ describe("installing helm chart from new tab", () => { }); it("calls for default configuration of the chart", () => { - expect(callForHelmChartValuesMock).toHaveBeenCalledWith( + expect(requestHelmChartValuesMock).toHaveBeenCalledWith( "some-repository", "some-name", "some-version", @@ -256,7 +225,7 @@ describe("installing helm chart from new tab", () => { }); it("calls for available versions", () => { - expect(callForHelmChartVersionsMock).toHaveBeenCalledWith( + expect(requestHelmChartVersionsMock).toHaveBeenCalledWith( "some-repository", "some-name", ); @@ -268,31 +237,13 @@ describe("installing helm chart from new tab", () => { ).toBeInTheDocument(); }); - it("given default configuration resolves but versions have not resolved yet, still shows the spinner", async () => { - await callForHelmChartValuesMock.resolve( - "some-default-configuration", - ); - - expect( - rendered.getByTestId("install-chart-tab-spinner"), - ).toBeInTheDocument(); - }); - - it("given versions resolve but default configuration has not resolved yet, still shows the spinner", async () => { - await callForHelmChartVersionsMock.resolve([]); - - expect( - rendered.getByTestId("install-chart-tab-spinner"), - ).toBeInTheDocument(); - }); - describe("when default configuration and versions resolve", () => { beforeEach(async () => { - await callForHelmChartValuesMock.resolve( + await requestHelmChartValuesMock.resolve( "some-default-configuration", ); - await callForHelmChartVersionsMock.resolve([ + await requestHelmChartVersionsMock.resolve([ HelmChart.create({ apiVersion: "some-api-version", name: "some-name", @@ -327,188 +278,24 @@ describe("installing helm chart from new tab", () => { ]); }); - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); + it("given versions resolve but default configuration has not resolved yet, still shows the spinner", async () => { + await requestHelmChartVersionsMock.resolve([]); - it("does not show spinner anymore", () => { expect( - rendered.queryByTestId("install-chart-tab-spinner"), - ).not.toBeInTheDocument(); + rendered.getByTestId("install-chart-tab-spinner"), + ).toBeInTheDocument(); }); - describe("when cancelled", () => { - beforeEach(() => { - const cancelButton = rendered.getByTestId( - "cancel-install-chart-from-tab-for-some-first-tab-id", - ); - - fireEvent.click(cancelButton); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("closes the tab", () => { - expect( - rendered.queryByTestId("dock-tab-for-some-first-tab-id"), - ).not.toBeInTheDocument(); - }); - }); - - describe("given no changes in configuration, when installing the chart", () => { - let installButton: HTMLButtonElement; - - beforeEach(() => { - installButton = rendered.getByTestId( - "install-chart-from-tab-for-some-first-tab-id", - ) as HTMLButtonElement; - - fireEvent.click(installButton); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("shows spinner in dock tab", () => { - expect( - rendered.getByTestId( - "installing-chart-from-tab-some-first-tab-id", - ), - ).toBeInTheDocument(); - }); - - it("install button is disabled", () => { - expect(installButton).toHaveAttribute("disabled"); - }); - - it("calls for installation with default configuration", () => { - expect(callForCreateHelmReleaseMock).toHaveBeenCalledWith({ - chart: "some-name", - name: undefined, - namespace: "default", - repo: "some-repository", - values: "some-default-configuration", - version: "some-version", - }); - }); - - describe("when installation resolves", () => { - beforeEach(async () => { - await callForCreateHelmReleaseMock.resolve({ - log: "some-execution-output", - - release: { - resources: [], - name: "some-release", - namespace: "default", - version: "some-version", - config: "some-config", - manifest: "some-manifest", - - info: { - deleted: "some-deleted", - description: "some-description", - first_deployed: "some-first-deployed", - last_deployed: "some-last-deployed", - notes: "some-notes", - status: "some-status", - }, - }, - }); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("does not show spinner anymore", () => { - expect( - rendered.queryByTestId( - "installing-chart-from-tab-some-first-tab-id", - ), - ).not.toBeInTheDocument(); - }); - - describe("when selected to see the installed release", () => { - beforeEach(() => { - const releaseButton = rendered.getByTestId( - "show-release-some-release-for-some-first-tab-id", - ); - - fireEvent.click(releaseButton); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("shows the details of installed release", () => { - const currentPath = windowDi - .inject(currentPathInjectable) - .get(); - - expect(currentPath).toBe( - "/helm/releases/default/some-release", - ); - }); - - it("closes the dock tab", () => { - expect( - rendered.queryByTestId( - "dock-tab-for-some-first-tab-id", - ), - ).not.toBeInTheDocument(); - }); - }); - - describe("when selected to show execution output", () => { - beforeEach(() => { - const showNotesButton = rendered.getByTestId( - "show-execution-output-for-some-release-in-some-first-tab-id", - ); - - fireEvent.click(showNotesButton); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("shows the execution output", () => { - expect( - rendered.getByTestId( - "logs-dialog-for-helm-chart-install", - ), - ).toHaveTextContent("some-execution-output"); - }); - - it("does not close the dock tab", () => { - expect( - rendered.getByTestId("dock-tab-for-some-first-tab-id"), - ).toBeInTheDocument(); - }); - }); - }); - }); - - describe("given opening details for second chart, when details resolve", () => { + describe("when default configuration and versions resolve", () => { beforeEach(async () => { - callForHelmChartReadmeMock.mockClear(); - callForHelmChartVersionsMock.mockClear(); - - const row = rendered.getByTestId( - "helm-chart-row-for-some-repository-some-other-name", + await requestHelmChartValuesMock.resolve( + "some-default-configuration", ); - fireEvent.click(row); - - await callForHelmChartVersionsMock.resolve([ + await requestHelmChartVersionsMock.resolve([ HelmChart.create({ apiVersion: "some-api-version", - name: "some-other-name", + name: "some-name", version: "some-version", repo: "some-repository", created: "2015-10-21T07:28:00Z", @@ -521,23 +308,63 @@ describe("installing helm chart from new tab", () => { maintainers: [], deprecated: false, }), - ]); - await callForHelmChartReadmeMock.resolve("some-readme"); + HelmChart.create({ + apiVersion: "some-api-version", + name: "some-name", + version: "some-other-version", + repo: "some-repository", + created: "2015-10-21T07:28:00Z", + description: "some-description", + keywords: [], + sources: [], + urls: [], + annotations: {}, + dependencies: [], + maintainers: [], + deprecated: false, + }), + ]); }); it("renders", () => { expect(rendered.baseElement).toMatchSnapshot(); }); - describe("when selecting to install second chart", () => { - beforeEach(() => { - callForHelmChartVersionsMock.mockClear(); + it("does not show spinner anymore", () => { + expect( + rendered.queryByTestId("install-chart-tab-spinner"), + ).not.toBeInTheDocument(); + }); - const installButton = rendered.getByTestId( - "install-chart-for-some-repository-some-other-name", + describe("when cancelled", () => { + beforeEach(() => { + const cancelButton = rendered.getByTestId( + "cancel-install-chart-from-tab-for-some-first-tab-id", ); + fireEvent.click(cancelButton); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("closes the tab", () => { + expect( + rendered.queryByTestId("dock-tab-for-some-first-tab-id"), + ).not.toBeInTheDocument(); + }); + }); + + describe("given no changes in configuration, when installing the chart", () => { + let installButton: HTMLButtonElement; + + beforeEach(() => { + installButton = rendered.getByTestId( + "install-chart-from-tab-for-some-first-tab-id", + ) as HTMLButtonElement; + fireEvent.click(installButton); }); @@ -545,48 +372,52 @@ describe("installing helm chart from new tab", () => { expect(rendered.baseElement).toMatchSnapshot(); }); - it("shows dock tab for installing second chart", () => { + it("shows spinner in dock tab", () => { expect( rendered.getByTestId( - "dock-tab-content-for-some-second-tab-id", + "installing-chart-from-tab-some-first-tab-id", ), ).toBeInTheDocument(); }); - it("still has the dock tab for installing first chart", () => { - expect( - rendered.getByTestId("dock-tab-for-some-first-tab-id"), - ).toBeInTheDocument(); + it("install button is disabled", () => { + expect(installButton).toHaveAttribute("disabled"); }); - it("calls for default configuration of the second chart", () => { - expect(callForHelmChartValuesMock).toHaveBeenCalledWith( - "some-repository", - "some-other-name", - "some-version", - ); + it("calls for installation with default configuration", () => { + expect(requestCreateHelmReleaseMock).toHaveBeenCalledWith({ + chart: "some-name", + name: undefined, + namespace: "default", + repo: "some-repository", + values: "some-default-configuration", + version: "some-version", + }); }); - it("calls for available versions for the second chart", () => { - expect(callForHelmChartVersionsMock).toHaveBeenCalledWith( - "some-repository", - "some-other-name", - ); - }); - - it("shows spinner in dock tab", () => { - expect( - rendered.getByTestId("install-chart-tab-spinner"), - ).toBeInTheDocument(); - }); - - describe("when configuration and versions resolve", () => { + describe("when installation resolves", () => { beforeEach(async () => { - await callForHelmChartValuesMock.resolve( - "some-other-default-configuration", - ); + await requestCreateHelmReleaseMock.resolve({ + log: "some-execution-output", - await callForHelmChartVersionsMock.resolve([]); + release: { + resources: [], + name: "some-release", + namespace: "default", + version: "some-version", + config: "some-config", + manifest: "some-manifest", + + info: { + deleted: "some-deleted", + description: "some-description", + first_deployed: "some-first-deployed", + last_deployed: "some-last-deployed", + notes: "some-notes", + status: "some-status", + }, + }, + }); }); it("renders", () => { @@ -595,432 +426,602 @@ describe("installing helm chart from new tab", () => { it("does not show spinner anymore", () => { expect( - rendered.queryByTestId("install-chart-tab-spinner"), + rendered.queryByTestId( + "installing-chart-from-tab-some-first-tab-id", + ), ).not.toBeInTheDocument(); }); - it("when installing the second chart, calls for installation of second chart", () => { - const installButton = rendered.getByTestId( - "install-chart-from-tab-for-some-second-tab-id", - ); - - fireEvent.click(installButton); - - expect( - callForCreateHelmReleaseMock, - ).toHaveBeenCalledWith({ - chart: "some-other-name", - name: undefined, - namespace: "default", - repo: "some-repository", - values: "some-other-default-configuration", - version: "some-version", - }); - }); - - describe("when selecting the dock tab for installing first chart", () => { + describe("when selected to see the installed release", () => { beforeEach(() => { - callForHelmChartValuesMock.mockClear(); - callForHelmChartVersionsMock.mockClear(); - - const tab = rendered.getByTestId( - "dock-tab-for-some-first-tab-id", + const releaseButton = rendered.getByTestId( + "show-release-some-release-for-some-first-tab-id", ); - fireEvent.click(tab); + fireEvent.click(releaseButton); }); it("renders", () => { expect(rendered.baseElement).toMatchSnapshot(); }); - it("does not call for default configuration", () => { - expect( - callForHelmChartValuesMock, - ).not.toHaveBeenCalled(); + it("shows the details of installed release", () => { + const currentPath = windowDi + .inject(currentPathInjectable) + .get(); + + expect(currentPath).toBe( + "/helm/releases/default/some-release", + ); }); - it("does not call for available versions", () => { + it("closes the dock tab", () => { expect( - callForHelmChartVersionsMock, - ).not.toHaveBeenCalled(); - }); - - it("does not show spinner", () => { - expect( - rendered.queryByTestId("install-chart-tab-spinner"), + rendered.queryByTestId( + "dock-tab-for-some-first-tab-id", + ), ).not.toBeInTheDocument(); }); + }); - it("when installing the first chart, calls for installation of first chart", () => { - const installButton = rendered.getByTestId( - "install-chart-from-tab-for-some-first-tab-id", + describe("when selected to show execution output", () => { + beforeEach(() => { + const showNotesButton = rendered.getByTestId( + "show-execution-output-for-some-release-in-some-first-tab-id", ); - fireEvent.click(installButton); + fireEvent.click(showNotesButton); + }); + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("shows the execution output", () => { expect( - callForCreateHelmReleaseMock, - ).toHaveBeenCalledWith({ - chart: "some-name", - name: undefined, - namespace: "default", - repo: "some-repository", - values: "some-default-configuration", - version: "some-version", - }); + rendered.getByTestId( + "logs-dialog-for-helm-chart-install", + ), + ).toHaveTextContent("some-execution-output"); + }); + + it("does not close the dock tab", () => { + expect( + rendered.getByTestId("dock-tab-for-some-first-tab-id"), + ).toBeInTheDocument(); }); }); }); }); - }); - describe("given changing version to be installed", () => { - let menu: { selectOption: (labelText: string) => void }; + describe("given opening details for second chart, when details resolve", () => { + beforeEach(async () => { + requestHelmChartReadmeMock.mockClear(); + requestHelmChartVersionsMock.mockClear(); - beforeEach(() => { - callForHelmChartVersionsMock.mockClear(); - callForHelmChartValuesMock.mockClear(); + const row = rendered.getByTestId( + "helm-chart-row-for-some-repository-some-other-name", + ); - const menuId = - "install-chart-version-select-for-some-first-tab-id"; + fireEvent.click(row); - menu = builder.select.openMenu(menuId); - }); + await requestHelmChartVersionsMock.resolve([ + HelmChart.create({ + apiVersion: "some-api-version", + name: "some-other-name", + version: "some-version", + repo: "some-repository", + created: "2015-10-21T07:28:00Z", + description: "some-description", + keywords: [], + sources: [], + urls: [], + annotations: {}, + dependencies: [], + maintainers: [], + deprecated: false, + }), + ]); - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - describe("when version is selected", () => { - let installButton: HTMLButtonElement; - - beforeEach(() => { - installButton = rendered.getByTestId( - "install-chart-from-tab-for-some-first-tab-id", - ) as HTMLButtonElement; - - menu.selectOption("some-other-version"); + await requestHelmChartReadmeMock.resolve("some-readme"); }); it("renders", () => { expect(rendered.baseElement).toMatchSnapshot(); }); - it("calls for default configuration for the version of chart", () => { - expect(callForHelmChartValuesMock).toHaveBeenCalledWith( - "some-repository", - "some-name", - "some-other-version", - ); - }); + describe("when selecting to install second chart", () => { + beforeEach(() => { + requestHelmChartVersionsMock.mockClear(); - it("shows spinner", () => { - expect( - rendered.getByTestId( - "install-chart-configuration-spinner", - ), - ).toBeInTheDocument(); - }); - - it("does not call for versions again", () => { - expect( - callForHelmChartVersionsMock, - ).not.toHaveBeenCalled(); - }); - - it("install button is disabled", () => { - expect(installButton).toHaveAttribute("disabled"); - }); - - it("stores the selected version", async () => { - const readJsonFile = windowDi.inject(readJsonFileInjectable); - - const actual = await readJsonFile( - "/some-directory-for-lens-local-storage/some-cluster-id.json", - ) as any; - - const version = actual.install_charts["some-first-tab-id"].version; - - expect(version).toBe("some-other-version"); - }); - - describe("when default configuration resolves", () => { - beforeEach(async () => { - await callForHelmChartValuesMock.resolve( - "some-default-configuration-for-other-version", + const installButton = rendered.getByTestId( + "install-chart-for-some-repository-some-other-name", ); + + fireEvent.click(installButton); }); it("renders", () => { expect(rendered.baseElement).toMatchSnapshot(); }); - it("does not show spinner", () => { + it("shows dock tab for installing second chart", () => { expect( - rendered.queryByTestId( - "install-chart-configuration-spinner", + rendered.getByTestId( + "dock-tab-content-for-some-second-tab-id", ), - ).not.toBeInTheDocument(); + ).toBeInTheDocument(); }); - it("install button is enabled", () => { - expect(installButton).not.toHaveAttribute("disabled"); - }); - - it("when installing the chart, calls for installation with changed version and default configuration", () => { - fireEvent.click(installButton); - + it("still has the dock tab for installing first chart", () => { expect( - callForCreateHelmReleaseMock, - ).toHaveBeenCalledWith({ - chart: "some-name", - name: undefined, - namespace: "default", - repo: "some-repository", - values: - "some-default-configuration-for-other-version", - version: "some-other-version", + rendered.getByTestId("dock-tab-for-some-first-tab-id"), + ).toBeInTheDocument(); + }); + + it("calls for default configuration of the second chart", () => { + expect(requestHelmChartValuesMock).toHaveBeenCalledWith( + "some-repository", + "some-other-name", + "some-version", + ); + }); + + it("calls for available versions for the second chart", () => { + expect(requestHelmChartVersionsMock).toHaveBeenCalledWith( + "some-repository", + "some-other-name", + ); + }); + + it("shows spinner in dock tab", () => { + expect( + rendered.getByTestId("install-chart-tab-spinner"), + ).toBeInTheDocument(); + }); + + describe("when configuration and versions resolve", () => { + beforeEach(async () => { + await requestHelmChartValuesMock.resolve( + "some-other-default-configuration", + ); + + await requestHelmChartVersionsMock.resolve([]); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("does not show spinner anymore", () => { + expect( + rendered.queryByTestId("install-chart-tab-spinner"), + ).not.toBeInTheDocument(); + }); + + it("when installing the second chart, calls for installation of second chart", () => { + const installButton = rendered.getByTestId( + "install-chart-from-tab-for-some-second-tab-id", + ); + + fireEvent.click(installButton); + + expect( + requestCreateHelmReleaseMock, + ).toHaveBeenCalledWith({ + chart: "some-other-name", + name: undefined, + namespace: "default", + repo: "some-repository", + values: "some-other-default-configuration", + version: "some-version", + }); + }); + + describe("when selecting the dock tab for installing first chart", () => { + beforeEach(() => { + requestHelmChartValuesMock.mockClear(); + requestHelmChartVersionsMock.mockClear(); + + const tab = rendered.getByTestId( + "dock-tab-for-some-first-tab-id", + ); + + fireEvent.click(tab); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("does not call for default configuration", () => { + expect( + requestHelmChartValuesMock, + ).not.toHaveBeenCalled(); + }); + + it("does not call for available versions", () => { + expect( + requestHelmChartVersionsMock, + ).not.toHaveBeenCalled(); + }); + + it("does not show spinner", () => { + expect( + rendered.queryByTestId("install-chart-tab-spinner"), + ).not.toBeInTheDocument(); + }); + + it("when installing the first chart, calls for installation of first chart", () => { + const installButton = rendered.getByTestId( + "install-chart-from-tab-for-some-first-tab-id", + ); + + fireEvent.click(installButton); + + expect( + requestCreateHelmReleaseMock, + ).toHaveBeenCalledWith({ + chart: "some-name", + name: undefined, + namespace: "default", + repo: "some-repository", + values: "some-default-configuration", + version: "some-version", + }); + }); }); }); }); }); - }); - describe("given namespace selection is opened", () => { - let menu: { selectOption: (labelText: string) => void }; + describe("given changing version to be installed", () => { + let menu: { selectOption: (labelText: string) => void }; - beforeEach(() => { - const menuId = - "install-chart-namespace-select-for-some-first-tab-id"; - - menu = builder.select.openMenu(menuId); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - describe("when namespace is selected", () => { beforeEach(() => { - menu.selectOption("some-other-namespace"); + requestHelmChartVersionsMock.mockClear(); + requestHelmChartValuesMock.mockClear(); + + const menuId = + "install-chart-version-select-for-some-first-tab-id"; + + menu = builder.select.openMenu(menuId); }); it("renders", () => { expect(rendered.baseElement).toMatchSnapshot(); }); - it("stores the selected namespace", async () => { + describe("when version is selected", () => { + let installButton: HTMLButtonElement; + + beforeEach(() => { + installButton = rendered.getByTestId( + "install-chart-from-tab-for-some-first-tab-id", + ) as HTMLButtonElement; + + menu.selectOption("some-other-version"); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("calls for default configuration for the version of chart", () => { + expect(requestHelmChartValuesMock).toHaveBeenCalledWith( + "some-repository", + "some-name", + "some-other-version", + ); + }); + + it("shows spinner", () => { + expect( + rendered.getByTestId( + "install-chart-configuration-spinner", + ), + ).toBeInTheDocument(); + }); + + it("does not call for versions again", () => { + expect( + requestHelmChartVersionsMock, + ).not.toHaveBeenCalled(); + }); + + it("install button is disabled", () => { + expect(installButton).toHaveAttribute("disabled"); + }); + + it("stores the selected version", async () => { + const readJsonFile = windowDi.inject(readJsonFileInjectable); + + const actual = await readJsonFile( + "/some-directory-for-lens-local-storage/some-cluster-id.json", + ) as any; + + const version = actual.install_charts["some-first-tab-id"].version; + + expect(version).toBe("some-other-version"); + }); + + describe("when default configuration resolves", () => { + beforeEach(async () => { + await requestHelmChartValuesMock.resolve( + "some-default-configuration-for-other-version", + ); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("does not show spinner", () => { + expect( + rendered.queryByTestId( + "install-chart-configuration-spinner", + ), + ).not.toBeInTheDocument(); + }); + + it("install button is enabled", () => { + expect(installButton).not.toHaveAttribute("disabled"); + }); + + it("when installing the chart, calls for installation with changed version and default configuration", () => { + fireEvent.click(installButton); + + expect( + requestCreateHelmReleaseMock, + ).toHaveBeenCalledWith({ + chart: "some-name", + name: undefined, + namespace: "default", + repo: "some-repository", + values: + "some-default-configuration-for-other-version", + version: "some-other-version", + }); + }); + }); + }); + }); + + describe("given namespace selection is opened", () => { + let menu: { selectOption: (labelText: string) => void }; + + beforeEach(() => { + const menuId = + "install-chart-namespace-select-for-some-first-tab-id"; + + menu = builder.select.openMenu(menuId); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + describe("when namespace is selected", () => { + beforeEach(() => { + menu.selectOption("some-other-namespace"); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("stores the selected namespace", async () => { + const readJsonFile = windowDi.inject(readJsonFileInjectable); + + const actual = await readJsonFile( + "/some-directory-for-lens-local-storage/some-cluster-id.json", + ) as any; + + const namespace = actual.install_charts["some-first-tab-id"].namespace; + + expect(namespace).toBe("some-other-namespace"); + }); + + it("when installing the chart, calls for installation with changed namespace", () => { + const installButton = rendered.getByTestId( + "install-chart-from-tab-for-some-first-tab-id", + ); + + fireEvent.click(installButton); + + expect(requestCreateHelmReleaseMock).toHaveBeenCalledWith( + { + chart: "some-name", + name: undefined, + namespace: "some-other-namespace", + repo: "some-repository", + values: "some-default-configuration", + version: "some-version", + }, + ); + }); + }); + }); + + describe("given invalid change in configuration", () => { + let installButton: HTMLButtonElement; + let input: HTMLInputElement; + + beforeEach(() => { + installButton = rendered.getByTestId( + "install-chart-from-tab-for-some-first-tab-id", + ) as HTMLButtonElement; + + input = rendered.getByTestId( + "monaco-editor-for-some-first-tab-id", + ) as HTMLInputElement; + + fireEvent.change(input, { + target: { value: "@some-invalid-configuration@" }, + }); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("updates the editor with the changed value", () => { + const input = rendered.getByTestId( + "monaco-editor-for-some-first-tab-id", + ); + + expect(input).toHaveValue("@some-invalid-configuration@"); + }); + + it("install button is disabled", () => { + expect(installButton).toHaveAttribute("disabled"); + }); + + it("when valid change in configuration, install button is enabled", () => { + fireEvent.change(input, { + target: { value: "some-valid-configuration" }, + }); + + expect(installButton).not.toHaveAttribute("disabled"); + }); + + it("given change in version, when default configuration resolves, install button is enabled", async () => { + builder.select + .openMenu( + "install-chart-version-select-for-some-first-tab-id", + ) + .selectOption("some-other-version"); + + await requestHelmChartValuesMock.resolve( + "some-default-configuration-for-other-version", + ); + + expect(installButton).not.toHaveAttribute("disabled"); + }); + }); + + describe("given valid change in configuration", () => { + beforeEach(() => { + const input = rendered.getByTestId( + "monaco-editor-for-some-first-tab-id", + ); + + fireEvent.change(input, { + target: { value: "some-valid-configuration" }, + }); + }); + + it("updates the editor with the changed value", () => { + const input = rendered.getByTestId( + "monaco-editor-for-some-first-tab-id", + ); + + expect(input).toHaveValue("some-valid-configuration"); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("stores the changed configuration", async () => { const readJsonFile = windowDi.inject(readJsonFileInjectable); const actual = await readJsonFile( "/some-directory-for-lens-local-storage/some-cluster-id.json", ) as any; - const namespace = actual.install_charts["some-first-tab-id"].namespace; + const configuration = actual.install_charts["some-first-tab-id"].values; - expect(namespace).toBe("some-other-namespace"); + expect(configuration).toBe("some-valid-configuration"); }); - it("when installing the chart, calls for installation with changed namespace", () => { + it("does not show spinner", () => { + expect( + rendered.queryByTestId("install-chart-tab-spinner"), + ).not.toBeInTheDocument(); + }); + + it("when installing the chart, calls for installation with changed configuration", () => { const installButton = rendered.getByTestId( "install-chart-from-tab-for-some-first-tab-id", ); fireEvent.click(installButton); - expect(callForCreateHelmReleaseMock).toHaveBeenCalledWith( - { - chart: "some-name", - name: undefined, - namespace: "some-other-namespace", - repo: "some-repository", - values: "some-default-configuration", - version: "some-version", - }, + expect(requestCreateHelmReleaseMock).toHaveBeenCalledWith({ + chart: "some-name", + name: undefined, + namespace: "default", + repo: "some-repository", + values: "some-valid-configuration", + version: "some-version", + }); + }); + + it("given version is changed, when default configuration resolves, defaults back to default configuration", async () => { + builder.select + .openMenu( + "install-chart-version-select-for-some-first-tab-id", + ) + .selectOption("some-other-version"); + + await requestHelmChartValuesMock.resolve( + "some-default-configuration-for-other-version", + ); + + const input = rendered.getByTestId( + "monaco-editor-for-some-first-tab-id", + ); + + expect(input).toHaveValue( + "some-default-configuration-for-other-version", ); }); }); - }); - describe("given invalid change in configuration", () => { - let installButton: HTMLButtonElement; - let input: HTMLInputElement; + describe("given custom name is inputted", () => { + beforeEach(() => { + const input = rendered.getByTestId( + "install-chart-custom-name-input-for-some-first-tab-id", + ); - beforeEach(() => { - installButton = rendered.getByTestId( - "install-chart-from-tab-for-some-first-tab-id", - ) as HTMLButtonElement; + fireEvent.change(input, { + target: { value: "some-custom-name" }, + }); - input = rendered.getByTestId( - "monaco-editor-for-some-first-tab-id", - ) as HTMLInputElement; - - fireEvent.change(input, { - target: { value: "@some-invalid-configuration@" }, - }); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("updates the editor with the changed value", () => { - const input = rendered.getByTestId( - "monaco-editor-for-some-first-tab-id", - ); - - expect(input).toHaveValue("@some-invalid-configuration@"); - }); - - it("install button is disabled", () => { - expect(installButton).toHaveAttribute("disabled"); - }); - - it("when valid change in configuration, install button is enabled", () => { - fireEvent.change(input, { - target: { value: "some-valid-configuration" }, }); - expect(installButton).not.toHaveAttribute("disabled"); - }); + it("stores the changed custom name", async () => { + const readJsonFile = windowDi.inject(readJsonFileInjectable); - it("given change in version, when default configuration resolves, install button is enabled", async () => { - builder.select - .openMenu( - "install-chart-version-select-for-some-first-tab-id", - ) - .selectOption("some-other-version"); + const actual = await readJsonFile( + "/some-directory-for-lens-local-storage/some-cluster-id.json", + ) as any; - await callForHelmChartValuesMock.resolve( - "some-default-configuration-for-other-version", - ); + const customName = actual.install_charts["some-first-tab-id"].releaseName; - expect(installButton).not.toHaveAttribute("disabled"); - }); - }); - - describe("given valid change in configuration", () => { - beforeEach(() => { - const input = rendered.getByTestId( - "monaco-editor-for-some-first-tab-id", - ); - - fireEvent.change(input, { - target: { value: "some-valid-configuration" }, - }); - }); - - it("updates the editor with the changed value", () => { - const input = rendered.getByTestId( - "monaco-editor-for-some-first-tab-id", - ); - - expect(input).toHaveValue("some-valid-configuration"); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("stores the changed configuration", async () => { - const readJsonFile = windowDi.inject(readJsonFileInjectable); - - const actual = await readJsonFile( - "/some-directory-for-lens-local-storage/some-cluster-id.json", - ) as any; - - const configuration = actual.install_charts["some-first-tab-id"].values; - - expect(configuration).toBe("some-valid-configuration"); - }); - - it("does not show spinner", () => { - expect( - rendered.queryByTestId("install-chart-tab-spinner"), - ).not.toBeInTheDocument(); - }); - - it("when installing the chart, calls for installation with changed configuration", () => { - const installButton = rendered.getByTestId( - "install-chart-from-tab-for-some-first-tab-id", - ); - - fireEvent.click(installButton); - - expect(callForCreateHelmReleaseMock).toHaveBeenCalledWith({ - chart: "some-name", - name: undefined, - namespace: "default", - repo: "some-repository", - values: "some-valid-configuration", - version: "some-version", - }); - }); - - it("given version is changed, when default configuration resolves, defaults back to default configuration", async () => { - builder.select - .openMenu( - "install-chart-version-select-for-some-first-tab-id", - ) - .selectOption("some-other-version"); - - await callForHelmChartValuesMock.resolve( - "some-default-configuration-for-other-version", - ); - - const input = rendered.getByTestId( - "monaco-editor-for-some-first-tab-id", - ); - - expect(input).toHaveValue( - "some-default-configuration-for-other-version", - ); - }); - }); - - describe("given custom name is inputted", () => { - beforeEach(() => { - const input = rendered.getByTestId( - "install-chart-custom-name-input-for-some-first-tab-id", - ); - - fireEvent.change(input, { - target: { value: "some-custom-name" }, + expect(customName).toBe("some-custom-name"); }); - }); + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); - it("stores the changed custom name", async () => { - const readJsonFile = windowDi.inject(readJsonFileInjectable); + it("when installed, calls for installation with custom name", () => { + const installButton = rendered.getByTestId( + "install-chart-from-tab-for-some-first-tab-id", + ); - const actual = await readJsonFile( - "/some-directory-for-lens-local-storage/some-cluster-id.json", - ) as any; + fireEvent.click(installButton); - const customName = actual.install_charts["some-first-tab-id"].releaseName; - - expect(customName).toBe("some-custom-name"); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("when installed, calls for installation with custom name", () => { - const installButton = rendered.getByTestId( - "install-chart-from-tab-for-some-first-tab-id", - ); - - fireEvent.click(installButton); - - expect(callForCreateHelmReleaseMock).toHaveBeenCalledWith({ - chart: "some-name", - name: "some-custom-name", - namespace: "default", - repo: "some-repository", - values: "some-default-configuration", - version: "some-version", + expect(requestCreateHelmReleaseMock).toHaveBeenCalledWith({ + chart: "some-name", + name: "some-custom-name", + namespace: "default", + repo: "some-repository", + values: "some-default-configuration", + version: "some-version", + }); }); }); }); diff --git a/src/features/helm-charts/installing-chart/installing-helm-chart-from-previously-opened-tab.test.ts b/src/features/helm-charts/installing-chart/installing-helm-chart-from-previously-opened-tab.test.ts index c49f3a7942..669b73eca3 100644 --- a/src/features/helm-charts/installing-chart/installing-helm-chart-from-previously-opened-tab.test.ts +++ b/src/features/helm-charts/installing-chart/installing-helm-chart-from-previously-opened-tab.test.ts @@ -9,23 +9,23 @@ import type { ApplicationBuilder } from "../../../renderer/components/test-utils import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder"; import { HelmChart } from "../../../common/k8s-api/endpoints/helm-charts.api"; import getRandomInstallChartTabIdInjectable from "../../../renderer/components/dock/install-chart/get-random-install-chart-tab-id.injectable"; -import type { CallForHelmChartValues } from "../../../renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable"; -import callForHelmChartValuesInjectable from "../../../renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable"; import namespaceStoreInjectable from "../../../renderer/components/+namespaces/store.injectable"; import type { NamespaceStore } from "../../../renderer/components/+namespaces/store"; -import type { CallForHelmChartVersions } from "../../../renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable"; -import callForHelmChartVersionsInjectable from "../../../renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable"; import writeJsonFileInjectable from "../../../common/fs/write-json-file.injectable"; import directoryForLensLocalStorageInjectable from "../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable"; import hostedClusterIdInjectable from "../../../renderer/cluster-frame-context/hosted-cluster-id.injectable"; import { TabKind } from "../../../renderer/components/dock/dock/store"; import { controlWhenStoragesAreReady } from "../../../renderer/utils/create-storage/storages-are-ready"; -import callForCreateHelmReleaseInjectable from "../../../renderer/components/+helm-releases/create-release/call-for-create-helm-release.injectable"; +import requestCreateHelmReleaseInjectable from "../../../common/k8s-api/endpoints/helm-releases.api/create.injectable"; +import type { RequestHelmChartVersions } from "../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; +import requestHelmChartVersionsInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; +import type { RequestHelmChartValues } from "../../../common/k8s-api/endpoints/helm-charts.api/get-values.injectable"; +import requestHelmChartValuesInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/get-values.injectable"; describe("installing helm chart from previously opened tab", () => { let builder: ApplicationBuilder; - let callForHelmChartVersionsMock: AsyncFnMock; - let callForHelmChartValuesMock: AsyncFnMock; + let requestHelmChartVersionsMock: AsyncFnMock; + let requestHelmChartValuesMock: AsyncFnMock; let storagesAreReady: () => Promise; beforeEach(() => { @@ -33,38 +33,17 @@ describe("installing helm chart from previously opened tab", () => { builder.setEnvironmentToClusterFrame(); - callForHelmChartVersionsMock = asyncFn(); - callForHelmChartValuesMock = asyncFn(); + requestHelmChartVersionsMock = asyncFn(); + requestHelmChartValuesMock = asyncFn(); builder.beforeWindowStart((windowDi) => { - windowDi.override( - directoryForLensLocalStorageInjectable, - () => "/some-directory-for-lens-local-storage", - ); - - windowDi.override(hostedClusterIdInjectable, () => "some-cluster-id"); - storagesAreReady = controlWhenStoragesAreReady(windowDi); - windowDi.override( - callForHelmChartVersionsInjectable, - () => callForHelmChartVersionsMock, - ); - - windowDi.override( - callForHelmChartValuesInjectable, - () => callForHelmChartValuesMock, - ); - - windowDi.override( - callForHelmChartValuesInjectable, - () => callForHelmChartValuesMock, - ); - - windowDi.override( - callForCreateHelmReleaseInjectable, - () => jest.fn(), - ); + windowDi.override(directoryForLensLocalStorageInjectable, () => "/some-directory-for-lens-local-storage"); + windowDi.override(hostedClusterIdInjectable, () => "some-cluster-id"); + windowDi.override(requestHelmChartVersionsInjectable, () => requestHelmChartVersionsMock); + windowDi.override(requestHelmChartValuesInjectable, () => requestHelmChartValuesMock); + windowDi.override(requestCreateHelmReleaseInjectable, () => jest.fn()); // TODO: Replace store mocking with mock for the actual side-effect (where the namespaces are coming from) windowDi.override( @@ -154,7 +133,7 @@ describe("installing helm chart from previously opened tab", () => { }); it("calls for default configuration of the chart", () => { - expect(callForHelmChartValuesMock).toHaveBeenCalledWith( + expect(requestHelmChartValuesMock).toHaveBeenCalledWith( "some-repository", "some-name", "some-other-version", @@ -162,7 +141,7 @@ describe("installing helm chart from previously opened tab", () => { }); it("calls for available versions", () => { - expect(callForHelmChartVersionsMock).toHaveBeenCalledWith( + expect(requestHelmChartVersionsMock).toHaveBeenCalledWith( "some-repository", "some-name", ); @@ -170,11 +149,11 @@ describe("installing helm chart from previously opened tab", () => { describe("when configuration and version resolves", () => { beforeEach(async () => { - await callForHelmChartValuesMock.resolve( + await requestHelmChartValuesMock.resolve( "some-default-configuration", ); - await callForHelmChartVersionsMock.resolve([ + await requestHelmChartVersionsMock.resolve([ HelmChart.create({ apiVersion: "some-api-version", name: "some-name", diff --git a/src/features/helm-charts/installing-chart/opening-dock-tab-for-installing-helm-chart.test.ts b/src/features/helm-charts/installing-chart/opening-dock-tab-for-installing-helm-chart.test.ts index ddc682afd2..a7f144cdd3 100644 --- a/src/features/helm-charts/installing-chart/opening-dock-tab-for-installing-helm-chart.test.ts +++ b/src/features/helm-charts/installing-chart/opening-dock-tab-for-installing-helm-chart.test.ts @@ -8,69 +8,44 @@ import type { RenderResult } from "@testing-library/react"; import { fireEvent } from "@testing-library/react"; import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder"; import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder"; -import type { CallForHelmCharts } from "../../../renderer/components/+helm-charts/helm-charts/call-for-helm-charts.injectable"; -import callForHelmChartsInjectable from "../../../renderer/components/+helm-charts/helm-charts/call-for-helm-charts.injectable"; import { HelmChart } from "../../../common/k8s-api/endpoints/helm-charts.api"; import getRandomInstallChartTabIdInjectable from "../../../renderer/components/dock/install-chart/get-random-install-chart-tab-id.injectable"; -import callForHelmChartValuesInjectable from "../../../renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable"; -import callForCreateHelmReleaseInjectable from "../../../renderer/components/+helm-releases/create-release/call-for-create-helm-release.injectable"; -import type { CallForHelmChartReadme } from "../../../renderer/components/+helm-charts/details/readme/call-for-helm-chart-readme.injectable"; -import callForHelmChartReadmeInjectable from "../../../renderer/components/+helm-charts/details/readme/call-for-helm-chart-readme.injectable"; -import type { CallForHelmChartVersions } from "../../../renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable"; -import callForHelmChartVersionsInjectable from "../../../renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable"; +import requestCreateHelmReleaseInjectable from "../../../common/k8s-api/endpoints/helm-releases.api/create.injectable"; import { flushPromises } from "../../../common/test-utils/flush-promises"; import directoryForLensLocalStorageInjectable from "../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable"; import hostedClusterIdInjectable from "../../../renderer/cluster-frame-context/hosted-cluster-id.injectable"; import dockStoreInjectable from "../../../renderer/components/dock/dock/store.injectable"; +import type { RequestHelmCharts } from "../../../common/k8s-api/endpoints/helm-charts.api/list.injectable"; +import type { RequestHelmChartVersions } from "../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; +import type { RequestHelmChartReadme } from "../../../common/k8s-api/endpoints/helm-charts.api/get-readme.injectable"; +import requestHelmChartsInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/list.injectable"; +import requestHelmChartVersionsInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; +import requestHelmChartReadmeInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/get-readme.injectable"; +import requestHelmChartValuesInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/get-values.injectable"; describe("opening dock tab for installing helm chart", () => { let builder: ApplicationBuilder; - let callForHelmChartsMock: AsyncFnMock; - let callForHelmChartVersionsMock: AsyncFnMock; - let callForHelmChartReadmeMock: AsyncFnMock; - let callForHelmChartValuesMock: jest.Mock; + let requestHelmChartsMock: AsyncFnMock; + let requestHelmChartVersionsMock: AsyncFnMock; + let requestHelmChartReadmeMock: AsyncFnMock; + let requestHelmChartValuesMock: jest.Mock; beforeEach(() => { builder = getApplicationBuilder(); - callForHelmChartsMock = asyncFn(); - callForHelmChartVersionsMock = asyncFn(); - callForHelmChartReadmeMock = asyncFn(); - callForHelmChartValuesMock = jest.fn(); + requestHelmChartsMock = asyncFn(); + requestHelmChartVersionsMock = asyncFn(); + requestHelmChartReadmeMock = asyncFn(); + requestHelmChartValuesMock = jest.fn(); builder.beforeWindowStart((windowDi) => { - windowDi.override( - directoryForLensLocalStorageInjectable, - () => "/some-directory-for-lens-local-storage", - ); - + windowDi.override(directoryForLensLocalStorageInjectable, () => "/some-directory-for-lens-local-storage"); windowDi.override(hostedClusterIdInjectable, () => "some-cluster-id"); - - windowDi.override( - callForHelmChartsInjectable, - () => callForHelmChartsMock, - ); - - windowDi.override( - callForHelmChartVersionsInjectable, - () => callForHelmChartVersionsMock, - ); - - windowDi.override( - callForHelmChartReadmeInjectable, - () => callForHelmChartReadmeMock, - ); - - windowDi.override( - callForHelmChartValuesInjectable, - () => callForHelmChartValuesMock, - ); - - windowDi.override( - callForCreateHelmReleaseInjectable, - () => jest.fn(), - ); - + windowDi.override(requestHelmChartsInjectable, () => requestHelmChartsMock); + windowDi.override(requestHelmChartVersionsInjectable, () => requestHelmChartVersionsMock); + windowDi.override(requestHelmChartReadmeInjectable, () => requestHelmChartReadmeMock); + windowDi.override(requestHelmChartValuesInjectable, () => requestHelmChartValuesMock); + windowDi.override(requestCreateHelmReleaseInjectable, () => jest.fn()); windowDi.override(getRandomInstallChartTabIdInjectable, () => jest .fn(() => "some-irrelevant-tab-id") @@ -102,12 +77,12 @@ describe("opening dock tab for installing helm chart", () => { }); it("calls for charts", () => { - expect(callForHelmChartsMock).toHaveBeenCalled(); + expect(requestHelmChartsMock).toHaveBeenCalled(); }); describe("when charts resolve", () => { beforeEach(async () => { - await callForHelmChartsMock.resolve([ + await requestHelmChartsMock.resolve([ HelmChart.create({ apiVersion: "some-api-version", name: "some-name", @@ -160,7 +135,7 @@ describe("opening dock tab for installing helm chart", () => { }); it("calls for chart versions", () => { - expect(callForHelmChartVersionsMock).toHaveBeenCalledWith( + expect(requestHelmChartVersionsMock).toHaveBeenCalledWith( "some-repository", "some-name", ); @@ -174,7 +149,7 @@ describe("opening dock tab for installing helm chart", () => { describe("when chart versions resolve", () => { beforeEach(async () => { - await callForHelmChartVersionsMock.resolve([ + await requestHelmChartVersionsMock.resolve([ HelmChart.create({ apiVersion: "some-api-version", name: "some-name", @@ -210,7 +185,7 @@ describe("opening dock tab for installing helm chart", () => { }); it("calls for chart readme for the version", () => { - expect(callForHelmChartReadmeMock).toHaveBeenCalledWith( + expect(requestHelmChartReadmeMock).toHaveBeenCalledWith( "some-repository", "some-name", "some-version", @@ -243,7 +218,7 @@ describe("opening dock tab for installing helm chart", () => { describe("when readme resolves", () => { beforeEach(async () => { - await callForHelmChartReadmeMock.resolve("some-readme"); + await requestHelmChartReadmeMock.resolve("some-readme"); }); it("renders", () => { @@ -258,7 +233,7 @@ describe("opening dock tab for installing helm chart", () => { describe("when selecting different version", () => { beforeEach(() => { - callForHelmChartReadmeMock.mockClear(); + requestHelmChartReadmeMock.mockClear(); builder.select .openMenu( @@ -280,7 +255,7 @@ describe("opening dock tab for installing helm chart", () => { }); it("calls for chart readme for the version", () => { - expect(callForHelmChartReadmeMock).toHaveBeenCalledWith( + expect(requestHelmChartReadmeMock).toHaveBeenCalledWith( "some-repository", "some-name", "some-other-version", @@ -289,7 +264,7 @@ describe("opening dock tab for installing helm chart", () => { describe("when readme resolves", () => { beforeEach(async () => { - await callForHelmChartReadmeMock.resolve("some-readme"); + await requestHelmChartReadmeMock.resolve("some-readme"); }); it("renders", () => { @@ -305,7 +280,7 @@ describe("opening dock tab for installing helm chart", () => { await flushPromises(); - expect(callForHelmChartValuesMock).toHaveBeenCalledWith( + expect(requestHelmChartValuesMock).toHaveBeenCalledWith( "some-repository", "some-name", "some-other-version", @@ -316,7 +291,7 @@ describe("opening dock tab for installing helm chart", () => { describe("when selecting to install the chart", () => { beforeEach(() => { - callForHelmChartVersionsMock.mockClear(); + requestHelmChartVersionsMock.mockClear(); const installButton = rendered.getByTestId( "install-chart-for-some-repository-some-name", diff --git a/src/features/helm-releases/showing-details-for-helm-release.test.ts b/src/features/helm-releases/showing-details-for-helm-release.test.ts index 4a4dc27149..840296e25d 100644 --- a/src/features/helm-releases/showing-details-for-helm-release.test.ts +++ b/src/features/helm-releases/showing-details-for-helm-release.test.ts @@ -9,27 +9,27 @@ import type { RenderResult } from "@testing-library/react"; import { fireEvent } from "@testing-library/react"; import type { AsyncFnMock } from "@async-fn/jest"; import asyncFn from "@async-fn/jest"; -import type { CallForHelmReleases } from "../../renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.injectable"; -import callForHelmReleasesInjectable from "../../renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.injectable"; +import type { RequestHelmReleases } from "../../common/k8s-api/endpoints/helm-releases.api/list.injectable"; +import requestHelmReleasesInjectable from "../../common/k8s-api/endpoints/helm-releases.api/list.injectable"; import namespaceStoreInjectable from "../../renderer/components/+namespaces/store.injectable"; import type { NamespaceStore } from "../../renderer/components/+namespaces/store"; -import type { CallForHelmReleaseConfiguration } from "../../renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release-configuration/call-for-helm-release-configuration.injectable"; -import callForHelmReleaseConfigurationInjectable from "../../renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release-configuration/call-for-helm-release-configuration.injectable"; -import type { CallForHelmReleaseUpdate } from "../../renderer/components/+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.injectable"; -import callForHelmReleaseUpdateInjectable from "../../renderer/components/+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.injectable"; +import type { RequestHelmReleaseConfiguration } from "../../common/k8s-api/endpoints/helm-releases.api/get-configuration.injectable"; +import requestHelmReleaseConfigurationInjectable from "../../common/k8s-api/endpoints/helm-releases.api/get-configuration.injectable"; +import type { RequestHelmReleaseUpdate } from "../../common/k8s-api/endpoints/helm-releases.api/update.injectable"; +import requestHelmReleaseUpdateInjectable from "../../common/k8s-api/endpoints/helm-releases.api/update.injectable"; import { useFakeTime } from "../../common/test-utils/use-fake-time"; -import type { CallForHelmRelease, DetailedHelmRelease } from "../../renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release.injectable"; -import callForHelmReleaseInjectable from "../../renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release.injectable"; +import type { RequestHelmRelease, DetailedHelmRelease } from "../../renderer/components/+helm-releases/release-details/release-details-model/request-helm-release.injectable"; +import requestHelmReleaseInjectable from "../../renderer/components/+helm-releases/release-details/release-details-model/request-helm-release.injectable"; import showSuccessNotificationInjectable from "../../renderer/components/notifications/show-success-notification.injectable"; import showCheckedErrorInjectable from "../../renderer/components/notifications/show-checked-error.injectable"; import getRandomUpgradeChartTabIdInjectable from "../../renderer/components/dock/upgrade-chart/get-random-upgrade-chart-tab-id.injectable"; describe("showing details for helm release", () => { let builder: ApplicationBuilder; - let callForHelmReleasesMock: AsyncFnMock; - let callForHelmReleaseMock: AsyncFnMock; - let callForHelmReleaseConfigurationMock: AsyncFnMock; - let callForHelmReleaseUpdateMock: AsyncFnMock; + let requestHelmReleasesMock: AsyncFnMock; + let requestHelmReleaseMock: AsyncFnMock; + let requestHelmReleaseConfigurationMock: AsyncFnMock; + let requestHelmReleaseUpdateMock: AsyncFnMock; let showSuccessNotificationMock: jest.Mock; let showCheckedErrorNotificationMock: jest.Mock; @@ -40,50 +40,22 @@ describe("showing details for helm release", () => { builder.setEnvironmentToClusterFrame(); - callForHelmReleasesMock = asyncFn(); - callForHelmReleaseMock = asyncFn(); - callForHelmReleaseConfigurationMock = asyncFn(); - callForHelmReleaseUpdateMock = asyncFn(); + requestHelmReleasesMock = asyncFn(); + requestHelmReleaseMock = asyncFn(); + requestHelmReleaseConfigurationMock = asyncFn(); + requestHelmReleaseUpdateMock = asyncFn(); showSuccessNotificationMock = jest.fn(); showCheckedErrorNotificationMock = jest.fn(); builder.beforeWindowStart((windowDi) => { - windowDi.override( - getRandomUpgradeChartTabIdInjectable, - () => () => "some-tab-id", - ); - - windowDi.override( - showSuccessNotificationInjectable, - () => showSuccessNotificationMock, - ); - - windowDi.override( - showCheckedErrorInjectable, - () => showCheckedErrorNotificationMock, - ); - - windowDi.override( - callForHelmReleasesInjectable, - () => callForHelmReleasesMock, - ); - - windowDi.override( - callForHelmReleaseInjectable, - () => callForHelmReleaseMock, - ); - - windowDi.override( - callForHelmReleaseConfigurationInjectable, - () => callForHelmReleaseConfigurationMock, - ); - - windowDi.override( - callForHelmReleaseUpdateInjectable, - () => callForHelmReleaseUpdateMock, - ); - + windowDi.override(getRandomUpgradeChartTabIdInjectable, () => () => "some-tab-id"); + windowDi.override(showSuccessNotificationInjectable, () => showSuccessNotificationMock); + windowDi.override(showCheckedErrorInjectable, () => showCheckedErrorNotificationMock); + windowDi.override(requestHelmReleasesInjectable, () => requestHelmReleasesMock); + windowDi.override(requestHelmReleaseInjectable, () => requestHelmReleaseMock); + windowDi.override(requestHelmReleaseConfigurationInjectable, () => requestHelmReleaseConfigurationMock); + windowDi.override(requestHelmReleaseUpdateInjectable, () => requestHelmReleaseUpdateMock); windowDi.override( namespaceStoreInjectable, () => @@ -119,7 +91,7 @@ describe("showing details for helm release", () => { }); it("calls for releases for each selected namespace", () => { - expect(callForHelmReleasesMock.mock.calls).toEqual([ + expect(requestHelmReleasesMock.mock.calls).toEqual([ ["some-namespace"], ["some-other-namespace"], ]); @@ -132,15 +104,15 @@ describe("showing details for helm release", () => { }); it("when releases resolve but there is none, renders", async () => { - await callForHelmReleasesMock.resolve([]); - await callForHelmReleasesMock.resolve([]); + await requestHelmReleasesMock.resolve([]); + await requestHelmReleasesMock.resolve([]); expect(rendered.baseElement).toMatchSnapshot(); }); describe("when releases resolve", () => { beforeEach(async () => { - await callForHelmReleasesMock.resolveSpecific( + await requestHelmReleasesMock.resolveSpecific( ([namespace]) => namespace === "some-namespace", [ { @@ -155,7 +127,7 @@ describe("showing details for helm release", () => { ], ); - await callForHelmReleasesMock.resolveSpecific( + await requestHelmReleasesMock.resolveSpecific( ([namespace]) => namespace === "some-other-namespace", [ { @@ -201,7 +173,7 @@ describe("showing details for helm release", () => { }); it("calls for release", () => { - expect(callForHelmReleaseMock).toHaveBeenCalledWith( + expect(requestHelmReleaseMock).toHaveBeenCalledWith( "some-name", "some-namespace", ); @@ -215,7 +187,7 @@ describe("showing details for helm release", () => { describe("when opening details for second release", () => { beforeEach(() => { - callForHelmReleaseMock.mockClear(); + requestHelmReleaseMock.mockClear(); const row = rendered.getByTestId( "helm-release-row-for-some-other-namespace/some-other-name", @@ -229,7 +201,7 @@ describe("showing details for helm release", () => { }); it("calls for another release", () => { - expect(callForHelmReleaseMock).toHaveBeenCalledWith( + expect(requestHelmReleaseMock).toHaveBeenCalledWith( "some-other-name", "some-other-namespace", ); @@ -269,7 +241,7 @@ describe("showing details for helm release", () => { describe("when opening details for same release", () => { beforeEach(() => { - callForHelmReleaseMock.mockClear(); + requestHelmReleaseMock.mockClear(); const row = rendered.getByTestId( "helm-release-row-for-some-namespace/some-name", @@ -283,7 +255,7 @@ describe("showing details for helm release", () => { }); it("does not reload", () => { - expect(callForHelmReleaseMock).not.toHaveBeenCalled(); + expect(requestHelmReleaseMock).not.toHaveBeenCalled(); }); }); }); @@ -291,7 +263,7 @@ describe("showing details for helm release", () => { describe("when call for release resolves with error", () => { beforeEach(async () => { - await callForHelmReleaseMock.resolve({ + await requestHelmReleaseMock.resolve({ callWasSuccessful: false, error: "some-error", }); @@ -314,13 +286,13 @@ describe("showing details for helm release", () => { }); it("does not call for release configuration", () => { - expect(callForHelmReleaseConfigurationMock).not.toHaveBeenCalled(); + expect(requestHelmReleaseConfigurationMock).not.toHaveBeenCalled(); }); }); describe("when call for release resolve with release", () => { beforeEach(async () => { - await callForHelmReleaseMock.resolve({ + await requestHelmReleaseMock.resolve({ callWasSuccessful: true, response: detailedReleaseFake, }); @@ -331,7 +303,7 @@ describe("showing details for helm release", () => { }); it("calls for release configuration", () => { - expect(callForHelmReleaseConfigurationMock).toHaveBeenCalledWith( + expect(requestHelmReleaseConfigurationMock).toHaveBeenCalledWith( "some-name", "some-namespace", true, @@ -340,7 +312,7 @@ describe("showing details for helm release", () => { describe("when configuration resolves", () => { beforeEach(async () => { - await callForHelmReleaseConfigurationMock.resolve( + await requestHelmReleaseConfigurationMock.resolve( "some-configuration", ); }); @@ -405,12 +377,12 @@ describe("showing details for helm release", () => { }); it("does not save changes yet", () => { - expect(callForHelmReleaseUpdateMock).not.toHaveBeenCalled(); + expect(requestHelmReleaseUpdateMock).not.toHaveBeenCalled(); }); describe("when toggling to see only user defined values", () => { beforeEach(() => { - callForHelmReleaseConfigurationMock.mockClear(); + requestHelmReleaseConfigurationMock.mockClear(); const toggle = rendered.getByTestId( "user-supplied-values-only-checkbox", @@ -420,7 +392,7 @@ describe("showing details for helm release", () => { }); it("calls for only user defined configuration", () => { - expect(callForHelmReleaseConfigurationMock).toHaveBeenCalledWith( + expect(requestHelmReleaseConfigurationMock).toHaveBeenCalledWith( "some-name", "some-namespace", false, @@ -429,7 +401,7 @@ describe("showing details for helm release", () => { describe("when configuration resolves", () => { beforeEach(async () => { - await callForHelmReleaseConfigurationMock.resolve( + await requestHelmReleaseConfigurationMock.resolve( "some-other-configuration", ); }); @@ -447,7 +419,7 @@ describe("showing details for helm release", () => { }); it("when toggling again, calls for all configuration", () => { - callForHelmReleaseConfigurationMock.mockClear(); + requestHelmReleaseConfigurationMock.mockClear(); const toggle = rendered.getByTestId( "user-supplied-values-only-checkbox", @@ -455,7 +427,7 @@ describe("showing details for helm release", () => { fireEvent.click(toggle); - expect(callForHelmReleaseConfigurationMock).toHaveBeenCalledWith( + expect(requestHelmReleaseConfigurationMock).toHaveBeenCalledWith( "some-name", "some-namespace", true, @@ -478,7 +450,7 @@ describe("showing details for helm release", () => { }); it("calls for update", () => { - expect(callForHelmReleaseUpdateMock).toHaveBeenCalledWith( + expect(requestHelmReleaseUpdateMock).toHaveBeenCalledWith( "some-name", "some-namespace", @@ -501,10 +473,10 @@ describe("showing details for helm release", () => { describe("when update resolves with success", () => { beforeEach(async () => { - callForHelmReleasesMock.mockClear(); - callForHelmReleaseConfigurationMock.mockClear(); + requestHelmReleasesMock.mockClear(); + requestHelmReleaseConfigurationMock.mockClear(); - await callForHelmReleaseUpdateMock.resolve({ + await requestHelmReleaseUpdateMock.resolve({ updateWasSuccessful: true, }); }); @@ -522,7 +494,7 @@ describe("showing details for helm release", () => { }); it("reloads the configuration", () => { - expect(callForHelmReleaseConfigurationMock).toHaveBeenCalledWith( + expect(requestHelmReleaseConfigurationMock).toHaveBeenCalledWith( "some-name", "some-namespace", true, @@ -540,10 +512,10 @@ describe("showing details for helm release", () => { describe("when update resolves with failure", () => { beforeEach(async () => { - callForHelmReleasesMock.mockClear(); - callForHelmReleaseConfigurationMock.mockClear(); + requestHelmReleasesMock.mockClear(); + requestHelmReleaseConfigurationMock.mockClear(); - await callForHelmReleaseUpdateMock.resolve({ + await requestHelmReleaseUpdateMock.resolve({ updateWasSuccessful: false, error: "some-error", }); @@ -562,7 +534,7 @@ describe("showing details for helm release", () => { }); it("does not reload the configuration", () => { - expect(callForHelmReleaseConfigurationMock).not.toHaveBeenCalled(); + expect(requestHelmReleaseConfigurationMock).not.toHaveBeenCalled(); }); it("does not show success notification", () => { diff --git a/src/main/getDiForUnitTesting.ts b/src/main/getDiForUnitTesting.ts index bbda6d5838..bdb2ab8cb4 100644 --- a/src/main/getDiForUnitTesting.ts +++ b/src/main/getDiForUnitTesting.ts @@ -74,7 +74,7 @@ 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 getHelmChartVersionsInjectable from "./helm/helm-service/get-helm-chart-versions.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"; @@ -161,7 +161,7 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) di.override(periodicalCheckForUpdatesInjectable, () => ({ start: () => {}, stop: () => {}, started: false })); overrideFunctionalInjectables(di, [ - getHelmChartInjectable, + getHelmChartVersionsInjectable, getHelmChartValuesInjectable, listHelmChartsInjectable, deleteHelmReleaseInjectable, diff --git a/src/main/helm/helm-service/get-helm-chart.injectable.ts b/src/main/helm/helm-service/get-helm-chart-readme.injectable.ts similarity index 73% rename from src/main/helm/helm-service/get-helm-chart.injectable.ts rename to src/main/helm/helm-service/get-helm-chart-readme.injectable.ts index bd9615a3c4..ff5aa2fd0a 100644 --- a/src/main/helm/helm-service/get-helm-chart.injectable.ts +++ b/src/main/helm/helm-service/get-helm-chart-readme.injectable.ts @@ -7,8 +7,8 @@ import getActiveHelmRepositoryInjectable from "../repositories/get-active-helm-r import type { HelmRepo } from "../../../common/helm/helm-repo"; import helmChartManagerInjectable from "../helm-chart-manager.injectable"; -const getHelmChartInjectable = getInjectable({ - id: "get-helm-chart", +const getHelmChartReadmeInjectable = getInjectable({ + id: "get-helm-chart-readme", instantiate: (di) => { const getActiveHelmRepository = di.inject(getActiveHelmRepositoryInjectable); @@ -21,16 +21,11 @@ const getHelmChartInjectable = getInjectable({ return undefined; } - const chartManager = getChartManager(repo); - - return { - readme: await chartManager.getReadme(chartName, version), - versions: await chartManager.chartVersions(chartName), - }; + return getChartManager(repo).getReadme(chartName, version); }; }, causesSideEffects: true, }); -export default getHelmChartInjectable; +export default getHelmChartReadmeInjectable; diff --git a/src/main/helm/helm-service/get-helm-chart-versions.injectable.ts b/src/main/helm/helm-service/get-helm-chart-versions.injectable.ts new file mode 100644 index 0000000000..715b09d565 --- /dev/null +++ b/src/main/helm/helm-service/get-helm-chart-versions.injectable.ts @@ -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 getHelmChartVersionsInjectable = getInjectable({ + id: "get-helm-chart-versions", + + instantiate: (di) => { + const getActiveHelmRepository = di.inject(getActiveHelmRepositoryInjectable); + + return async (repoName: string, chartName: string) => { + const repo = await getActiveHelmRepository(repoName); + + if (!repo) { + return undefined; + } + + return HelmChartManager.forRepo(repo).chartVersions(chartName); + }; + }, + + causesSideEffects: true, +}); + +export default getHelmChartVersionsInjectable; diff --git a/src/main/routes/helm/charts/get-chart-route.injectable.ts b/src/main/routes/helm/charts/get-readme-route.injectable.ts similarity index 58% rename from src/main/routes/helm/charts/get-chart-route.injectable.ts rename to src/main/routes/helm/charts/get-readme-route.injectable.ts index 012584dbfc..f3b52073c2 100644 --- a/src/main/routes/helm/charts/get-chart-route.injectable.ts +++ b/src/main/routes/helm/charts/get-readme-route.injectable.ts @@ -5,22 +5,22 @@ import { getRouteInjectable } from "../../../router/router.injectable"; import { apiPrefix } from "../../../../common/vars"; import { route } from "../../../router/route"; -import getHelmChartInjectable from "../../../helm/helm-service/get-helm-chart.injectable"; +import getHelmChartReadmeInjectable from "../../../helm/helm-service/get-helm-chart-readme.injectable"; -const getChartRouteInjectable = getRouteInjectable({ - id: "get-chart-route", +const getHelmChartReadmeRouteInjectable = getRouteInjectable({ + id: "get-helm-chart-readme-route", instantiate: (di) => { - const getHelmChart = di.inject(getHelmChartInjectable); + const getHelmChartReadme = di.inject(getHelmChartReadmeInjectable); return route({ method: "get", - path: `${apiPrefix}/v2/charts/{repo}/{chart}`, + path: `${apiPrefix}/v2/charts/{repo}/{chart}/readme`, })(async ({ params, query }) => { const { repo, chart } = params; return { - response: await getHelmChart( + response: await getHelmChartReadme( repo, chart, query.get("version") ?? undefined, @@ -30,4 +30,4 @@ const getChartRouteInjectable = getRouteInjectable({ }, }); -export default getChartRouteInjectable; +export default getHelmChartReadmeRouteInjectable; diff --git a/src/main/routes/helm/charts/get-chart-values-route.injectable.ts b/src/main/routes/helm/charts/get-values-route.injectable.ts similarity index 84% rename from src/main/routes/helm/charts/get-chart-values-route.injectable.ts rename to src/main/routes/helm/charts/get-values-route.injectable.ts index 3cb7fd8f46..49efe5fb0c 100644 --- a/src/main/routes/helm/charts/get-chart-values-route.injectable.ts +++ b/src/main/routes/helm/charts/get-values-route.injectable.ts @@ -7,8 +7,8 @@ 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", +const getHelmChartRouteValuesInjectable = getRouteInjectable({ + id: "get-helm-chart-values-route", instantiate: (di) => { const getHelmChartValues = di.inject(getHelmChartValuesInjectable); @@ -26,4 +26,4 @@ const getChartRouteValuesInjectable = getRouteInjectable({ }, }); -export default getChartRouteValuesInjectable; +export default getHelmChartRouteValuesInjectable; diff --git a/src/main/routes/helm/charts/get-versions-route.injectable.ts b/src/main/routes/helm/charts/get-versions-route.injectable.ts new file mode 100644 index 0000000000..933d94743b --- /dev/null +++ b/src/main/routes/helm/charts/get-versions-route.injectable.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getRouteInjectable } from "../../../router/router.injectable"; +import { apiPrefix } from "../../../../common/vars"; +import { route } from "../../../router/route"; +import getHelmChartVersionsInjectable from "../../../helm/helm-service/get-helm-chart-versions.injectable"; + +const getHelmChartVersionsRouteInjectable = getRouteInjectable({ + id: "get-helm-chart-versions-route", + + instantiate: (di) => { + const getHelmChartVersions = di.inject(getHelmChartVersionsInjectable); + + return route({ + method: "get", + path: `${apiPrefix}/v2/charts/{repo}/{chart}/versions`, + })(async ({ params: { repo, chart }}) => ({ + response: await getHelmChartVersions(repo, chart), + })); + }, +}); + +export default getHelmChartVersionsRouteInjectable; diff --git a/src/main/routes/helm/charts/list-charts-route.injectable.ts b/src/main/routes/helm/charts/list-route.injectable.ts similarity index 82% rename from src/main/routes/helm/charts/list-charts-route.injectable.ts rename to src/main/routes/helm/charts/list-route.injectable.ts index 946b7fe022..402a3d7cd1 100644 --- a/src/main/routes/helm/charts/list-charts-route.injectable.ts +++ b/src/main/routes/helm/charts/list-route.injectable.ts @@ -7,8 +7,8 @@ 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", +const listHelmChartsRouteInjectable = getRouteInjectable({ + id: "list-helm-charts-route", instantiate: (di) => { const listHelmCharts = di.inject(listHelmChartsInjectable); @@ -22,4 +22,4 @@ const listChartsRouteInjectable = getRouteInjectable({ }, }); -export default listChartsRouteInjectable; +export default listHelmChartsRouteInjectable; diff --git a/src/renderer/components/+helm-charts/details/readme-of-selected-helm-chart.injectable.ts b/src/renderer/components/+helm-charts/details/readme-of-selected-helm-chart.injectable.ts index 21e8bcf7a9..f551c15966 100644 --- a/src/renderer/components/+helm-charts/details/readme-of-selected-helm-chart.injectable.ts +++ b/src/renderer/components/+helm-charts/details/readme-of-selected-helm-chart.injectable.ts @@ -4,16 +4,16 @@ */ import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import { asyncComputed } from "@ogre-tools/injectable-react"; -import callForHelmChartReadmeInjectable from "./readme/call-for-helm-chart-readme.injectable"; import helmChartDetailsVersionSelectionInjectable from "./versions/helm-chart-details-version-selection.injectable"; import type { HelmChart } from "../../../../common/k8s-api/endpoints/helm-charts.api"; +import requestHelmChartReadmeInjectable from "../../../../common/k8s-api/endpoints/helm-charts.api/get-readme.injectable"; const readmeOfSelectedHelmChartInjectable = getInjectable({ id: "readme-of-selected-helm-chart", instantiate: (di, chart: HelmChart) => { const selection = di.inject(helmChartDetailsVersionSelectionInjectable, chart); - const callForHelmChartReadme = di.inject(callForHelmChartReadmeInjectable); + const requestHelmChartReadme = di.inject(requestHelmChartReadmeInjectable); return asyncComputed(async () => { const chartVersion = selection.value.get(); @@ -22,7 +22,7 @@ const readmeOfSelectedHelmChartInjectable = getInjectable({ return ""; } - return await callForHelmChartReadme( + return await requestHelmChartReadme( chartVersion.getRepository(), chartVersion.getName(), chartVersion.getVersion(), diff --git a/src/renderer/components/+helm-charts/details/readme/call-for-helm-chart-readme.injectable.ts b/src/renderer/components/+helm-charts/details/readme/call-for-helm-chart-readme.injectable.ts deleted file mode 100644 index ae9c99edeb..0000000000 --- a/src/renderer/components/+helm-charts/details/readme/call-for-helm-chart-readme.injectable.ts +++ /dev/null @@ -1,29 +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 { getChartDetails } from "../../../../../common/k8s-api/endpoints/helm-charts.api"; - -export type CallForHelmChartReadme = ( - repo: string, - name: string, - version: string, -) => Promise; - -const callForHelmChartReadmeInjectable = getInjectable({ - id: "call-for-helm-chart-readme", - - instantiate: - (): CallForHelmChartReadme => - async (repository: string, name: string, version: string) => { - // TODO: Dismantle wrong abstraction - const details = await getChartDetails(repository, name, { version }); - - return details.readme; - }, - - causesSideEffects: true, -}); - -export default callForHelmChartReadmeInjectable; diff --git a/src/renderer/components/+helm-charts/details/versions-of-selected-helm-chart.injectable.ts b/src/renderer/components/+helm-charts/details/versions-of-selected-helm-chart.injectable.ts index 14ea00fce2..2058d6bde5 100644 --- a/src/renderer/components/+helm-charts/details/versions-of-selected-helm-chart.injectable.ts +++ b/src/renderer/components/+helm-charts/details/versions-of-selected-helm-chart.injectable.ts @@ -4,18 +4,18 @@ */ import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import { asyncComputed } from "@ogre-tools/injectable-react"; -import callForHelmChartVersionsInjectable from "./versions/call-for-helm-chart-versions.injectable"; import type { HelmChart } from "../../../../common/k8s-api/endpoints/helm-charts.api"; +import requestHelmChartVersionsInjectable from "../../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; const versionsOfSelectedHelmChartInjectable = getInjectable({ id: "versions-of-selected-helm-chart", instantiate: (di, chart: HelmChart) => { - const callForHelmChartVersions = di.inject(callForHelmChartVersionsInjectable); + const requestHelmChartVersions = di.inject(requestHelmChartVersionsInjectable); return asyncComputed( async () => - await callForHelmChartVersions(chart.getRepository(), chart.getName()), + await requestHelmChartVersions(chart.getRepository(), chart.getName()), [], ); }, diff --git a/src/renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable.ts b/src/renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable.ts deleted file mode 100644 index a20f5b60e9..0000000000 --- a/src/renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable.ts +++ /dev/null @@ -1,28 +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 type { HelmChart } from "../../../../../common/k8s-api/endpoints/helm-charts.api"; -import { getChartDetails } from "../../../../../common/k8s-api/endpoints/helm-charts.api"; - -export type CallForHelmChartVersions = ( - repo: string, - name: string -) => Promise; - -const callForHelmChartVersionsInjectable = getInjectable({ - id: "call-for-helm-chart-versions", - - instantiate: - (): CallForHelmChartVersions => async (repository: string, name: string) => { - // TODO: Dismantle wrong abstraction - const details = await getChartDetails(repository, name); - - return details.versions; - }, - - causesSideEffects: true, -}); - -export default callForHelmChartVersionsInjectable; diff --git a/src/renderer/components/+helm-charts/get-char-details.injectable.ts b/src/renderer/components/+helm-charts/get-char-details.injectable.ts deleted file mode 100644 index e2c5ccca62..0000000000 --- a/src/renderer/components/+helm-charts/get-char-details.injectable.ts +++ /dev/null @@ -1,17 +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 type { GetChartDetailsOptions, IHelmChartDetails } from "../../../common/k8s-api/endpoints/helm-charts.api"; -import { getChartDetails } from "../../../common/k8s-api/endpoints/helm-charts.api"; - -export type GetChartDetails = (repo: string, name: string, opts?: GetChartDetailsOptions) => Promise; - -const getChartDetailsInjectable = getInjectable({ - id: "get-chart-details", - instantiate: (): GetChartDetails => getChartDetails, - causesSideEffects: true, -}); - -export default getChartDetailsInjectable; diff --git a/src/renderer/components/+helm-charts/helm-chart-store.injectable.ts b/src/renderer/components/+helm-charts/helm-chart-store.injectable.ts deleted file mode 100644 index ac05d23368..0000000000 --- a/src/renderer/components/+helm-charts/helm-chart-store.injectable.ts +++ /dev/null @@ -1,13 +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 { HelmChartStore } from "./helm-chart.store"; - -const helmChartStoreInjectable = getInjectable({ - id: "helm-chart-store", - instantiate: () => new HelmChartStore(), -}); - -export default helmChartStoreInjectable; diff --git a/src/renderer/components/+helm-charts/helm-charts.tsx b/src/renderer/components/+helm-charts/helm-charts.tsx index 5a603cf7aa..ede7b87bdc 100644 --- a/src/renderer/components/+helm-charts/helm-charts.tsx +++ b/src/renderer/components/+helm-charts/helm-charts.tsx @@ -7,7 +7,6 @@ import "./helm-charts.scss"; import React, { Component } from "react"; import { observer } from "mobx-react"; -import { helmChartStore } from "./helm-chart.store"; import type { HelmChart } from "../../../common/k8s-api/endpoints/helm-charts.api"; import { HelmChartDetails } from "./helm-chart-details"; import { ItemListLayout } from "../item-object-list/list-layout"; @@ -21,6 +20,8 @@ import navigateToHelmChartsInjectable from "../../../common/front-end-routing/ro import { HelmChartIcon } from "./icon"; import helmChartsInjectable from "./helm-charts/helm-charts.injectable"; import selectedHelmChartInjectable from "./helm-charts/selected-helm-chart.injectable"; +import type { HelmChartStore } from "./store"; +import helmChartStoreInjectable from "./store.injectable"; enum columnId { name = "name", @@ -35,11 +36,10 @@ interface Dependencies { chartName: IComputedValue; repo: IComputedValue; }; - navigateToHelmCharts: NavigateToHelmCharts; - charts: IAsyncComputed; selectedChart: IComputedValue; + helmChartStore: HelmChartStore; } @observer @@ -79,7 +79,7 @@ class NonInjectedHelmCharts extends Component { isConfigurable tableId="helm_charts" className="HelmCharts" - store={helmChartStore} + store={this.props.helmChartStore} getItems={() => this.props.charts.value.get()} isSelectable={false} sortingCallbacks={{ @@ -132,16 +132,14 @@ class NonInjectedHelmCharts extends Component { } } -export const HelmCharts = withInjectables( - NonInjectedHelmCharts, - - { - getProps: (di) => ({ - routeParameters: di.inject(helmChartsRouteParametersInjectable), - navigateToHelmCharts: di.inject(navigateToHelmChartsInjectable), - charts: di.inject(helmChartsInjectable), - selectedChart: di.inject(selectedHelmChartInjectable), - }), - }, +export const HelmCharts = withInjectables(NonInjectedHelmCharts, { + getProps: (di) => ({ + routeParameters: di.inject(helmChartsRouteParametersInjectable), + navigateToHelmCharts: di.inject(navigateToHelmChartsInjectable), + charts: di.inject(helmChartsInjectable), + selectedChart: di.inject(selectedHelmChartInjectable), + helmChartStore: di.inject(helmChartStoreInjectable), + }), +}, ); diff --git a/src/renderer/components/+helm-charts/helm-charts/call-for-helm-charts.injectable.ts b/src/renderer/components/+helm-charts/helm-charts/call-for-helm-charts.injectable.ts deleted file mode 100644 index 5edc0d7bea..0000000000 --- a/src/renderer/components/+helm-charts/helm-charts/call-for-helm-charts.injectable.ts +++ /dev/null @@ -1,17 +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 type { HelmChart } from "../../../../common/k8s-api/endpoints/helm-charts.api"; -import { listCharts } from "../../../../common/k8s-api/endpoints/helm-charts.api"; - -export type CallForHelmCharts = () => Promise; - -const callForHelmChartsInjectable = getInjectable({ - id: "call-for-helm-charts", - instantiate: (): CallForHelmCharts => async () => await listCharts(), - causesSideEffects: true, -}); - -export default callForHelmChartsInjectable; diff --git a/src/renderer/components/+helm-charts/helm-charts/helm-charts.injectable.ts b/src/renderer/components/+helm-charts/helm-charts/helm-charts.injectable.ts index 1324e382a9..389762f306 100644 --- a/src/renderer/components/+helm-charts/helm-charts/helm-charts.injectable.ts +++ b/src/renderer/components/+helm-charts/helm-charts/helm-charts.injectable.ts @@ -4,15 +4,15 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { asyncComputed } from "@ogre-tools/injectable-react"; -import callForHelmChartsInjectable from "./call-for-helm-charts.injectable"; +import requestHelmChartsInjectable from "../../../../common/k8s-api/endpoints/helm-charts.api/list.injectable"; const helmChartsInjectable = getInjectable({ id: "helm-charts", instantiate: (di) => { - const callForHelmCharts = di.inject(callForHelmChartsInjectable); + const requestHelmCharts = di.inject(requestHelmChartsInjectable); - return asyncComputed(async () => await callForHelmCharts(), []); + return asyncComputed(async () => await requestHelmCharts(), []); }, }); diff --git a/src/renderer/components/+helm-charts/store.injectable.ts b/src/renderer/components/+helm-charts/store.injectable.ts new file mode 100644 index 0000000000..99764c38c8 --- /dev/null +++ b/src/renderer/components/+helm-charts/store.injectable.ts @@ -0,0 +1,18 @@ +/** + * 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 requestHelmChartVersionsInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; +import requestHelmChartsInjectable from "../../../common/k8s-api/endpoints/helm-charts.api/list.injectable"; +import { HelmChartStore } from "./store"; + +const helmChartStoreInjectable = getInjectable({ + id: "helm-chart-store", + instantiate: (di) => new HelmChartStore({ + requestHelmCharts: di.inject(requestHelmChartsInjectable), + requestHelmChartVersions: di.inject(requestHelmChartVersionsInjectable), + }), +}); + +export default helmChartStoreInjectable; diff --git a/src/renderer/components/+helm-charts/helm-chart.store.ts b/src/renderer/components/+helm-charts/store.ts similarity index 81% rename from src/renderer/components/+helm-charts/helm-chart.store.ts rename to src/renderer/components/+helm-charts/store.ts index 415fe3e333..fee2a381de 100644 --- a/src/renderer/components/+helm-charts/helm-chart.store.ts +++ b/src/renderer/components/+helm-charts/store.ts @@ -7,19 +7,25 @@ import semver from "semver"; import { observable, makeObservable } from "mobx"; import { autoBind, sortCompareChartVersions } from "../../utils"; import type { HelmChart } from "../../../common/k8s-api/endpoints/helm-charts.api"; -import { getChartDetails, listCharts } from "../../../common/k8s-api/endpoints/helm-charts.api"; import { ItemStore } from "../../../common/item.store"; import flatten from "lodash/flatten"; +import type { RequestHelmCharts } from "../../../common/k8s-api/endpoints/helm-charts.api/list.injectable"; +import type { RequestHelmChartVersions } from "../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; export interface ChartVersion { repo: string; version: string; } +interface Dependencies { + requestHelmCharts: RequestHelmCharts; + requestHelmChartVersions: RequestHelmChartVersions; +} + export class HelmChartStore extends ItemStore { @observable versions = observable.map(); - constructor() { + constructor(protected readonly dependencies: Dependencies) { super(); makeObservable(this); @@ -28,7 +34,7 @@ export class HelmChartStore extends ItemStore { async loadAll() { try { - const res = await this.loadItems(() => listCharts()); + const res = await this.loadItems(() => this.dependencies.requestHelmCharts()); this.failedLoading = false; @@ -68,7 +74,7 @@ export class HelmChartStore extends ItemStore { } const loadVersions = async (repo: string) => { - const { versions } = await getChartDetails(repo, chartName); + const versions = await this.dependencies.requestHelmChartVersions(repo, chartName); return versions.map(chart => ({ repo, @@ -104,5 +110,3 @@ export class HelmChartStore extends ItemStore { throw new Error("removeItems is not supported"); } } - -export const helmChartStore = new HelmChartStore(); diff --git a/src/renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.global-override-for-injectable.ts b/src/renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.global-override-for-injectable.ts deleted file mode 100644 index 282ef22fe3..0000000000 --- a/src/renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.global-override-for-injectable.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import callForHelmReleasesInjectable from "./call-for-helm-releases.injectable"; -import { getGlobalOverride } from "../../../../common/test-utils/get-global-override"; - -export default getGlobalOverride( - callForHelmReleasesInjectable, - () => () => { - throw new Error( - "Tried to call for helm releases without explicit override.", - ); - }, -); diff --git a/src/renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.injectable.ts b/src/renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.injectable.ts deleted file mode 100644 index d166091352..0000000000 --- a/src/renderer/components/+helm-releases/call-for-helm-releases/call-for-helm-releases.injectable.ts +++ /dev/null @@ -1,24 +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 type { HelmReleaseDto } from "../../../../common/k8s-api/endpoints/helm-releases.api"; - -import { apiBase } from "../../../../common/k8s-api"; -import { endpoint } from "../../../../common/k8s-api/endpoints/helm-releases.api"; - -export type CallForHelmReleases = ( - namespace?: string -) => Promise; - -const callForHelmReleasesInjectable = getInjectable({ - id: "call-for-helm-releases", - - instantiate: (): CallForHelmReleases => async (namespace) => - await apiBase.get(endpoint({ namespace })), - - causesSideEffects: true, -}); - -export default callForHelmReleasesInjectable; diff --git a/src/renderer/components/+helm-releases/create-release/call-for-create-helm-release.injectable.ts b/src/renderer/components/+helm-releases/create-release/call-for-create-helm-release.injectable.ts deleted file mode 100644 index 9e3e3800a3..0000000000 --- a/src/renderer/components/+helm-releases/create-release/call-for-create-helm-release.injectable.ts +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import yaml from "js-yaml"; -import { getInjectable } from "@ogre-tools/injectable"; -import type { HelmReleaseUpdateDetails } from "../../../../common/k8s-api/endpoints/helm-releases.api"; -import { endpoint } from "../../../../common/k8s-api/endpoints/helm-releases.api"; -import { apiBase } from "../../../../common/k8s-api"; - -interface HelmReleaseCreatePayload { - name?: string; - repo: string; - chart: string; - namespace: string; - version: string; - values: string; -} - -export type CallForCreateHelmRelease = ( - payload: HelmReleaseCreatePayload -) => Promise; - -const callForCreateHelmReleaseInjectable = getInjectable({ - id: "call-for-create-helm-release", - - instantiate: (): CallForCreateHelmRelease => (payload) => { - const { repo, chart: rawChart, values: rawValues, ...data } = payload; - const chart = `${repo}/${rawChart}`; - const values = yaml.load(rawValues); - - return apiBase.post(endpoint(), { - data: { - chart, - values, - ...data, - }, - }); - }, - - causesSideEffects: true, -}); - -export default callForCreateHelmReleaseInjectable; diff --git a/src/renderer/components/+helm-releases/create-release/create-release.injectable.ts b/src/renderer/components/+helm-releases/create-release/create-release.injectable.ts index 51006266c8..793e564188 100644 --- a/src/renderer/components/+helm-releases/create-release/create-release.injectable.ts +++ b/src/renderer/components/+helm-releases/create-release/create-release.injectable.ts @@ -5,15 +5,15 @@ import { getInjectable } from "@ogre-tools/injectable"; import releasesInjectable from "../releases.injectable"; -import type { CallForCreateHelmRelease } from "./call-for-create-helm-release.injectable"; -import callForCreateHelmReleaseInjectable from "./call-for-create-helm-release.injectable"; +import type { RequestCreateHelmRelease } from "../../../../common/k8s-api/endpoints/helm-releases.api/create.injectable"; +import requestCreateHelmReleaseInjectable from "../../../../common/k8s-api/endpoints/helm-releases.api/create.injectable"; const createReleaseInjectable = getInjectable({ id: "create-release", - instantiate: (di): CallForCreateHelmRelease => { + instantiate: (di): RequestCreateHelmRelease => { const releases = di.inject(releasesInjectable); - const callForCreateRelease = di.inject(callForCreateHelmReleaseInjectable); + const callForCreateRelease = di.inject(requestCreateHelmReleaseInjectable); return async (payload) => { const release = await callForCreateRelease(payload); diff --git a/src/renderer/components/+helm-releases/delete-release/delete-release.injectable.ts b/src/renderer/components/+helm-releases/delete-release/delete-release.injectable.ts index 4619ddaf1f..9b2328fb98 100644 --- a/src/renderer/components/+helm-releases/delete-release/delete-release.injectable.ts +++ b/src/renderer/components/+helm-releases/delete-release/delete-release.injectable.ts @@ -3,11 +3,8 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { - HelmRelease } from "../../../../common/k8s-api/endpoints/helm-releases.api"; -import { - deleteRelease, -} from "../../../../common/k8s-api/endpoints/helm-releases.api"; +import type { HelmRelease } from "../../../../common/k8s-api/endpoints/helm-releases.api"; +import requestDeleteHelmReleaseInjectable from "../../../../common/k8s-api/endpoints/helm-releases.api/delete.injectable"; import releasesInjectable from "../releases.injectable"; const deleteReleaseInjectable = getInjectable({ @@ -15,9 +12,10 @@ const deleteReleaseInjectable = getInjectable({ instantiate: (di) => { const releases = di.inject(releasesInjectable); + const requestDeleteHelmRelease = di.inject(requestDeleteHelmReleaseInjectable); return async (release: HelmRelease) => { - await deleteRelease(release.getName(), release.getNs()); + await requestDeleteHelmRelease(release.getName(), release.getNs()); releases.invalidate(); }; diff --git a/src/renderer/components/+helm-releases/dialog/dialog.tsx b/src/renderer/components/+helm-releases/dialog/dialog.tsx index 5655720e10..2c9d87c1fc 100644 --- a/src/renderer/components/+helm-releases/dialog/dialog.tsx +++ b/src/renderer/components/+helm-releases/dialog/dialog.tsx @@ -13,20 +13,23 @@ import type { DialogProps } from "../../dialog"; import { Dialog } from "../../dialog"; import { Wizard, WizardStep } from "../../wizard"; import type { HelmRelease } from "../../../../common/k8s-api/endpoints/helm-releases.api"; -import { getReleaseHistory, type HelmReleaseRevision } from "../../../../common/k8s-api/endpoints/helm-releases.api"; import { Select } from "../../select"; import { Notifications } from "../../notifications"; import orderBy from "lodash/orderBy"; import { withInjectables } from "@ogre-tools/injectable-react"; import releaseRollbackDialogStateInjectable from "./state.injectable"; +import type { RollbackRelease } from "../rollback-release/rollback-release.injectable"; import rollbackReleaseInjectable from "../rollback-release/rollback-release.injectable"; +import type { HelmReleaseRevision, RequestHelmReleaseHistory } from "../../../../common/k8s-api/endpoints/helm-releases.api/get-history.injectable"; +import requestHelmReleaseHistoryInjectable from "../../../../common/k8s-api/endpoints/helm-releases.api/get-history.injectable"; export interface ReleaseRollbackDialogProps extends DialogProps { } interface Dependencies { - rollbackRelease: (releaseName: string, namespace: string, revisionNumber: number) => Promise; + rollbackRelease: RollbackRelease; state: IObservableValue; + requestHelmReleaseHistory: RequestHelmReleaseHistory; } @observer @@ -48,7 +51,7 @@ class NonInjectedReleaseRollbackDialog extends React.Component { this.isLoading.set(true); - const releases = await getReleaseHistory(release.getName(), release.getNs()); + const releases = await this.props.requestHelmReleaseHistory(release.getName(), release.getNs()); runInAction(() => { this.revisions.replace(orderBy(releases, "revision", "desc")); @@ -134,14 +137,11 @@ class NonInjectedReleaseRollbackDialog extends React.Component( - NonInjectedReleaseRollbackDialog, - - { - getProps: (di, props) => ({ - rollbackRelease: di.inject(rollbackReleaseInjectable), - state: di.inject(releaseRollbackDialogStateInjectable), - ...props, - }), - }, -); +export const ReleaseRollbackDialog = withInjectables(NonInjectedReleaseRollbackDialog, { + getProps: (di, props) => ({ + ...props, + rollbackRelease: di.inject(rollbackReleaseInjectable), + state: di.inject(releaseRollbackDialogStateInjectable), + requestHelmReleaseHistory: di.inject(requestHelmReleaseHistoryInjectable), + }), +}); diff --git a/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release-configuration/call-for-helm-release-configuration.global-override-for-injectable.ts b/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release-configuration/call-for-helm-release-configuration.global-override-for-injectable.ts deleted file mode 100644 index e54f980728..0000000000 --- a/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release-configuration/call-for-helm-release-configuration.global-override-for-injectable.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getGlobalOverride } from "../../../../../../common/test-utils/get-global-override"; -import callForHelmReleaseConfigurationInjectable from "./call-for-helm-release-configuration.injectable"; - -export default getGlobalOverride( - callForHelmReleaseConfigurationInjectable, - () => () => { - throw new Error( - "Tried to call for helm release configuration without explicit override.", - ); - }, -); diff --git a/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release-configuration/call-for-helm-release-configuration.injectable.ts b/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release-configuration/call-for-helm-release-configuration.injectable.ts deleted file mode 100644 index d0ed0fac7c..0000000000 --- a/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release-configuration/call-for-helm-release-configuration.injectable.ts +++ /dev/null @@ -1,29 +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 { apiBase } from "../../../../../../common/k8s-api"; -import { endpoint } from "../../../../../../common/k8s-api/endpoints/helm-releases.api"; - -export type CallForHelmReleaseConfiguration = ( - name: string, - namespace: string, - all: boolean -) => Promise; - -const callForHelmReleaseConfigurationInjectable = getInjectable({ - id: "call-for-helm-release-configuration", - - instantiate: - (): CallForHelmReleaseConfiguration => async (name, namespace, all: boolean) => { - const route = "values"; - const path = endpoint({ name, namespace, route }, { all }); - - return apiBase.get(path); - }, - - causesSideEffects: true, -}); - -export default callForHelmReleaseConfigurationInjectable; diff --git a/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release-details/call-for-helm-release-details.global-override-for-injectable.ts b/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release-details/call-for-helm-release-details.global-override-for-injectable.ts deleted file mode 100644 index 373b7cae4f..0000000000 --- a/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release-details/call-for-helm-release-details.global-override-for-injectable.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getGlobalOverride } from "../../../../../../../common/test-utils/get-global-override"; -import callForHelmReleaseDetailsInjectable from "./call-for-helm-release-details.injectable"; - -export default getGlobalOverride( - callForHelmReleaseDetailsInjectable, - () => () => { - throw new Error( - "Tried to call for helm release details without explicit override.", - ); - }, -); diff --git a/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release-details/call-for-helm-release-details.injectable.ts b/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release-details/call-for-helm-release-details.injectable.ts deleted file mode 100644 index e5dccb1340..0000000000 --- a/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release-details/call-for-helm-release-details.injectable.ts +++ /dev/null @@ -1,45 +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 { apiBase } from "../../../../../../../common/k8s-api"; -import { endpoint } from "../../../../../../../common/k8s-api/endpoints/helm-releases.api"; -import type { KubeJsonApiData } from "../../../../../../../common/k8s-api/kube-json-api"; - -export interface HelmReleaseDetails { - resources: KubeJsonApiData[]; - name: string; - namespace: string; - version: string; - config: string; // release values - manifest: string; - - info: { - deleted: string; - description: string; - first_deployed: string; - last_deployed: string; - notes: string; - status: string; - }; -} - -export type CallForHelmReleaseDetails = ( - name: string, - namespace: string -) => Promise; - -const callForHelmReleaseDetailsInjectable = getInjectable({ - id: "call-for-helm-release-details", - - instantiate: (): CallForHelmReleaseDetails => async (name, namespace) => { - const path = endpoint({ name, namespace }); - - return apiBase.get(path); - }, - - causesSideEffects: true, -}); - -export default callForHelmReleaseDetailsInjectable; diff --git a/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release.injectable.ts b/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release.injectable.ts deleted file mode 100644 index bfcc947d08..0000000000 --- a/src/renderer/components/+helm-releases/release-details/release-details-model/call-for-helm-release/call-for-helm-release.injectable.ts +++ /dev/null @@ -1,51 +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 type { HelmReleaseDto } from "../../../../../../common/k8s-api/endpoints/helm-releases.api"; -import callForHelmReleasesInjectable from "../../../call-for-helm-releases/call-for-helm-releases.injectable"; -import type { HelmReleaseDetails } from "./call-for-helm-release-details/call-for-helm-release-details.injectable"; -import callForHelmReleaseDetailsInjectable from "./call-for-helm-release-details/call-for-helm-release-details.injectable"; -import type { AsyncResult } from "../../../../../../common/utils/async-result"; - -export interface DetailedHelmRelease { - release: HelmReleaseDto; - details: HelmReleaseDetails; -} - -export type CallForHelmRelease = ( - name: string, - namespace: string -) => Promise>; - -const callForHelmReleaseInjectable = getInjectable({ - id: "call-for-helm-release", - - instantiate: (di): CallForHelmRelease => { - const callForHelmReleases = di.inject(callForHelmReleasesInjectable); - const callForHelmReleaseDetails = di.inject(callForHelmReleaseDetailsInjectable); - - return async (name, namespace) => { - const [releases, details] = await Promise.all([ - callForHelmReleases(namespace), - callForHelmReleaseDetails(name, namespace), - ]); - - const release = releases.find( - (rel) => rel.name === name && rel.namespace === namespace, - ); - - if (!release) { - return { - callWasSuccessful: false, - error: `Release ${name} didn't exist in ${namespace} namespace.`, - }; - } - - return { callWasSuccessful: true, response: { release, details }}; - }; - }, -}); - -export default callForHelmReleaseInjectable; diff --git a/src/renderer/components/+helm-releases/release-details/release-details-model/release-details-model.injectable.tsx b/src/renderer/components/+helm-releases/release-details/release-details-model/release-details-model.injectable.tsx index ebedbcdcdf..9056e31a1d 100644 --- a/src/renderer/components/+helm-releases/release-details/release-details-model/release-details-model.injectable.tsx +++ b/src/renderer/components/+helm-releases/release-details/release-details-model/release-details-model.injectable.tsx @@ -6,18 +6,17 @@ import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import type { IComputedValue, IObservableValue } from "mobx"; import { runInAction, action, observable, computed } from "mobx"; import type { TargetHelmRelease } from "../target-helm-release.injectable"; -import type { CallForHelmRelease, DetailedHelmRelease } from "./call-for-helm-release/call-for-helm-release.injectable"; -import callForHelmReleaseInjectable from "./call-for-helm-release/call-for-helm-release.injectable"; +import type { RequestHelmRelease, DetailedHelmRelease } from "./request-helm-release.injectable"; +import requestHelmReleaseInjectable from "./request-helm-release.injectable"; import type { LensTheme } from "../../../../themes/store"; -import type { CallForHelmReleaseConfiguration } from "./call-for-helm-release-configuration/call-for-helm-release-configuration.injectable"; -import callForHelmReleaseConfigurationInjectable from "./call-for-helm-release-configuration/call-for-helm-release-configuration.injectable"; -import { toHelmRelease } from "../../releases.injectable"; +import type { RequestHelmReleaseConfiguration } from "../../../../../common/k8s-api/endpoints/helm-releases.api/get-configuration.injectable"; +import requestHelmReleaseConfigurationInjectable from "../../../../../common/k8s-api/endpoints/helm-releases.api/get-configuration.injectable"; import { pipeline } from "@ogre-tools/fp"; import { groupBy, map } from "lodash/fp"; import type { KubeJsonApiData } from "../../../../../common/k8s-api/kube-json-api"; import type { GetResourceDetailsUrl } from "./get-resource-details-url.injectable"; import getResourceDetailsUrlInjectable from "./get-resource-details-url.injectable"; -import type { CallForHelmReleaseUpdate } from "../../update-release/call-for-helm-release-update/call-for-helm-release-update.injectable"; +import type { RequestHelmReleaseUpdate } from "../../../../../common/k8s-api/endpoints/helm-releases.api/update.injectable"; import updateReleaseInjectable from "../../update-release/update-release.injectable"; import type { ShowCheckedErrorNotification } from "../../../notifications/show-checked-error.injectable"; import showCheckedErrorNotificationInjectable from "../../../notifications/show-checked-error.injectable"; @@ -26,35 +25,29 @@ import showSuccessNotificationInjectable from "../../../notifications/show-succe import React from "react"; import createUpgradeChartTabInjectable from "../../../dock/upgrade-chart/create-upgrade-chart-tab.injectable"; import type { HelmRelease } from "../../../../../common/k8s-api/endpoints/helm-releases.api"; +import type { NavigateToHelmReleases } from "../../../../../common/front-end-routing/routes/cluster/helm/releases/navigate-to-helm-releases.injectable"; import navigateToHelmReleasesInjectable from "../../../../../common/front-end-routing/routes/cluster/helm/releases/navigate-to-helm-releases.injectable"; import assert from "assert"; import activeThemeInjectable from "../../../../themes/active.injectable"; +import type { ToHelmRelease } from "../../to-helm-release.injectable"; +import toHelmReleaseInjectable from "../../to-helm-release.injectable"; const releaseDetailsModelInjectable = getInjectable({ id: "release-details-model", instantiate: async (di, targetRelease: TargetHelmRelease) => { - const callForHelmRelease = di.inject(callForHelmReleaseInjectable); - const callForHelmReleaseConfiguration = di.inject(callForHelmReleaseConfigurationInjectable); - const activeTheme = di.inject(activeThemeInjectable); - const getResourceDetailsUrl = di.inject(getResourceDetailsUrlInjectable); - const updateRelease = di.inject(updateReleaseInjectable); - const showCheckedErrorNotification = di.inject(showCheckedErrorNotificationInjectable); - const showSuccessNotification = di.inject(showSuccessNotificationInjectable); - const createUpgradeChartTab = di.inject(createUpgradeChartTabInjectable); - const navigateToHelmReleases = di.inject(navigateToHelmReleasesInjectable); - const model = new ReleaseDetailsModel({ - callForHelmRelease, + requestHelmRelease: di.inject(requestHelmReleaseInjectable), targetRelease, - activeTheme, - callForHelmReleaseConfiguration, - getResourceDetailsUrl, - updateRelease, - showCheckedErrorNotification, - showSuccessNotification, - createUpgradeChartTab, - navigateToHelmReleases, + activeTheme: di.inject(activeThemeInjectable), + requestHelmReleaseConfiguration: di.inject(requestHelmReleaseConfigurationInjectable), + getResourceDetailsUrl: di.inject(getResourceDetailsUrlInjectable), + updateRelease: di.inject(updateReleaseInjectable), + showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable), + showSuccessNotification: di.inject(showSuccessNotificationInjectable), + createUpgradeChartTab: di.inject(createUpgradeChartTabInjectable), + navigateToHelmReleases: di.inject(navigateToHelmReleasesInjectable), + toHelmRelease: di.inject(toHelmReleaseInjectable), }); await model.load(); @@ -85,20 +78,21 @@ export interface ConfigurationInput { interface Dependencies { readonly targetRelease: TargetHelmRelease; readonly activeTheme: IComputedValue; - callForHelmRelease: CallForHelmRelease; - callForHelmReleaseConfiguration: CallForHelmReleaseConfiguration; + requestHelmRelease: RequestHelmRelease; + requestHelmReleaseConfiguration: RequestHelmReleaseConfiguration; getResourceDetailsUrl: GetResourceDetailsUrl; - updateRelease: CallForHelmReleaseUpdate; + updateRelease: RequestHelmReleaseUpdate; showCheckedErrorNotification: ShowCheckedErrorNotification; showSuccessNotification: ShowNotification; createUpgradeChartTab: (release: HelmRelease) => string; - navigateToHelmReleases: () => void; + navigateToHelmReleases: NavigateToHelmReleases; + toHelmRelease: ToHelmRelease; } export class ReleaseDetailsModel { readonly id = `${this.dependencies.targetRelease.namespace}/${this.dependencies.targetRelease.name}`; - constructor(private readonly dependencies: Dependencies) {} + constructor(protected readonly dependencies: Dependencies) {} private readonly detailedRelease = observable.box(); @@ -171,7 +165,7 @@ export class ReleaseDetailsModel { load = async () => { const { name, namespace } = this.dependencies.targetRelease; - const result = await this.dependencies.callForHelmRelease( + const result = await this.dependencies.requestHelmRelease( name, namespace, ); @@ -199,7 +193,7 @@ export class ReleaseDetailsModel { const { name, namespace } = this.release; const configuration = - await this.dependencies.callForHelmReleaseConfiguration( + await this.dependencies.requestHelmReleaseConfiguration( name, namespace, !this.onlyUserSuppliedValuesAreShown.value.get(), @@ -216,7 +210,7 @@ export class ReleaseDetailsModel { assert(detailedRelease, "Tried to access release before load"); - return toHelmRelease(detailedRelease.release); + return this.dependencies.toHelmRelease(detailedRelease.release); } @computed private get details() { diff --git a/src/renderer/components/+helm-releases/release-details/release-details-model/request-helm-release.injectable.ts b/src/renderer/components/+helm-releases/release-details/release-details-model/request-helm-release.injectable.ts new file mode 100644 index 0000000000..a87768f1d8 --- /dev/null +++ b/src/renderer/components/+helm-releases/release-details/release-details-model/request-helm-release.injectable.ts @@ -0,0 +1,51 @@ +/** + * 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 { HelmReleaseDto } from "../../../../../common/k8s-api/endpoints/helm-releases.api"; +import requestHelmReleasesInjectable from "../../../../../common/k8s-api/endpoints/helm-releases.api/list.injectable"; +import type { HelmReleaseDetails } from "../../../../../common/k8s-api/endpoints/helm-releases.api/get-details.injectable"; +import requestHelmReleaseDetailsInjectable from "../../../../../common/k8s-api/endpoints/helm-releases.api/get-details.injectable"; +import type { AsyncResult } from "../../../../../common/utils/async-result"; + +export interface DetailedHelmRelease { + release: HelmReleaseDto; + details: HelmReleaseDetails; +} + +export type RequestHelmRelease = ( + name: string, + namespace: string +) => Promise>; + +const requestHelmReleaseInjectable = getInjectable({ + id: "call-for-helm-release", + + instantiate: (di): RequestHelmRelease => { + const requestHelmReleases = di.inject(requestHelmReleasesInjectable); + const requestHelmReleaseDetails = di.inject(requestHelmReleaseDetailsInjectable); + + return async (name, namespace) => { + const [releases, details] = await Promise.all([ + requestHelmReleases(namespace), + requestHelmReleaseDetails(name, namespace), + ]); + + const release = releases.find( + (rel) => rel.name === name && rel.namespace === namespace, + ); + + if (!release) { + return { + callWasSuccessful: false, + error: `Release ${name} didn't exist in ${namespace} namespace.`, + }; + } + + return { callWasSuccessful: true, response: { release, details }}; + }; + }, +}); + +export default requestHelmReleaseInjectable; diff --git a/src/renderer/components/+helm-releases/releases.injectable.ts b/src/renderer/components/+helm-releases/releases.injectable.ts index 694f0d379e..dcbb0296f6 100644 --- a/src/renderer/components/+helm-releases/releases.injectable.ts +++ b/src/renderer/components/+helm-releases/releases.injectable.ts @@ -7,11 +7,8 @@ import { asyncComputed } from "@ogre-tools/injectable-react"; import namespaceStoreInjectable from "../+namespaces/store.injectable"; import clusterFrameContextInjectable from "../../cluster-frame-context/cluster-frame-context.injectable"; import releaseSecretsInjectable from "./release-secrets.injectable"; -import callForHelmReleasesInjectable from "./call-for-helm-releases/call-for-helm-releases.injectable"; -import type { HelmRelease, HelmReleaseDto } from "../../../common/k8s-api/endpoints/helm-releases.api"; -import { formatDuration } from "../../../common/utils"; -import { helmChartStore } from "../+helm-charts/helm-chart.store"; -import { capitalize } from "lodash/fp"; +import requestHelmReleasesInjectable from "../../../common/k8s-api/endpoints/helm-releases.api/list.injectable"; +import toHelmReleaseInjectable from "./to-helm-release.injectable"; const releasesInjectable = getInjectable({ id: "releases", @@ -20,7 +17,8 @@ const releasesInjectable = getInjectable({ const clusterContext = di.inject(clusterFrameContextInjectable); const namespaceStore = di.inject(namespaceStoreInjectable); const releaseSecrets = di.inject(releaseSecretsInjectable); - const callForHelmReleases = di.inject(callForHelmReleasesInjectable); + const requestHelmReleases = di.inject(requestHelmReleasesInjectable); + const toHelmRelease = di.inject(toHelmReleaseInjectable); return asyncComputed(async () => { const contextNamespaces = namespaceStore.contextNamespaces || []; @@ -34,9 +32,9 @@ const releasesInjectable = getInjectable({ contextNamespaces.includes(namespace), ); - const releaseArrays = await (isLoadingAll ? callForHelmReleases() : Promise.all( + const releaseArrays = await (isLoadingAll ? requestHelmReleases() : Promise.all( contextNamespaces.map((namespace) => - callForHelmReleases(namespace), + requestHelmReleases(namespace), ), )); @@ -45,72 +43,5 @@ const releasesInjectable = getInjectable({ }, }); -export const toHelmRelease = (release: HelmReleaseDto) : HelmRelease => ({ - ...release, - - getId() { - return `${this.namespace}/${this.name}`; - }, - - getName() { - return this.name; - }, - - getNs() { - return this.namespace; - }, - - getChart(withVersion = false) { - let chart = this.chart; - - if (!withVersion && this.getVersion() != "") { - const search = new RegExp(`-${this.getVersion()}`); - - chart = chart.replace(search, ""); - } - - return chart; - }, - - getRevision() { - return parseInt(this.revision, 10); - }, - - getStatus() { - return capitalize(this.status); - }, - - getVersion() { - const versions = this.chart.match(/(?<=-)(v?\d+)[^-].*$/); - - return versions?.[0] ?? ""; - }, - - getUpdated(humanize = true, compact = true) { - const updated = this.updated.replace(/\s\w*$/, ""); // 2019-11-26 10:58:09 +0300 MSK -> 2019-11-26 10:58:09 +0300 to pass into Date() - const updatedDate = new Date(updated).getTime(); - const diff = Date.now() - updatedDate; - - if (humanize) { - return formatDuration(diff, compact); - } - - return diff; - }, - - // Helm does not store from what repository the release is installed, - // so we have to try to guess it by searching charts - async getRepo() { - const chartName = this.getChart(); - const version = this.getVersion(); - const versions = await helmChartStore.getVersions(chartName); - const chartVersion = versions.find( - (chartVersion) => chartVersion.version === version, - ); - - return chartVersion ? chartVersion.repo : ""; - }, -}); - export default releasesInjectable; diff --git a/src/renderer/components/+helm-releases/rollback-release/rollback-release.injectable.ts b/src/renderer/components/+helm-releases/rollback-release/rollback-release.injectable.ts index c7ace21e06..8bc47de8da 100644 --- a/src/renderer/components/+helm-releases/rollback-release/rollback-release.injectable.ts +++ b/src/renderer/components/+helm-releases/rollback-release/rollback-release.injectable.ts @@ -3,17 +3,20 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { rollbackRelease } from "../../../../common/k8s-api/endpoints/helm-releases.api"; +import requestHelmReleaseRollbackInjectable from "../../../../common/k8s-api/endpoints/helm-releases.api/rollback.injectable"; import releasesInjectable from "../releases.injectable"; +export type RollbackRelease = (name: string, namespace: string, revision: number) => Promise; + const rollbackReleaseInjectable = getInjectable({ id: "rollback-release", - instantiate: (di) => { + instantiate: (di): RollbackRelease => { const releases = di.inject(releasesInjectable); + const requestHelmReleaseRollback = di.inject(requestHelmReleaseRollbackInjectable); - return async (name: string, namespace: string, revision: number) => { - await rollbackRelease(name, namespace, revision); + return async (name, namespace, revision) => { + await requestHelmReleaseRollback(name, namespace, revision); releases.invalidate(); }; diff --git a/src/renderer/components/+helm-releases/to-helm-release.injectable.ts b/src/renderer/components/+helm-releases/to-helm-release.injectable.ts new file mode 100644 index 0000000000..a7a1aca5c8 --- /dev/null +++ b/src/renderer/components/+helm-releases/to-helm-release.injectable.ts @@ -0,0 +1,87 @@ +/** + * 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 { capitalize } from "lodash"; +import helmChartStoreInjectable from "../+helm-charts/store.injectable"; +import type { HelmRelease, HelmReleaseDto } from "../../../common/k8s-api/endpoints/helm-releases.api"; +import { formatDuration } from "../../utils"; + +export type ToHelmRelease = (release: HelmReleaseDto) => HelmRelease; + +const toHelmReleaseInjectable = getInjectable({ + id: "to-helm-release", + instantiate: (di): ToHelmRelease => { + const helmChartStore = di.inject(helmChartStoreInjectable); + + return (release) => ({ + ...release, + + getId() { + return `${this.namespace}/${this.name}`; + }, + + getName() { + return this.name; + }, + + getNs() { + return this.namespace; + }, + + getChart(withVersion = false) { + let chart = this.chart; + + if (!withVersion && this.getVersion() != "") { + const search = new RegExp(`-${this.getVersion()}`); + + chart = chart.replace(search, ""); + } + + return chart; + }, + + getRevision() { + return parseInt(this.revision, 10); + }, + + getStatus() { + return capitalize(this.status); + }, + + getVersion() { + const versions = this.chart.match(/(?<=-)(v?\d+)[^-].*$/); + + return versions?.[0] ?? ""; + }, + + getUpdated(humanize = true, compact = true) { + const updated = this.updated.replace(/\s\w*$/, ""); // 2019-11-26 10:58:09 +0300 MSK -> 2019-11-26 10:58:09 +0300 to pass into Date() + const updatedDate = new Date(updated).getTime(); + const diff = Date.now() - updatedDate; + + if (humanize) { + return formatDuration(diff, compact); + } + + return diff; + }, + + // Helm does not store from what repository the release is installed, + // so we have to try to guess it by searching charts + async getRepo() { + const chartName = this.getChart(); + const version = this.getVersion(); + const versions = await helmChartStore.getVersions(chartName); + const chartVersion = versions.find( + (chartVersion) => chartVersion.version === version, + ); + + return chartVersion ? chartVersion.repo : ""; + }, + }); + }, +}); + +export default toHelmReleaseInjectable; diff --git a/src/renderer/components/+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.global-override-for-injectable.ts b/src/renderer/components/+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.global-override-for-injectable.ts deleted file mode 100644 index 34cc147e8d..0000000000 --- a/src/renderer/components/+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.global-override-for-injectable.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getGlobalOverride } from "../../../../../common/test-utils/get-global-override"; -import callForHelmReleaseUpdateInjectable from "./call-for-helm-release-update.injectable"; - -export default getGlobalOverride( - callForHelmReleaseUpdateInjectable, - () => () => { - throw new Error( - "Tried to call for helm release update without explicit override.", - ); - }, -); diff --git a/src/renderer/components/+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.injectable.ts b/src/renderer/components/+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.injectable.ts deleted file mode 100644 index b3cc590163..0000000000 --- a/src/renderer/components/+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.injectable.ts +++ /dev/null @@ -1,50 +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 { apiBase } from "../../../../../common/k8s-api"; -import { endpoint } from "../../../../../common/k8s-api/endpoints/helm-releases.api"; -import yaml from "js-yaml"; - -interface HelmReleaseUpdatePayload { - repo: string; - chart: string; - version: string; - values: string; -} - -export type CallForHelmReleaseUpdate = ( - name: string, - namespace: string, - payload: HelmReleaseUpdatePayload -) => Promise<{ updateWasSuccessful: true } | { updateWasSuccessful: false; error: unknown }>; - -const callForHelmReleaseUpdateInjectable = getInjectable({ - id: "call-for-helm-release-update", - - instantiate: - (): CallForHelmReleaseUpdate => async (name, namespace, payload) => { - const { repo, chart: rawChart, values: rawValues, ...data } = payload; - const chart = `${repo}/${rawChart}`; - const values = yaml.load(rawValues); - - try { - await apiBase.put(endpoint({ name, namespace }), { - data: { - chart, - values, - ...data, - }, - }); - } catch (e) { - return { updateWasSuccessful: false, error: e }; - } - - return { updateWasSuccessful: true }; - }, - - causesSideEffects: true, -}); - -export default callForHelmReleaseUpdateInjectable; diff --git a/src/renderer/components/+helm-releases/update-release/update-release.injectable.ts b/src/renderer/components/+helm-releases/update-release/update-release.injectable.ts index dce16e2dd1..f12a50fbc6 100644 --- a/src/renderer/components/+helm-releases/update-release/update-release.injectable.ts +++ b/src/renderer/components/+helm-releases/update-release/update-release.injectable.ts @@ -4,15 +4,15 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import releasesInjectable from "../releases.injectable"; -import type { CallForHelmReleaseUpdate } from "./call-for-helm-release-update/call-for-helm-release-update.injectable"; -import callForHelmReleaseUpdateInjectable from "./call-for-helm-release-update/call-for-helm-release-update.injectable"; +import type { RequestHelmReleaseUpdate } from "../../../../common/k8s-api/endpoints/helm-releases.api/update.injectable"; +import requestHelmReleaseUpdateInjectable from "../../../../common/k8s-api/endpoints/helm-releases.api/update.injectable"; const updateReleaseInjectable = getInjectable({ id: "update-release", - instantiate: (di): CallForHelmReleaseUpdate => { + instantiate: (di): RequestHelmReleaseUpdate => { const releases = di.inject(releasesInjectable); - const callForHelmReleaseUpdate = di.inject(callForHelmReleaseUpdateInjectable); + const callForHelmReleaseUpdate = di.inject(requestHelmReleaseUpdateInjectable); return async ( name, diff --git a/src/renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable.ts b/src/renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable.ts deleted file mode 100644 index 1c379b56e5..0000000000 --- a/src/renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable.ts +++ /dev/null @@ -1,20 +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 { getChartValues } from "../../../../../common/k8s-api/endpoints/helm-charts.api"; - -export type CallForHelmChartValues = ( - repo: string, - name: string, - version: string -) => Promise; - -const callForHelmChartValuesInjectable = getInjectable({ - id: "call-for-helm-chart-values", - instantiate: (): CallForHelmChartValues => getChartValues, - causesSideEffects: true, -}); - -export default callForHelmChartValuesInjectable; diff --git a/src/renderer/components/dock/install-chart/install-chart-model.injectable.tsx b/src/renderer/components/dock/install-chart/install-chart-model.injectable.tsx index 64f2e27e12..fa001f1bbb 100644 --- a/src/renderer/components/dock/install-chart/install-chart-model.injectable.tsx +++ b/src/renderer/components/dock/install-chart/install-chart-model.injectable.tsx @@ -5,36 +5,31 @@ import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import installChartTabStoreInjectable from "./store.injectable"; import { waitUntilDefined } from "../../../../common/utils"; -import type { CallForHelmChartValues } from "./chart-data/call-for-helm-chart-values.injectable"; -import callForHelmChartValuesInjectable from "./chart-data/call-for-helm-chart-values.injectable"; import type { IChartInstallData, InstallChartTabStore } from "./store"; import type { HelmChart } from "../../../../common/k8s-api/endpoints/helm-charts.api"; import React from "react"; -import { - action, - computed, - observable, - runInAction, -} from "mobx"; +import { action, computed, observable, runInAction } from "mobx"; import assert from "assert"; -import type { CallForCreateHelmRelease } from "../../+helm-releases/create-release/call-for-create-helm-release.injectable"; -import callForCreateHelmReleaseInjectable from "../../+helm-releases/create-release/call-for-create-helm-release.injectable"; +import type { RequestCreateHelmRelease } from "../../../../common/k8s-api/endpoints/helm-releases.api/create.injectable"; +import requestCreateHelmReleaseInjectable from "../../../../common/k8s-api/endpoints/helm-releases.api/create.injectable"; import type { HelmReleaseUpdateDetails } from "../../../../common/k8s-api/endpoints/helm-releases.api"; import dockStoreInjectable from "../dock/store.injectable"; import type { NavigateToHelmReleases } from "../../../../common/front-end-routing/routes/cluster/helm/releases/navigate-to-helm-releases.injectable"; import navigateToHelmReleasesInjectable from "../../../../common/front-end-routing/routes/cluster/helm/releases/navigate-to-helm-releases.injectable"; import type { SingleValue } from "react-select"; -import type { CallForHelmChartVersions } from "../../+helm-charts/details/versions/call-for-helm-chart-versions.injectable"; -import callForHelmChartVersionsInjectable from "../../+helm-charts/details/versions/call-for-helm-chart-versions.injectable"; +import type { RequestHelmChartValues } from "../../../../common/k8s-api/endpoints/helm-charts.api/get-values.injectable"; +import requestHelmChartValuesInjectable from "../../../../common/k8s-api/endpoints/helm-charts.api/get-values.injectable"; +import type { RequestHelmChartVersions } from "../../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; +import requestHelmChartVersionsInjectable from "../../../../common/k8s-api/endpoints/helm-charts.api/get-versions.injectable"; const installChartModelInjectable = getInjectable({ id: "install-chart-model", instantiate: async (di, tabId: string) => { const store = di.inject(installChartTabStoreInjectable); - const callForHelmChartValues = di.inject(callForHelmChartValuesInjectable); - const callForHelmChartVersions = di.inject(callForHelmChartVersionsInjectable); - const callForCreateHelmRelease = di.inject(callForCreateHelmReleaseInjectable); + const requestHelmChartValues = di.inject(requestHelmChartValuesInjectable); + const requestHelmChartVersions = di.inject(requestHelmChartVersionsInjectable); + const callForCreateHelmRelease = di.inject(requestCreateHelmReleaseInjectable); const dockStore = di.inject(dockStoreInjectable); const navigateToHelmReleases = di.inject(navigateToHelmReleasesInjectable); const closeTab = () => dockStore.closeTab(tabId); @@ -49,8 +44,8 @@ const installChartModelInjectable = getInjectable({ callForCreateHelmRelease, closeTab, navigateToHelmReleases, - callForHelmChartValues, - callForHelmChartVersions, + requestHelmChartValues, + requestHelmChartVersions, store, }); @@ -71,9 +66,9 @@ interface Dependencies { closeTab: () => void; navigateToHelmReleases: NavigateToHelmReleases; waitForChart: () => Promise; - callForCreateHelmRelease: CallForCreateHelmRelease; - callForHelmChartValues: CallForHelmChartValues; - callForHelmChartVersions: CallForHelmChartVersions; + callForCreateHelmRelease: RequestCreateHelmRelease; + requestHelmChartValues: RequestHelmChartValues; + requestHelmChartVersions: RequestHelmChartVersions; store: InstallChartTabStore; } @@ -127,7 +122,7 @@ export class InstallChartModel { this.configuration.isLoading.set(true); }); - const configuration = await this.dependencies.callForHelmChartValues( + const configuration = await this.dependencies.requestHelmChartValues( this.chart.repo, this.chart.name, version, @@ -193,13 +188,13 @@ export class InstallChartModel { await this.dependencies.waitForChart(); const [defaultConfiguration, versions] = await Promise.all([ - this.dependencies.callForHelmChartValues( + this.dependencies.requestHelmChartValues( this.chart.repo, this.chart.name, this.chart.version, ), - this.dependencies.callForHelmChartVersions( + this.dependencies.requestHelmChartVersions( this.chart.repo, this.chart.name, ), diff --git a/src/renderer/components/dock/upgrade-chart/store.injectable.ts b/src/renderer/components/dock/upgrade-chart/store.injectable.ts index 29a53c41d3..2dd3612e56 100644 --- a/src/renderer/components/dock/upgrade-chart/store.injectable.ts +++ b/src/renderer/components/dock/upgrade-chart/store.injectable.ts @@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import { UpgradeChartTabStore } from "./store"; import createDockTabStoreInjectable from "../dock-tab-store/create-dock-tab-store.injectable"; import createStorageInjectable from "../../../utils/create-storage/create-storage.injectable"; +import requestHelmReleaseConfigurationInjectable from "../../../../common/k8s-api/endpoints/helm-releases.api/get-configuration.injectable"; const upgradeChartTabStoreInjectable = getInjectable({ id: "upgrade-chart-tab-store", @@ -16,6 +17,7 @@ const upgradeChartTabStoreInjectable = getInjectable({ return new UpgradeChartTabStore({ createStorage: di.inject(createStorageInjectable), valuesStore: createDockTabStore(), + requestHelmReleaseConfiguration: di.inject(requestHelmReleaseConfigurationInjectable), }); }, }); diff --git a/src/renderer/components/dock/upgrade-chart/store.ts b/src/renderer/components/dock/upgrade-chart/store.ts index 3e699c01b1..c5e4ea774e 100644 --- a/src/renderer/components/dock/upgrade-chart/store.ts +++ b/src/renderer/components/dock/upgrade-chart/store.ts @@ -7,8 +7,8 @@ import { action, computed, makeObservable } from "mobx"; import type { TabId } from "../dock/store"; import type { DockTabStoreDependencies } from "../dock-tab-store/dock-tab.store"; import { DockTabStore } from "../dock-tab-store/dock-tab.store"; -import { getReleaseValues } from "../../../../common/k8s-api/endpoints/helm-releases.api"; import assert from "assert"; +import type { RequestHelmReleaseConfiguration } from "../../../../common/k8s-api/endpoints/helm-releases.api/get-configuration.injectable"; export interface IChartUpgradeData { releaseName: string; @@ -17,6 +17,7 @@ export interface IChartUpgradeData { export interface UpgradeChartTabStoreDependencies extends DockTabStoreDependencies { valuesStore: DockTabStore; + requestHelmReleaseConfiguration: RequestHelmReleaseConfiguration; } export class UpgradeChartTabStore extends DockTabStore { @@ -44,7 +45,7 @@ export class UpgradeChartTabStore extends DockTabStore { assert(data, "cannot reload values if no data"); const { releaseName, releaseNamespace } = data; - const values = await getReleaseValues(releaseName, releaseNamespace, true); + const values = await this.dependencies.requestHelmReleaseConfiguration(releaseName, releaseNamespace, true); this.values.setData(tabId, values); } diff --git a/src/renderer/components/dock/upgrade-chart/view.tsx b/src/renderer/components/dock/upgrade-chart/view.tsx index 11d60b6c87..4955d55b3b 100644 --- a/src/renderer/components/dock/upgrade-chart/view.tsx +++ b/src/renderer/components/dock/upgrade-chart/view.tsx @@ -15,7 +15,7 @@ import type { UpgradeChartTabStore } from "./store"; import { Spinner } from "../../spinner"; import { Badge } from "../../badge"; import { EditorPanel } from "../editor-panel"; -import { helmChartStore, type ChartVersion } from "../../+helm-charts/helm-chart.store"; +import type { HelmChartStore, ChartVersion } from "../../+helm-charts/store"; import type { HelmRelease } from "../../../../common/k8s-api/endpoints/helm-releases.api"; import type { SelectOption } from "../../select"; import { Select } from "../../select"; @@ -24,8 +24,9 @@ import { withInjectables } from "@ogre-tools/injectable-react"; import upgradeChartTabStoreInjectable from "./store.injectable"; import updateReleaseInjectable from "../../+helm-releases/update-release/update-release.injectable"; import releasesInjectable from "../../+helm-releases/releases.injectable"; -import type { CallForHelmReleaseUpdate } from "../../+helm-releases/update-release/call-for-helm-release-update/call-for-helm-release-update.injectable"; +import type { RequestHelmReleaseUpdate } from "../../../../common/k8s-api/endpoints/helm-releases.api/update.injectable"; import { first } from "lodash/fp"; +import helmChartStoreInjectable from "../../+helm-charts/store.injectable"; export interface UpgradeChartProps { className?: string; @@ -35,7 +36,8 @@ export interface UpgradeChartProps { interface Dependencies { releases: IAsyncComputed; upgradeChartTabStore: UpgradeChartTabStore; - updateRelease: CallForHelmReleaseUpdate; + updateRelease: RequestHelmReleaseUpdate; + helmChartStore: HelmChartStore; } @observer @@ -95,7 +97,7 @@ export class NonInjectedUpgradeChart extends React.Component(NonInjectedUpgradeChart, { getProps: (di, props) => ({ + ...props, releases: di.inject(releasesInjectable), updateRelease: di.inject(updateReleaseInjectable), upgradeChartTabStore: di.inject(upgradeChartTabStoreInjectable), - ...props, + helmChartStore: di.inject(helmChartStoreInjectable), }), });