From 5f88f68859fd91ffbf17b78286a107f939c5fd37 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 16 Dec 2022 16:21:45 +0300 Subject: [PATCH 01/26] Fix loosing osx dock and tray icons on window reopen (#6770) Signed-off-by: Alex Andreev Signed-off-by: Alex Andreev --- .../setup-runnables-after-window-is-opened.injectable.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/electron-app/runnables/setup-runnables-after-window-is-opened.injectable.ts b/src/main/electron-app/runnables/setup-runnables-after-window-is-opened.injectable.ts index fe501d4750..dc80998de0 100644 --- a/src/main/electron-app/runnables/setup-runnables-after-window-is-opened.injectable.ts +++ b/src/main/electron-app/runnables/setup-runnables-after-window-is-opened.injectable.ts @@ -18,7 +18,9 @@ const setupRunnablesAfterWindowIsOpenedInjectable = getInjectable({ return { id: "setup-runnables-after-window-is-opened", run: () => { - app.on("browser-window-created", () => afterWindowIsOpened); + app.on("browser-window-created", () => { + afterWindowIsOpened(); + }); return undefined; }, From 4b31229516700948e8d3fa2e37c5a8ed974b0394 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Dec 2022 08:22:08 -0500 Subject: [PATCH 02/26] Bump moment-timezone from 0.5.39 to 0.5.40 (#6767) Bumps [moment-timezone](https://github.com/moment/moment-timezone) from 0.5.39 to 0.5.40. - [Release notes](https://github.com/moment/moment-timezone/releases) - [Changelog](https://github.com/moment/moment-timezone/blob/develop/changelog.md) - [Commits](https://github.com/moment/moment-timezone/compare/0.5.39...0.5.40) --- updated-dependencies: - dependency-name: moment-timezone dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index bf49235294..4f487ba279 100644 --- a/package.json +++ b/package.json @@ -248,7 +248,7 @@ "mobx-utils": "^6.0.4", "mock-fs": "^5.2.0", "moment": "^2.29.4", - "moment-timezone": "^0.5.39", + "moment-timezone": "^0.5.40", "monaco-editor": "^0.29.1", "monaco-editor-webpack-plugin": "^5.0.0", "node-fetch": "^3.3.0", diff --git a/yarn.lock b/yarn.lock index f546e03aca..b859f2a6bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9241,10 +9241,10 @@ mock-http@^1.1.0: dependencies: mergee "^1.0.0" -moment-timezone@^0.5.39: - version "0.5.39" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.39.tgz#342625a3b98810f04c8f4ea917e448d3525e600b" - integrity sha512-hoB6suq4ISDj7BDgctiOy6zljBsdYT0++0ZzZm9rtxIvJhIbQ3nmbgSWe7dNFGurl6/7b1OUkHlmN9JWgXVz7w== +moment-timezone@^0.5.40: + version "0.5.40" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.40.tgz#c148f5149fd91dd3e29bf481abc8830ecba16b89" + integrity sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg== dependencies: moment ">= 2.9.0" From ef613f122ff219291db0f3087ed9dd0747ea32cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Dec 2022 08:22:47 -0500 Subject: [PATCH 03/26] Bump got from 11.8.5 to 11.8.6 (#6768) Bumps [got](https://github.com/sindresorhus/got) from 11.8.5 to 11.8.6. - [Release notes](https://github.com/sindresorhus/got/releases) - [Commits](https://github.com/sindresorhus/got/compare/v11.8.5...v11.8.6) --- updated-dependencies: - dependency-name: got dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 4f487ba279..6236b72fda 100644 --- a/package.json +++ b/package.json @@ -224,7 +224,7 @@ "filehound": "^1.17.6", "fs-extra": "^9.0.1", "glob-to-regexp": "^0.4.1", - "got": "^11.8.5", + "got": "^11.8.6", "grapheme-splitter": "^1.0.4", "handlebars": "^4.7.7", "history": "^4.10.1", diff --git a/yarn.lock b/yarn.lock index b859f2a6bb..24c8d7f954 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6629,10 +6629,10 @@ globrex@^0.1.2: resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== -got@^11.8.5: - version "11.8.5" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046" - integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ== +got@^11.8.6: + version "11.8.6" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== dependencies: "@sindresorhus/is" "^4.0.0" "@szmarczak/http-timer" "^4.0.5" From 774641464e37b2e3759bbac60226835fba968745 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Dec 2022 08:26:03 -0500 Subject: [PATCH 04/26] Bump rfc6902 from 5.0.0 to 5.0.1 (#6766) Bumps [rfc6902](https://github.com/chbrown/rfc6902) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/chbrown/rfc6902/releases) - [Commits](https://github.com/chbrown/rfc6902/compare/v5.0.0...v5.0.1) --- updated-dependencies: - dependency-name: rfc6902 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 6236b72fda..28827d4a4e 100644 --- a/package.json +++ b/package.json @@ -267,7 +267,7 @@ "readable-stream": "^3.6.0", "request": "^2.88.2", "request-promise-native": "^1.0.9", - "rfc6902": "^5.0.0", + "rfc6902": "^5.0.1", "selfsigned": "^2.1.1", "semver": "^7.3.8", "tar": "^6.1.13", diff --git a/yarn.lock b/yarn.lock index 24c8d7f954..bfaa24760a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11189,10 +11189,10 @@ rfc4648@^1.3.0: resolved "https://registry.yarnpkg.com/rfc4648/-/rfc4648-1.5.1.tgz#b0b16756e33d9de8c0c7833e94b28e627ec372a4" integrity sha512-60e/YWs2/D3MV1ErdjhJHcmlgnyLUiG4X/14dgsfm9/zmCWLN16xI6YqJYSCd/OANM7bUNzJqPY5B8/02S9Ibw== -rfc6902@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/rfc6902/-/rfc6902-5.0.0.tgz#cb53ac1cb8a700edc1ddc6c19afbb93422f9e385" - integrity sha512-6d0Q7DgN+RWHhvY/jb7QWG6ol+XreFqQn4NzvHB8CSALA70fRLRmbJaMvxlFf/JIzfkiNWq0lQF0l5yWb4yuLA== +rfc6902@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/rfc6902/-/rfc6902-5.0.1.tgz#e16f18dc322c755d6dd948423ddf52bb451eca3d" + integrity sha512-tYGfLpKIq9X7lrt4o3IkD9w9bpeAtsejfAqWNR98AoxfTsZqCepKa8eDlRiX8QMiCOD9vMx0/YbKLx0G1nPi5w== rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" From 2d38ec55fbd30ae645621f2989541bd0e806c0fc Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 16 Dec 2022 05:48:03 -0800 Subject: [PATCH 05/26] Fix queries for operator provider metrics (#6679) Signed-off-by: Sebastian Malton Signed-off-by: Sebastian Malton --- src/main/prometheus/operator-provider.injectable.ts.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/prometheus/operator-provider.injectable.ts.ts b/src/main/prometheus/operator-provider.injectable.ts.ts index 02891d873b..5215f2dff2 100644 --- a/src/main/prometheus/operator-provider.injectable.ts.ts +++ b/src/main/prometheus/operator-provider.injectable.ts.ts @@ -71,23 +71,23 @@ export const getOperatorLikeQueryFor = ({ rateAccuracy }: { rateAccuracy: string case "pods": switch (queryName) { case "cpuUsage": - return `sum(rate(container_cpu_usage_seconds_total{container!="", image!="", pod=~"${opts.pods}", namespace="${opts.namespace}"}[${rateAccuracy}])) by (${opts.selector})`; + return `sum(rate(container_cpu_usage_seconds_total{pod=~"${opts.pods}", namespace="${opts.namespace}"}[${rateAccuracy}])) by (${opts.selector})`; case "cpuRequests": return `sum(kube_pod_container_resource_requests{pod=~"${opts.pods}", resource="cpu", namespace="${opts.namespace}"}) by (${opts.selector})`; case "cpuLimits": return `sum(kube_pod_container_resource_limits{pod=~"${opts.pods}", resource="cpu", namespace="${opts.namespace}"}) by (${opts.selector})`; case "memoryUsage": - return `sum(container_memory_working_set_bytes{container!="", image!="", pod=~"${opts.pods}", namespace="${opts.namespace}"}) by (${opts.selector})`; + return `sum(container_memory_working_set_bytes{pod=~"${opts.pods}", namespace="${opts.namespace}"}) by (${opts.selector})`; case "memoryRequests": return `sum(kube_pod_container_resource_requests{pod=~"${opts.pods}", resource="memory", namespace="${opts.namespace}"}) by (${opts.selector})`; case "memoryLimits": return `sum(kube_pod_container_resource_limits{pod=~"${opts.pods}", resource="memory", namespace="${opts.namespace}"}) by (${opts.selector})`; case "fsUsage": - return `sum(container_fs_usage_bytes{container!="", pod=~"${opts.pods}", namespace="${opts.namespace}"}) by (${opts.selector})`; + return `sum(container_fs_usage_bytes{pod=~"${opts.pods}", namespace="${opts.namespace}"}) by (${opts.selector})`; case "fsWrites": - return `sum(rate(container_fs_writes_bytes_total{container!="", pod=~"${opts.pods}", namespace="${opts.namespace}"}[${rateAccuracy}])) by (${opts.selector})`; + return `sum(rate(container_fs_writes_bytes_total{pod=~"${opts.pods}", namespace="${opts.namespace}"}[${rateAccuracy}])) by (${opts.selector})`; case "fsReads": - return `sum(rate(container_fs_reads_bytes_total{container!="", pod=~"${opts.pods}", namespace="${opts.namespace}"}[${rateAccuracy}])) by (${opts.selector})`; + return `sum(rate(container_fs_reads_bytes_total{pod=~"${opts.pods}", namespace="${opts.namespace}"}[${rateAccuracy}])) by (${opts.selector})`; case "networkReceive": return `sum(rate(container_network_receive_bytes_total{pod=~"${opts.pods}", namespace="${opts.namespace}"}[${rateAccuracy}])) by (${opts.selector})`; case "networkTransmit": From 9c576c7f802b09b9a161f911060688364a041ba6 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 16 Dec 2022 05:53:37 -0800 Subject: [PATCH 06/26] Fix release workflow file (#6772) Signed-off-by: Sebastian Malton Signed-off-by: Sebastian Malton --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ab7ee4c273..2c5d84bf0e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,6 +33,6 @@ jobs: publish-npm: uses: ./.github/workflows/publish-release-npm.yml needs: release - if: ${{ jobs.release.outputs.version != '' }} + if: ${{ needs.release.outputs.version != '' }} with: - version: ${{ jobs.release.outputs.version }} + version: ${{ needs.release.outputs.version }} From de789ff9554fcb5c2227e35b2f09958f3ddef8c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Dec 2022 09:23:48 -0500 Subject: [PATCH 07/26] Bump @kubernetes/client-node from 0.17.1 to 0.18.0 (#6769) * Bump @kubernetes/client-node from 0.17.1 to 0.18.0 Bumps [@kubernetes/client-node](https://github.com/kubernetes-client/javascript) from 0.17.1 to 0.18.0. - [Release notes](https://github.com/kubernetes-client/javascript/releases) - [Changelog](https://github.com/kubernetes-client/javascript/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes-client/javascript/compare/0.17.1...0.18.0) --- updated-dependencies: - dependency-name: "@kubernetes/client-node" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Fix typing Signed-off-by: Sebastian Malton * Fix technical test Signed-off-by: Sebastian Malton Signed-off-by: dependabot[bot] Signed-off-by: Sebastian Malton Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sebastian Malton --- package.json | 2 +- .../local-shell-session/techincal.test.ts | 9 ++- yarn.lock | 67 +++++++++++-------- 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 28827d4a4e..3383a036cd 100644 --- a/package.json +++ b/package.json @@ -200,7 +200,7 @@ "@astronautlabs/jsonpath": "^1.1.0", "@hapi/call": "^9.0.0", "@hapi/subtext": "^7.0.4", - "@kubernetes/client-node": "^0.17.1", + "@kubernetes/client-node": "^0.18.0", "@material-ui/styles": "^4.11.5", "@ogre-tools/fp": "^12.0.1", "@ogre-tools/injectable": "^12.0.1", diff --git a/src/main/shell-session/local-shell-session/techincal.test.ts b/src/main/shell-session/local-shell-session/techincal.test.ts index 37228a6ddc..5c471d923e 100644 --- a/src/main/shell-session/local-shell-session/techincal.test.ts +++ b/src/main/shell-session/local-shell-session/techincal.test.ts @@ -4,7 +4,7 @@ */ import type { DiContainer } from "@ogre-tools/injectable"; -import { WebSocket } from "ws"; +import type WebSocket from "ws"; import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; import type { Cluster } from "../../../common/cluster/cluster"; import pathExistsSyncInjectable from "../../../common/fs/path-exists-sync.injectable"; @@ -86,13 +86,18 @@ describe("technical unit tests for local shell sessions", () => { }; }); + const websocket = { + on: jest.fn(() => websocket), + once: jest.fn(() => websocket), + } as Partial as WebSocket; + await openLocalShellSession({ cluster: { getProxyKubeconfigPath: async () => "/some-proxy-kubeconfig", preferences: {}, } as Partial as Cluster, tabId: "my-tab-id", - websocket: new WebSocket(null), + websocket, }); }); }); diff --git a/yarn.lock b/yarn.lock index bfaa24760a..7fa5790ffa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1184,11 +1184,15 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@kubernetes/client-node@^0.17.1": - version "0.17.1" - resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.17.1.tgz#a5740712848d77823e7d0eee70229936398b4142" - integrity sha512-qXANjukuTq/drb1hq1NCYZafpdRTvbyTzbliWO6RwW7eEb2b9qwINbw0DiVHpBQg3e9DeQd8+brI1sR1Fck5kQ== +"@kubernetes/client-node@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.18.0.tgz#b1002f3c19fb7509ce521ea78f500589f8e3e047" + integrity sha512-Mp6q0OkZQBp+HslIgvHYpsPJk8z6mch231QWtIZQHvs+PaTE6mkUfusYE8fNw3jMjru5mVO/JDz6PTjB9YT2rQ== dependencies: + "@types/js-yaml" "^4.0.1" + "@types/node" "^10.12.0" + "@types/request" "^2.47.1" + "@types/ws" "^6.0.1" byline "^5.0.0" execa "5.0.0" isomorphic-ws "^4.0.1" @@ -1200,11 +1204,11 @@ stream-buffers "^3.0.2" tar "^6.1.11" tmp-promise "^3.0.2" - tslib "^1.9.3" - underscore "^1.9.1" + tslib "^2.4.1" + underscore "^1.13.6" ws "^7.3.1" optionalDependencies: - openid-client "^5.1.6" + openid-client "^5.3.0" "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" @@ -2249,7 +2253,7 @@ jest-matcher-utils "^28.0.0" pretty-format "^28.0.0" -"@types/js-yaml@^4.0.5": +"@types/js-yaml@^4.0.1", "@types/js-yaml@^4.0.5": version "4.0.5" resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.5.tgz#738dd390a6ecc5442f35e7f03fa1431353f7e138" integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA== @@ -2348,6 +2352,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.24.tgz#20ba1bf69c1b4ab405c7a01e950c4f446b05029f" integrity sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g== +"@types/node@^10.12.0": + version "10.17.60" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" + integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== + "@types/node@^16.11.26", "@types/node@^16.18.9": version "16.18.9" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.9.tgz#47c491cfbc10460571d766c16526748fa9ad96a1" @@ -2510,7 +2519,7 @@ dependencies: "@types/request" "*" -"@types/request@*", "@types/request@^2.48.7": +"@types/request@*", "@types/request@^2.47.1", "@types/request@^2.48.7": version "2.48.8" resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.8.tgz#0b90fde3b655ab50976cb8c5ac00faca22f5a82c" integrity sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ== @@ -2712,6 +2721,13 @@ tapable "^2.2.0" webpack "^5" +"@types/ws@^6.0.1": + version "6.0.4" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.4.tgz#7797707c8acce8f76d8c34b370d4645b70421ff1" + integrity sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg== + dependencies: + "@types/node" "*" + "@types/ws@^8.5.1": version "8.5.3" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" @@ -8045,10 +8061,10 @@ joi@^17.7.0: "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" -jose@^4.1.4: - version "4.9.3" - resolved "https://registry.yarnpkg.com/jose/-/jose-4.9.3.tgz#890abd3f26725fe0f2aa720bc2f7835702b624db" - integrity sha512-f8E/z+T3Q0kA9txzH2DKvH/ds2uggcw0m3vVPSB9HrSkrQ7mojjifvS7aR8cw+lQl2Fcmx9npwaHpM/M3GD8UQ== +jose@^4.10.0: + version "4.11.1" + resolved "https://registry.yarnpkg.com/jose/-/jose-4.11.1.tgz#8f7443549befe5bddcf4bae664a9cbc1a62da4fa" + integrity sha512-YRv4Tk/Wlug8qicwqFNFVEZSdbROCHRAC6qu/i0dyNKr5JQdoa2pIGoS04lLO/jXQX7Z9omoNewYIVIxqZBd9Q== joycon@^3.0.1: version "3.1.1" @@ -9893,12 +9909,12 @@ opener@^1.5.2: resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== -openid-client@^5.1.6: - version "5.1.8" - resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.1.8.tgz#3a24910288b32c32f548fb6e391f44178ce6370f" - integrity sha512-EPxJY6bT7YIYQEXSGxRC5flQ3GUhLy98ufdto6+BVBrFGPmwjUpy4xBcYuU/Wt9nPkO/3EgljBrr6Ezx4lp1RQ== +openid-client@^5.3.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.3.1.tgz#69a5fa7d2b5ad479032f576852d40b4d4435488a" + integrity sha512-RLfehQiHch9N6tRWNx68cicf3b1WR0x74bJWHRc25uYIbSRwjxYcTFaRnzbbpls5jroLAaB/bFIodTgA5LJMvw== dependencies: - jose "^4.1.4" + jose "^4.10.0" lru-cache "^6.0.0" object-hash "^2.0.1" oidc-token-hash "^5.0.1" @@ -12468,12 +12484,7 @@ tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - -tslib@^2.4.0: +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== @@ -12640,10 +12651,10 @@ undefsafe@^2.0.5: resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== -underscore@1.7.0, underscore@^1.12.1, underscore@^1.9.1: - version "1.13.4" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee" - integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ== +underscore@1.7.0, underscore@^1.12.1, underscore@^1.13.6: + version "1.13.6" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" + integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== unique-filename@^1.1.1: version "1.1.1" From 5c6402b60a1ab2b8315c9c8a6a85c61cd503ea9a Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 16 Dec 2022 13:13:57 -0800 Subject: [PATCH 08/26] Make apiBase not an InjectionToken and make openNodeShellSession not special (#6774) * Replace apiBaseInjectionToken with tokens for configuration instead Signed-off-by: Sebastian Malton * Use new ordering to make openNodeShellSession non-special Signed-off-by: Sebastian Malton Signed-off-by: Sebastian Malton --- src/common/k8s-api/api-base-configs.ts | 14 ++++++++ src/common/k8s-api/api-base.injectable.ts | 33 +++++++++++++++++ src/common/k8s-api/api-base.ts | 11 ------ .../create-kube-api-for-cluster.injectable.ts | 4 +-- ...te-kube-json-api-for-cluster.injectable.ts | 7 ++-- .../request-charts.injectable.ts | 4 +-- .../request-readme.injectable.ts | 4 +-- .../request-values.injectable.ts | 4 +-- .../request-versions.injectable.ts | 4 +-- .../request-configuration.injectable.ts | 4 +-- .../request-create.injectable.ts | 4 +-- .../request-delete.injectable.ts | 4 +-- .../request-details.injectable.ts | 4 +-- .../request-history.injectable.ts | 4 +-- .../request-releases.injectable.ts | 4 +-- .../request-rollback.injectable.ts | 4 +-- .../request-update.injectable.ts | 4 +-- .../request-values.injectable.ts | 4 +-- .../metrics.api/request-metrics.injectable.ts | 4 +-- .../request-providers.injectable.ts | 4 +-- .../request-patch.injectable.ts | 4 +-- .../request-update.injectable.ts | 4 +-- .../k8s/api-base-host-header.injectable.ts | 19 ++++++++++ .../k8s/api-base-server-address.injectable.ts | 19 ++++++++++ src/main/k8s/api-base.injectable.ts | 33 ----------------- .../create-shell-session.injectable.ts | 3 +- .../node-shell-session/open.injectable.ts | 17 +++++---- ...e-account-kube-config-dialog.injectable.ts | 2 +- .../k8s/api-base-host-header.injectable.ts | 15 ++++++++ .../k8s/api-base-server-address.injectable.ts | 19 ++++++++++ src/renderer/k8s/api-base.injectable.ts | 36 ------------------- .../port-forward-store.injectable.ts | 4 +-- .../request-active-port-forward.injectable.ts | 4 +-- 33 files changed, 175 insertions(+), 133 deletions(-) create mode 100644 src/common/k8s-api/api-base-configs.ts create mode 100644 src/common/k8s-api/api-base.injectable.ts delete mode 100644 src/common/k8s-api/api-base.ts create mode 100644 src/main/k8s/api-base-host-header.injectable.ts create mode 100644 src/main/k8s/api-base-server-address.injectable.ts delete mode 100644 src/main/k8s/api-base.injectable.ts create mode 100644 src/renderer/k8s/api-base-host-header.injectable.ts create mode 100644 src/renderer/k8s/api-base-server-address.injectable.ts delete mode 100644 src/renderer/k8s/api-base.injectable.ts diff --git a/src/common/k8s-api/api-base-configs.ts b/src/common/k8s-api/api-base-configs.ts new file mode 100644 index 0000000000..5ac67229ec --- /dev/null +++ b/src/common/k8s-api/api-base-configs.ts @@ -0,0 +1,14 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { getInjectionToken } from "@ogre-tools/injectable"; + +export const apiBaseServerAddressInjectionToken = getInjectionToken({ + id: "api-base-config-server-address-token", +}); + +export const apiBaseHostHeaderInjectionToken = getInjectionToken({ + id: "api-base-host-header-token", +}); diff --git a/src/common/k8s-api/api-base.injectable.ts b/src/common/k8s-api/api-base.injectable.ts new file mode 100644 index 0000000000..b340882672 --- /dev/null +++ b/src/common/k8s-api/api-base.injectable.ts @@ -0,0 +1,33 @@ +/** + * 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 { apiPrefix } from "../vars"; +import isDebuggingInjectable from "../vars/is-debugging.injectable"; +import isDevelopmentInjectable from "../vars/is-development.injectable"; +import { apiBaseHostHeaderInjectionToken, apiBaseServerAddressInjectionToken } from "./api-base-configs"; +import createJsonApiInjectable from "./create-json-api.injectable"; + +const apiBaseInjectable = getInjectable({ + id: "api-base", + instantiate: (di) => { + const createJsonApi = di.inject(createJsonApiInjectable); + const isDebugging = di.inject(isDebuggingInjectable); + const isDevelopment = di.inject(isDevelopmentInjectable); + const serverAddress = di.inject(apiBaseServerAddressInjectionToken); + const hostHeaderValue = di.inject(apiBaseHostHeaderInjectionToken); + + return createJsonApi({ + serverAddress, + apiBase: apiPrefix, + debug: isDevelopment || isDebugging, + }, { + headers: { + "Host": hostHeaderValue, + }, + }); + }, +}); + +export default apiBaseInjectable; diff --git a/src/common/k8s-api/api-base.ts b/src/common/k8s-api/api-base.ts deleted file mode 100644 index 9544e4f60c..0000000000 --- a/src/common/k8s-api/api-base.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import type { JsonApi } from "./json-api"; -import { getInjectionToken } from "@ogre-tools/injectable"; - -export const apiBaseInjectionToken = getInjectionToken({ - id: "api-base-token", -}); diff --git a/src/common/k8s-api/create-kube-api-for-cluster.injectable.ts b/src/common/k8s-api/create-kube-api-for-cluster.injectable.ts index e7509dcbc7..eec3752e3a 100644 --- a/src/common/k8s-api/create-kube-api-for-cluster.injectable.ts +++ b/src/common/k8s-api/create-kube-api-for-cluster.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import { apiKubePrefix } from "../vars"; import isDevelopmentInjectable from "../vars/is-development.injectable"; -import { apiBaseInjectionToken } from "./api-base"; +import apiBaseInjectable from "./api-base.injectable"; import createKubeJsonApiInjectable from "./create-kube-json-api.injectable"; import type { KubeApiOptions } from "./kube-api"; import { KubeApi } from "./kube-api"; @@ -33,7 +33,7 @@ export interface CreateKubeApiForCluster { const createKubeApiForClusterInjectable = getInjectable({ id: "create-kube-api-for-cluster", instantiate: (di): CreateKubeApiForCluster => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); const isDevelopment = di.inject(isDevelopmentInjectable); const createKubeJsonApi = di.inject(createKubeJsonApiInjectable); diff --git a/src/common/k8s-api/create-kube-json-api-for-cluster.injectable.ts b/src/common/k8s-api/create-kube-json-api-for-cluster.injectable.ts index 9901731c94..799b0bf963 100644 --- a/src/common/k8s-api/create-kube-json-api-for-cluster.injectable.ts +++ b/src/common/k8s-api/create-kube-json-api-for-cluster.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import { apiKubePrefix } from "../vars"; import isDebuggingInjectable from "../vars/is-debugging.injectable"; -import { apiBaseInjectionToken } from "./api-base"; +import { apiBaseHostHeaderInjectionToken, apiBaseServerAddressInjectionToken } from "./api-base-configs"; import createKubeJsonApiInjectable from "./create-kube-json-api.injectable"; import type { KubeJsonApi } from "./kube-json-api"; @@ -14,19 +14,18 @@ export type CreateKubeJsonApiForCluster = (clusterId: string) => KubeJsonApi; const createKubeJsonApiForClusterInjectable = getInjectable({ id: "create-kube-json-api-for-cluster", instantiate: (di): CreateKubeJsonApiForCluster => { - const apiBase = di.inject(apiBaseInjectionToken); const createKubeJsonApi = di.inject(createKubeJsonApiInjectable); const isDebugging = di.inject(isDebuggingInjectable); return (clusterId) => createKubeJsonApi( { - serverAddress: apiBase.config.serverAddress, + serverAddress: di.inject(apiBaseServerAddressInjectionToken), apiBase: apiKubePrefix, debug: isDebugging, }, { headers: { - "Host": `${clusterId}.localhost:${new URL(apiBase.config.serverAddress).port}`, + "Host": `${clusterId}.${di.inject(apiBaseHostHeaderInjectionToken)}`, }, }, ); diff --git a/src/common/k8s-api/endpoints/helm-charts.api/request-charts.injectable.ts b/src/common/k8s-api/endpoints/helm-charts.api/request-charts.injectable.ts index 89de5f9d17..4d9bfc55b1 100644 --- a/src/common/k8s-api/endpoints/helm-charts.api/request-charts.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-charts.api/request-charts.injectable.ts @@ -3,10 +3,10 @@ * 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"; +import apiBaseInjectable from "../../api-base.injectable"; export type RequestHelmCharts = () => Promise; export type RepoHelmChartList = Record; @@ -17,7 +17,7 @@ export type RepoHelmChartList = Record; const requestHelmChartsInjectable = getInjectable({ id: "request-helm-charts", instantiate: (di) => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return async () => { const data = await apiBase.get>("/v2/charts"); diff --git a/src/common/k8s-api/endpoints/helm-charts.api/request-readme.injectable.ts b/src/common/k8s-api/endpoints/helm-charts.api/request-readme.injectable.ts index c6815c4b93..4314d68578 100644 --- a/src/common/k8s-api/endpoints/helm-charts.api/request-readme.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-charts.api/request-readme.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { urlBuilderFor } from "../../../utils/buildUrl"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; const requestReadmeEndpoint = urlBuilderFor("/v2/charts/:repo/:name/readme"); @@ -13,7 +13,7 @@ export type RequestHelmChartReadme = (repo: string, name: string, version?: stri const requestHelmChartReadmeInjectable = getInjectable({ id: "request-helm-chart-readme", instantiate: (di): RequestHelmChartReadme => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (repo, name, version) => ( apiBase.get(requestReadmeEndpoint.compile({ name, repo }, { version })) diff --git a/src/common/k8s-api/endpoints/helm-charts.api/request-values.injectable.ts b/src/common/k8s-api/endpoints/helm-charts.api/request-values.injectable.ts index ec927fc37a..c48461bba5 100644 --- a/src/common/k8s-api/endpoints/helm-charts.api/request-values.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-charts.api/request-values.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { urlBuilderFor } from "../../../utils/buildUrl"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; const requestValuesEndpoint = urlBuilderFor("/v2/charts/:repo/:name/values"); @@ -13,7 +13,7 @@ export type RequestHelmChartValues = (repo: string, name: string, version: strin const requestHelmChartValuesInjectable = getInjectable({ id: "request-helm-chart-values", instantiate: (di): RequestHelmChartValues => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (repo, name, version) => ( apiBase.get(requestValuesEndpoint.compile({ repo, name }, { version })) diff --git a/src/common/k8s-api/endpoints/helm-charts.api/request-versions.injectable.ts b/src/common/k8s-api/endpoints/helm-charts.api/request-versions.injectable.ts index 410d8ea596..ab85594ec6 100644 --- a/src/common/k8s-api/endpoints/helm-charts.api/request-versions.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-charts.api/request-versions.injectable.ts @@ -4,10 +4,10 @@ */ 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"; +import apiBaseInjectable from "../../api-base.injectable"; const requestVersionsEndpoint = urlBuilderFor("/v2/charts/:repo/:name/versions"); @@ -16,7 +16,7 @@ export type RequestHelmChartVersions = (repo: string, chartName: string) => Prom const requestHelmChartVersionsInjectable = getInjectable({ id: "request-helm-chart-versions", instantiate: (di): RequestHelmChartVersions => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return async (repo, name) => { const rawVersions = await apiBase.get(requestVersionsEndpoint.compile({ name, repo })) as RawHelmChart[]; diff --git a/src/common/k8s-api/endpoints/helm-releases.api/request-configuration.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/request-configuration.injectable.ts index 1bfe168b11..e1581c5d76 100644 --- a/src/common/k8s-api/endpoints/helm-releases.api/request-configuration.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-releases.api/request-configuration.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { urlBuilderFor } from "../../../utils/buildUrl"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; export type RequestHelmReleaseConfiguration = ( name: string, @@ -18,7 +18,7 @@ const requestHelmReleaseConfigurationInjectable = getInjectable({ id: "request-helm-release-configuration", instantiate: (di): RequestHelmReleaseConfiguration => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (name, namespace, all: boolean) => ( apiBase.get(requestConfigurationEnpoint.compile({ name, namespace }, { all })) diff --git a/src/common/k8s-api/endpoints/helm-releases.api/request-create.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/request-create.injectable.ts index bad802d3cc..c1cd09d40f 100644 --- a/src/common/k8s-api/endpoints/helm-releases.api/request-create.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-releases.api/request-create.injectable.ts @@ -5,8 +5,8 @@ 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"; +import apiBaseInjectable from "../../api-base.injectable"; interface HelmReleaseCreatePayload { name?: string; @@ -25,7 +25,7 @@ const requestCreateHelmReleaseInjectable = getInjectable({ id: "request-create-helm-release", instantiate: (di): RequestCreateHelmRelease => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return ({ repo, chart, values, ...data }) => { return apiBase.post(requestCreateEndpoint.compile({}), { diff --git a/src/common/k8s-api/endpoints/helm-releases.api/request-delete.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/request-delete.injectable.ts index 66b2013770..44af4311a9 100644 --- a/src/common/k8s-api/endpoints/helm-releases.api/request-delete.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-releases.api/request-delete.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { urlBuilderFor } from "../../../utils/buildUrl"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; export type RequestDeleteHelmRelease = (name: string, namespace: string) => Promise; @@ -13,7 +13,7 @@ const requestDeleteEndpoint = urlBuilderFor("/v2/releases/:namespace/:name"); const requestDeleteHelmReleaseInjectable = getInjectable({ id: "request-delete-helm-release", instantiate: (di): RequestDeleteHelmRelease => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (name, namespace) => apiBase.del(requestDeleteEndpoint.compile({ name, namespace })); }, diff --git a/src/common/k8s-api/endpoints/helm-releases.api/request-details.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/request-details.injectable.ts index 0b712cd78e..37f2287377 100644 --- a/src/common/k8s-api/endpoints/helm-releases.api/request-details.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-releases.api/request-details.injectable.ts @@ -4,8 +4,8 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import type { KubeJsonApiData } from "../../kube-json-api"; -import { apiBaseInjectionToken } from "../../api-base"; import { urlBuilderFor } from "../../../utils/buildUrl"; +import apiBaseInjectable from "../../api-base.injectable"; export interface HelmReleaseDetails { resources: KubeJsonApiData[]; @@ -32,7 +32,7 @@ const requestHelmReleaseDetailsInjectable = getInjectable({ id: "call-for-helm-release-details", instantiate: (di): CallForHelmReleaseDetails => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (name, namespace) => apiBase.get(requestDetailsEnpoint.compile({ name, namespace })); }, diff --git a/src/common/k8s-api/endpoints/helm-releases.api/request-history.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/request-history.injectable.ts index b6e9794fe7..58b6a37dbb 100644 --- a/src/common/k8s-api/endpoints/helm-releases.api/request-history.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-releases.api/request-history.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { urlBuilderFor } from "../../../utils/buildUrl"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; export interface HelmReleaseRevision { revision: number; @@ -22,7 +22,7 @@ const requestHistoryEnpoint = urlBuilderFor("/v2/releases/:namespace/:name/histo const requestHelmReleaseHistoryInjectable = getInjectable({ id: "request-helm-release-history", instantiate: (di): RequestHelmReleaseHistory => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (name, namespace) => apiBase.get(requestHistoryEnpoint.compile({ name, namespace })); }, diff --git a/src/common/k8s-api/endpoints/helm-releases.api/request-releases.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/request-releases.injectable.ts index 2619e289c6..ee6503ca99 100644 --- a/src/common/k8s-api/endpoints/helm-releases.api/request-releases.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-releases.api/request-releases.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { urlBuilderFor } from "../../../utils/buildUrl"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; import type { HelmReleaseDto } from "../helm-releases.api"; export type RequestHelmReleases = (namespace?: string) => Promise; @@ -15,7 +15,7 @@ const requestHelmReleasesInjectable = getInjectable({ id: "request-helm-releases", instantiate: (di): RequestHelmReleases => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (namespace) => apiBase.get(requestHelmReleasesEndpoint.compile({ namespace })); }, diff --git a/src/common/k8s-api/endpoints/helm-releases.api/request-rollback.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/request-rollback.injectable.ts index 1a9229b73a..036b399ef2 100644 --- a/src/common/k8s-api/endpoints/helm-releases.api/request-rollback.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-releases.api/request-rollback.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { urlBuilderFor } from "../../../utils/buildUrl"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; export type RequestHelmReleaseRollback = (name: string, namespace: string, revision: number) => Promise; @@ -13,7 +13,7 @@ const requestRollbackEndpoint = urlBuilderFor("/v2/releases/:namespace/:name"); const requestHelmReleaseRollbackInjectable = getInjectable({ id: "request-helm-release-rollback", instantiate: (di): RequestHelmReleaseRollback => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return async (name, namespace, revision) => { await apiBase.put( diff --git a/src/common/k8s-api/endpoints/helm-releases.api/request-update.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/request-update.injectable.ts index 8f46a3a210..715a21cea9 100644 --- a/src/common/k8s-api/endpoints/helm-releases.api/request-update.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-releases.api/request-update.injectable.ts @@ -3,9 +3,9 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { apiBaseInjectionToken } from "../../api-base"; import { urlBuilderFor } from "../../../utils/buildUrl"; import type { AsyncResult } from "../../../utils/async-result"; +import apiBaseInjectable from "../../api-base.injectable"; interface HelmReleaseUpdatePayload { repo: string; @@ -26,7 +26,7 @@ const requestHelmReleaseUpdateInjectable = getInjectable({ id: "request-helm-release-update", instantiate: (di): RequestHelmReleaseUpdate => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return async (name, namespace, { repo, chart, values, version }) => { try { diff --git a/src/common/k8s-api/endpoints/helm-releases.api/request-values.injectable.ts b/src/common/k8s-api/endpoints/helm-releases.api/request-values.injectable.ts index d30f9973c4..99f1cc17d0 100644 --- a/src/common/k8s-api/endpoints/helm-releases.api/request-values.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-releases.api/request-values.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { urlBuilderFor } from "../../../utils/buildUrl"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; export type RequestHelmReleaseValues = (name: string, namespace: string, all?: boolean) => Promise; @@ -13,7 +13,7 @@ const requestValuesEndpoint = urlBuilderFor("/v2/release/:namespace/:name/values const requestHelmReleaseValuesInjectable = getInjectable({ id: "request-helm-release-values", instantiate: (di): RequestHelmReleaseValues => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (name, namespace, all) => apiBase.get(requestValuesEndpoint.compile({ name, namespace }, { all })); }, diff --git a/src/common/k8s-api/endpoints/metrics.api/request-metrics.injectable.ts b/src/common/k8s-api/endpoints/metrics.api/request-metrics.injectable.ts index 0da0bc95ec..e83c52b9aa 100644 --- a/src/common/k8s-api/endpoints/metrics.api/request-metrics.injectable.ts +++ b/src/common/k8s-api/endpoints/metrics.api/request-metrics.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { getSecondsFromUnixEpoch } from "../../../utils/date/get-current-date-time"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; import type { MetricData } from "../metrics.api"; @@ -46,7 +46,7 @@ export interface RequestMetrics { const requestMetricsInjectable = getInjectable({ id: "request-metrics", instantiate: (di) => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (async (query: object, params: RequestMetricsParams = {}) => { const { range = 3600, step = 60, namespace } = params; diff --git a/src/common/k8s-api/endpoints/metrics.api/request-providers.injectable.ts b/src/common/k8s-api/endpoints/metrics.api/request-providers.injectable.ts index 4711333ca6..0c74c4d58d 100644 --- a/src/common/k8s-api/endpoints/metrics.api/request-providers.injectable.ts +++ b/src/common/k8s-api/endpoints/metrics.api/request-providers.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; export interface MetricProviderInfo { name: string; @@ -17,7 +17,7 @@ export type RequestMetricsProviders = () => Promise; const requestMetricsProvidersInjectable = getInjectable({ id: "request-metrics-providers", instantiate: (di): RequestMetricsProviders => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return () => apiBase.get("/metrics/providers"); }, diff --git a/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts b/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts index c8ad3435fd..7290263a41 100644 --- a/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts +++ b/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import type { Patch } from "rfc6902"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; import type { KubeJsonApiData } from "../../kube-json-api"; export type RequestKubeObjectPatch = (name: string, kind: string, ns: string | undefined, patch: Patch) => Promise; @@ -12,7 +12,7 @@ export type RequestKubeObjectPatch = (name: string, kind: string, ns: string | u const requestKubeObjectPatchInjectable = getInjectable({ id: "request-kube-object-patch", instantiate: (di): RequestKubeObjectPatch => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (name, kind, ns, patch) => ( apiBase.patch("/stack", { diff --git a/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts b/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts index 52824cd86c..7d996253ee 100644 --- a/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts +++ b/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { apiBaseInjectionToken } from "../../api-base"; +import apiBaseInjectable from "../../api-base.injectable"; import type { KubeJsonApiData } from "../../kube-json-api"; export type RequestKubeObjectCreation = (resourceDescriptor: string) => Promise; @@ -11,7 +11,7 @@ export type RequestKubeObjectCreation = (resourceDescriptor: string) => Promise< const requestKubeObjectCreationInjectable = getInjectable({ id: "request-kube-object-creation", instantiate: (di): RequestKubeObjectCreation => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); return (data) => apiBase.post("/stack", { data }); }, diff --git a/src/main/k8s/api-base-host-header.injectable.ts b/src/main/k8s/api-base-host-header.injectable.ts new file mode 100644 index 0000000000..281c4fda84 --- /dev/null +++ b/src/main/k8s/api-base-host-header.injectable.ts @@ -0,0 +1,19 @@ +/** + * 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 { apiBaseHostHeaderInjectionToken } from "../../common/k8s-api/api-base-configs"; +import lensProxyPortInjectable from "../lens-proxy/lens-proxy-port.injectable"; + +const apiBaseHostHeaderInjectable = getInjectable({ + id: "api-base-host-header", + instantiate: (di) => { + const lensProxyPort = di.inject(lensProxyPortInjectable); + + return `localhost:${lensProxyPort.get()}`; + }, + injectionToken: apiBaseHostHeaderInjectionToken, +}); + +export default apiBaseHostHeaderInjectable; diff --git a/src/main/k8s/api-base-server-address.injectable.ts b/src/main/k8s/api-base-server-address.injectable.ts new file mode 100644 index 0000000000..ae217cb3e2 --- /dev/null +++ b/src/main/k8s/api-base-server-address.injectable.ts @@ -0,0 +1,19 @@ +/** + * 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 { apiBaseServerAddressInjectionToken } from "../../common/k8s-api/api-base-configs"; +import lensProxyPortInjectable from "../lens-proxy/lens-proxy-port.injectable"; + +const apiBaseServerAddressInjectable = getInjectable({ + id: "api-base-server-address", + instantiate: (di) => { + const lensProxyPort = di.inject(lensProxyPortInjectable); + + return `http://127.0.0.1:${lensProxyPort.get()}`; + }, + injectionToken: apiBaseServerAddressInjectionToken, +}); + +export default apiBaseServerAddressInjectable; diff --git a/src/main/k8s/api-base.injectable.ts b/src/main/k8s/api-base.injectable.ts deleted file mode 100644 index 07a9424993..0000000000 --- a/src/main/k8s/api-base.injectable.ts +++ /dev/null @@ -1,33 +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 { apiBaseInjectionToken } from "../../common/k8s-api/api-base"; -import createJsonApiInjectable from "../../common/k8s-api/create-json-api.injectable"; -import { apiPrefix } from "../../common/vars"; -import isDebuggingInjectable from "../../common/vars/is-debugging.injectable"; -import isDevelopmentInjectable from "../../common/vars/is-development.injectable"; -import lensProxyPortInjectable from "../lens-proxy/lens-proxy-port.injectable"; - -const apiBaseInjectable = getInjectable({ - id: "api-base", - instantiate: (di) => { - const proxyPort = di.inject(lensProxyPortInjectable); - const createJsonApi = di.inject(createJsonApiInjectable); - const isDebugging = di.inject(isDebuggingInjectable); - - return createJsonApi({ - serverAddress: `http://127.0.0.1:${proxyPort.get()}`, - apiBase: apiPrefix, - debug: di.inject(isDevelopmentInjectable) || isDebugging, - }, { - headers: { - "Host": `localhost:${proxyPort.get()}`, - }, - }); - }, - injectionToken: apiBaseInjectionToken, -}); - -export default apiBaseInjectable; diff --git a/src/main/shell-session/create-shell-session.injectable.ts b/src/main/shell-session/create-shell-session.injectable.ts index 49ba44cb67..6af65dc908 100644 --- a/src/main/shell-session/create-shell-session.injectable.ts +++ b/src/main/shell-session/create-shell-session.injectable.ts @@ -22,10 +22,11 @@ const openShellSessionInjectable = getInjectable({ instantiate: (di): OpenShellSession => { const openLocalShellSession = di.inject(openLocalShellSessionInjectable); + const openNodeShellSession = di.inject(openNodeShellSessionInjectable); return ({ nodeName, ...args }) => ( nodeName - ? di.inject(openNodeShellSessionInjectable, { nodeName, ...args }) + ? openNodeShellSession({ nodeName, ...args }) : openLocalShellSession(args) ); }, diff --git a/src/main/shell-session/node-shell-session/open.injectable.ts b/src/main/shell-session/node-shell-session/open.injectable.ts index 739bd7497c..47b97994b7 100644 --- a/src/main/shell-session/node-shell-session/open.injectable.ts +++ b/src/main/shell-session/node-shell-session/open.injectable.ts @@ -2,7 +2,7 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; +import { getInjectable } from "@ogre-tools/injectable"; import type { Cluster } from "../../../common/cluster/cluster"; import type WebSocket from "ws"; import createKubectlInjectable from "../../kubectl/create-kubectl.injectable"; @@ -27,9 +27,11 @@ export interface NodeShellSessionArgs { nodeName: string; } +export type OpenNodeShellSession = (args: NodeShellSessionArgs) => Promise; + const openNodeShellSessionInjectable = getInjectable({ id: "open-node-shell-session", - instantiate: (di, params: NodeShellSessionArgs) => { + instantiate: (di): OpenNodeShellSession => { const createKubectl = di.inject(createKubectlInjectable); const dependencies: NodeShellSessionDependencies = { isMac: di.inject(isMacInjectable), @@ -44,13 +46,14 @@ const openNodeShellSessionInjectable = getInjectable({ emitAppEvent: di.inject(emitAppEventInjectable), stat: di.inject(statInjectable), }; - const kubectl = createKubectl(params.cluster.version); - const session = new NodeShellSession(dependencies, { kubectl, ...params }); - return session.open(); + return async (args) => { + const kubectl = createKubectl(args.cluster.version); + const session = new NodeShellSession(dependencies, { kubectl, ...args }); + + return session.open(); + }; }, - // NOTE: this must be transient to bypass the circular dependency of `createKubeJsonApiForClusterInjectable` on the lens proxy port - lifecycle: lifecycleEnum.transient, }); export default openNodeShellSessionInjectable; diff --git a/src/renderer/components/kubeconfig-dialog/open-service-account-kube-config-dialog.injectable.ts b/src/renderer/components/kubeconfig-dialog/open-service-account-kube-config-dialog.injectable.ts index 3a612dec2e..4c0e4255b1 100644 --- a/src/renderer/components/kubeconfig-dialog/open-service-account-kube-config-dialog.injectable.ts +++ b/src/renderer/components/kubeconfig-dialog/open-service-account-kube-config-dialog.injectable.ts @@ -3,9 +3,9 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; +import apiBaseInjectable from "../../../common/k8s-api/api-base.injectable"; import type { ServiceAccount } from "../../../common/k8s-api/endpoints"; import { urlBuilderFor } from "../../../common/utils/buildUrl"; -import apiBaseInjectable from "../../k8s/api-base.injectable"; import openKubeconfigDialogInjectable from "./open.injectable"; export type OpenServiceAccountKubeConfigDialog = (account: ServiceAccount) => void; diff --git a/src/renderer/k8s/api-base-host-header.injectable.ts b/src/renderer/k8s/api-base-host-header.injectable.ts new file mode 100644 index 0000000000..6ca954c85c --- /dev/null +++ b/src/renderer/k8s/api-base-host-header.injectable.ts @@ -0,0 +1,15 @@ +/** + * 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 { apiBaseHostHeaderInjectionToken } from "../../common/k8s-api/api-base-configs"; +import windowLocationInjectable from "../../common/k8s-api/window-location.injectable"; + +const apiBaseHostHeaderInjectable = getInjectable({ + id: "api-base-host-header", + instantiate: (di) => di.inject(windowLocationInjectable).host, + injectionToken: apiBaseHostHeaderInjectionToken, +}); + +export default apiBaseHostHeaderInjectable; diff --git a/src/renderer/k8s/api-base-server-address.injectable.ts b/src/renderer/k8s/api-base-server-address.injectable.ts new file mode 100644 index 0000000000..acb1f525d3 --- /dev/null +++ b/src/renderer/k8s/api-base-server-address.injectable.ts @@ -0,0 +1,19 @@ +/** + * 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 { apiBaseServerAddressInjectionToken } from "../../common/k8s-api/api-base-configs"; +import windowLocationInjectable from "../../common/k8s-api/window-location.injectable"; + +const apiBaseServerAddressInjectable = getInjectable({ + id: "api-base-server-address", + instantiate: (di) => { + const { port } = di.inject(windowLocationInjectable); + + return `http://127.0.0.1:${port}`; + }, + injectionToken: apiBaseServerAddressInjectionToken, +}); + +export default apiBaseServerAddressInjectable; diff --git a/src/renderer/k8s/api-base.injectable.ts b/src/renderer/k8s/api-base.injectable.ts deleted file mode 100644 index 9ce5ab5f98..0000000000 --- a/src/renderer/k8s/api-base.injectable.ts +++ /dev/null @@ -1,36 +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 { apiBaseInjectionToken } from "../../common/k8s-api/api-base"; -import createJsonApiInjectable from "../../common/k8s-api/create-json-api.injectable"; -import windowLocationInjectable from "../../common/k8s-api/window-location.injectable"; -import { apiPrefix } from "../../common/vars"; -import isDebuggingInjectable from "../../common/vars/is-debugging.injectable"; -import isDevelopmentInjectable from "../../common/vars/is-development.injectable"; - -const apiBaseInjectable = getInjectable({ - id: "api-base", - instantiate: (di) => { - const createJsonApi = di.inject(createJsonApiInjectable); - const isDebugging = di.inject(isDebuggingInjectable); - const { port, host } = di.inject(windowLocationInjectable); - - return createJsonApi( - { - serverAddress: `http://127.0.0.1:${port}`, - apiBase: apiPrefix, - debug: di.inject(isDevelopmentInjectable) || isDebugging, - }, - { - headers: { - "Host": host, - }, - }, - ); - }, - injectionToken: apiBaseInjectionToken, -}); - -export default apiBaseInjectable; diff --git a/src/renderer/port-forward/port-forward-store/port-forward-store.injectable.ts b/src/renderer/port-forward/port-forward-store/port-forward-store.injectable.ts index 5339a3e4e7..2d309c315d 100644 --- a/src/renderer/port-forward/port-forward-store/port-forward-store.injectable.ts +++ b/src/renderer/port-forward/port-forward-store/port-forward-store.injectable.ts @@ -7,8 +7,8 @@ import { PortForwardStore } from "./port-forward-store"; import type { ForwardedPort } from "../port-forward-item"; import createStorageInjectable from "../../utils/create-storage/create-storage.injectable"; import notifyErrorPortForwardingInjectable from "../notify-error-port-forwarding.injectable"; -import { apiBaseInjectionToken } from "../../../common/k8s-api/api-base"; import requestActivePortForwardInjectable from "./request-active-port-forward.injectable"; +import apiBaseInjectable from "../../../common/k8s-api/api-base.injectable"; const portForwardStoreInjectable = getInjectable({ id: "port-forward-store", @@ -22,7 +22,7 @@ const portForwardStoreInjectable = getInjectable({ undefined, ), notifyErrorPortForwarding: di.inject(notifyErrorPortForwardingInjectable), - apiBase: di.inject(apiBaseInjectionToken), + apiBase: di.inject(apiBaseInjectable), requestActivePortForward: di.inject(requestActivePortForwardInjectable), }); }, diff --git a/src/renderer/port-forward/port-forward-store/request-active-port-forward.injectable.ts b/src/renderer/port-forward/port-forward-store/request-active-port-forward.injectable.ts index 4939f4d955..90f91320c8 100644 --- a/src/renderer/port-forward/port-forward-store/request-active-port-forward.injectable.ts +++ b/src/renderer/port-forward/port-forward-store/request-active-port-forward.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; -import { apiBaseInjectionToken } from "../../../common/k8s-api/api-base"; +import apiBaseInjectable from "../../../common/k8s-api/api-base.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import { urlBuilderFor } from "../../../common/utils/buildUrl"; import type { ForwardedPort } from "../port-forward-item"; @@ -16,7 +16,7 @@ const requestActiveEndpoint = urlBuilderFor("/pods/port-forward/:namespace/:kind const requestActivePortForwardInjectable = getInjectable({ id: "request-active-port-forward", instantiate: (di): RequestActivePortForward => { - const apiBase = di.inject(apiBaseInjectionToken); + const apiBase = di.inject(apiBaseInjectable); const logger = di.inject(loggerInjectable); return async ({ port, forwardPort, namespace, kind, name, ...rest }) => { From bf6550918c6ce8c36c723c04242fdc75e096d981 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Mon, 19 Dec 2022 16:14:49 +0300 Subject: [PATCH 09/26] Fix helm chart readme load app crash (#6781) * Change request readme types to be AsyncResult Signed-off-by: Alex Andreev * Linter fix Signed-off-by: Alex Andreev Signed-off-by: Alex Andreev --- .../request-readme.injectable.ts | 3 +- ...tab-for-installing-helm-chart.test.ts.snap | 913 ++++++++++++++++++ ...installing-helm-chart-from-new-tab.test.ts | 10 +- ...dock-tab-for-installing-helm-chart.test.ts | 23 +- ...eadme-of-selected-helm-chart.injectable.ts | 4 +- 5 files changed, 947 insertions(+), 6 deletions(-) diff --git a/src/common/k8s-api/endpoints/helm-charts.api/request-readme.injectable.ts b/src/common/k8s-api/endpoints/helm-charts.api/request-readme.injectable.ts index 4314d68578..fb8eaafa10 100644 --- a/src/common/k8s-api/endpoints/helm-charts.api/request-readme.injectable.ts +++ b/src/common/k8s-api/endpoints/helm-charts.api/request-readme.injectable.ts @@ -3,12 +3,13 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; +import type { AsyncResult } from "../../../utils/async-result"; import { urlBuilderFor } from "../../../utils/buildUrl"; import apiBaseInjectable from "../../api-base.injectable"; const requestReadmeEndpoint = urlBuilderFor("/v2/charts/:repo/:name/readme"); -export type RequestHelmChartReadme = (repo: string, name: string, version?: string) => Promise; +export type RequestHelmChartReadme = (repo: string, name: string, version?: string) => Promise>; const requestHelmChartReadmeInjectable = getInjectable({ id: "request-helm-chart-readme", diff --git a/src/features/helm-charts/installing-chart/__snapshots__/opening-dock-tab-for-installing-helm-chart.test.ts.snap b/src/features/helm-charts/installing-chart/__snapshots__/opening-dock-tab-for-installing-helm-chart.test.ts.snap index bdd6779b76..e949e6c3c6 100644 --- a/src/features/helm-charts/installing-chart/__snapshots__/opening-dock-tab-for-installing-helm-chart.test.ts.snap +++ b/src/features/helm-charts/installing-chart/__snapshots__/opening-dock-tab-for-installing-helm-chart.test.ts.snap @@ -4631,6 +4631,919 @@ exports[`opening dock tab for installing helm chart given application is started `; +exports[`opening dock tab for installing helm chart given application is started, when navigating to helm charts when charts resolve when opening details of a chart when chart versions resolve when readme resolves when selecting different version when readme rejects renders 1`] = ` + +
+
+
+
@@ -1110,7 +1110,7 @@ exports[` when clicked when 'test-2' is clicked when cl - test-11 + test-7
@@ -1134,7 +1134,7 @@ exports[` when clicked when 'test-2' is clicked when cl - test-12 + test-8 @@ -1158,7 +1158,7 @@ exports[` when clicked when 'test-2' is clicked when cl - test-13 + test-9 @@ -1168,7 +1168,7 @@ exports[` when clicked when 'test-2' is clicked when cl `; -exports[` when clicked when 'test-2' is clicked when clicked again when 'test-1' is clicked renders 1`] = ` +exports[` once the subscribe resolves when clicked when 'test-2' is clicked when clicked again when 'test-1' is clicked renders 1`] = `
when clicked when 'test-2' is clicked when cl `; -exports[` when clicked when 'test-2' is clicked when clicked again when 'test-1' is clicked when clicked again, then holding down multi select key when 'test-3' is clicked renders 1`] = ` +exports[` once the subscribe resolves when clicked when 'test-2' is clicked when clicked again when 'test-1' is clicked when clicked again, then holding down multi select key when 'test-3' is clicked renders 1`] = `
when clicked when 'test-2' is clicked when cl class="Select__option css-10wo9uf-option" id="react-select-namespace-select-filter-option-2" tabindex="-1" + > +
+ + + layers + + + + test-10 + +
+
+
+
+ + + layers + + + + test-11 + +
+
+
+
+ + + layers + + + + test-12 + +
+
+
+
+ + + layers + + + + test-13 + +
+
+
when clicked when 'test-2' is clicked when cl
when clicked when 'test-2' is clicked when cl
when clicked when 'test-2' is clicked when cl
when clicked when 'test-2' is clicked when cl
when clicked when 'test-2' is clicked when cl
when clicked when 'test-2' is clicked when cl
when clicked when 'test-2' is clicked when cl
when clicked when 'test-2' is clicked when cl
-
-
- - - layers - - - - test-10 - -
-
-
-
- - - layers - - - - test-11 - -
-
-
-
- - - layers - - - - test-12 - -
-
-
-
- - - layers - - - - test-13 - -
-
diff --git a/src/renderer/components/+namespaces/namespace-select-filter.test.tsx b/src/renderer/components/+namespaces/namespace-select-filter.test.tsx index a81e32e263..0a4626b251 100644 --- a/src/renderer/components/+namespaces/namespace-select-filter.test.tsx +++ b/src/renderer/components/+namespaces/namespace-select-filter.test.tsx @@ -3,14 +3,25 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ +import type { AsyncFnMock } from "@async-fn/jest"; +import asyncFn from "@async-fn/jest"; import type { DiContainer } from "@ogre-tools/injectable"; import type { RenderResult } from "@testing-library/react"; import { fireEvent } from "@testing-library/react"; import React from "react"; +import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; +import type { Fetch } from "../../../common/fetch/fetch.injectable"; +import fetchInjectable from "../../../common/fetch/fetch.injectable"; import { Namespace } from "../../../common/k8s-api/endpoints"; +import { createMockResponseFromString } from "../../../test-utils/mock-responses"; +import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; +import createClusterInjectable from "../../cluster/create-cluster.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; +import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; +import type { Disposer } from "../../utils"; +import { disposer } from "../../utils"; import { renderFor } from "../test-utils/renderFor"; import { NamespaceSelectFilter } from "./namespace-select-filter"; import type { NamespaceStore } from "./store"; @@ -32,147 +43,197 @@ function createNamespace(name: string): Namespace { describe("", () => { let di: DiContainer; let namespaceStore: NamespaceStore; + let fetchMock: AsyncFnMock; let result: RenderResult; + let cleanup: Disposer; beforeEach(() => { di = getDiForUnitTesting({ doGeneralOverrides: true }); - di.override(directoryForUserDataInjectable, () => "/some-directory"); + di.unoverride(subscribeStoresInjectable); + + di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); + di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); di.override(storesAndApisCanBeCreatedInjectable, () => true); + + const createCluster = di.inject(createClusterInjectable); + + di.override(hostedClusterInjectable, () => createCluster({ + contextName: "some-context-name", + id: "some-cluster-id", + kubeConfigPath: "/some-path-to-a-kubeconfig", + }, { + clusterServerUrl: "https://localhost:8080", + })); + namespaceStore = di.inject(namespaceStoreInjectable); - const render = renderFor(di); + const subscribeStores = di.inject(subscribeStoresInjectable); - namespaceStore.items.replace([ - createNamespace("test-1"), - createNamespace("test-2"), - createNamespace("test-3"), - createNamespace("test-4"), - createNamespace("test-5"), - createNamespace("test-6"), - createNamespace("test-7"), - createNamespace("test-8"), - createNamespace("test-9"), - createNamespace("test-10"), - createNamespace("test-11"), - createNamespace("test-12"), - createNamespace("test-13"), - ]); + cleanup = disposer(subscribeStores([namespaceStore])); + + fetchMock = asyncFn(); + di.override(fetchInjectable, () => fetchMock); + + const render = renderFor(di); result = render(( )); }); - it("renders", () => { - expect(result.baseElement).toMatchSnapshot(); + afterEach(() => { + cleanup(); }); - describe("when clicked", () => { - beforeEach(() => { - result.getByTestId("namespace-select-filter").click(); + describe("once the subscribe resolves", () => { + beforeEach(async () => { + await fetchMock.resolveSpecific([ + "http://127.0.0.1:12345/api-kube/api/v1/namespaces", + ], createMockResponseFromString("http://127.0.0.1:12345/api-kube/api/v1/namespaces", JSON.stringify({ + apiVersion: "v1", + kind: "NamespaceList", + metadata: {}, + items: [ + createNamespace("test-1"), + createNamespace("test-2"), + createNamespace("test-3"), + createNamespace("test-4"), + createNamespace("test-5"), + createNamespace("test-6"), + createNamespace("test-7"), + createNamespace("test-8"), + createNamespace("test-9"), + createNamespace("test-10"), + createNamespace("test-11"), + createNamespace("test-12"), + createNamespace("test-13"), + ], + }))); }); it("renders", () => { expect(result.baseElement).toMatchSnapshot(); }); - it("opens menu", () => { - expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).not.toBeNull(); - }); - - describe("when 'test-2' is clicked", () => { + describe("when clicked", () => { beforeEach(() => { - result.getByText("test-2").click(); + result.getByTestId("namespace-select-filter").click(); }); it("renders", () => { expect(result.baseElement).toMatchSnapshot(); }); - it("has only 'test-2' is selected in the store", () => { - expect(namespaceStore.contextNamespaces).toEqual(["test-2"]); + it("opens menu", () => { + expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).not.toBeNull(); }); - it("closes menu", () => { - expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).toBeNull(); - }); - - describe("when clicked again", () => { + describe("when 'test-2' is clicked", () => { beforeEach(() => { - result.getByTestId("namespace-select-filter").click(); + result.getByText("test-2").click(); }); it("renders", () => { expect(result.baseElement).toMatchSnapshot(); }); - it("shows 'test-2' as selected", () => { - expect(result.queryByTestId("namespace-select-filter-option-test-2-selected")).not.toBeNull(); + it("has only 'test-2' is selected in the store", () => { + expect(namespaceStore.contextNamespaces).toEqual(["test-2"]); }); - it("does not show 'test-1' as selected", () => { - expect(result.queryByTestId("namespace-select-filter-option-test-1-selected")).toBeNull(); + it("closes menu", () => { + expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).toBeNull(); }); - describe("when 'test-1' is clicked", () => { + describe("when clicked again", () => { beforeEach(() => { - result.getByText("test-1").click(); + result.getByTestId("namespace-select-filter").click(); }); it("renders", () => { expect(result.baseElement).toMatchSnapshot(); }); - it("has only 'test-1' is selected in the store", () => { - expect(namespaceStore.contextNamespaces).toEqual(["test-1"]); + it("shows 'test-2' as selected", () => { + expect(result.queryByTestId("namespace-select-filter-option-test-2-selected")).not.toBeNull(); }); - it("closes menu", () => { - expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).toBeNull(); + it("does not show 'test-1' as selected", () => { + expect(result.queryByTestId("namespace-select-filter-option-test-1-selected")).toBeNull(); }); - describe("when clicked again, then holding down multi select key", () => { + describe("when 'test-1' is clicked", () => { beforeEach(() => { - const filter = result.getByTestId("namespace-select-filter"); - - filter.click(); - fireEvent.keyDown(filter, { key: "Meta" }); + result.getByText("test-1").click(); }); - describe("when 'test-3' is clicked", () => { + it("renders", () => { + expect(result.baseElement).toMatchSnapshot(); + }); + + it("has only 'test-1' is selected in the store", () => { + expect(namespaceStore.contextNamespaces).toEqual(["test-1"]); + }); + + it("closes menu", () => { + expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).toBeNull(); + }); + + describe("when clicked again, then holding down multi select key", () => { beforeEach(() => { - result.getByText("test-3").click(); + const filter = result.getByTestId("namespace-select-filter"); + + filter.click(); + fireEvent.keyDown(filter, { key: "Meta" }); }); - it("renders", () => { - expect(result.baseElement).toMatchSnapshot(); - }); - - it("has both 'test-1' and 'test-3' as selected in the store", () => { - expect(new Set(namespaceStore.contextNamespaces)).toEqual(new Set(["test-1", "test-3"])); - }); - - it("keeps menu open", () => { - expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).not.toBeNull(); - }); - - it("does not show 'kube-system' as selected", () => { - expect(result.queryByTestId("namespace-select-filter-option-kube-system-selected")).toBeNull(); - }); - - describe("when 'test-13' is clicked", () => { + describe("when 'test-3' is clicked", () => { beforeEach(() => { - result.getByText("test-13").click(); + result.getByText("test-3").click(); }); - it("has all of 'test-1', 'test-3', and 'test-13' selected in the store", () => { - expect(new Set(namespaceStore.contextNamespaces)).toEqual(new Set(["test-1", "test-3", "test-13"])); + it("renders", () => { + expect(result.baseElement).toMatchSnapshot(); }); - it("'test-13' is not sorted to the top of the list", () => { - const topLevelElement = result.getByText("test-13").parentElement?.parentElement as HTMLElement; + it("has both 'test-1' and 'test-3' as selected in the store", () => { + expect(new Set(namespaceStore.contextNamespaces)).toEqual(new Set(["test-1", "test-3"])); + }); - expect(topLevelElement.nextSibling).toBe(null); + it("keeps menu open", () => { + expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).not.toBeNull(); + }); + + it("does not show 'kube-system' as selected", () => { + expect(result.queryByTestId("namespace-select-filter-option-kube-system-selected")).toBeNull(); + }); + + describe("when 'test-13' is clicked", () => { + beforeEach(() => { + result.getByText("test-13").click(); + }); + + it("has all of 'test-1', 'test-3', and 'test-13' selected in the store", () => { + expect(new Set(namespaceStore.contextNamespaces)).toEqual(new Set(["test-1", "test-3", "test-13"])); + }); + + it("'test-13' is not sorted to the top of the list", () => { + const topLevelElement = result.getByText("test-13").parentElement?.parentElement as HTMLElement; + + expect(topLevelElement.previousSibling).not.toBe(null); + }); + }); + + describe("when releasing multi select key", () => { + beforeEach(() => { + const filter = result.getByTestId("namespace-select-filter"); + + fireEvent.keyUp(filter, { key: "Meta" }); + }); + + it("closes menu", () => { + expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).toBeNull(); + }); }); }); @@ -183,46 +244,24 @@ describe("", () => { fireEvent.keyUp(filter, { key: "Meta" }); }); - it("closes menu", () => { - expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).toBeNull(); + it("keeps menu open", () => { + expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).not.toBeNull(); }); }); }); - - describe("when releasing multi select key", () => { - beforeEach(() => { - const filter = result.getByTestId("namespace-select-filter"); - - fireEvent.keyUp(filter, { key: "Meta" }); - }); - - it("keeps menu open", () => { - expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).not.toBeNull(); - }); - }); }); }); }); - }); - describe("when multi-selection key is pressed", () => { - beforeEach(() => { - const filter = result.getByTestId("namespace-select-filter"); - - fireEvent.keyDown(filter, { key: "Meta" }); - }); - - it("should show placeholder text as 'All namespaces'", () => { - expect(result.baseElement.querySelector("#react-select-namespace-select-filter-placeholder")).toHaveTextContent("All namespaces"); - }); - - describe("when 'test-2' is clicked", () => { + describe("when multi-selection key is pressed", () => { beforeEach(() => { - result.getByText("test-2").click(); + const filter = result.getByTestId("namespace-select-filter"); + + fireEvent.keyDown(filter, { key: "Meta" }); }); - it("should not show placeholder text as 'All namespaces'", () => { - expect(result.baseElement.querySelector("#react-select-namespace-select-filter-placeholder")).not.toHaveTextContent("All namespaces"); + it("should show placeholder text as 'All namespaces'", () => { + expect(result.baseElement.querySelector("#react-select-namespace-select-filter-placeholder")).toHaveTextContent("All namespaces"); }); describe("when 'test-2' is clicked", () => { @@ -230,20 +269,30 @@ describe("", () => { result.getByText("test-2").click(); }); - it("should not show placeholder as 'All namespaces'", () => { + it("should not show placeholder text as 'All namespaces'", () => { expect(result.baseElement.querySelector("#react-select-namespace-select-filter-placeholder")).not.toHaveTextContent("All namespaces"); }); - describe("when multi-selection key is raised", () => { + describe("when 'test-2' is clicked", () => { beforeEach(() => { - const filter = result.getByTestId("namespace-select-filter"); - - fireEvent.keyUp(filter, { key: "Meta" }); + result.getByText("test-2").click(); }); - it("should show placeholder text as 'All namespaces'", () => { + it("should not show placeholder as 'All namespaces'", () => { expect(result.baseElement.querySelector("#react-select-namespace-select-filter-placeholder")).not.toHaveTextContent("All namespaces"); }); + + describe("when multi-selection key is raised", () => { + beforeEach(() => { + const filter = result.getByTestId("namespace-select-filter"); + + fireEvent.keyUp(filter, { key: "Meta" }); + }); + + it("should show placeholder text as 'All namespaces'", () => { + expect(result.baseElement.querySelector("#react-select-namespace-select-filter-placeholder")).not.toHaveTextContent("All namespaces"); + }); + }); }); }); }); diff --git a/src/renderer/components/+namespaces/store.injectable.ts b/src/renderer/components/+namespaces/store.injectable.ts index 68d611e837..eb2a7e4a35 100644 --- a/src/renderer/components/+namespaces/store.injectable.ts +++ b/src/renderer/components/+namespaces/store.injectable.ts @@ -9,6 +9,8 @@ import createStorageInjectable from "../../utils/create-storage/create-storage.i import namespaceApiInjectable from "../../../common/k8s-api/endpoints/namespace.api.injectable"; import assert from "assert"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; +import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; +import clusterConfiguredAccessibleNamespacesInjectable from "../../cluster/accessible-namespaces.injectable"; const namespaceStoreInjectable = getInjectable({ id: "namespace-store", @@ -20,7 +22,9 @@ const namespaceStoreInjectable = getInjectable({ const api = di.inject(namespaceApiInjectable); return new NamespaceStore({ + context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable), storage: createStorage("selected_namespaces", undefined), + clusterConfiguredAccessibleNamespaces: di.inject(clusterConfiguredAccessibleNamespacesInjectable), }, api); }, injectionToken: kubeObjectStoreInjectionToken, diff --git a/src/renderer/components/+namespaces/store.ts b/src/renderer/components/+namespaces/store.ts index 1b2342facf..4c178a8a96 100644 --- a/src/renderer/components/+namespaces/store.ts +++ b/src/renderer/components/+namespaces/store.ts @@ -3,22 +3,23 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { IReactionDisposer } from "mobx"; +import type { IComputedValue, IReactionDisposer } from "mobx"; import { action, comparer, computed, makeObservable, reaction } from "mobx"; import type { StorageLayer } from "../../utils"; import { autoBind, noop, toggle } from "../../utils"; -import type { KubeObjectStoreLoadingParams } from "../../../common/k8s-api/kube-object.store"; +import type { KubeObjectStoreDependencies, KubeObjectStoreLoadingParams } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; import type { NamespaceApi } from "../../../common/k8s-api/endpoints/namespace.api"; import { Namespace } from "../../../common/k8s-api/endpoints/namespace.api"; -interface Dependencies { - storage: StorageLayer; +interface Dependencies extends KubeObjectStoreDependencies { + readonly storage: StorageLayer; + readonly clusterConfiguredAccessibleNamespaces: IComputedValue; } export class NamespaceStore extends KubeObjectStore { constructor(protected readonly dependencies: Dependencies, api: NamespaceApi) { - super(api); + super(dependencies, api); makeObservable(this); autoBind(this); @@ -26,11 +27,21 @@ export class NamespaceStore extends KubeObjectStore { } private async init() { - await this.contextReady; await this.dependencies.storage.whenReady; - this.selectNamespaces(this.initialNamespaces); - this.autoLoadAllowedNamespaces(); + const { allowedNamespaces } = this; + const selectedNamespaces = this.dependencies.storage.get(); // raw namespaces, undefined on first load + + // return previously saved namespaces from local-storage (if any) + if (Array.isArray(selectedNamespaces)) { + this.selectNamespaces(selectedNamespaces.filter(namespace => allowedNamespaces.includes(namespace))); + } else if (allowedNamespaces.includes("default")) { + this.selectNamespaces(["default"]); + } else if (allowedNamespaces.length) { + this.selectNamespaces([allowedNamespaces[0]]); + } else { + this.selectNamespaces([]); + } } public onContextChange(callback: (namespaces: string[]) => void, opts: { fireImmediately?: boolean } = {}): IReactionDisposer { @@ -40,32 +51,6 @@ export class NamespaceStore extends KubeObjectStore { }); } - private autoLoadAllowedNamespaces(): IReactionDisposer { - return reaction(() => this.allowedNamespaces, namespaces => this.loadAll({ namespaces }), { - fireImmediately: true, - equals: comparer.shallow, - }); - } - - private get initialNamespaces(): string[] { - const { allowedNamespaces } = this; - const selectedNamespaces = this.dependencies.storage.get(); // raw namespaces, undefined on first load - - // return previously saved namespaces from local-storage (if any) - if (Array.isArray(selectedNamespaces)) { - return selectedNamespaces.filter(namespace => allowedNamespaces.includes(namespace)); - } - - // otherwise select "default" or first allowed namespace - if (allowedNamespaces.includes("default")) { - return ["default"]; - } else if (allowedNamespaces.length) { - return [allowedNamespaces[0]]; - } - - return []; - } - /** * @private * The current value (list of namespaces names) in the storage layer @@ -75,10 +60,7 @@ export class NamespaceStore extends KubeObjectStore { } @computed get allowedNamespaces(): string[] { - return Array.from(new Set([ - ...(this.context?.allNamespaces ?? []), // allowed namespaces from cluster (main), updating every 30s - ...this.items.map(item => item.getName()), // loaded namespaces from k8s api - ].flat())); + return this.items.map(item => item.getName()); } /** @@ -110,11 +92,13 @@ export class NamespaceStore extends KubeObjectStore { } subscribe() { + const clusterConfiguredAccessibleNamespaces = this.dependencies.clusterConfiguredAccessibleNamespaces.get(); + /** * if user has given static list of namespaces let's not start watches * because watch adds stuff that's not wanted or will just fail */ - if ((this.context?.cluster.accessibleNamespaces.length ?? 0) > 0) { + if (clusterConfiguredAccessibleNamespaces.length > 0) { return noop; } @@ -122,17 +106,13 @@ export class NamespaceStore extends KubeObjectStore { } protected async loadItems(params: KubeObjectStoreLoadingParams): Promise { - const { allowedNamespaces } = this; + const clusterConfiguredAccessibleNamespaces = this.dependencies.clusterConfiguredAccessibleNamespaces.get(); - let namespaces = await super.loadItems(params).catch(() => []); - - namespaces = namespaces.filter(namespace => allowedNamespaces.includes(namespace.getName())); - - if (!namespaces.length && allowedNamespaces.length > 0) { - return allowedNamespaces.map(getDummyNamespace); + if (clusterConfiguredAccessibleNamespaces.length > 0) { + return clusterConfiguredAccessibleNamespaces.map(getDummyNamespace); } - return namespaces; + return super.loadItems(params); } @action selectNamespaces = (namespace: string | string[]) => { diff --git a/src/renderer/components/+network-endpoints/store.injectable.ts b/src/renderer/components/+network-endpoints/store.injectable.ts index a63014ea70..7531b933b3 100644 --- a/src/renderer/components/+network-endpoints/store.injectable.ts +++ b/src/renderer/components/+network-endpoints/store.injectable.ts @@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import endpointsApiInjectable from "../../../common/k8s-api/endpoints/endpoint.api.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { EndpointsStore } from "./store"; @@ -16,7 +17,9 @@ const endpointsStoreInjectable = getInjectable({ const api = di.inject(endpointsApiInjectable); - return new EndpointsStore(api); + return new EndpointsStore({ + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+network-ingresses/store.injectable.ts b/src/renderer/components/+network-ingresses/store.injectable.ts index 9b95939e9f..0084a006a2 100644 --- a/src/renderer/components/+network-ingresses/store.injectable.ts +++ b/src/renderer/components/+network-ingresses/store.injectable.ts @@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import ingressApiInjectable from "../../../common/k8s-api/endpoints/ingress.api.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { IngressStore } from "./store"; @@ -16,7 +17,9 @@ const ingressStoreInjectable = getInjectable({ const api = di.inject(ingressApiInjectable); - return new IngressStore(api); + return new IngressStore({ + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+network-policies/store.injectable.ts b/src/renderer/components/+network-policies/store.injectable.ts index a666c04cb4..ad79a89b54 100644 --- a/src/renderer/components/+network-policies/store.injectable.ts +++ b/src/renderer/components/+network-policies/store.injectable.ts @@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import networkPolicyApiInjectable from "../../../common/k8s-api/endpoints/network-policy.api.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { NetworkPolicyStore } from "./store"; @@ -16,7 +17,9 @@ const networkPolicyStoreInjectable = getInjectable({ const api = di.inject(networkPolicyApiInjectable); - return new NetworkPolicyStore(api); + return new NetworkPolicyStore({ + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+network-services/store.injectable.ts b/src/renderer/components/+network-services/store.injectable.ts index 6013a97f15..e54f994162 100644 --- a/src/renderer/components/+network-services/store.injectable.ts +++ b/src/renderer/components/+network-services/store.injectable.ts @@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import serviceApiInjectable from "../../../common/k8s-api/endpoints/service.api.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { ServiceStore } from "./store"; @@ -16,7 +17,9 @@ const serviceStoreInjectable = getInjectable({ const api = di.inject(serviceApiInjectable); - return new ServiceStore(api); + return new ServiceStore({ + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+nodes/store.injectable.ts b/src/renderer/components/+nodes/store.injectable.ts index adb69a99ad..ac149210bd 100644 --- a/src/renderer/components/+nodes/store.injectable.ts +++ b/src/renderer/components/+nodes/store.injectable.ts @@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import nodeApiInjectable from "../../../common/k8s-api/endpoints/node.api.injectable"; +import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { NodeStore } from "./store"; @@ -16,7 +17,9 @@ const nodeStoreInjectable = getInjectable({ const api = di.inject(nodeApiInjectable); - return new NodeStore(api); + return new NodeStore({ + context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+nodes/store.ts b/src/renderer/components/+nodes/store.ts index 9f4be4b620..87fafa9256 100644 --- a/src/renderer/components/+nodes/store.ts +++ b/src/renderer/components/+nodes/store.ts @@ -6,13 +6,13 @@ import { sum } from "lodash"; import { computed, makeObservable } from "mobx"; import type { Node, NodeApi } from "../../../common/k8s-api/endpoints"; -import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; +import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; import { autoBind } from "../../utils"; export class NodeStore extends KubeObjectStore { - constructor(api: NodeApi, opts?: KubeObjectStoreOptions) { - super(api, opts); + constructor(dependencies: KubeObjectStoreDependencies, api: NodeApi, opts?: KubeObjectStoreOptions) { + super(dependencies, api, opts); makeObservable(this); autoBind(this); diff --git a/src/renderer/components/+pod-security-policies/store.injectable.ts b/src/renderer/components/+pod-security-policies/store.injectable.ts index b010b60c97..44ab372d70 100644 --- a/src/renderer/components/+pod-security-policies/store.injectable.ts +++ b/src/renderer/components/+pod-security-policies/store.injectable.ts @@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import podSecurityPolicyApiInjectable from "../../../common/k8s-api/endpoints/pod-security-policy.api.injectable"; +import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { PodSecurityPolicyStore } from "./store"; @@ -16,7 +17,9 @@ const podSecurityPolicyStoreInjectable = getInjectable({ const api = di.inject(podSecurityPolicyApiInjectable); - return new PodSecurityPolicyStore(api); + return new PodSecurityPolicyStore({ + context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+storage-classes/store.injectable.ts b/src/renderer/components/+storage-classes/store.injectable.ts index ab4ae8c784..17f6da93db 100644 --- a/src/renderer/components/+storage-classes/store.injectable.ts +++ b/src/renderer/components/+storage-classes/store.injectable.ts @@ -7,6 +7,7 @@ import assert from "assert"; import getPersistentVolumesByStorageClassInjectable from "../+storage-volumes/get-persisten-volumes-by-storage-class.injectable"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import storageClassApiInjectable from "../../../common/k8s-api/endpoints/storage-class.api.injectable"; +import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { StorageClassStore } from "./store"; @@ -19,6 +20,7 @@ const storageClassStoreInjectable = getInjectable({ return new StorageClassStore({ getPersistentVolumesByStorageClass: di.inject(getPersistentVolumesByStorageClassInjectable), + context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable), }, api); }, injectionToken: kubeObjectStoreInjectionToken, diff --git a/src/renderer/components/+storage-classes/store.ts b/src/renderer/components/+storage-classes/store.ts index 8037a8d67d..8c01c145b3 100644 --- a/src/renderer/components/+storage-classes/store.ts +++ b/src/renderer/components/+storage-classes/store.ts @@ -3,12 +3,12 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; +import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; import type { StorageClass, StorageClassApi, StorageClassData } from "../../../common/k8s-api/endpoints/storage-class.api"; import type { GetPersistentVolumesByStorageClass } from "../+storage-volumes/get-persisten-volumes-by-storage-class.injectable"; -export interface StorageClassStoreDependencies { +export interface StorageClassStoreDependencies extends KubeObjectStoreDependencies { getPersistentVolumesByStorageClass: GetPersistentVolumesByStorageClass; } @@ -18,7 +18,7 @@ export class StorageClassStore extends KubeObjectStore { let render: DiRender; @@ -20,8 +23,19 @@ describe("ClusterRoleBindingDialog tests", () => { beforeEach(() => { const di = getDiForUnitTesting({ doGeneralOverrides: true }); + di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); + di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); di.override(storesAndApisCanBeCreatedInjectable, () => true); - di.override(directoryForUserDataInjectable, () => "/some-path-for-user-data"); + + const createCluster = di.inject(createClusterInjectable); + + di.override(hostedClusterInjectable, () => createCluster({ + contextName: "some-context-name", + id: "some-cluster-id", + kubeConfigPath: "/some-path-to-a-kubeconfig", + }, { + clusterServerUrl: "https://localhost:8080", + })); render = renderFor(di); diff --git a/src/renderer/components/+user-management/+cluster-role-bindings/store.injectable.ts b/src/renderer/components/+user-management/+cluster-role-bindings/store.injectable.ts index afaf3e7400..a2e3223fa7 100644 --- a/src/renderer/components/+user-management/+cluster-role-bindings/store.injectable.ts +++ b/src/renderer/components/+user-management/+cluster-role-bindings/store.injectable.ts @@ -8,6 +8,7 @@ import { storesAndApisCanBeCreatedInjectionToken } from "../../../../common/k8s- import clusterRoleBindingApiInjectable from "../../../../common/k8s-api/endpoints/cluster-role-binding.api.injectable"; import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; import { ClusterRoleBindingStore } from "./store"; +import clusterFrameContextForClusterScopedResourcesInjectable from "../../../cluster-frame-context/for-cluster-scoped-resources.injectable"; const clusterRoleBindingStoreInjectable = getInjectable({ id: "cluster-role-binding-store", @@ -16,7 +17,9 @@ const clusterRoleBindingStoreInjectable = getInjectable({ const api = di.inject(clusterRoleBindingApiInjectable); - return new ClusterRoleBindingStore(api); + return new ClusterRoleBindingStore({ + context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+user-management/+cluster-roles/store.injectable.ts b/src/renderer/components/+user-management/+cluster-roles/store.injectable.ts index bfd83f3b3b..9ae877f635 100644 --- a/src/renderer/components/+user-management/+cluster-roles/store.injectable.ts +++ b/src/renderer/components/+user-management/+cluster-roles/store.injectable.ts @@ -8,6 +8,7 @@ import { storesAndApisCanBeCreatedInjectionToken } from "../../../../common/k8s- import clusterRoleApiInjectable from "../../../../common/k8s-api/endpoints/cluster-role.api.injectable"; import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; import { ClusterRoleStore } from "./store"; +import clusterFrameContextForClusterScopedResourcesInjectable from "../../../cluster-frame-context/for-cluster-scoped-resources.injectable"; const clusterRoleStoreInjectable = getInjectable({ id: "cluster-role-store", @@ -16,7 +17,9 @@ const clusterRoleStoreInjectable = getInjectable({ const api = di.inject(clusterRoleApiInjectable); - return new ClusterRoleStore(api); + return new ClusterRoleStore({ + context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+user-management/+role-bindings/__tests__/dialog.test.tsx b/src/renderer/components/+user-management/+role-bindings/__tests__/dialog.test.tsx index 82e3a7c9d7..08067ed817 100644 --- a/src/renderer/components/+user-management/+role-bindings/__tests__/dialog.test.tsx +++ b/src/renderer/components/+user-management/+role-bindings/__tests__/dialog.test.tsx @@ -13,6 +13,9 @@ import { renderFor } from "../../../test-utils/renderFor"; import directoryForUserDataInjectable from "../../../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; import clusterRoleStoreInjectable from "../../+cluster-roles/store.injectable"; import storesAndApisCanBeCreatedInjectable from "../../../../stores-apis-can-be-created.injectable"; +import directoryForKubeConfigsInjectable from "../../../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; +import hostedClusterInjectable from "../../../../cluster-frame-context/hosted-cluster.injectable"; +import createClusterInjectable from "../../../../cluster/create-cluster.injectable"; describe("RoleBindingDialog tests", () => { let render: DiRender; @@ -20,8 +23,19 @@ describe("RoleBindingDialog tests", () => { beforeEach(() => { const di = getDiForUnitTesting({ doGeneralOverrides: true }); + di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); + di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); di.override(storesAndApisCanBeCreatedInjectable, () => true); - di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data"); + + const createCluster = di.inject(createClusterInjectable); + + di.override(hostedClusterInjectable, () => createCluster({ + contextName: "some-context-name", + id: "some-cluster-id", + kubeConfigPath: "/some-path-to-a-kubeconfig", + }, { + clusterServerUrl: "https://localhost:8080", + })); render = renderFor(di); diff --git a/src/renderer/components/+user-management/+role-bindings/store.injectable.ts b/src/renderer/components/+user-management/+role-bindings/store.injectable.ts index 20122b47d6..a3f33e76bc 100644 --- a/src/renderer/components/+user-management/+role-bindings/store.injectable.ts +++ b/src/renderer/components/+user-management/+role-bindings/store.injectable.ts @@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; import roleBindingApiInjectable from "../../../../common/k8s-api/endpoints/role-binding.api.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable"; import { RoleBindingStore } from "./store"; @@ -16,7 +17,9 @@ const roleBindingStoreInjectable = getInjectable({ const api = di.inject(roleBindingApiInjectable); - return new RoleBindingStore(api); + return new RoleBindingStore({ + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+user-management/+roles/store.injectable.ts b/src/renderer/components/+user-management/+roles/store.injectable.ts index ac10dc831b..8b86ddb0ab 100644 --- a/src/renderer/components/+user-management/+roles/store.injectable.ts +++ b/src/renderer/components/+user-management/+roles/store.injectable.ts @@ -8,6 +8,7 @@ import roleApiInjectable from "../../../../common/k8s-api/endpoints/role.api.inj import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable"; import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; import { RoleStore } from "./store"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable"; const roleStoreInjectable = getInjectable({ id: "role-store", @@ -16,7 +17,9 @@ const roleStoreInjectable = getInjectable({ const api = di.inject(roleApiInjectable); - return new RoleStore(api); + return new RoleStore({ + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+user-management/+service-accounts/store.injectable.ts b/src/renderer/components/+user-management/+service-accounts/store.injectable.ts index 75b4b791d5..98570c9017 100644 --- a/src/renderer/components/+user-management/+service-accounts/store.injectable.ts +++ b/src/renderer/components/+user-management/+service-accounts/store.injectable.ts @@ -8,6 +8,7 @@ import serviceAccountApiInjectable from "../../../../common/k8s-api/endpoints/se import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable"; import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; import { ServiceAccountStore } from "./store"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable"; const serviceAccountStoreInjectable = getInjectable({ id: "service-account-store", @@ -16,7 +17,9 @@ const serviceAccountStoreInjectable = getInjectable({ const api = di.inject(serviceAccountApiInjectable); - return new ServiceAccountStore(api); + return new ServiceAccountStore({ + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), + }, api); }, injectionToken: kubeObjectStoreInjectionToken, }); diff --git a/src/renderer/components/+workloads-cronjobs/store.injectable.ts b/src/renderer/components/+workloads-cronjobs/store.injectable.ts index a71352685f..6b0fab2c9c 100644 --- a/src/renderer/components/+workloads-cronjobs/store.injectable.ts +++ b/src/renderer/components/+workloads-cronjobs/store.injectable.ts @@ -7,6 +7,7 @@ import assert from "assert"; import getJobsByOwnerInjectable from "../+workloads-jobs/get-jobs-by-owner.injectable"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import cronJobApiInjectable from "../../../common/k8s-api/endpoints/cron-job.api.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { CronJobStore } from "./store"; @@ -19,6 +20,7 @@ const cronJobStoreInjectable = getInjectable({ return new CronJobStore({ getJobsByOwner: di.inject(getJobsByOwnerInjectable), + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), }, api); }, injectionToken: kubeObjectStoreInjectionToken, diff --git a/src/renderer/components/+workloads-cronjobs/store.ts b/src/renderer/components/+workloads-cronjobs/store.ts index 67e006ac90..fe6c765723 100644 --- a/src/renderer/components/+workloads-cronjobs/store.ts +++ b/src/renderer/components/+workloads-cronjobs/store.ts @@ -3,18 +3,18 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; +import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; import type { CronJob, CronJobApi } from "../../../common/k8s-api/endpoints/cron-job.api"; import type { GetJobsByOwner } from "../+workloads-jobs/get-jobs-by-owner.injectable"; -interface Dependencies { +interface Dependencies extends KubeObjectStoreDependencies { getJobsByOwner: GetJobsByOwner; } export class CronJobStore extends KubeObjectStore { constructor(protected readonly dependencies: Dependencies, api: CronJobApi, opts?: KubeObjectStoreOptions) { - super(api, opts); + super(dependencies, api, opts); } getStatuses(cronJobs?: CronJob[]) { diff --git a/src/renderer/components/+workloads-daemonsets/store.injectable.ts b/src/renderer/components/+workloads-daemonsets/store.injectable.ts index 3b7611dc43..5711ad625f 100644 --- a/src/renderer/components/+workloads-daemonsets/store.injectable.ts +++ b/src/renderer/components/+workloads-daemonsets/store.injectable.ts @@ -9,6 +9,7 @@ import daemonSetApiInjectable from "../../../common/k8s-api/endpoints/daemon-set import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import { DaemonSetStore } from "./store"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; const daemonSetStoreInjectable = getInjectable({ id: "daemon-set-store", @@ -19,6 +20,7 @@ const daemonSetStoreInjectable = getInjectable({ return new DaemonSetStore({ getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable), + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), }, api); }, injectionToken: kubeObjectStoreInjectionToken, diff --git a/src/renderer/components/+workloads-daemonsets/store.ts b/src/renderer/components/+workloads-daemonsets/store.ts index 66216e3f76..1345468b62 100644 --- a/src/renderer/components/+workloads-daemonsets/store.ts +++ b/src/renderer/components/+workloads-daemonsets/store.ts @@ -6,16 +6,16 @@ import type { GetPodsByOwnerId } from "../+workloads-pods/get-pods-by-owner-id.injectable"; import type { DaemonSet, DaemonSetApi, Pod } from "../../../common/k8s-api/endpoints"; import { PodStatusPhase } from "../../../common/k8s-api/endpoints"; -import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; +import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; -export interface DaemonSetStoreDependencies { +export interface DaemonSetStoreDependencies extends KubeObjectStoreDependencies { readonly getPodsByOwnerId: GetPodsByOwnerId; } export class DaemonSetStore extends KubeObjectStore { constructor(protected readonly dependencies: DaemonSetStoreDependencies, api: DaemonSetApi, opts?: KubeObjectStoreOptions) { - super(api, opts); + super(dependencies, api, opts); } getChildPods(daemonSet: DaemonSet): Pod[] { diff --git a/src/renderer/components/+workloads-deployments/store.injectable.ts b/src/renderer/components/+workloads-deployments/store.injectable.ts index 02eb3da48c..b77d9aa496 100644 --- a/src/renderer/components/+workloads-deployments/store.injectable.ts +++ b/src/renderer/components/+workloads-deployments/store.injectable.ts @@ -9,6 +9,7 @@ import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manag import { storesAndApisCanBeCreatedInjectionToken } from "../../../common/k8s-api/stores-apis-can-be-created.token"; import deploymentApiInjectable from "../../../common/k8s-api/endpoints/deployment.api.injectable"; import { DeploymentStore } from "./store"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; const deploymentStoreInjectable = getInjectable({ id: "deployment-store", @@ -19,6 +20,7 @@ const deploymentStoreInjectable = getInjectable({ return new DeploymentStore({ podStore: di.inject(podStoreInjectable), + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), }, api); }, injectionToken: kubeObjectStoreInjectionToken, diff --git a/src/renderer/components/+workloads-deployments/store.ts b/src/renderer/components/+workloads-deployments/store.ts index 014f1c2abc..af5d085594 100644 --- a/src/renderer/components/+workloads-deployments/store.ts +++ b/src/renderer/components/+workloads-deployments/store.ts @@ -6,7 +6,7 @@ import type { PodStore } from "../+workloads-pods/store"; import type { Deployment, DeploymentApi } from "../../../common/k8s-api/endpoints"; import { PodStatusPhase } from "../../../common/k8s-api/endpoints"; -import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; +import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; // This needs to be disables because of https://github.com/microsoft/TypeScript/issues/15300 @@ -17,13 +17,13 @@ export type DeploymentStatuses = { pending: number; }; -export interface DeploymentStoreDependencies { +export interface DeploymentStoreDependencies extends KubeObjectStoreDependencies { readonly podStore: PodStore; } export class DeploymentStore extends KubeObjectStore { constructor(protected readonly dependencies: DeploymentStoreDependencies, api: DeploymentApi, opts?: KubeObjectStoreOptions) { - super(api, opts); + super(dependencies, api, opts); } protected sortItems(items: Deployment[]) { diff --git a/src/renderer/components/+workloads-jobs/store.injectable.ts b/src/renderer/components/+workloads-jobs/store.injectable.ts index 46e4d26fb4..8f394a1bf5 100644 --- a/src/renderer/components/+workloads-jobs/store.injectable.ts +++ b/src/renderer/components/+workloads-jobs/store.injectable.ts @@ -7,6 +7,7 @@ import assert from "assert"; import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import jobApiInjectable from "../../../common/k8s-api/endpoints/job.api.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { JobStore } from "./store"; @@ -19,6 +20,7 @@ const jobStoreInjectable = getInjectable({ return new JobStore({ getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable), + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), }, api); }, injectionToken: kubeObjectStoreInjectionToken, diff --git a/src/renderer/components/+workloads-jobs/store.ts b/src/renderer/components/+workloads-jobs/store.ts index 47fc09d931..2f6f671aad 100644 --- a/src/renderer/components/+workloads-jobs/store.ts +++ b/src/renderer/components/+workloads-jobs/store.ts @@ -3,20 +3,20 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; +import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; import type { Job, JobApi } from "../../../common/k8s-api/endpoints/job.api"; import type { CronJob, Pod } from "../../../common/k8s-api/endpoints"; import { PodStatusPhase } from "../../../common/k8s-api/endpoints"; import type { GetPodsByOwnerId } from "../+workloads-pods/get-pods-by-owner-id.injectable"; -interface Dependencies { +interface Dependencies extends KubeObjectStoreDependencies { getPodsByOwnerId: GetPodsByOwnerId; } export class JobStore extends KubeObjectStore { constructor(protected readonly dependencies: Dependencies, api: JobApi, opts?: KubeObjectStoreOptions) { - super(api, opts); + super(dependencies, api, opts); } getChildPods(job: Job): Pod[] { diff --git a/src/renderer/components/+workloads-overview/overview-statuses.tsx b/src/renderer/components/+workloads-overview/overview-statuses.tsx index 2430409d30..19c81712a9 100644 --- a/src/renderer/components/+workloads-overview/overview-statuses.tsx +++ b/src/renderer/components/+workloads-overview/overview-statuses.tsx @@ -12,6 +12,7 @@ import { withInjectables } from "@ogre-tools/injectable-react"; import type { IComputedValue } from "mobx"; import workloadsInjectable from "./workloads/workloads.injectable"; import type { Workload } from "./workloads/workload-injection-token"; +import { formatKubeApiResource } from "../../../common/rbac"; export interface OverviewStatusesProps {} @@ -24,7 +25,7 @@ const NonInjectedOverviewStatuses = observer(
{workloads.get().map((workload) => ( -
+
{`${workload.title} (${workload.amountOfItems.get()})`} diff --git a/src/renderer/components/+workloads-overview/overview.tsx b/src/renderer/components/+workloads-overview/overview.tsx index 7c93bd429c..8b60676da2 100644 --- a/src/renderer/components/+workloads-overview/overview.tsx +++ b/src/renderer/components/+workloads-overview/overview.tsx @@ -17,8 +17,7 @@ import { NamespaceSelectFilter } from "../+namespaces/namespace-select-filter"; import { Icon } from "../icon"; import { TooltipPosition } from "../tooltip"; import { withInjectables } from "@ogre-tools/injectable-react"; -import clusterFrameContextInjectable from "../../cluster-frame-context/cluster-frame-context.injectable"; -import type { ClusterFrameContext } from "../../cluster-frame-context/cluster-frame-context"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api"; import workloadOverviewDetailsInjectable from "./workload-overview-details/workload-overview-details.injectable"; import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout"; @@ -35,10 +34,11 @@ import jobStoreInjectable from "../+workloads-jobs/store.injectable"; import statefulSetStoreInjectable from "../+workloads-statefulsets/store.injectable"; import type { EventStore } from "../+events/store"; import eventStoreInjectable from "../+events/store.injectable"; +import type { ClusterContext } from "../../cluster-frame-context/cluster-frame-context"; interface Dependencies { detailComponents: IComputedValue[]>; - clusterFrameContext: ClusterFrameContext; + clusterFrameContext: ClusterContext; subscribeStores: SubscribeStores; podStore: PodStore; daemonSetStore: DaemonSetStore; @@ -123,7 +123,7 @@ class NonInjectedWorkloadsOverview extends React.Component { export const WorkloadsOverview = withInjectables(NonInjectedWorkloadsOverview, { getProps: (di) => ({ detailComponents: di.inject(workloadOverviewDetailsInjectable), - clusterFrameContext: di.inject(clusterFrameContextInjectable), + clusterFrameContext: di.inject(clusterFrameContextForNamespacedResourcesInjectable), subscribeStores: di.inject(subscribeStoresInjectable), daemonSetStore: di.inject(daemonSetStoreInjectable), podStore: di.inject(podStoreInjectable), diff --git a/src/renderer/components/+workloads-overview/workloads/implementations/cron-jobs-workload.injectable.ts b/src/renderer/components/+workloads-overview/workloads/implementations/cron-jobs-workload.injectable.ts index b4e22d64ba..7e8ab5cf6e 100644 --- a/src/renderer/components/+workloads-overview/workloads/implementations/cron-jobs-workload.injectable.ts +++ b/src/renderer/components/+workloads-overview/workloads/implementations/cron-jobs-workload.injectable.ts @@ -19,17 +19,17 @@ const cronJobsWorkloadInjectable = getInjectable({ const store = di.inject(cronJobsStoreInjectable); return { - resourceName: "cronjobs", + resource: { + apiName: "cronjobs", + group: "batch", + }, open: navigate, - amountOfItems: computed( () => store.getAllByNs(namespaceStore.contextNamespaces).length, ), - status: computed(() => store.getStatuses(store.getAllByNs(namespaceStore.contextNamespaces)), ), - title: ResourceNames.cronjobs, orderNumber: 70, }; diff --git a/src/renderer/components/+workloads-overview/workloads/implementations/daemonsets-workload.injectable.ts b/src/renderer/components/+workloads-overview/workloads/implementations/daemonsets-workload.injectable.ts index 0124c0d1ce..7b6d7d750f 100644 --- a/src/renderer/components/+workloads-overview/workloads/implementations/daemonsets-workload.injectable.ts +++ b/src/renderer/components/+workloads-overview/workloads/implementations/daemonsets-workload.injectable.ts @@ -19,7 +19,10 @@ const daemonsetsWorkloadInjectable = getInjectable({ const store = di.inject(daemonsetsStoreInjectable); return { - resourceName: "daemonsets", + resource: { + apiName: "daemonsets", + group: "apps", + }, open: navigate, amountOfItems: computed( diff --git a/src/renderer/components/+workloads-overview/workloads/implementations/deployments-workload.injectable.ts b/src/renderer/components/+workloads-overview/workloads/implementations/deployments-workload.injectable.ts index 27ca74fe97..b41e4ea5ca 100644 --- a/src/renderer/components/+workloads-overview/workloads/implementations/deployments-workload.injectable.ts +++ b/src/renderer/components/+workloads-overview/workloads/implementations/deployments-workload.injectable.ts @@ -19,7 +19,10 @@ const deploymentsWorkloadInjectable = getInjectable({ const store = di.inject(deploymentsStoreInjectable); return { - resourceName: "deployments", + resource: { + apiName: "deployments", + group: "apps", + }, open: navigate, amountOfItems: computed( diff --git a/src/renderer/components/+workloads-overview/workloads/implementations/jobs-workload.injectable.ts b/src/renderer/components/+workloads-overview/workloads/implementations/jobs-workload.injectable.ts index 3442aabaf7..e68fd88c1c 100644 --- a/src/renderer/components/+workloads-overview/workloads/implementations/jobs-workload.injectable.ts +++ b/src/renderer/components/+workloads-overview/workloads/implementations/jobs-workload.injectable.ts @@ -19,7 +19,10 @@ const jobsWorkloadInjectable = getInjectable({ const store = di.inject(jobStoreInjectable); return { - resourceName: "jobs", + resource: { + apiName: "jobs", + group: "batch", + }, open: navigate, amountOfItems: computed( diff --git a/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts b/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts index 2a2afefe3a..452f7903aa 100644 --- a/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts +++ b/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts @@ -19,7 +19,10 @@ const podsWorkloadInjectable = getInjectable({ const store = di.inject(podStoreInjectable); return { - resourceName: "pods", + resource: { + apiName: "pods", + group: "v1", + }, open: navigate, amountOfItems: computed( diff --git a/src/renderer/components/+workloads-overview/workloads/implementations/replicasets-workload.injectable.ts b/src/renderer/components/+workloads-overview/workloads/implementations/replicasets-workload.injectable.ts index 6102e70b19..86189e4634 100644 --- a/src/renderer/components/+workloads-overview/workloads/implementations/replicasets-workload.injectable.ts +++ b/src/renderer/components/+workloads-overview/workloads/implementations/replicasets-workload.injectable.ts @@ -19,7 +19,10 @@ const replicasetsWorkloadInjectable = getInjectable({ const store = di.inject(replicasetsStoreInjectable); return { - resourceName: "replicasets", + resource: { + apiName: "replicasets", + group: "apps", + }, open: navigate, amountOfItems: computed( diff --git a/src/renderer/components/+workloads-overview/workloads/implementations/statefulsets-workload.injectable.ts b/src/renderer/components/+workloads-overview/workloads/implementations/statefulsets-workload.injectable.ts index 8a12f3c0af..19b85c4fa0 100644 --- a/src/renderer/components/+workloads-overview/workloads/implementations/statefulsets-workload.injectable.ts +++ b/src/renderer/components/+workloads-overview/workloads/implementations/statefulsets-workload.injectable.ts @@ -19,7 +19,10 @@ const statefulsetsWorkloadInjectable = getInjectable({ const store = di.inject(statefulsetsStoreInjectable); return { - resourceName: "statefulsets", + resource: { + apiName: "statefulsets", + group: "apps", + }, open: navigate, amountOfItems: computed( diff --git a/src/renderer/components/+workloads-overview/workloads/workload-injection-token.ts b/src/renderer/components/+workloads-overview/workloads/workload-injection-token.ts index decb5a1f7c..fca19148a7 100644 --- a/src/renderer/components/+workloads-overview/workloads/workload-injection-token.ts +++ b/src/renderer/components/+workloads-overview/workloads/workload-injection-token.ts @@ -4,10 +4,11 @@ */ import { getInjectionToken } from "@ogre-tools/injectable"; import type { IComputedValue } from "mobx"; +import type { KubeApiResourceDescriptor } from "../../../../common/rbac"; import type { WorkloadStatus } from "../overview-workload-status"; export interface Workload { - resourceName: string; + resource: KubeApiResourceDescriptor; open: () => void; amountOfItems: IComputedValue; status: IComputedValue; diff --git a/src/renderer/components/+workloads-overview/workloads/workloads.injectable.ts b/src/renderer/components/+workloads-overview/workloads/workloads.injectable.ts index aeaa62ed4a..d6b23b582f 100644 --- a/src/renderer/components/+workloads-overview/workloads/workloads.injectable.ts +++ b/src/renderer/components/+workloads-overview/workloads/workloads.injectable.ts @@ -2,18 +2,11 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { pipeline } from "@ogre-tools/fp"; import { getInjectable } from "@ogre-tools/injectable"; -import { filter, sortBy as sortByWithBadTyping } from "lodash/fp"; import { computed } from "mobx"; -import type { Workload } from "./workload-injection-token"; +import { shouldShowResourceInjectionToken } from "../../../../common/cluster-store/allowed-resources-injection-token"; +import { byOrderNumber } from "../../../../common/utils/composable-responsibilities/orderable/orderable"; import { workloadInjectionToken } from "./workload-injection-token"; -import isAllowedResourceInjectable from "../../../../common/utils/is-allowed-resource.injectable"; - -const sortBy = - (propertyPath: string) => - (collection: Collection[]) => - sortByWithBadTyping(propertyPath, collection); const workloadsInjectable = getInjectable({ id: "workloads", @@ -21,22 +14,11 @@ const workloadsInjectable = getInjectable({ instantiate: (di) => { const workloads = di.injectMany(workloadInjectionToken); - const isAllowedResource = (resourceName: string) => - di.inject(isAllowedResourceInjectable, resourceName); - - return computed(() => - pipeline( - workloads, - - filter((workload: Workload) => { - const isAllowed = isAllowedResource(workload.resourceName); - - return isAllowed.get(); - }), - - sortBy("orderNumber"), - ), - ); + return computed(() => ( + workloads + .filter(w => di.inject(shouldShowResourceInjectionToken, w.resource).get()) + .sort(byOrderNumber) + )); }, }); diff --git a/src/renderer/components/+workloads-pods/store.injectable.ts b/src/renderer/components/+workloads-pods/store.injectable.ts index 59b91b8c27..a1bf527bef 100644 --- a/src/renderer/components/+workloads-pods/store.injectable.ts +++ b/src/renderer/components/+workloads-pods/store.injectable.ts @@ -9,6 +9,7 @@ import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-create import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import { PodStore } from "./store"; import podMetricsApiInjectable from "../../../common/k8s-api/endpoints/pod-metrics.api.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; const podStoreInjectable = getInjectable({ id: "pod-store", @@ -19,6 +20,7 @@ const podStoreInjectable = getInjectable({ return new PodStore({ podMetricsApi: di.inject(podMetricsApiInjectable), + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), }, api); }, injectionToken: kubeObjectStoreInjectionToken, diff --git a/src/renderer/components/+workloads-pods/store.ts b/src/renderer/components/+workloads-pods/store.ts index 146eb0b390..5ce9dca041 100644 --- a/src/renderer/components/+workloads-pods/store.ts +++ b/src/renderer/components/+workloads-pods/store.ts @@ -5,13 +5,13 @@ import countBy from "lodash/countBy"; import { observable } from "mobx"; -import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; +import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; import { cpuUnitsToNumber, unitsToBytes } from "../../utils"; import type { Pod, PodMetrics, PodApi, PodMetricsApi } from "../../../common/k8s-api/endpoints"; import type { KubeObject, NamespaceScopedMetadata } from "../../../common/k8s-api/kube-object"; -export interface PodStoreDependencies { +export interface PodStoreDependencies extends KubeObjectStoreDependencies { readonly podMetricsApi: PodMetricsApi; } @@ -21,7 +21,7 @@ export class PodStore extends KubeObjectStore { api: PodApi, opts?: KubeObjectStoreOptions, ) { - super(api, opts); + super(dependencies, api, opts); } readonly kubeMetrics = observable.array([]); diff --git a/src/renderer/components/+workloads-replicasets/store.injectable.ts b/src/renderer/components/+workloads-replicasets/store.injectable.ts index 73da498071..c961e504ad 100644 --- a/src/renderer/components/+workloads-replicasets/store.injectable.ts +++ b/src/renderer/components/+workloads-replicasets/store.injectable.ts @@ -9,6 +9,7 @@ import replicaSetApiInjectable from "../../../common/k8s-api/endpoints/replica-s import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import { ReplicaSetStore } from "./store"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; const replicaSetStoreInjectable = getInjectable({ id: "replica-set-store", @@ -19,6 +20,7 @@ const replicaSetStoreInjectable = getInjectable({ return new ReplicaSetStore({ getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable), + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), }, api); }, injectionToken: kubeObjectStoreInjectionToken, diff --git a/src/renderer/components/+workloads-replicasets/store.ts b/src/renderer/components/+workloads-replicasets/store.ts index d782846cd0..1a6ac96610 100644 --- a/src/renderer/components/+workloads-replicasets/store.ts +++ b/src/renderer/components/+workloads-replicasets/store.ts @@ -6,16 +6,16 @@ import type { GetPodsByOwnerId } from "../+workloads-pods/get-pods-by-owner-id.injectable"; import type { Deployment, ReplicaSet, ReplicaSetApi } from "../../../common/k8s-api/endpoints"; import { PodStatusPhase } from "../../../common/k8s-api/endpoints/pod.api"; -import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; +import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; -interface Dependencies { +export interface ReplicaSetStoreDependencies extends KubeObjectStoreDependencies { getPodsByOwnerId: GetPodsByOwnerId; } export class ReplicaSetStore extends KubeObjectStore { - constructor(protected readonly dependencies: Dependencies, api: ReplicaSetApi, opts?: KubeObjectStoreOptions) { - super(api, opts); + constructor(protected readonly dependencies: ReplicaSetStoreDependencies, api: ReplicaSetApi, opts?: KubeObjectStoreOptions) { + super(dependencies, api, opts); } getChildPods(replicaSet: ReplicaSet) { diff --git a/src/renderer/components/+workloads-statefulsets/store.injectable.ts b/src/renderer/components/+workloads-statefulsets/store.injectable.ts index 0e440d969e..5931b5dfaf 100644 --- a/src/renderer/components/+workloads-statefulsets/store.injectable.ts +++ b/src/renderer/components/+workloads-statefulsets/store.injectable.ts @@ -7,6 +7,7 @@ import assert from "assert"; import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable"; import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; import statefulSetApiInjectable from "../../../common/k8s-api/endpoints/stateful-set.api.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { StatefulSetStore } from "./store"; @@ -19,6 +20,7 @@ const statefulSetStoreInjectable = getInjectable({ return new StatefulSetStore({ getPodsByOwnerId: di.inject(getPodsByOwnerIdInjectable), + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), }, api); }, injectionToken: kubeObjectStoreInjectionToken, diff --git a/src/renderer/components/+workloads-statefulsets/store.ts b/src/renderer/components/+workloads-statefulsets/store.ts index 0732ae5680..bdedcdcaf7 100644 --- a/src/renderer/components/+workloads-statefulsets/store.ts +++ b/src/renderer/components/+workloads-statefulsets/store.ts @@ -6,16 +6,16 @@ import type { GetPodsByOwnerId } from "../+workloads-pods/get-pods-by-owner-id.injectable"; import type { StatefulSet, StatefulSetApi } from "../../../common/k8s-api/endpoints"; import { PodStatusPhase } from "../../../common/k8s-api/endpoints"; -import type { KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; +import type { KubeObjectStoreDependencies, KubeObjectStoreOptions } from "../../../common/k8s-api/kube-object.store"; import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; -interface Dependencies { +interface Dependencies extends KubeObjectStoreDependencies { getPodsByOwnerId: GetPodsByOwnerId; } export class StatefulSetStore extends KubeObjectStore { constructor(protected readonly dependencies: Dependencies, api: StatefulSetApi, opts?: KubeObjectStoreOptions) { - super(api, opts); + super(dependencies, api, opts); } getChildPods(statefulSet: StatefulSet) { diff --git a/src/renderer/components/__tests__/cronjob.store.test.ts b/src/renderer/components/__tests__/cronjob.store.test.ts index 307c005aec..322e609953 100644 --- a/src/renderer/components/__tests__/cronjob.store.test.ts +++ b/src/renderer/components/__tests__/cronjob.store.test.ts @@ -7,6 +7,10 @@ import cronJobStoreInjectable from "../+workloads-cronjobs/store.injectable"; import { CronJob } from "../../../common/k8s-api/endpoints"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; +import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; +import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; +import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; +import createClusterInjectable from "../../cluster/create-cluster.injectable"; const scheduledCronJob = new CronJob({ apiVersion: "foo", @@ -119,8 +123,20 @@ describe("CronJob Store tests", () => { beforeEach(() => { const di = getDiForUnitTesting({ doGeneralOverrides: true }); + di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); + di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); di.override(storesAndApisCanBeCreatedInjectable, () => true); + const createCluster = di.inject(createClusterInjectable); + + di.override(hostedClusterInjectable, () => createCluster({ + contextName: "some-context-name", + id: "some-cluster-id", + kubeConfigPath: "/some-path-to-a-kubeconfig", + }, { + clusterServerUrl: "https://localhost:8080", + })); + cronJobStore = di.inject(cronJobStoreInjectable); }); diff --git a/src/renderer/components/__tests__/daemonset.store.test.ts b/src/renderer/components/__tests__/daemonset.store.test.ts index 76afb3188a..da5a167ffd 100644 --- a/src/renderer/components/__tests__/daemonset.store.test.ts +++ b/src/renderer/components/__tests__/daemonset.store.test.ts @@ -10,6 +10,10 @@ import podStoreInjectable from "../+workloads-pods/store.injectable"; import { DaemonSet, Pod } from "../../../common/k8s-api/endpoints"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; +import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; +import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; +import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; +import createClusterInjectable from "../../cluster/create-cluster.injectable"; const runningDaemonSet = new DaemonSet({ apiVersion: "foo", @@ -136,8 +140,20 @@ describe("DaemonSet Store tests", () => { beforeEach(() => { const di = getDiForUnitTesting({ doGeneralOverrides: true }); + di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); + di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); di.override(storesAndApisCanBeCreatedInjectable, () => true); + const createCluster = di.inject(createClusterInjectable); + + di.override(hostedClusterInjectable, () => createCluster({ + contextName: "some-context-name", + id: "some-cluster-id", + kubeConfigPath: "/some-path-to-a-kubeconfig", + }, { + clusterServerUrl: "https://localhost:8080", + })); + const podStore = di.inject(podStoreInjectable); daemonSetStore = di.inject(daemonSetStoreInjectable); diff --git a/src/renderer/components/__tests__/deployments.store.test.ts b/src/renderer/components/__tests__/deployments.store.test.ts index a478c03d2a..dc50f85ccf 100644 --- a/src/renderer/components/__tests__/deployments.store.test.ts +++ b/src/renderer/components/__tests__/deployments.store.test.ts @@ -11,6 +11,10 @@ import type { PodSpec } from "../../../common/k8s-api/endpoints"; import { Deployment, Pod } from "../../../common/k8s-api/endpoints"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; +import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; +import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; +import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; +import createClusterInjectable from "../../cluster/create-cluster.injectable"; const spec: PodSpec = { containers: [{ @@ -208,8 +212,20 @@ describe("Deployment Store tests", () => { beforeEach(() => { const di = getDiForUnitTesting({ doGeneralOverrides: true }); + di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); + di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); di.override(storesAndApisCanBeCreatedInjectable, () => true); + const createCluster = di.inject(createClusterInjectable); + + di.override(hostedClusterInjectable, () => createCluster({ + contextName: "some-context-name", + id: "some-cluster-id", + kubeConfigPath: "/some-path-to-a-kubeconfig", + }, { + clusterServerUrl: "https://localhost:8080", + })); + const podStore = di.inject(podStoreInjectable); // Add pods to pod store diff --git a/src/renderer/components/__tests__/job.store.test.ts b/src/renderer/components/__tests__/job.store.test.ts index 6fdc63bd50..5a000d18ae 100644 --- a/src/renderer/components/__tests__/job.store.test.ts +++ b/src/renderer/components/__tests__/job.store.test.ts @@ -10,6 +10,10 @@ import podStoreInjectable from "../+workloads-pods/store.injectable"; import { Job, Pod } from "../../../common/k8s-api/endpoints"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; +import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; +import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; +import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; +import createClusterInjectable from "../../cluster/create-cluster.injectable"; const runningJob = new Job({ apiVersion: "foo", @@ -173,8 +177,20 @@ describe("Job Store tests", () => { beforeEach(() => { const di = getDiForUnitTesting({ doGeneralOverrides: true }); + di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); + di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); di.override(storesAndApisCanBeCreatedInjectable, () => true); + const createCluster = di.inject(createClusterInjectable); + + di.override(hostedClusterInjectable, () => createCluster({ + contextName: "some-context-name", + id: "some-cluster-id", + kubeConfigPath: "/some-path-to-a-kubeconfig", + }, { + clusterServerUrl: "https://localhost:8080", + })); + jobStore = di.inject(jobStoreInjectable); const podStore = di.inject(podStoreInjectable); diff --git a/src/renderer/components/__tests__/pods.store.test.ts b/src/renderer/components/__tests__/pods.store.test.ts index 72e124a686..229c94c2d8 100644 --- a/src/renderer/components/__tests__/pods.store.test.ts +++ b/src/renderer/components/__tests__/pods.store.test.ts @@ -8,6 +8,10 @@ import type { PodStore } from "../+workloads-pods/store"; import podStoreInjectable from "../+workloads-pods/store.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; +import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; +import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; +import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; +import createClusterInjectable from "../../cluster/create-cluster.injectable"; const runningPod = new Pod({ apiVersion: "foo", @@ -119,8 +123,20 @@ describe("Pod Store tests", () => { beforeEach(() => { const di = getDiForUnitTesting({ doGeneralOverrides: true }); + di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); + di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); di.override(storesAndApisCanBeCreatedInjectable, () => true); + const createCluster = di.inject(createClusterInjectable); + + di.override(hostedClusterInjectable, () => createCluster({ + contextName: "some-context-name", + id: "some-cluster-id", + kubeConfigPath: "/some-path-to-a-kubeconfig", + }, { + clusterServerUrl: "https://localhost:8080", + })); + podStore = di.inject(podStoreInjectable); }); diff --git a/src/renderer/components/__tests__/replicaset.store.test.ts b/src/renderer/components/__tests__/replicaset.store.test.ts index 29352c34e1..3186725981 100644 --- a/src/renderer/components/__tests__/replicaset.store.test.ts +++ b/src/renderer/components/__tests__/replicaset.store.test.ts @@ -10,6 +10,10 @@ import type { ReplicaSetStore } from "../+workloads-replicasets/store"; import { ReplicaSet, Pod } from "../../../common/k8s-api/endpoints"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; +import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; +import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; +import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; +import createClusterInjectable from "../../cluster/create-cluster.injectable"; const runningReplicaSet = new ReplicaSet({ apiVersion: "foo", @@ -136,8 +140,20 @@ describe("ReplicaSet Store tests", () => { beforeEach(() => { const di = getDiForUnitTesting({ doGeneralOverrides: true }); + di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); + di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); di.override(storesAndApisCanBeCreatedInjectable, () => true); + const createCluster = di.inject(createClusterInjectable); + + di.override(hostedClusterInjectable, () => createCluster({ + contextName: "some-context-name", + id: "some-cluster-id", + kubeConfigPath: "/some-path-to-a-kubeconfig", + }, { + clusterServerUrl: "https://localhost:8080", + })); + const podStore = di.inject(podStoreInjectable); replicaSetStore = di.inject(replicasetsStoreInjectable); diff --git a/src/renderer/components/__tests__/statefulset.store.test.ts b/src/renderer/components/__tests__/statefulset.store.test.ts index 00471c8805..742955884c 100644 --- a/src/renderer/components/__tests__/statefulset.store.test.ts +++ b/src/renderer/components/__tests__/statefulset.store.test.ts @@ -10,6 +10,10 @@ import statefulSetStoreInjectable from "../+workloads-statefulsets/store.injecta import { StatefulSet, Pod } from "../../../common/k8s-api/endpoints"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; +import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; +import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; +import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; +import createClusterInjectable from "../../cluster/create-cluster.injectable"; const runningStatefulSet = new StatefulSet({ apiVersion: "foo", @@ -136,8 +140,20 @@ describe("StatefulSet Store tests", () => { beforeEach(() => { const di = getDiForUnitTesting({ doGeneralOverrides: true }); + di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); + di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); di.override(storesAndApisCanBeCreatedInjectable, () => true); + const createCluster = di.inject(createClusterInjectable); + + di.override(hostedClusterInjectable, () => createCluster({ + contextName: "some-context-name", + id: "some-cluster-id", + kubeConfigPath: "/some-path-to-a-kubeconfig", + }, { + clusterServerUrl: "https://localhost:8080", + })); + statefulSetStore = di.inject(statefulSetStoreInjectable); const podStore = di.inject(podStoreInjectable); diff --git a/src/renderer/components/cluster-settings/accessible-namespaces.tsx b/src/renderer/components/cluster-settings/accessible-namespaces.tsx index 479cc8f443..2f3b9b930d 100644 --- a/src/renderer/components/cluster-settings/accessible-namespaces.tsx +++ b/src/renderer/components/cluster-settings/accessible-namespaces.tsx @@ -32,13 +32,13 @@ export class ClusterAccessibleNamespaces extends React.Component { this.namespaces.add(newNamespace); - this.props.cluster.accessibleNamespaces = Array.from(this.namespaces); + this.props.cluster.accessibleNamespaces.replace([...this.namespaces]); }} validators={systemName} items={Array.from(this.namespaces)} remove={({ oldItem: oldNamespace }) => { this.namespaces.delete(oldNamespace); - this.props.cluster.accessibleNamespaces = Array.from(this.namespaces); + this.props.cluster.accessibleNamespaces.replace([...this.namespaces]); }} inputTheme="round-black" /> diff --git a/src/renderer/components/dock/create-resource/view.tsx b/src/renderer/components/dock/create-resource/view.tsx index d84a823259..00221a7b32 100644 --- a/src/renderer/components/dock/create-resource/view.tsx +++ b/src/renderer/components/dock/create-resource/view.tsx @@ -13,8 +13,8 @@ import { observer } from "mobx-react"; import type { CreateResourceTabStore } from "./store"; import { EditorPanel } from "../editor-panel"; import { InfoPanel } from "../info-panel"; -import { Notifications } from "../../notifications"; -import logger from "../../../../common/logger"; +import type { ShowNotification } from "../../notifications"; +import type { Logger } from "../../../../common/logger"; import type { ApiManager } from "../../../../common/k8s-api/api-manager"; import { isObject, prevDefault } from "../../../utils"; import { withInjectables } from "@ogre-tools/injectable-react"; @@ -29,6 +29,10 @@ import getDetailsUrlInjectable from "../../kube-detail-params/get-details-url.in import navigateInjectable from "../../../navigation/navigate.injectable"; import type { RequestKubeObjectCreation } from "../../../../common/k8s-api/endpoints/resource-applier.api/request-update.injectable"; import requestKubeObjectCreationInjectable from "../../../../common/k8s-api/endpoints/resource-applier.api/request-update.injectable"; +import loggerInjectable from "../../../../common/logger.injectable"; +import type { ShowCheckedErrorNotification } from "../../notifications/show-checked-error.injectable"; +import showSuccessNotificationInjectable from "../../notifications/show-success-notification.injectable"; +import showCheckedErrorNotificationInjectable from "../../notifications/show-checked-error.injectable"; export interface CreateResourceProps { tabId: string; @@ -38,9 +42,12 @@ interface Dependencies { createResourceTemplates: IComputedValue[]>; createResourceTabStore: CreateResourceTabStore; apiManager: ApiManager; + logger: Logger; navigate: Navigate; getDetailsUrl: GetDetailsUrl; requestKubeObjectCreation: RequestKubeObjectCreation; + showSuccessNotification: ShowNotification; + showCheckedErrorNotification: ShowCheckedErrorNotification; } @observer @@ -81,34 +88,38 @@ class NonInjectedCreateResource extends React.Component { - try { - const data = await requestKubeObjectCreation(dump(resource)); - const { kind, apiVersion, metadata: { name, namespace }} = data; + const result = await requestKubeObjectCreation(dump(resource)); - const showDetails = () => { - const resourceLink = apiManager.lookupApiLink({ kind, apiVersion, name, namespace }); + if (!result.callWasSuccessful) { + this.props.logger.warn("Failed to create resource", { resource }, result.error); + this.props.showCheckedErrorNotification(result.error, "Unknown error occured while creating resources"); - navigate(getDetailsUrl(resourceLink)); - close(); - }; - - const close = Notifications.ok( -

- {kind} - {" "} - - {name} - - {" successfully created."} -

, - ); - } catch (error) { - Notifications.checkedError(error, "Unknown error occured while creating resources"); + return; } + + const { kind, apiVersion, metadata: { name, namespace }} = result.response; + + const close = this.props.showSuccessNotification(( +

+ {kind} + {" "} + { + const resourceLink = apiManager.lookupApiLink({ kind, apiVersion, name, namespace }); + + navigate(getDetailsUrl(resourceLink)); + close(); + })} + > + {name} + + {" successfully created."} +

+ )); }); await Promise.allSettled(creatingResources); @@ -168,8 +179,11 @@ export const CreateResource = withInjectables createResourceTabStore: di.inject(createResourceTabStoreInjectable), createResourceTemplates: await di.inject(createResourceTemplatesInjectable), apiManager: di.inject(apiManagerInjectable), + logger: di.inject(loggerInjectable), getDetailsUrl: di.inject(getDetailsUrlInjectable), navigate: di.inject(navigateInjectable), requestKubeObjectCreation: di.inject(requestKubeObjectCreationInjectable), + showSuccessNotification: di.inject(showSuccessNotificationInjectable), + showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable), }), }); diff --git a/src/renderer/components/input/search-input.tsx b/src/renderer/components/input/search-input.tsx index 1c5a66bdc2..4aff4a6ffa 100644 --- a/src/renderer/components/input/search-input.tsx +++ b/src/renderer/components/input/search-input.tsx @@ -11,7 +11,8 @@ import { cssNames, autoBind } from "../../utils"; import { Icon } from "../icon"; import type { InputProps } from "./input"; import { Input } from "./input"; -import { isMac } from "../../../common/vars"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import isMacInjectable from "../../../common/vars/is-mac.injectable"; export interface SearchInputProps extends InputProps { compact?: boolean; // show only search-icon when not focused @@ -27,13 +28,17 @@ const defaultProps: Partial = { placeholder: "Search...", }; +interface Dependencies { + isMac: boolean; +} + @observer -export class SearchInput extends React.Component { +class NonInjectedSearchInput extends React.Component { static defaultProps = defaultProps as object; private inputRef = createRef(); - constructor(props: SearchInputProps) { + constructor(props: SearchInputProps & Dependencies) { super(props); autoBind(this); } @@ -48,7 +53,7 @@ export class SearchInput extends React.Component { } onGlobalKey(evt: KeyboardEvent) { - if (evt.key === "f" && (isMac ? evt.metaKey : evt.ctrlKey)) { + if (evt.key === "f" && (this.props.isMac ? evt.metaKey : evt.ctrlKey)) { this.inputRef.current?.focus(); } } @@ -71,7 +76,7 @@ export class SearchInput extends React.Component { } render() { - const { className, compact, onClear, showClearIcon, bindGlobalFocusHotkey, value, ...inputProps } = this.props; + const { className, compact, onClear, showClearIcon, bindGlobalFocusHotkey, value, isMac, ...inputProps } = this.props; let rightIcon = ; if (showClearIcon && value) { @@ -97,3 +102,10 @@ export class SearchInput extends React.Component { ); } } + +export const SearchInput = withInjectables(NonInjectedSearchInput, { + getProps: (di, props) => ({ + ...props, + isMac: di.inject(isMacInjectable), + }), +}); diff --git a/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx b/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx index 707351c231..bd4fa3d81d 100644 --- a/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx +++ b/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx @@ -20,8 +20,7 @@ import { ResourceKindMap, ResourceNames } from "../../utils/rbac"; import { Icon } from "../icon"; import { TooltipPosition } from "../tooltip"; import { withInjectables } from "@ogre-tools/injectable-react"; -import type { ClusterFrameContext } from "../../cluster-frame-context/cluster-frame-context"; -import clusterFrameContextInjectable from "../../cluster-frame-context/cluster-frame-context.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import type { SubscribableStore, SubscribeStores } from "../../kube-watch-api/kube-watch-api"; import type { KubeApi } from "../../../common/k8s-api/kube-api"; import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable"; @@ -29,6 +28,7 @@ import type { PageParam } from "../../navigation"; import type { ToggleKubeDetailsPane } from "../kube-detail-params/toggle-details.injectable"; import kubeSelectedUrlParamInjectable from "../kube-detail-params/kube-selected-url.injectable"; import toggleKubeDetailsPaneInjectable from "../kube-detail-params/toggle-details.injectable"; +import type { ClusterContext } from "../../cluster-frame-context/cluster-frame-context"; export interface KubeObjectListLayoutProps< K extends KubeObject, @@ -43,7 +43,7 @@ export interface KubeObjectListLayoutProps< } interface Dependencies { - clusterFrameContext: ClusterFrameContext; + clusterFrameContext: ClusterContext; subscribeToStores: SubscribeStores; kubeSelectedUrlParam: PageParam; toggleKubeDetailsPane: ToggleKubeDetailsPane; @@ -177,7 +177,7 @@ export const KubeObjectListLayout = withInjectables< >(NonInjectedKubeObjectListLayout, { getProps: (di, props) => ({ ...props, - clusterFrameContext: di.inject(clusterFrameContextInjectable), + clusterFrameContext: di.inject(clusterFrameContextForNamespacedResourcesInjectable), subscribeToStores: di.inject(subscribeStoresInjectable), kubeSelectedUrlParam: di.inject(kubeSelectedUrlParamInjectable), toggleKubeDetailsPane: di.inject(toggleKubeDetailsPaneInjectable), diff --git a/src/renderer/components/layout/top-bar/start-state-sync.injectable.ts b/src/renderer/components/layout/top-bar/start-state-sync.injectable.ts index 666966ddad..92488851c5 100644 --- a/src/renderer/components/layout/top-bar/start-state-sync.injectable.ts +++ b/src/renderer/components/layout/top-bar/start-state-sync.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { action } from "mobx"; -import { beforeFrameStartsInjectionToken } from "../../../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../../../before-frame-starts/tokens"; import ipcRendererInjectable from "../../../utils/channel/ipc-renderer.injectable"; import topBarStateInjectable from "./state.injectable"; @@ -26,7 +26,7 @@ const startTopbarStateSyncInjectable = getInjectable({ })); }, }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, causesSideEffects: true, }); diff --git a/src/renderer/components/monaco-editor/monaco-themes/clouds-midnight.json b/src/renderer/components/monaco-editor/monaco-themes/clouds-midnight.json deleted file mode 100644 index 48696d8d0a..0000000000 --- a/src/renderer/components/monaco-editor/monaco-themes/clouds-midnight.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "name": "clouds-midnight", - "base": "vs-dark", - "inherit": true, - "rules": [ - { - "background": "191919", - "token": "" - }, - { - "foreground": "3c403b", - "token": "comment" - }, - { - "foreground": "5d90cd", - "token": "string" - }, - { - "foreground": "46a609", - "token": "constant.numeric" - }, - { - "foreground": "39946a", - "token": "constant.language" - }, - { - "foreground": "927c5d", - "token": "keyword" - }, - { - "foreground": "927c5d", - "token": "support.constant.property-value" - }, - { - "foreground": "927c5d", - "token": "constant.other.color" - }, - { - "foreground": "366f1a", - "token": "keyword.other.unit" - }, - { - "foreground": "a46763", - "token": "entity.other.attribute-name.html" - }, - { - "foreground": "4b4b4b", - "token": "keyword.operator" - }, - { - "foreground": "e92e2e", - "token": "storage" - }, - { - "foreground": "858585", - "token": "entity.other.inherited-class" - }, - { - "foreground": "606060", - "token": "entity.name.tag" - }, - { - "foreground": "a165ac", - "token": "constant.character.entity" - }, - { - "foreground": "a165ac", - "token": "support.class.js" - }, - { - "foreground": "606060", - "token": "entity.other.attribute-name" - }, - { - "foreground": "e92e2e", - "token": "meta.selector.css" - }, - { - "foreground": "e92e2e", - "token": "entity.name.tag.css" - }, - { - "foreground": "e92e2e", - "token": "entity.other.attribute-name.id.css" - }, - { - "foreground": "e92e2e", - "token": "entity.other.attribute-name.class.css" - }, - { - "foreground": "616161", - "token": "meta.property-name.css" - }, - { - "foreground": "e92e2e", - "token": "support.function" - }, - { - "foreground": "ffffff", - "background": "e92e2e", - "token": "invalid" - }, - { - "foreground": "e92e2e", - "token": "punctuation.section.embedded" - }, - { - "foreground": "606060", - "token": "punctuation.definition.tag" - }, - { - "foreground": "a165ac", - "token": "constant.other.color.rgb-value.css" - }, - { - "foreground": "a165ac", - "token": "support.constant.property-value.css" - } - ], - "colors": { - "editor.foreground": "#929292", - "editor.background": "#191919", - "editor.selectionBackground": "#000000", - "editor.lineHighlightBackground": "#D7D7D708", - "editorCursor.foreground": "#7DA5DC", - "editorWhitespace.foreground": "#BFBFBF" - } -} \ No newline at end of file diff --git a/src/renderer/components/test-utils/get-application-builder.tsx b/src/renderer/components/test-utils/get-application-builder.tsx index 7e2dde5296..405a4e3179 100644 --- a/src/renderer/components/test-utils/get-application-builder.tsx +++ b/src/renderer/components/test-utils/get-application-builder.tsx @@ -9,10 +9,10 @@ import type { IComputedValue, ObservableMap } from "mobx"; import { action, computed, observable, runInAction } from "mobx"; import React from "react"; import { Router } from "react-router"; -import allowedResourcesInjectable from "../../cluster-frame-context/allowed-resources.injectable"; import type { RenderResult } from "@testing-library/react"; import { fireEvent, queryByText } from "@testing-library/react"; -import type { KubeResource } from "../../../common/rbac"; +import type { KubeApiResourceDescriptor } from "../../../common/rbac"; +import { formatKubeApiResource } from "../../../common/rbac"; import type { DiContainer, Injectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable"; import mainExtensionsInjectable from "../../../extensions/main-extensions.injectable"; @@ -22,10 +22,7 @@ import navigateToPreferencesInjectable from "../../../features/preferences/commo import type { NavigateToHelmCharts } from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable"; import navigateToHelmChartsInjectable from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable"; import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; -import { ClusterFrameContext } from "../../cluster-frame-context/cluster-frame-context"; import type { Cluster } from "../../../common/cluster/cluster"; -import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; -import clusterFrameContextInjectable from "../../cluster-frame-context/cluster-frame-context.injectable"; import startMainApplicationInjectable from "../../../main/start-main-application/start-main-application.injectable"; import startFrameInjectable from "../../start-frame/start-frame.injectable"; import type { NamespaceStore } from "../+namespaces/store"; @@ -52,7 +49,6 @@ import hostedClusterIdInjectable from "../../cluster-frame-context/hosted-cluste import activeKubernetesClusterInjectable from "../../cluster-frame-context/active-kubernetes-cluster.injectable"; import { catalogEntityFromCluster } from "../../../main/cluster/manager"; import namespaceStoreInjectable from "../+namespaces/store.injectable"; -import { isAllowedResource } from "../../../common/cluster/is-allowed-resource"; import createApplicationWindowInjectable from "../../../main/start-main-application/lens-window/application-window/create-application-window.injectable"; import type { CreateElectronWindow } from "../../../main/start-main-application/lens-window/application-window/create-electron-window.injectable"; import createElectronWindowInjectable from "../../../main/start-main-application/lens-window/application-window/create-electron-window.injectable"; @@ -115,7 +111,7 @@ export interface ApplicationBuilder { create: (id: string) => LensWindowWithHelpers; }; - allowKubeResource: (resourceName: KubeResource) => ApplicationBuilder; + allowKubeResource: (resource: KubeApiResourceDescriptor) => ApplicationBuilder; beforeApplicationStart: (callback: Callback) => ApplicationBuilder; afterApplicationStart: (callback: Callback) => ApplicationBuilder; beforeWindowStart: (callback: Callback) => ApplicationBuilder; @@ -214,7 +210,7 @@ export const getApplicationBuilder = () => { }, })); - const allowedResourcesState = observable.array(); + const allowedResourcesState = observable.set(); const windowHelpers = new Map RenderResult }>(); @@ -502,15 +498,11 @@ export const getApplicationBuilder = () => { environment = environments.clusterFrame; builder.beforeWindowStart((windowDi) => { - windowDi.override(allowedResourcesInjectable, () => - computed(() => new Set([...allowedResourcesState])), - ); - const clusterStub = { id: "some-cluster-id", - accessibleNamespaces: [], - isAllowedResource: isAllowedResource(allowedResourcesState), - } as unknown as Cluster; + accessibleNamespaces: observable.array(), + shouldShowResource: (kind) => allowedResourcesState.has(formatKubeApiResource(kind)), + } as Partial as Cluster; windowDi.override(activeKubernetesClusterInjectable, () => computed(() => catalogEntityFromCluster(clusterStub)), @@ -538,20 +530,8 @@ export const getApplicationBuilder = () => { getTotalCount: () => namespaceItems.length, } as Partial as NamespaceStore; - const clusterFrameContextFake = new ClusterFrameContext( - clusterStub, - - { - namespaceStore: namespaceStoreStub, - }, - ); - windowDi.override(namespaceStoreInjectable, () => namespaceStoreStub); windowDi.override(hostedClusterInjectable, () => clusterStub); - windowDi.override(clusterFrameContextInjectable, () => clusterFrameContextFake); - - // Todo: get rid of global state. - KubeObjectStore.defaultContext.set(clusterFrameContextFake); }); return builder; @@ -635,11 +615,11 @@ export const getApplicationBuilder = () => { }, }, - allowKubeResource: (resourceName) => { + allowKubeResource: (resource) => { environment.onAllowKubeResource(); runInAction(() => { - allowedResourcesState.push(resourceName); + allowedResourcesState.add(formatKubeApiResource(resource)); }); return builder; diff --git a/src/renderer/frames/cluster-frame/cluster-frame.test.tsx b/src/renderer/frames/cluster-frame/cluster-frame.test.tsx index f95a80fee2..b969291fd2 100644 --- a/src/renderer/frames/cluster-frame/cluster-frame.test.tsx +++ b/src/renderer/frames/cluster-frame/cluster-frame.test.tsx @@ -15,13 +15,12 @@ import { ClusterFrame } from "./cluster-frame"; import historyInjectable from "../../navigation/history.injectable"; import { computed } from "mobx"; import type { Cluster } from "../../../common/cluster/cluster"; -import createClusterInjectable from "../../create-cluster/create-cluster.injectable"; +import createClusterInjectable from "../../cluster/create-cluster.injectable"; import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable"; import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import legacyOnChannelListenInjectable from "../../ipc/legacy-channel-listen.injectable"; import currentRouteComponentInjectable from "../../routes/current-route-component.injectable"; -import allowedResourcesInjectable from "../../cluster-frame-context/allowed-resources.injectable"; import hostedClusterIdInjectable from "../../cluster-frame-context/hosted-cluster-id.injectable"; import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; import { useFakeTime } from "../../../common/test-utils/use-fake-time"; @@ -69,7 +68,8 @@ describe("", () => { describe("given cluster with list nodes and namespaces permissions", () => { beforeEach(() => { - di.override(allowedResourcesInjectable, () => computed(() => new Set(["nodes", "namespaces"]))); + // TODO: replace with not using private info + (cluster as any).allowedResources.replace(["v1/nodes", "v1/namespaces"]); }); it("renders", () => { @@ -110,7 +110,7 @@ describe("", () => { describe("given cluster without list nodes, but with namespaces permissions", () => { beforeEach(() => { - di.override(allowedResourcesInjectable, () => computed(() => new Set(["namespaces"]))); + (cluster as any).allowedResources.replace(["v1/namespaces"]); }); it("renders", () => { diff --git a/src/renderer/frames/cluster-frame/init-cluster-frame/init-cluster-frame.injectable.ts b/src/renderer/frames/cluster-frame/init-cluster-frame/init-cluster-frame.injectable.ts index 909834a047..c640264ee3 100644 --- a/src/renderer/frames/cluster-frame/init-cluster-frame/init-cluster-frame.injectable.ts +++ b/src/renderer/frames/cluster-frame/init-cluster-frame/init-cluster-frame.injectable.ts @@ -7,10 +7,11 @@ import { initClusterFrame } from "./init-cluster-frame"; import catalogEntityRegistryInjectable from "../../../api/catalog/entity/registry.injectable"; import frameRoutingIdInjectable from "./frame-routing-id/frame-routing-id.injectable"; import hostedClusterInjectable from "../../../cluster-frame-context/hosted-cluster.injectable"; -import clusterFrameContextInjectable from "../../../cluster-frame-context/cluster-frame-context.injectable"; import assert from "assert"; import emitAppEventInjectable from "../../../../common/app-event-bus/emit-event.injectable"; import loadExtensionsInjectable from "../../load-extensions.injectable"; +import loggerInjectable from "../../../../common/logger.injectable"; +import showErrorNotificationInjectable from "../../../components/notifications/show-error-notification.injectable"; const initClusterFrameInjectable = getInjectable({ id: "init-cluster-frame", @@ -26,7 +27,8 @@ const initClusterFrameInjectable = getInjectable({ catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable), frameRoutingId: di.inject(frameRoutingIdInjectable), emitAppEvent: di.inject(emitAppEventInjectable), - clusterFrameContext: di.inject(clusterFrameContextInjectable), + logger: di.inject(loggerInjectable), + showErrorNotification: di.inject(showErrorNotificationInjectable), }); }, }); diff --git a/src/renderer/frames/cluster-frame/init-cluster-frame/init-cluster-frame.ts b/src/renderer/frames/cluster-frame/init-cluster-frame/init-cluster-frame.ts index 9476393366..109ae0f0bc 100644 --- a/src/renderer/frames/cluster-frame/init-cluster-frame/init-cluster-frame.ts +++ b/src/renderer/frames/cluster-frame/init-cluster-frame/init-cluster-frame.ts @@ -4,13 +4,11 @@ */ import type { Cluster } from "../../../../common/cluster/cluster"; import type { CatalogEntityRegistry } from "../../../api/catalog/entity/registry"; -import logger from "../../../../main/logger"; -import { Notifications } from "../../../components/notifications"; +import type { ShowNotification } from "../../../components/notifications"; import { when } from "mobx"; -import type { ClusterFrameContext } from "../../../cluster-frame-context/cluster-frame-context"; -import { KubeObjectStore } from "../../../../common/k8s-api/kube-object.store"; import { requestSetClusterFrameId } from "../../../ipc"; import type { EmitAppEvent } from "../../../../common/app-event-bus/emit-event.injectable"; +import type { Logger } from "../../../../common/logger"; interface Dependencies { hostedCluster: Cluster; @@ -18,9 +16,8 @@ interface Dependencies { catalogEntityRegistry: CatalogEntityRegistry; frameRoutingId: number; emitAppEvent: EmitAppEvent; - - // TODO: This dependency belongs to KubeObjectStore - clusterFrameContext: ClusterFrameContext; + logger: Logger; + showErrorNotification: ShowNotification; } const logPrefix = "[CLUSTER-FRAME]:"; @@ -31,7 +28,8 @@ export const initClusterFrame = ({ catalogEntityRegistry, frameRoutingId, emitAppEvent, - clusterFrameContext, + logger, + showErrorNotification, }: Dependencies) => async (unmountRoot: () => void) => { // TODO: Make catalogEntityRegistry already initialized when passed as dependency @@ -55,14 +53,12 @@ export const initClusterFrame = ({ { timeout: 15_000, onError: (error) => { - console.warn( + logger.warn( "[CLUSTER-FRAME]: error from activeEntity when()", error, ); - Notifications.error( - "Failed to get KubernetesCluster for this view. Extensions will not be loaded.", - ); + showErrorNotification("Failed to get KubernetesCluster for this view. Extensions will not be loaded."); }, }, ); @@ -84,6 +80,4 @@ export const initClusterFrame = ({ unmountRoot(); }; - // TODO: Make context dependency of KubeObjectStore - KubeObjectStore.defaultContext.set(clusterFrameContext); }; diff --git a/src/renderer/frames/root-frame/setup-system-ca.injectable.ts b/src/renderer/frames/root-frame/setup-system-ca.injectable.ts index 698a769be7..557d87c81f 100644 --- a/src/renderer/frames/root-frame/setup-system-ca.injectable.ts +++ b/src/renderer/frames/root-frame/setup-system-ca.injectable.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { beforeFrameStartsInjectionToken } from "../../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../../before-frame-starts/tokens"; import injectSystemCAsInjectable from "../../../common/certificate-authorities/inject-system-cas.injectable"; const setupSystemCaInjectable = getInjectable({ @@ -12,7 +12,7 @@ const setupSystemCaInjectable = getInjectable({ id: "setup-system-ca", run: di.inject(injectSystemCAsInjectable), }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, }); export default setupSystemCaInjectable; diff --git a/src/renderer/initializers/workload-events.tsx b/src/renderer/initializers/workload-events.tsx index 734b5105f0..735b4e2c74 100644 --- a/src/renderer/initializers/workload-events.tsx +++ b/src/renderer/initializers/workload-events.tsx @@ -7,7 +7,7 @@ import { withInjectables } from "@ogre-tools/injectable-react"; import type { IComputedValue } from "mobx"; import { observer } from "mobx-react"; import React from "react"; -import isAllowedResourceInjectable from "../../common/utils/is-allowed-resource.injectable"; +import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token"; import { Events } from "../components/+events/events"; export interface WorkloadEventsProps {} @@ -32,7 +32,10 @@ const NonInjectedWorkloadEvents = observer(({ workloadEventsAreAllowed }: Depend export const WorkloadEvents = withInjectables(NonInjectedWorkloadEvents, { getProps: (di, props) => ({ - workloadEventsAreAllowed: di.inject(isAllowedResourceInjectable, "events"), + workloadEventsAreAllowed: di.inject(shouldShowResourceInjectionToken, { + apiName: "events", + group: "v1", + }), ...props, }), }); diff --git a/src/renderer/kube-watch-api/kube-watch-api.injectable.ts b/src/renderer/kube-watch-api/kube-watch-api.injectable.ts index 3fc8aa60d3..23e53bf7cc 100644 --- a/src/renderer/kube-watch-api/kube-watch-api.injectable.ts +++ b/src/renderer/kube-watch-api/kube-watch-api.injectable.ts @@ -3,14 +3,14 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import clusterFrameContextInjectable from "../cluster-frame-context/cluster-frame-context.injectable"; +import clusterFrameContextForNamespacedResourcesInjectable from "../cluster-frame-context/for-namespaced-resources.injectable"; import { KubeWatchApi } from "./kube-watch-api"; const kubeWatchApiInjectable = getInjectable({ id: "kube-watch-api", instantiate: (di) => new KubeWatchApi({ - clusterFrameContext: di.inject(clusterFrameContextInjectable), + clusterContext: di.inject(clusterFrameContextForNamespacedResourcesInjectable), }), }); diff --git a/src/renderer/kube-watch-api/kube-watch-api.ts b/src/renderer/kube-watch-api/kube-watch-api.ts index c3eca74d29..4fc31bd1d5 100644 --- a/src/renderer/kube-watch-api/kube-watch-api.ts +++ b/src/renderer/kube-watch-api/kube-watch-api.ts @@ -6,10 +6,10 @@ import { comparer, reaction } from "mobx"; import type { Disposer } from "../../common/utils"; import { disposer, getOrInsert, noop, WrappedAbortController } from "../../common/utils"; import { once } from "lodash"; -import type { ClusterFrameContext } from "../cluster-frame-context/cluster-frame-context"; import logger from "../../common/logger"; import type { KubeObjectStoreLoadAllParams, KubeObjectStoreSubscribeParams } from "../../common/k8s-api/kube-object.store"; import AbortController from "abort-controller"; +import type { ClusterContext } from "../cluster-frame-context/cluster-frame-context"; // Kubernetes watch-api client // API: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams @@ -68,7 +68,7 @@ export interface KubeWatchSubscribeStoreOptions { } interface Dependencies { - clusterFrameContext: ClusterFrameContext; + readonly clusterContext: ClusterContext; } export interface SubscribableStore { @@ -86,7 +86,7 @@ export type SubscribeStores = (stores: SubscribableStore[], opts?: KubeWatchSubs export class KubeWatchApi { readonly #watch = new WatchCount(); - constructor(private dependencies: Dependencies) {} + constructor(private readonly dependencies: Dependencies) {} private subscribeStore({ store, parent, namespaces, onLoadFailure }: SubscribeStoreParams): Disposer { const isNamespaceFilterWatch = !namespaces; @@ -96,7 +96,7 @@ export class KubeWatchApi { return () => this.#watch.dec(store); } - namespaces ??= this.dependencies.clusterFrameContext?.contextNamespaces ?? []; + namespaces ??= this.dependencies.clusterContext?.contextNamespaces ?? []; let childController = new WrappedAbortController(parent); const unsubscribe = disposer(); @@ -123,7 +123,7 @@ export class KubeWatchApi { const cancelReloading = isNamespaceFilterWatch && store.api.isNamespaced ? reaction( // Note: must slice because reaction won't fire if it isn't there - () => [this.dependencies.clusterFrameContext.contextNamespaces.slice(), this.dependencies.clusterFrameContext.hasSelectedAll] as const, + () => [this.dependencies.clusterContext.contextNamespaces.slice(), this.dependencies.clusterContext.hasSelectedAll] as const, ([namespaces, curSelectedAll], [prevNamespaces, prevSelectedAll]) => { if (curSelectedAll && prevSelectedAll) { const action = namespaces.length > prevNamespaces.length ? "created" : "deleted"; diff --git a/src/renderer/kube-watch-api/subscribe-stores.injectable.ts b/src/renderer/kube-watch-api/subscribe-stores.injectable.ts index f34a3d21f4..81c38c387e 100644 --- a/src/renderer/kube-watch-api/subscribe-stores.injectable.ts +++ b/src/renderer/kube-watch-api/subscribe-stores.injectable.ts @@ -7,7 +7,6 @@ import kubeWatchApiInjectable from "./kube-watch-api.injectable"; const subscribeStoresInjectable = getInjectable({ id: "subscribe-stores", - causesSideEffects: true, instantiate: (di) => di.inject(kubeWatchApiInjectable).subscribeStores, }); diff --git a/src/renderer/navigation/events.ts b/src/renderer/navigation/events.ts index 7cacd1b313..452d16af9b 100644 --- a/src/renderer/navigation/events.ts +++ b/src/renderer/navigation/events.ts @@ -3,39 +3,9 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { ipcRenderer } from "electron"; -import { reaction } from "mobx"; -import { broadcastMessage } from "../../common/ipc"; -import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; -import matchedClusterIdInjectable from "./matched-cluster-id.injectable"; - +// export const enum IpcRendererNavigationEvents { - CLUSTER_VIEW_CURRENT_ID = "renderer:cluster-id-of-active-view", NAVIGATE_IN_APP = "renderer:navigate", NAVIGATE_IN_CLUSTER = "renderer:navigate-in-cluster", LOADED = "renderer:loaded", } - -export function bindEvents() { - if (!ipcRenderer) { - return; - } - - if (process.isMainFrame) { - bindClusterManagerRouteEvents(); - } -} - -// Handle events only in main window renderer process (see also: cluster-manager.tsx) -function bindClusterManagerRouteEvents() { - const di = getLegacyGlobalDiForExtensionApi(); - - const matchedClusterId = di.inject(matchedClusterIdInjectable); - - // Keep track of active cluster-id for handling IPC/menus/etc. - reaction(() => matchedClusterId.get(), clusterId => { - broadcastMessage(IpcRendererNavigationEvents.CLUSTER_VIEW_CURRENT_ID, clusterId); - }, { - fireImmediately: true, - }); -} diff --git a/src/renderer/start-frame/start-frame.injectable.ts b/src/renderer/start-frame/start-frame.injectable.ts index 60e8d590d0..3f1934aa1c 100644 --- a/src/renderer/start-frame/start-frame.injectable.ts +++ b/src/renderer/start-frame/start-frame.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { runManyFor } from "../../common/runnable/run-many-for"; -import { beforeFrameStartsInjectionToken, beforeClusterFrameStartsInjectionToken, beforeFrameStartsFirstInjectionToken, beforeMainFrameStartsInjectionToken } from "../before-frame-starts/tokens"; +import * as tokens from "../before-frame-starts/tokens"; import currentlyInClusterFrameInjectable from "../routes/currently-in-cluster-frame.injectable"; const startFrameInjectable = getInjectable({ @@ -13,22 +13,30 @@ const startFrameInjectable = getInjectable({ // TODO: Consolidate contents of bootstrap.tsx here instantiate: (di) => { const runMany = runManyFor(di); - const beforeFrameStartsFirst = runMany(beforeFrameStartsFirstInjectionToken); - const beforeMainFrameStarts = runMany(beforeMainFrameStartsInjectionToken); - const beforeClusterFrameStarts = runMany(beforeClusterFrameStartsInjectionToken); - const beforeFrameStarts = runMany(beforeFrameStartsInjectionToken); + const beforeFrameStartsFirst = runMany(tokens.beforeFrameStartsFirstInjectionToken); + const beforeMainFrameStartsFirst = runMany(tokens.beforeMainFrameStartsFirstInjectionToken); + const beforeClusterFrameStartsFirst = runMany(tokens.beforeClusterFrameStartsFirstInjectionToken); + const beforeFrameStartsSecond = runMany(tokens.beforeFrameStartsSecondInjectionToken); + const beforeMainFrameStartsSecond = runMany(tokens.beforeMainFrameStartsSecondInjectionToken); + const beforeClusterFrameStartsSecond = runMany(tokens.beforeClusterFrameStartsSecondInjectionToken); const currentlyInClusterFrame = di.inject(currentlyInClusterFrameInjectable); return async () => { await beforeFrameStartsFirst(); if (currentlyInClusterFrame) { - await beforeClusterFrameStarts(); + await beforeClusterFrameStartsFirst(); } else { - await beforeMainFrameStarts(); + await beforeMainFrameStartsFirst(); } - await beforeFrameStarts(); + await beforeFrameStartsSecond(); + + if (currentlyInClusterFrame) { + await beforeClusterFrameStartsSecond(); + } else { + await beforeMainFrameStartsSecond(); + } }; }, }); diff --git a/src/renderer/stores/init-user-store.injectable.ts b/src/renderer/stores/init-user-store.injectable.ts index a65181ca67..fba2287fe0 100644 --- a/src/renderer/stores/init-user-store.injectable.ts +++ b/src/renderer/stores/init-user-store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import userStoreInjectable from "../../common/user-store/user-store.injectable"; -import { beforeFrameStartsInjectionToken } from "../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../before-frame-starts/tokens"; import initDefaultUpdateChannelInjectable from "../vars/default-update-channel/init.injectable"; const initUserStoreInjectable = getInjectable({ @@ -19,7 +19,7 @@ const initUserStoreInjectable = getInjectable({ }, runAfter: di.inject(initDefaultUpdateChannelInjectable), }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, }); export default initUserStoreInjectable; diff --git a/src/renderer/themes/setup-apply-active-theme.injectable.ts b/src/renderer/themes/setup-apply-active-theme.injectable.ts index 17b2e655a5..960f5f8764 100644 --- a/src/renderer/themes/setup-apply-active-theme.injectable.ts +++ b/src/renderer/themes/setup-apply-active-theme.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import { reaction } from "mobx"; import initializeSystemThemeTypeInjectable from "../../features/theme/system-type/renderer/initialize.injectable"; -import { beforeFrameStartsInjectionToken } from "../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../before-frame-starts/tokens"; import initUserStoreInjectable from "../stores/init-user-store.injectable"; import activeThemeInjectable from "./active.injectable"; import applyLensThemeInjectable from "./apply-lens-theme.injectable"; @@ -31,7 +31,7 @@ const setupApplyActiveThemeInjectable = getInjectable({ di.inject(initUserStoreInjectable), ], }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, }); export default setupApplyActiveThemeInjectable; diff --git a/src/renderer/utils/channel/channel-listeners/start-listening-of-channels.injectable.ts b/src/renderer/utils/channel/channel-listeners/start-listening-of-channels.injectable.ts index cbcf63ea76..aea98b3360 100644 --- a/src/renderer/utils/channel/channel-listeners/start-listening-of-channels.injectable.ts +++ b/src/renderer/utils/channel/channel-listeners/start-listening-of-channels.injectable.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { beforeFrameStartsInjectionToken } from "../../../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../../../before-frame-starts/tokens"; import listeningOnMessageChannelsInjectable from "../../../../common/utils/channel/listening-on-message-channels.injectable"; const startListeningOfChannelsInjectable = getInjectable({ @@ -18,7 +18,7 @@ const startListeningOfChannelsInjectable = getInjectable({ }, }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, }); export default startListeningOfChannelsInjectable; diff --git a/src/renderer/utils/rbac.ts b/src/renderer/utils/rbac.ts index 46219febf6..93c153435f 100644 --- a/src/renderer/utils/rbac.ts +++ b/src/renderer/utils/rbac.ts @@ -5,6 +5,7 @@ import type { KubeResource } from "../../common/rbac"; import { apiResourceRecord } from "../../common/rbac"; +import { object } from "../../common/utils"; export const ResourceNames: Record = { "namespaces": "Namespaces", @@ -42,7 +43,7 @@ export const ResourceNames: Record = { "serviceaccounts": "Service Accounts", }; -export const ResourceKindMap: Record = Object.fromEntries( - Object.entries(apiResourceRecord) - .map(([resource, { kind }]) => [kind, resource as KubeResource]), +export const ResourceKindMap = object.fromEntries( + object.entries(apiResourceRecord) + .map(([resource, { kind }]) => [kind, resource]), ); diff --git a/src/renderer/utils/sync-box/provide-initial-values-for-sync-boxes.injectable.ts b/src/renderer/utils/sync-box/provide-initial-values-for-sync-boxes.injectable.ts index f813445855..3666bf0840 100644 --- a/src/renderer/utils/sync-box/provide-initial-values-for-sync-boxes.injectable.ts +++ b/src/renderer/utils/sync-box/provide-initial-values-for-sync-boxes.injectable.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { beforeFrameStartsInjectionToken } from "../../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../../before-frame-starts/tokens"; import { syncBoxInitialValueChannel } from "../../../common/utils/sync-box/channels"; import createSyncBoxStateInjectable from "../../../common/utils/sync-box/sync-box-state.injectable"; import { requestFromChannelInjectionToken } from "../../../common/utils/channel/request-from-channel-injection-token"; @@ -32,7 +32,7 @@ const provideInitialValuesForSyncBoxesInjectable = getInjectable({ }, }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, }); export default provideInitialValuesForSyncBoxesInjectable; diff --git a/src/renderer/vars/build-version/init.injectable.ts b/src/renderer/vars/build-version/init.injectable.ts index 7e7b7e9876..0734960289 100644 --- a/src/renderer/vars/build-version/init.injectable.ts +++ b/src/renderer/vars/build-version/init.injectable.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { beforeFrameStartsInjectionToken } from "../../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../../before-frame-starts/tokens"; import buildVersionInjectable from "./build-version.injectable"; const initializeBuildVersionInjectable = getInjectable({ @@ -16,7 +16,7 @@ const initializeBuildVersionInjectable = getInjectable({ await buildVersion.init(); }, }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, }); export default initializeBuildVersionInjectable; diff --git a/src/renderer/vars/default-update-channel/init.injectable.ts b/src/renderer/vars/default-update-channel/init.injectable.ts index c7435230c8..a349769815 100644 --- a/src/renderer/vars/default-update-channel/init.injectable.ts +++ b/src/renderer/vars/default-update-channel/init.injectable.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { beforeFrameStartsInjectionToken } from "../../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../../before-frame-starts/tokens"; import initReleaseChannelInjectable from "../release-channel/init.injectable"; import defaultUpdateChannelInjectable from "../../../features/application-update/common/selected-update-channel/default-update-channel.injectable"; @@ -18,7 +18,7 @@ const initDefaultUpdateChannelInjectable = getInjectable({ }, runAfter: di.inject(initReleaseChannelInjectable), }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, }); export default initDefaultUpdateChannelInjectable; diff --git a/src/renderer/vars/release-channel/init.injectable.ts b/src/renderer/vars/release-channel/init.injectable.ts index 016ec0826d..e0092abf55 100644 --- a/src/renderer/vars/release-channel/init.injectable.ts +++ b/src/renderer/vars/release-channel/init.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import releaseChannelInjectable from "../../../common/vars/release-channel.injectable"; -import { beforeFrameStartsInjectionToken } from "../../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../../before-frame-starts/tokens"; import initSemanticBuildVersionInjectable from "../semantic-build-version/init.injectable"; const initReleaseChannelInjectable = getInjectable({ @@ -18,7 +18,7 @@ const initReleaseChannelInjectable = getInjectable({ }, runAfter: di.inject(initSemanticBuildVersionInjectable), }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, }); export default initReleaseChannelInjectable; diff --git a/src/renderer/vars/semantic-build-version/init.injectable.ts b/src/renderer/vars/semantic-build-version/init.injectable.ts index bf9d3e02d4..62a9a3387f 100644 --- a/src/renderer/vars/semantic-build-version/init.injectable.ts +++ b/src/renderer/vars/semantic-build-version/init.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import buildSemanticVersionInjectable from "../../../common/vars/build-semantic-version.injectable"; -import { beforeFrameStartsInjectionToken } from "../../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../../before-frame-starts/tokens"; import initializeBuildVersionInjectable from "../build-version/init.injectable"; const initSemanticBuildVersionInjectable = getInjectable({ @@ -18,7 +18,7 @@ const initSemanticBuildVersionInjectable = getInjectable({ }, runAfter: di.inject(initializeBuildVersionInjectable), }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, }); export default initSemanticBuildVersionInjectable; diff --git a/src/test-utils/mock-responses.ts b/src/test-utils/mock-responses.ts new file mode 100644 index 0000000000..ce016cabc7 --- /dev/null +++ b/src/test-utils/mock-responses.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { Response, Headers as NodeFetchHeaders } from "node-fetch"; +import { PassThrough } from "stream"; + +export const createMockResponseFromString = (url: string, data: string, statusCode = 200) => { + const res: jest.Mocked = { + buffer: jest.fn(async () => { throw new Error("buffer() is not supported"); }), + clone: jest.fn(() => res), + arrayBuffer: jest.fn(async () => { throw new Error("arrayBuffer() is not supported"); }), + blob: jest.fn(async () => { throw new Error("blob() is not supported"); }), + body: new PassThrough(), + bodyUsed: false, + headers: new Headers() as NodeFetchHeaders, + json: jest.fn(async () => JSON.parse(await res.text())), + ok: 200 <= statusCode && statusCode < 300, + redirected: 300 <= statusCode && statusCode < 400, + size: data.length, + status: statusCode, + statusText: "some-text", + text: jest.fn(async () => data), + type: "basic", + url, + formData: jest.fn(async () => { throw new Error("formData() is not supported"); }), + }; + + return res; +}; + +export const createMockResponseFromStream = (url: string, stream: NodeJS.ReadableStream, statusCode = 200) => { + const res: jest.Mocked = { + buffer: jest.fn(async () => { throw new Error("buffer() is not supported"); }), + clone: jest.fn(() => res), + arrayBuffer: jest.fn(async () => { throw new Error("arrayBuffer() is not supported"); }), + blob: jest.fn(async () => { throw new Error("blob() is not supported"); }), + body: stream, + bodyUsed: false, + headers: new Headers() as NodeFetchHeaders, + json: jest.fn(async () => JSON.parse(await res.text())), + ok: 200 <= statusCode && statusCode < 300, + redirected: 300 <= statusCode && statusCode < 400, + size: 10, + status: statusCode, + statusText: "some-text", + text: jest.fn(() => { + const chunks: Buffer[] = []; + + return new Promise((resolve, reject) => { + stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))); + stream.on("error", (err) => reject(err)); + stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))); + }); + }), + type: "basic", + url, + formData: jest.fn(async () => { throw new Error("formData() is not supported"); }), + }; + + return res; +}; From 24240655c01f615fa6b4baea8b6496427536614b Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Tue, 20 Dec 2022 08:00:15 -0800 Subject: [PATCH 25/26] Split out use of httpsProxy preference (#6771) * Split out use of httpsProxy preference Signed-off-by: Sebastian Malton * Rename file Signed-off-by: Sebastian Malton Signed-off-by: Sebastian Malton --- src/common/fetch/download-json.injectable.ts | 55 ------------------- src/common/fetch/download-json/impl.ts | 46 ++++++++++++++++ .../fetch/download-json/normal.injectable.ts | 14 +++++ .../fetch/download-json/proxy.injectable.ts | 14 +++++ src/common/fetch/fetch-module.injectable.ts | 19 +++++++ src/common/fetch/fetch.injectable.ts | 23 ++------ src/common/fetch/proxy-fetch.injectable.ts | 30 ++++++++++ .../navigation-using-application-menu.test.ts | 8 --- ...est-public-helm-repositories.injectable.ts | 4 +- .../+extensions/__tests__/extensions.test.tsx | 6 -- .../attempt-install-by-info.injectable.tsx | 2 +- 11 files changed, 130 insertions(+), 91 deletions(-) delete mode 100644 src/common/fetch/download-json.injectable.ts create mode 100644 src/common/fetch/download-json/impl.ts create mode 100644 src/common/fetch/download-json/normal.injectable.ts create mode 100644 src/common/fetch/download-json/proxy.injectable.ts create mode 100644 src/common/fetch/fetch-module.injectable.ts create mode 100644 src/common/fetch/proxy-fetch.injectable.ts diff --git a/src/common/fetch/download-json.injectable.ts b/src/common/fetch/download-json.injectable.ts deleted file mode 100644 index 78a7d030d7..0000000000 --- a/src/common/fetch/download-json.injectable.ts +++ /dev/null @@ -1,55 +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 { RequestInit, Response } from "node-fetch"; -import type { AsyncResult } from "../utils/async-result"; -import fetchInjectable from "./fetch.injectable"; - -export interface DownloadJsonOptions { - signal?: AbortSignal | null | undefined; -} - -export type DownloadJson = (url: string, opts?: DownloadJsonOptions) => Promise>; - -const downloadJsonInjectable = getInjectable({ - id: "download-json", - instantiate: (di): DownloadJson => { - const fetch = di.inject(fetchInjectable); - - return async (url, opts) => { - let result: Response; - - try { - result = await fetch(url, opts as RequestInit); - } catch (error) { - return { - callWasSuccessful: false, - error: String(error), - }; - } - - if (result.status < 200 || 300 <= result.status) { - return { - callWasSuccessful: false, - error: result.statusText, - }; - } - - try { - return { - callWasSuccessful: true, - response: await result.json(), - }; - } catch (error) { - return { - callWasSuccessful: false, - error: String(error), - }; - } - }; - }, -}); - -export default downloadJsonInjectable; diff --git a/src/common/fetch/download-json/impl.ts b/src/common/fetch/download-json/impl.ts new file mode 100644 index 0000000000..9faf9af124 --- /dev/null +++ b/src/common/fetch/download-json/impl.ts @@ -0,0 +1,46 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { AsyncResult } from "../../utils/async-result"; +import type { Fetch } from "../fetch.injectable"; +import type { RequestInit, Response } from "node-fetch"; + +export interface DownloadJsonOptions { + signal?: AbortSignal | null | undefined; +} + +export type DownloadJson = (url: string, opts?: DownloadJsonOptions) => Promise>; + +export const downloadJsonWith = (fetch: Fetch): DownloadJson => async (url, opts) => { + let result: Response; + + try { + result = await fetch(url, opts as RequestInit); + } catch (error) { + return { + callWasSuccessful: false, + error: String(error), + }; + } + + if (result.status < 200 || 300 <= result.status) { + return { + callWasSuccessful: false, + error: result.statusText, + }; + } + + try { + return { + callWasSuccessful: true, + response: await result.json(), + }; + } catch (error) { + return { + callWasSuccessful: false, + error: String(error), + }; + } +}; + diff --git a/src/common/fetch/download-json/normal.injectable.ts b/src/common/fetch/download-json/normal.injectable.ts new file mode 100644 index 0000000000..adb5e35d82 --- /dev/null +++ b/src/common/fetch/download-json/normal.injectable.ts @@ -0,0 +1,14 @@ +/** + * 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 fetchInjectable from "../fetch.injectable"; +import { downloadJsonWith } from "./impl"; + +const downloadJsonInjectable = getInjectable({ + id: "download-json", + instantiate: (di) => downloadJsonWith(di.inject(fetchInjectable)), +}); + +export default downloadJsonInjectable; diff --git a/src/common/fetch/download-json/proxy.injectable.ts b/src/common/fetch/download-json/proxy.injectable.ts new file mode 100644 index 0000000000..46268d4ddb --- /dev/null +++ b/src/common/fetch/download-json/proxy.injectable.ts @@ -0,0 +1,14 @@ +/** + * 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 proxyFetchInjectable from "../proxy-fetch.injectable"; +import { downloadJsonWith } from "./impl"; + +const proxyDownloadJsonInjectable = getInjectable({ + id: "proxy-download-json", + instantiate: (di) => downloadJsonWith(di.inject(proxyFetchInjectable)), +}); + +export default proxyDownloadJsonInjectable; diff --git a/src/common/fetch/fetch-module.injectable.ts b/src/common/fetch/fetch-module.injectable.ts new file mode 100644 index 0000000000..444333f196 --- /dev/null +++ b/src/common/fetch/fetch-module.injectable.ts @@ -0,0 +1,19 @@ +/** + * 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 * as FetchModule from "node-fetch"; + +const { NodeFetch } = require("../../../build/webpack/node-fetch.bundle") as { NodeFetch: typeof FetchModule }; + +/** + * NOTE: while using this module can cause side effects, this specific injectable is not marked as + * such since sometimes the request can be wholely within the perview of unit test + */ +const nodeFetchModuleInjectable = getInjectable({ + id: "node-fetch-module", + instantiate: () => NodeFetch, +}); + +export default nodeFetchModuleInjectable; diff --git a/src/common/fetch/fetch.injectable.ts b/src/common/fetch/fetch.injectable.ts index bd1ba89db7..d4f51efe0d 100644 --- a/src/common/fetch/fetch.injectable.ts +++ b/src/common/fetch/fetch.injectable.ts @@ -3,32 +3,17 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { HttpsProxyAgent } from "hpagent"; -import type * as FetchModule from "node-fetch"; -import userStoreInjectable from "../user-store/user-store.injectable"; - -const { NodeFetch: { default: fetch }} = require("../../../build/webpack/node-fetch.bundle") as { NodeFetch: typeof FetchModule }; - -type Response = FetchModule.Response; -type RequestInit = FetchModule.RequestInit; +import type { RequestInit, Response } from "node-fetch"; +import nodeFetchModuleInjectable from "./fetch-module.injectable"; export type Fetch = (url: string, init?: RequestInit) => Promise; const fetchInjectable = getInjectable({ id: "fetch", instantiate: (di): Fetch => { - const { httpsProxy, allowUntrustedCAs } = di.inject(userStoreInjectable); - const agent = httpsProxy - ? new HttpsProxyAgent({ - proxy: httpsProxy, - rejectUnauthorized: !allowUntrustedCAs, - }) - : undefined; + const { default: fetch } = di.inject(nodeFetchModuleInjectable); - return (url, init = {}) => fetch(url, { - agent, - ...init, - }); + return (url, init) => fetch(url, init); }, causesSideEffects: true, }); diff --git a/src/common/fetch/proxy-fetch.injectable.ts b/src/common/fetch/proxy-fetch.injectable.ts new file mode 100644 index 0000000000..f13842c410 --- /dev/null +++ b/src/common/fetch/proxy-fetch.injectable.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { HttpsProxyAgent } from "hpagent"; +import userStoreInjectable from "../user-store/user-store.injectable"; +import type { Fetch } from "./fetch.injectable"; +import fetchInjectable from "./fetch.injectable"; + +const proxyFetchInjectable = getInjectable({ + id: "proxy-fetch", + instantiate: (di): Fetch => { + const fetch = di.inject(fetchInjectable); + const { httpsProxy, allowUntrustedCAs } = di.inject(userStoreInjectable); + const agent = httpsProxy + ? new HttpsProxyAgent({ + proxy: httpsProxy, + rejectUnauthorized: !allowUntrustedCAs, + }) + : undefined; + + return (url, init = {}) => fetch(url, { + agent, + ...init, + }); + }, +}); + +export default proxyFetchInjectable; diff --git a/src/features/extensions/navigation-using-application-menu.test.ts b/src/features/extensions/navigation-using-application-menu.test.ts index c17653d7a3..237e0a93a1 100644 --- a/src/features/extensions/navigation-using-application-menu.test.ts +++ b/src/features/extensions/navigation-using-application-menu.test.ts @@ -6,8 +6,6 @@ import type { RenderResult } 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 downloadBinaryInjectable, { type DownloadBinary } from "../../common/fetch/download-binary.injectable"; -import downloadJsonInjectable, { type DownloadJson } from "../../common/fetch/download-json.injectable"; import focusWindowInjectable from "../../renderer/navigation/focus-window.injectable"; // TODO: Make components free of side effects by making them deterministic @@ -17,20 +15,14 @@ describe("extensions - navigation using application menu", () => { let builder: ApplicationBuilder; let rendered: RenderResult; let focusWindowMock: jest.Mock; - let downloadJson: jest.MockedFunction; - let downloadBinary: jest.MockedFunction; beforeEach(async () => { builder = getApplicationBuilder(); builder.beforeWindowStart((windowDi) => { focusWindowMock = jest.fn(); - downloadJson = jest.fn().mockImplementation((url) => { throw new Error(`Unexpected call to downloadJson for url=${url}`); }); - downloadBinary = jest.fn().mockImplementation((url) => { throw new Error(`Unexpected call to downloadJson for url=${url}`); }); windowDi.override(focusWindowInjectable, () => focusWindowMock); - windowDi.override(downloadJsonInjectable, () => downloadJson); - windowDi.override(downloadBinaryInjectable, () => downloadBinary); }); rendered = await builder.render(); diff --git a/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable.ts b/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable.ts index 64e130aa09..325f3e305d 100644 --- a/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable.ts +++ b/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { sortBy } from "lodash/fp"; -import downloadJsonInjectable from "../../../../../../../common/fetch/download-json.injectable"; +import proxyDownloadJsonInjectable from "../../../../../../../common/fetch/download-json/proxy.injectable"; import { withTimeout } from "../../../../../../../common/fetch/timeout-controller"; import type { HelmRepo } from "../../../../../../../common/helm/helm-repo"; import loggerInjectable from "../../../../../../../common/logger.injectable"; @@ -15,7 +15,7 @@ const requestPublicHelmRepositoriesInjectable = getInjectable({ id: "request-public-helm-repositories", instantiate: (di) => { - const downloadJson = di.inject(downloadJsonInjectable); + const downloadJson = di.inject(proxyDownloadJsonInjectable); const logger = di.inject(loggerInjectable); return async (): Promise => { diff --git a/src/renderer/components/+extensions/__tests__/extensions.test.tsx b/src/renderer/components/+extensions/__tests__/extensions.test.tsx index b17b6bc782..751c1a38cc 100644 --- a/src/renderer/components/+extensions/__tests__/extensions.test.tsx +++ b/src/renderer/components/+extensions/__tests__/extensions.test.tsx @@ -25,9 +25,7 @@ import extensionInstallationStateStoreInjectable from "../../../../extensions/ex import { observable, when } from "mobx"; import type { RemovePath } from "../../../../common/fs/remove.injectable"; import removePathInjectable from "../../../../common/fs/remove.injectable"; -import type { DownloadJson } from "../../../../common/fetch/download-json.injectable"; import type { DownloadBinary } from "../../../../common/fetch/download-binary.injectable"; -import downloadJsonInjectable from "../../../../common/fetch/download-json.injectable"; import downloadBinaryInjectable from "../../../../common/fetch/download-binary.injectable"; import currentlyInClusterFrameInjectable from "../../../routes/currently-in-cluster-frame.injectable"; @@ -38,7 +36,6 @@ describe("Extensions", () => { let extensionInstallationStateStore: ExtensionInstallationStateStore; let render: DiRender; let deleteFileMock: jest.MockedFunction; - let downloadJson: jest.MockedFunction; let downloadBinary: jest.MockedFunction; beforeEach(() => { @@ -56,9 +53,6 @@ describe("Extensions", () => { deleteFileMock = jest.fn(); di.override(removePathInjectable, () => deleteFileMock); - downloadJson = jest.fn().mockImplementation((url) => { throw new Error(`Unexpected call to downloadJson for url=${url}`); }); - di.override(downloadJsonInjectable, () => downloadJson); - downloadBinary = jest.fn().mockImplementation((url) => { throw new Error(`Unexpected call to downloadJson for url=${url}`); }); di.override(downloadBinaryInjectable, () => downloadBinary); diff --git a/src/renderer/components/+extensions/attempt-install-by-info.injectable.tsx b/src/renderer/components/+extensions/attempt-install-by-info.injectable.tsx index 317162cc9f..1f3d65c802 100644 --- a/src/renderer/components/+extensions/attempt-install-by-info.injectable.tsx +++ b/src/renderer/components/+extensions/attempt-install-by-info.injectable.tsx @@ -15,7 +15,7 @@ import { reduce } from "lodash"; import getBasenameOfPathInjectable from "../../../common/path/get-basename.injectable"; import { withTimeout } from "../../../common/fetch/timeout-controller"; import downloadBinaryInjectable from "../../../common/fetch/download-binary.injectable"; -import downloadJsonInjectable from "../../../common/fetch/download-json.injectable"; +import downloadJsonInjectable from "../../../common/fetch/download-json/normal.injectable"; import type { PackageJson } from "type-fest"; import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable"; import loggerInjectable from "../../../common/logger.injectable"; From 4dac9a8b2b66cbb15946e3c4d5c2c8879b925f1e Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Tue, 20 Dec 2022 08:07:29 -0800 Subject: [PATCH 26/26] Fix broken import after PR merge (#6803) Signed-off-by: Sebastian Malton Signed-off-by: Sebastian Malton --- .../navigation/setup-logging-for-navigation.injectable.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/navigation/setup-logging-for-navigation.injectable.ts b/src/renderer/navigation/setup-logging-for-navigation.injectable.ts index b769b92db1..e6a1bce903 100644 --- a/src/renderer/navigation/setup-logging-for-navigation.injectable.ts +++ b/src/renderer/navigation/setup-logging-for-navigation.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import loggerInjectable from "../../common/logger.injectable"; -import { beforeFrameStartsInjectionToken } from "../before-frame-starts/tokens"; +import { beforeFrameStartsSecondInjectionToken } from "../before-frame-starts/tokens"; import observableHistoryInjectable from "./observable-history.injectable"; const setupLoggingForNavigationInjectable = getInjectable({ @@ -27,7 +27,7 @@ const setupLoggingForNavigationInjectable = getInjectable({ }); }, }), - injectionToken: beforeFrameStartsInjectionToken, + injectionToken: beforeFrameStartsSecondInjectionToken, }); export default setupLoggingForNavigationInjectable;