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
+
+
+
+
+
+ Chart: some-repository/some-name
+
+
+ content_copy
+
+
+
+ Copy
+
+
+
+
+ close
+
+
+
+ Close
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ some-description
+
+ Install
+
+
+
+
+ Version
+
+
+
+
+
+
+
+
+ some-other-version
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Maintainers
+
+
+
+ Some Foo<some@foo.com>
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts b/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts
index 9d6c43790d..6a28ea7284 100644
--- a/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts
+++ b/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts
@@ -178,7 +178,10 @@ describe("installing helm chart from new tab", () => {
}),
]);
- await requestHelmChartReadmeMock.resolve("some-readme");
+ await requestHelmChartReadmeMock.resolve({
+ callWasSuccessful: true,
+ response: "some-readme",
+ });
});
it("renders", () => {
@@ -472,7 +475,10 @@ describe("installing helm chart from new tab", () => {
}),
]);
- await requestHelmChartReadmeMock.resolve("some-readme");
+ await requestHelmChartReadmeMock.resolve({
+ callWasSuccessful: true,
+ response: "some-readme",
+ });
});
it("renders", () => {
diff --git a/src/features/helm-charts/installing-chart/opening-dock-tab-for-installing-helm-chart.test.ts b/src/features/helm-charts/installing-chart/opening-dock-tab-for-installing-helm-chart.test.ts
index c41a7f14ad..3fd6a7deb7 100644
--- a/src/features/helm-charts/installing-chart/opening-dock-tab-for-installing-helm-chart.test.ts
+++ b/src/features/helm-charts/installing-chart/opening-dock-tab-for-installing-helm-chart.test.ts
@@ -230,7 +230,10 @@ describe("opening dock tab for installing helm chart", () => {
describe("when readme resolves", () => {
beforeEach(async () => {
- await requestHelmChartReadmeMock.resolve("some-readme");
+ await requestHelmChartReadmeMock.resolve({
+ callWasSuccessful: true,
+ response: "some-readme",
+ });
});
it("renders", () => {
@@ -276,7 +279,10 @@ describe("opening dock tab for installing helm chart", () => {
describe("when readme resolves", () => {
beforeEach(async () => {
- await requestHelmChartReadmeMock.resolve("some-readme");
+ await requestHelmChartReadmeMock.resolve({
+ callWasSuccessful: true,
+ response: "some-readme",
+ });
});
it("renders", () => {
@@ -299,6 +305,19 @@ describe("opening dock tab for installing helm chart", () => {
);
});
});
+
+ describe("when readme rejects", () => {
+ beforeEach(async () => {
+ await requestHelmChartReadmeMock.resolve({
+ callWasSuccessful: false,
+ error: "some-error",
+ });
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+ });
});
describe("when selecting to install the chart", () => {
diff --git a/src/renderer/components/+helm-charts/details/readme-of-selected-helm-chart.injectable.ts b/src/renderer/components/+helm-charts/details/readme-of-selected-helm-chart.injectable.ts
index 839493bed3..8aa61a74da 100644
--- a/src/renderer/components/+helm-charts/details/readme-of-selected-helm-chart.injectable.ts
+++ b/src/renderer/components/+helm-charts/details/readme-of-selected-helm-chart.injectable.ts
@@ -26,11 +26,13 @@ const readmeOfSelectedHelmChartInjectable = getInjectable({
return "";
}
- return await requestHelmChartReadme(
+ const result = await requestHelmChartReadme(
chartVersion.getRepository(),
chartVersion.getName(),
chartVersion.getVersion(),
);
+
+ return result.callWasSuccessful ? result.response : "";
},
valueWhenPending: "",
From 50896350658e06f6e1f45b5ba58946cfe0e32fde Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 19 Dec 2022 08:15:36 -0500
Subject: [PATCH 10/26] Bump eslint from 8.29.0 to 8.30.0 (#6776)
Bumps [eslint](https://github.com/eslint/eslint) from 8.29.0 to 8.30.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.29.0...v8.30.0)
---
updated-dependencies:
- dependency-name: eslint
dependency-type: direct:development
update-type: version-update:semver-minor
...
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 | 44 ++++++++++++++++++++++----------------------
2 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/package.json b/package.json
index 3383a036cd..283a057693 100644
--- a/package.json
+++ b/package.json
@@ -367,7 +367,7 @@
"electron-notarize": "^0.3.0",
"esbuild": "^0.16.7",
"esbuild-loader": "^2.20.0",
- "eslint": "^8.29.0",
+ "eslint": "^8.30.0",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-header": "^3.1.1",
"eslint-plugin-import": "^2.26.0",
diff --git a/yarn.lock b/yarn.lock
index 7fa5790ffa..3af5316708 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -718,15 +718,15 @@
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.7.tgz#966ac3fc41758e6843cbd5844b2466bbdc34dada"
integrity sha512-QaQ8IH0JLacfGf5cf0HCCPnQuCTd/dAI257vXBgb/cccKGbH/6pVtI1gwhdAQ0Y48QSpTIFrh9etVyNdZY+zzw==
-"@eslint/eslintrc@^1.3.3":
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95"
- integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==
+"@eslint/eslintrc@^1.4.0":
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.0.tgz#8ec64e0df3e7a1971ee1ff5158da87389f167a63"
+ integrity sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
espree "^9.4.0"
- globals "^13.15.0"
+ globals "^13.19.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
js-yaml "^4.1.0"
@@ -861,14 +861,14 @@
"@hapi/bourne" "2.x.x"
"@hapi/hoek" "9.x.x"
-"@humanwhocodes/config-array@^0.11.6":
- version "0.11.6"
- resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.6.tgz#6a51d603a3aaf8d4cf45b42b3f2ac9318a4adc4b"
- integrity sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==
+"@humanwhocodes/config-array@^0.11.8":
+ version "0.11.8"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9"
+ integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==
dependencies:
"@humanwhocodes/object-schema" "^1.2.1"
debug "^4.1.1"
- minimatch "^3.0.4"
+ minimatch "^3.0.5"
"@humanwhocodes/module-importer@^1.0.1":
version "1.0.1"
@@ -5785,13 +5785,13 @@ eslint-visitor-keys@^3.3.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
-eslint@^8.29.0:
- version "8.29.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.29.0.tgz#d74a88a20fb44d59c51851625bc4ee8d0ec43f87"
- integrity sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==
+eslint@^8.30.0:
+ version "8.30.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.30.0.tgz#83a506125d089eef7c5b5910eeea824273a33f50"
+ integrity sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==
dependencies:
- "@eslint/eslintrc" "^1.3.3"
- "@humanwhocodes/config-array" "^0.11.6"
+ "@eslint/eslintrc" "^1.4.0"
+ "@humanwhocodes/config-array" "^0.11.8"
"@humanwhocodes/module-importer" "^1.0.1"
"@nodelib/fs.walk" "^1.2.8"
ajv "^6.10.0"
@@ -5810,7 +5810,7 @@ eslint@^8.29.0:
file-entry-cache "^6.0.1"
find-up "^5.0.0"
glob-parent "^6.0.2"
- globals "^13.15.0"
+ globals "^13.19.0"
grapheme-splitter "^1.0.4"
ignore "^5.2.0"
import-fresh "^3.0.0"
@@ -6598,10 +6598,10 @@ globals@^11.1.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
-globals@^13.15.0:
- version "13.15.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-13.15.0.tgz#38113218c907d2f7e98658af246cef8b77e90bac"
- integrity sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==
+globals@^13.19.0:
+ version "13.19.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-13.19.0.tgz#7a42de8e6ad4f7242fbcca27ea5b23aca367b5c8"
+ integrity sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==
dependencies:
type-fest "^0.20.2"
@@ -9081,7 +9081,7 @@ minimatch@3.0.4:
dependencies:
brace-expansion "^1.1.7"
-minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.2:
+minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
From f302fa94d5721a34606eed276d40ed37cf9692cb Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 19 Dec 2022 08:15:47 -0500
Subject: [PATCH 11/26] Bump sass from 1.56.1 to 1.57.0 (#6777)
Bumps [sass](https://github.com/sass/dart-sass) from 1.56.1 to 1.57.0.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.56.1...1.57.0)
---
updated-dependencies:
- dependency-name: sass
dependency-type: direct:development
update-type: version-update:semver-minor
...
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 283a057693..d642c77e60 100644
--- a/package.json
+++ b/package.json
@@ -404,7 +404,7 @@
"react-select-event": "^5.5.1",
"react-table": "^7.8.0",
"react-window": "^1.8.8",
- "sass": "^1.56.1",
+ "sass": "^1.57.0",
"sass-loader": "^12.6.0",
"sharp": "^0.31.2",
"style-loader": "^3.3.1",
diff --git a/yarn.lock b/yarn.lock
index 3af5316708..01bc4eec00 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -11299,10 +11299,10 @@ sass-loader@^12.6.0:
klona "^2.0.4"
neo-async "^2.6.2"
-sass@^1.32.13, sass@^1.56.1:
- version "1.56.1"
- resolved "https://registry.yarnpkg.com/sass/-/sass-1.56.1.tgz#94d3910cd468fd075fa87f5bb17437a0b617d8a7"
- integrity sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==
+sass@^1.32.13, sass@^1.57.0:
+ version "1.57.0"
+ resolved "https://registry.yarnpkg.com/sass/-/sass-1.57.0.tgz#64c4144ed4e1c0ccb96dc18aef2c424cdbc0c12b"
+ integrity sha512-IZNEJDTK1cF5B1cGA593TPAV/1S0ysUDxq9XHjX/+SMy0QfUny+nfUsq5ZP7wWSl4eEf7wDJcEZ8ABYFmh3m/w==
dependencies:
chokidar ">=3.0.0 <4.0.0"
immutable "^4.0.0"
From 511d6affb07199fee05993c1e5167e917d659631 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 19 Dec 2022 08:15:58 -0500
Subject: [PATCH 12/26] Bump esbuild from 0.16.7 to 0.16.9 (#6778)
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.16.7 to 0.16.9.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.16.7...v0.16.9)
---
updated-dependencies:
- dependency-name: esbuild
dependency-type: direct:development
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 | 228 +++++++++++++++++++++++++--------------------------
2 files changed, 115 insertions(+), 115 deletions(-)
diff --git a/package.json b/package.json
index d642c77e60..88b5e267c3 100644
--- a/package.json
+++ b/package.json
@@ -365,7 +365,7 @@
"electron": "^19.1.9",
"electron-builder": "^23.6.0",
"electron-notarize": "^0.3.0",
- "esbuild": "^0.16.7",
+ "esbuild": "^0.16.9",
"esbuild-loader": "^2.20.0",
"eslint": "^8.30.0",
"eslint-import-resolver-typescript": "^3.5.2",
diff --git a/yarn.lock b/yarn.lock
index 01bc4eec00..5853daebeb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -598,125 +598,125 @@
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
-"@esbuild/android-arm64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.7.tgz#2df472016c77dba3e79596a84da74c541698910f"
- integrity sha512-tYFw0lBJSEvLoGzzYh1kXuzoX1iPkbOk3O29VqzQb0HbOy7t/yw1hGkvwoJhXHwzQUPsShyYcTgRf6bDBcfnTw==
+"@esbuild/android-arm64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.9.tgz#474da719599f99d820ec010c92846a4f685fa28a"
+ integrity sha512-ndIAZJUeLx4O+4AJbFQCurQW4VRUXjDsUvt1L+nP8bVELOWdmdCEOtlIweCUE6P+hU0uxYbEK2AEP0n5IVQvhg==
"@esbuild/android-arm@0.15.18":
version "0.15.18"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz#266d40b8fdcf87962df8af05b76219bc786b4f80"
integrity sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==
-"@esbuild/android-arm@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.7.tgz#15f1a9b27b1637c38377b3e1f2d90b9782cdc141"
- integrity sha512-yhzDbiVcmq6T1/XEvdcJIVcXHdLjDJ5cQ0Dp9R9p9ERMBTeO1dR5tc8YYv8zwDeBw1xZm+Eo3MRo8cwclhBS0g==
+"@esbuild/android-arm@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.9.tgz#b0747ec074bba3ca652bfa8de3f55acfbb2d259e"
+ integrity sha512-kW5ccqWHVOOTGUkkJbtfoImtqu3kA1PFkivM+9QPFSHphPfPBlBalX9eDRqPK+wHCqKhU48/78T791qPgC9e9A==
-"@esbuild/android-x64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.7.tgz#cb34b7d666bf52266061cfb1a19c1d788b6c5ac1"
- integrity sha512-3P2OuTxwAtM3k/yEWTNUJRjMPG1ce8rXs51GTtvEC5z1j8fC1plHeVVczdeHECU7aM2/Buc0MwZ6ciM/zysnWg==
+"@esbuild/android-x64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.9.tgz#1cd75e8ed7d6d7eb5f9896f623df63882bd8e887"
+ integrity sha512-UbMcJB4EHrAVOnknQklREPgclNU2CPet2h+sCBCXmF2mfoYWopBn/CfTfeyOkb/JglOcdEADqAljFndMKnFtOw==
-"@esbuild/darwin-arm64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.7.tgz#be1fabd0c2f6af111c16e9e9b18bf336c1e11634"
- integrity sha512-VUb9GK23z8jkosHU9yJNUgQpsfJn+7ZyBm6adi2Ec5/U241eR1tAn82QicnUzaFDaffeixiHwikjmnec/YXEZg==
+"@esbuild/darwin-arm64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.9.tgz#820c88738cd97621737abcd5f05400ae5e0c66e6"
+ integrity sha512-d7D7/nrt4CxPul98lx4PXhyNZwTYtbdaHhOSdXlZuu5zZIznjqtMqLac8Bv+IuT6SVHiHUwrkL6ywD7mOgLW+A==
-"@esbuild/darwin-x64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.7.tgz#2206042ac4396bb18dd53b379df83bec47eeb5fb"
- integrity sha512-duterlv3tit3HI9vhzMWnSVaB1B6YsXpFq1Ntd6Fou82BB1l4tucYy3FI9dHv3tvtDuS0NiGf/k6XsdBqPZ01w==
+"@esbuild/darwin-x64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.9.tgz#5a19c00781595e0dfeef1826b3512d04c37b98ff"
+ integrity sha512-LZc+Wlz06AkJYtwWsBM3x2rSqTG8lntDuftsUNQ3fCx9ZttYtvlDcVtgb+NQ6t9s6K5No5zutN3pcjZEC2a4iQ==
-"@esbuild/freebsd-arm64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.7.tgz#ca52bd64b0bba69ae4063245366f25838357c332"
- integrity sha512-9kkycpBFes/vhi7B7o0cf+q2WdJi+EpVzpVTqtWFNiutARWDFFLcB93J8PR1cG228sucsl3B+7Ts27izE6qiaQ==
+"@esbuild/freebsd-arm64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.9.tgz#2b7c16f5d15c259ed279b293b97c28c4a4bb107f"
+ integrity sha512-gIj0UQZlQo93CHYouHKkpzP7AuruSaMIm1etcWIxccFEVqCN1xDr6BWlN9bM+ol/f0W9w3hx3HDuEwcJVtGneQ==
-"@esbuild/freebsd-x64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.7.tgz#bc01c146e6af5430c5eb325844de43f01e0264c4"
- integrity sha512-5Ahf6jzWXJ4J2uh9dpy5DKOO+PeRUE/9DMys6VuYfwgQzd6n5+pVFm58L2Z2gRe611RX6SdydnNaiIKM3svY7g==
+"@esbuild/freebsd-x64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.9.tgz#2db48ffeeab149c2b970494a60b82bf3004b8630"
+ integrity sha512-GNors4vaMJ7lzGOuhzNc7jvgsQZqErGA8rsW+nck8N1nYu86CvsJW2seigVrQQWOV4QzEP8Zf3gm+QCjA2hnBQ==
-"@esbuild/linux-arm64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.7.tgz#23267ff1cdd2a8f150d5aca1d6d2a4dfd4be7909"
- integrity sha512-2wv0xYDskk2+MzIm/AEprDip39a23Chptc4mL7hsHg26P0gD8RUhzmDu0KCH2vMThUI1sChXXoK9uH0KYQKaDg==
+"@esbuild/linux-arm64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.9.tgz#4c63c9f8ddd690d140ac3e0f360226d3fcdd75d8"
+ integrity sha512-YPxQunReYp8RQ1FvexFrOEqqf+nLbS3bKVZF5FRT2uKM7Wio7BeATqAwO02AyrdSEntt3I5fhFsujUChIa8CZg==
-"@esbuild/linux-arm@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.7.tgz#2c7cf7244e4b8a6f757a87a113d83d8a0c1f5297"
- integrity sha512-QqJnyCfu5OF78Olt7JJSZ7OSv/B4Hf+ZJWp4kkq9xwMsgu7yWq3crIic8gGOpDYTqVKKMDAVDgRXy5Wd/nWZyQ==
+"@esbuild/linux-arm@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.9.tgz#7704de1c2a30bc68d8f615d3ecb1cf68f001256a"
+ integrity sha512-cNx1EF99c2t1Ztn0lk9N+MuwBijGF8mH6nx9GFsB3e0lpUpPkCE/yt5d+7NP9EwJf5uzqdjutgVYoH1SNqzudA==
-"@esbuild/linux-ia32@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.7.tgz#a15dc3edf6953c5414add4264fd8335f48775490"
- integrity sha512-APVYbEilKbD5ptmKdnIcXej2/+GdV65TfTjxR2Uk8t1EsOk49t6HapZW6DS/Bwlvh5hDwtLapdSumIVNGxgqLg==
+"@esbuild/linux-ia32@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.9.tgz#bf0fda9f046e6c8332d7c8350b8a94d63acb4ceb"
+ integrity sha512-zb12ixDIKNwFpIqR00J88FFitVwOEwO78EiUi8wi8FXlmSc3GtUuKV/BSO+730Kglt0B47+ZrJN1BhhOxZaVrw==
"@esbuild/linux-loong64@0.15.18":
version "0.15.18"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz#128b76ecb9be48b60cf5cfc1c63a4f00691a3239"
integrity sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==
-"@esbuild/linux-loong64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.7.tgz#b3ce8539cf307b543796530839cf62507d9c7e84"
- integrity sha512-5wPUAGclplQrAW7EFr3F84Y/d++7G0KykohaF4p54+iNWhUnMVU8Bh2sxiEOXUy4zKIdpHByMgJ5/Ko6QhtTUw==
+"@esbuild/linux-loong64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.9.tgz#c16378b898fa38f5f788f76fbce16a45c49c8793"
+ integrity sha512-X8te4NLxtHiNT6H+4Pfm5RklzItA1Qy4nfyttihGGX+Koc53Ar20ViC+myY70QJ8PDEOehinXZj/F7QK3A+MKQ==
-"@esbuild/linux-mips64el@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.7.tgz#7c1c8f3de254b4e975ac2580bba187b87b959256"
- integrity sha512-hxzlXtWF6yWfkE/SMTscNiVqLOAn7fOuIF3q/kiZaXxftz1DhZW/HpnTmTTWrzrS7zJWQxHHT4QSxyAj33COmA==
+"@esbuild/linux-mips64el@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.9.tgz#492605f13f19dc06c350d94e4048c21478b9dec4"
+ integrity sha512-ZqyMDLt02c5smoS3enlF54ndK5zK4IpClLTxF0hHfzHJlfm4y8IAkIF8LUW0W7zxcKy7oAwI7BRDqeVvC120SA==
-"@esbuild/linux-ppc64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.7.tgz#72a00c9788f3ca5df56ecec060d5b92f945c9a2d"
- integrity sha512-WM83Dac0LdXty5xPhlOuCD5Egfk1xLND/oRLYeB7Jb/tY4kzFSDgLlq91wYbHua/s03tQGA9iXvyjgymMw62Vw==
+"@esbuild/linux-ppc64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.9.tgz#ccaf759fc4f7a5fe72bdac05b4f5bf18ef1fe01b"
+ integrity sha512-k+ca5W5LDBEF3lfDwMV6YNXwm4wEpw9krMnNvvlNz3MrKSD2Eb2c861O0MaKrZkG/buTQAP4vkavbLwgIe6xjg==
-"@esbuild/linux-riscv64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.7.tgz#545fd57e44dc3331a86956889f2a5b42bd116c9b"
- integrity sha512-3nkNnNg4Ax6MS/l8O8Ynq2lGEVJYyJ2EoY3PHjNJ4PuZ80EYLMrFTFZ4L/Hc16AxgtXKwmNP9TM0YKNiBzBiJQ==
+"@esbuild/linux-riscv64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.9.tgz#542d0e68bc99fb658fe732b0917931c09775f1a3"
+ integrity sha512-GuInVdogjmg9DhgkEmNipHkC+3tzkanPJzgzTC2ihsvrruLyFoR1YrTGixblNSMPudQLpiqkcwGwwe0oqfrvfA==
-"@esbuild/linux-s390x@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.7.tgz#a36fd4605904c49310616dd648c0c25a267a19c0"
- integrity sha512-3SA/2VJuv0o1uD7zuqxEP+RrAyRxnkGddq0bwHQ98v1KNlzXD/JvxwTO3T6GM5RH6JUd29RTVQTOJfyzMkkppA==
+"@esbuild/linux-s390x@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.9.tgz#4398f9d9d64dba4cfa6eed267476eaa9c9b7f214"
+ integrity sha512-49wQ0aYkvwXonGsxc7LuuLNICMX8XtO92Iqmug5Qau0kpnV6SP34jk+jIeu4suHwAbSbRhVFtDv75yRmyfQcHw==
-"@esbuild/linux-x64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.7.tgz#104f3f8f3f25f1f26b70cee05470974861ca5a5e"
- integrity sha512-xi/tbqCqvPIzU+zJVyrpz12xqciTAPMi2fXEWGnapZymoGhuL2GIWIRXg4O2v5BXaYA5TSaiKYE14L0QhUTuQg==
+"@esbuild/linux-x64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.9.tgz#67c6b418ef36addbca17af0d7a2274c37ddffba2"
+ integrity sha512-Nx4oKEAJ6EcQlt4dK7qJyuZUoXZG7CAeY22R7rqZijFzwFfMOD+gLP56uV7RrV86jGf8PeRY8TBsRmOcZoG42w==
-"@esbuild/netbsd-x64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.7.tgz#0fd59fea5e6b94ee82e81b3b389e561efe77b347"
- integrity sha512-NUsYbq3B+JdNKn8SXkItFvdes9qTwEoS3aLALtiWciW/ystiCKM20Fgv9XQBOXfhUHyh5CLEeZDXzLOrwBXuCQ==
+"@esbuild/netbsd-x64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.9.tgz#22ed58e404ebeb2475b821bc4e25f1027eb0c912"
+ integrity sha512-d0WnpgJ+FTiMZXEQ1NOv9+0gvEhttbgKEvVqWWAtl1u9AvlspKXbodKHzQ5MLP6YV1y52Xp+p8FMYqj8ykTahg==
-"@esbuild/openbsd-x64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.7.tgz#c04072a70f31be1bd47204955d2c71ca393c9eb4"
- integrity sha512-qjwzsgeve9I8Tbsko2FEkdSk2iiezuNGFgipQxY/736NePXDaDZRodIejYGWOlbYXugdxb0nif5yvypH6lKBmA==
+"@esbuild/openbsd-x64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.9.tgz#2b2597b4edd4d26946f7c56838680fbeb4d455eb"
+ integrity sha512-jccK11278dvEscHFfMk5EIPjF4wv1qGD0vps7mBV1a6TspdR36O28fgPem/SA/0pcsCPHjww5ouCLwP+JNAFlw==
-"@esbuild/sunos-x64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.7.tgz#11c4cd341be1de93cb5e3bf096f3b63ae1497626"
- integrity sha512-mFWDz4RoBTzPphTCkM7Kc7Qpa0o/Z01acajR+Ai7LdfKgcP/C6jYOaKwv7nKzD0+MjOT20j7You9g4ozYy1dKQ==
+"@esbuild/sunos-x64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.9.tgz#c132603a19ef79c0d7bd95afb09f41618ea8dda2"
+ integrity sha512-OetwTSsv6mIDLqN7I7I2oX9MmHGwG+AP+wKIHvq+6sIHwcPPJqRx+DJB55jy9JG13CWcdcQno/7V5MTJ5a0xfQ==
-"@esbuild/win32-arm64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.7.tgz#95091269394f16352e318124790a3906bf370141"
- integrity sha512-m39UmX19RvEIuC8sYZ0M+eQtdXw4IePDSZ78ZQmYyFaXY9krq4YzQCK2XWIJomNLtg4q+W5aXr8bW3AbqWNoVg==
+"@esbuild/win32-arm64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.9.tgz#bf74d007d7f0fe1fe32c4fff82d27b271b3e1d58"
+ integrity sha512-tKSSSK6unhxbGbHg+Cc+JhRzemkcsX0tPBvG0m5qsWbkShDK9c+/LSb13L18LWVdOQZwuA55Vbakxmt6OjBDOQ==
-"@esbuild/win32-ia32@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.7.tgz#2bda285a0b7084a93417472c460b0209bef0c39d"
- integrity sha512-1cbzSEZA1fANwmT6rjJ4G1qQXHxCxGIcNYFYR9ctI82/prT38lnwSRZ0i5p/MVXksw9eMlHlet6pGu2/qkXFCg==
+"@esbuild/win32-ia32@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.9.tgz#e46478e77431bca1a8b80f6260fc6b0020aa8127"
+ integrity sha512-ZTQ5vhNS5gli0KK8I6/s6+LwXmNEfq1ftjnSVyyNm33dBw8zDpstqhGXYUbZSWWLvkqiRRjgxgmoncmi6Yy7Ng==
-"@esbuild/win32-x64@0.16.7":
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.7.tgz#966ac3fc41758e6843cbd5844b2466bbdc34dada"
- integrity sha512-QaQ8IH0JLacfGf5cf0HCCPnQuCTd/dAI257vXBgb/cccKGbH/6pVtI1gwhdAQ0Y48QSpTIFrh9etVyNdZY+zzw==
+"@esbuild/win32-x64@0.16.9":
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.9.tgz#4595a29c2930c5157aa1be0963abbbac989647c9"
+ integrity sha512-C4ZX+YFIp6+lPrru3tpH6Gaapy8IBRHw/e7l63fzGDhn/EaiGpQgbIlT5paByyy+oMvRFQoxxyvC4LE0AjJMqQ==
"@eslint/eslintrc@^1.4.0":
version "1.4.0"
@@ -5584,33 +5584,33 @@ esbuild@^0.15.6:
esbuild-windows-64 "0.15.18"
esbuild-windows-arm64 "0.15.18"
-esbuild@^0.16.7:
- version "0.16.7"
- resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.7.tgz#3288f685a83c6097dea8ddf1759ca30d6e06535b"
- integrity sha512-P6OBFYFSQOGzfApqCeYKqfKRRbCIRsdppTXFo4aAvtiW3o8TTyiIplBvHJI171saPAiy3WlawJHCveJVIOIx1A==
+esbuild@^0.16.9:
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.9.tgz#01b6c3a6cbc072108253ac160a0734229bf8c921"
+ integrity sha512-gkH83yHyijMSZcZFs1IWew342eMdFuWXmQo3zkDPTre25LIPBJsXryg02M3u8OpTwCJdBkdaQwqKkDLnAsAeLQ==
optionalDependencies:
- "@esbuild/android-arm" "0.16.7"
- "@esbuild/android-arm64" "0.16.7"
- "@esbuild/android-x64" "0.16.7"
- "@esbuild/darwin-arm64" "0.16.7"
- "@esbuild/darwin-x64" "0.16.7"
- "@esbuild/freebsd-arm64" "0.16.7"
- "@esbuild/freebsd-x64" "0.16.7"
- "@esbuild/linux-arm" "0.16.7"
- "@esbuild/linux-arm64" "0.16.7"
- "@esbuild/linux-ia32" "0.16.7"
- "@esbuild/linux-loong64" "0.16.7"
- "@esbuild/linux-mips64el" "0.16.7"
- "@esbuild/linux-ppc64" "0.16.7"
- "@esbuild/linux-riscv64" "0.16.7"
- "@esbuild/linux-s390x" "0.16.7"
- "@esbuild/linux-x64" "0.16.7"
- "@esbuild/netbsd-x64" "0.16.7"
- "@esbuild/openbsd-x64" "0.16.7"
- "@esbuild/sunos-x64" "0.16.7"
- "@esbuild/win32-arm64" "0.16.7"
- "@esbuild/win32-ia32" "0.16.7"
- "@esbuild/win32-x64" "0.16.7"
+ "@esbuild/android-arm" "0.16.9"
+ "@esbuild/android-arm64" "0.16.9"
+ "@esbuild/android-x64" "0.16.9"
+ "@esbuild/darwin-arm64" "0.16.9"
+ "@esbuild/darwin-x64" "0.16.9"
+ "@esbuild/freebsd-arm64" "0.16.9"
+ "@esbuild/freebsd-x64" "0.16.9"
+ "@esbuild/linux-arm" "0.16.9"
+ "@esbuild/linux-arm64" "0.16.9"
+ "@esbuild/linux-ia32" "0.16.9"
+ "@esbuild/linux-loong64" "0.16.9"
+ "@esbuild/linux-mips64el" "0.16.9"
+ "@esbuild/linux-ppc64" "0.16.9"
+ "@esbuild/linux-riscv64" "0.16.9"
+ "@esbuild/linux-s390x" "0.16.9"
+ "@esbuild/linux-x64" "0.16.9"
+ "@esbuild/netbsd-x64" "0.16.9"
+ "@esbuild/openbsd-x64" "0.16.9"
+ "@esbuild/sunos-x64" "0.16.9"
+ "@esbuild/win32-arm64" "0.16.9"
+ "@esbuild/win32-ia32" "0.16.9"
+ "@esbuild/win32-x64" "0.16.9"
escalade@^3.1.1:
version "3.1.1"
From 8b752981a0229dbefa34cc28d985cccb1e3bd5fc Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 19 Dec 2022 08:16:42 -0500
Subject: [PATCH 13/26] Bump playwright from 1.28.1 to 1.29.0 (#6779)
Bumps [playwright](https://github.com/Microsoft/playwright) from 1.28.1 to 1.29.0.
- [Release notes](https://github.com/Microsoft/playwright/releases)
- [Commits](https://github.com/Microsoft/playwright/compare/v1.28.1...v1.29.0)
---
updated-dependencies:
- dependency-name: playwright
dependency-type: direct:development
update-type: version-update:semver-minor
...
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 | 18 +++++++++---------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/package.json b/package.json
index 88b5e267c3..c6258f0668 100644
--- a/package.json
+++ b/package.json
@@ -391,7 +391,7 @@
"node-gyp": "^8.3.0",
"node-loader": "^2.0.0",
"nodemon": "^2.0.20",
- "playwright": "^1.28.1",
+ "playwright": "^1.29.0",
"postcss": "^8.4.20",
"postcss-loader": "^6.2.1",
"query-string": "^7.1.3",
diff --git a/yarn.lock b/yarn.lock
index 5853daebeb..8c1cc6e72b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10241,17 +10241,17 @@ pkg-up@^3.1.0:
dependencies:
find-up "^3.0.0"
-playwright-core@1.28.1:
- version "1.28.1"
- resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.28.1.tgz#8400be9f4a8d1c0489abdb9e75a4cc0ffc3c00cb"
- integrity sha512-3PixLnGPno0E8rSBJjtwqTwJe3Yw72QwBBBxNoukIj3lEeBNXwbNiKrNuB1oyQgTBw5QHUhNO3SteEtHaMK6ag==
+playwright-core@1.29.0:
+ version "1.29.0"
+ resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.29.0.tgz#314653618395afef5031156d691c7aa0826e5d05"
+ integrity sha512-pboOm1m0RD6z1GtwAbEH60PYRfF87vKdzOSRw2RyO0Y0a7utrMyWN2Au1ojGvQr4umuBMODkKTv607YIRypDSQ==
-playwright@^1.28.1:
- version "1.28.1"
- resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.28.1.tgz#f23247f1de466ff73d7230d94df96271e5da6583"
- integrity sha512-92Sz6XBlfHlb9tK5UCDzIFAuIkHHpemA9zwUaqvo+w7sFMSmVMGmvKcbptof/eJObq63PGnMhM75x7qxhTR78Q==
+playwright@^1.29.0:
+ version "1.29.0"
+ resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.29.0.tgz#14b70f373a7d433b9e304ee1666cb70e93336364"
+ integrity sha512-vtXgX3FPNcAJq1QoIVCvmiHHKOLVTZkSYEo60n+EnX5MrNznAJzGquxT8c2sv+BG3CDyLeKm351e491HnF7yjw==
dependencies:
- playwright-core "1.28.1"
+ playwright-core "1.29.0"
plist@^3.0.1, plist@^3.0.4:
version "3.0.5"
From e0bccfabd4b0ddf61b2a72aa9c2c051db0e08a97 Mon Sep 17 00:00:00 2001
From: Alex Andreev
Date: Mon, 19 Dec 2022 17:00:13 +0300
Subject: [PATCH 14/26] Fix app crash opening Install Chart dock tab (#6782)
* Change type of RequestHelmChartValues to be AsyncResult
Signed-off-by: Alex Andreev
* Fixing tests
Signed-off-by: Alex Andreev
* Linter fix
Signed-off-by: Alex Andreev
Signed-off-by: Alex Andreev
---
.../request-values.injectable.ts | 3 +-
...installing-helm-chart-from-new-tab.test.ts | 35 +++++++++++--------
...m-chart-from-previously-opened-tab.test.ts | 7 ++--
.../install-chart-model.injectable.tsx | 13 ++++---
4 files changed, 35 insertions(+), 23 deletions(-)
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 c48461bba5..71105c9ff9 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
@@ -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 requestValuesEndpoint = urlBuilderFor("/v2/charts/:repo/:name/values");
-export type RequestHelmChartValues = (repo: string, name: string, version: string) => Promise;
+export type RequestHelmChartValues = (repo: string, name: string, version: string) => Promise>;
const requestHelmChartValuesInjectable = getInjectable({
id: "request-helm-chart-values",
diff --git a/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts b/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts
index 6a28ea7284..f7aef8dd88 100644
--- a/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts
+++ b/src/features/helm-charts/installing-chart/installing-helm-chart-from-new-tab.test.ts
@@ -240,9 +240,10 @@ describe("installing helm chart from new tab", () => {
describe("when default configuration and versions resolve", () => {
beforeEach(async () => {
- await requestHelmChartValuesMock.resolve(
- "some-default-configuration",
- );
+ await requestHelmChartValuesMock.resolve({
+ callWasSuccessful: true,
+ response: "some-default-configuration",
+ });
await requestHelmChartVersionsMock.resolve([
HelmChart.create({
@@ -537,9 +538,10 @@ describe("installing helm chart from new tab", () => {
describe("when configuration and versions resolve", () => {
beforeEach(async () => {
- await requestHelmChartValuesMock.resolve(
- "some-other-default-configuration",
- );
+ await requestHelmChartValuesMock.resolve({
+ callWasSuccessful: true,
+ response: "some-other-default-configuration",
+ });
await requestHelmChartVersionsMock.resolve([]);
});
@@ -702,9 +704,10 @@ describe("installing helm chart from new tab", () => {
describe("when default configuration resolves", () => {
beforeEach(async () => {
- await requestHelmChartValuesMock.resolve(
- "some-default-configuration-for-other-version",
- );
+ await requestHelmChartValuesMock.resolve({
+ callWasSuccessful: true,
+ response: "some-default-configuration-for-other-version",
+ });
});
it("renders", () => {
@@ -847,9 +850,10 @@ describe("installing helm chart from new tab", () => {
)
.selectOption("some-other-version");
- await requestHelmChartValuesMock.resolve(
- "some-default-configuration-for-other-version",
- );
+ await requestHelmChartValuesMock.resolve({
+ callWasSuccessful: true,
+ response: "some-default-configuration-for-other-version",
+ });
expect(installButton).not.toHaveAttribute("disabled");
});
@@ -920,9 +924,10 @@ describe("installing helm chart from new tab", () => {
)
.selectOption("some-other-version");
- await requestHelmChartValuesMock.resolve(
- "some-default-configuration-for-other-version",
- );
+ await requestHelmChartValuesMock.resolve({
+ callWasSuccessful: true,
+ response: "some-default-configuration-for-other-version",
+ });
const input = rendered.getByTestId(
"monaco-editor-for-some-first-tab-id",
diff --git a/src/features/helm-charts/installing-chart/installing-helm-chart-from-previously-opened-tab.test.ts b/src/features/helm-charts/installing-chart/installing-helm-chart-from-previously-opened-tab.test.ts
index 978e1635a7..0b4f749acc 100644
--- a/src/features/helm-charts/installing-chart/installing-helm-chart-from-previously-opened-tab.test.ts
+++ b/src/features/helm-charts/installing-chart/installing-helm-chart-from-previously-opened-tab.test.ts
@@ -149,9 +149,10 @@ describe("installing helm chart from previously opened tab", () => {
describe("when configuration and version resolves", () => {
beforeEach(async () => {
- await requestHelmChartValuesMock.resolve(
- "some-default-configuration",
- );
+ await requestHelmChartValuesMock.resolve({
+ callWasSuccessful: true,
+ response: "some-default-configuration",
+ });
await requestHelmChartVersionsMock.resolve([
HelmChart.create({
diff --git a/src/renderer/components/dock/install-chart/install-chart-model.injectable.tsx b/src/renderer/components/dock/install-chart/install-chart-model.injectable.tsx
index 0db94fbd59..b0bfcfcacc 100644
--- a/src/renderer/components/dock/install-chart/install-chart-model.injectable.tsx
+++ b/src/renderer/components/dock/install-chart/install-chart-model.injectable.tsx
@@ -122,14 +122,18 @@ export class InstallChartModel {
this.configuration.isLoading.set(true);
});
- const configuration = await this.dependencies.requestHelmChartValues(
+ const chartValuesRequest = await this.dependencies.requestHelmChartValues(
this.chart.repo,
this.chart.name,
version,
);
+ if (!chartValuesRequest.callWasSuccessful) {
+ throw chartValuesRequest.error;
+ }
+
runInAction(() => {
- this.configuration.onChange(configuration);
+ this.configuration.onChange(chartValuesRequest.response);
this.configuration.isLoading.set(false);
});
},
@@ -187,7 +191,7 @@ export class InstallChartModel {
load = async () => {
await this.dependencies.waitForChart();
- const [defaultConfiguration, versions] = await Promise.all([
+ const [defaultConfigurationRequest, versions] = await Promise.all([
this.dependencies.requestHelmChartValues(
this.chart.repo,
this.chart.name,
@@ -203,13 +207,14 @@ export class InstallChartModel {
runInAction(() => {
// TODO: Make "default" not hard-coded
const namespace = this.chart.namespace || "default";
+ const values = this.chart.values || (defaultConfigurationRequest.callWasSuccessful ? defaultConfigurationRequest.response : "");
this.versions.replace(versions);
this.save({
version: this.chart.version,
namespace,
- values: this.chart.values || defaultConfiguration,
+ values,
releaseName: this.chart.releaseName,
});
});
From 56197d8e2e3d00a47a56142aed6eafe0fe031812 Mon Sep 17 00:00:00 2001
From: Alex Andreev
Date: Mon, 19 Dec 2022 19:44:04 +0300
Subject: [PATCH 15/26] Fix resize anchor z-index (#6784)
Signed-off-by: Alex Andreev
Signed-off-by: Alex Andreev
---
src/renderer/components/resizing-anchor/resizing-anchor.scss | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/renderer/components/resizing-anchor/resizing-anchor.scss b/src/renderer/components/resizing-anchor/resizing-anchor.scss
index 7e18e789c5..4abfd4e933 100644
--- a/src/renderer/components/resizing-anchor/resizing-anchor.scss
+++ b/src/renderer/components/resizing-anchor/resizing-anchor.scss
@@ -13,7 +13,7 @@ body.resizing {
$dimension: 12px;
position: absolute;
- z-index: var(--z-index-base);
+ z-index: var(--z-index-above);
&::after {
content: " ";
From 10849ae02726d8680b8396bc9fd522c82ff06846 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 20 Dec 2022 07:53:17 -0500
Subject: [PATCH 16/26] Bump @types/node from 16.18.9 to 16.18.10 (#6791)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.18.9 to 16.18.10.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)
---
updated-dependencies:
- dependency-name: "@types/node"
dependency-type: direct:development
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 c6258f0668..232a4395ad 100644
--- a/package.json
+++ b/package.json
@@ -321,7 +321,7 @@
"@types/memorystream": "^0.3.0",
"@types/mini-css-extract-plugin": "^2.4.0",
"@types/mock-fs": "^4.13.1",
- "@types/node": "^16.18.9",
+ "@types/node": "^16.18.10",
"@types/proper-lockfile": "^4.1.2",
"@types/randomcolor": "^0.5.7",
"@types/react": "^17.0.45",
diff --git a/yarn.lock b/yarn.lock
index 8c1cc6e72b..3d971d840a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2357,10 +2357,10 @@
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"
- integrity sha512-nhrqXYxiQ+5B/tPorWum37VgAiefi/wmfJ1QZKGKKecC8/3HqcTTJD0O+VABSPwtseMMF7NCPVT9uGgwn0YqsQ==
+"@types/node@^16.11.26", "@types/node@^16.18.10":
+ version "16.18.10"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.10.tgz#d7415ef18c94f8d4e4a82ebcc8b8999f965d8920"
+ integrity sha512-XU1+v7h81p7145ddPfjv7jtWvkSilpcnON3mQ+bDi9Yuf7OI56efOglXRyXWgQ57xH3fEQgh7WOJMncRHVew5w==
"@types/parse-json@^4.0.0":
version "4.0.0"
From 8db81a4731445ea16b6cc6bbf14afaea8f2fa8ab Mon Sep 17 00:00:00 2001
From: Sebastian Malton
Date: Tue, 20 Dec 2022 04:53:33 -0800
Subject: [PATCH 17/26] Remove in-tree extensions to help facilitate a more
secure and faster booting lens (#6775)
* Remove kube-object-event-status extension
Signed-off-by: Sebastian Malton
* Remove cluster-metrics-feature intree extension
Signed-off-by: Sebastian Malton
* Remove lens-node-menu intree extension
Signed-off-by: Sebastian Malton
* Remove lens-pod-menu intree extension
Signed-off-by: Sebastian Malton
* Remove building extensions as part of build
Signed-off-by: Sebastian Malton
* Remove integration test touching previously bundled code
Signed-off-by: Sebastian Malton
Signed-off-by: Sebastian Malton
---
.eslintrc.js | 1 -
.github/workflows/test.yml | 4 -
.gitignore | 1 -
.idea/lens.iml | 6 +-
Makefile | 35 +-
extensions/.eslintrc.js | 20 -
extensions/.gitignore | 1 -
extensions/kube-object-event-status/Makefile | 8 -
.../kube-object-event-status/package.json | 21 -
.../kube-object-event-status/renderer.tsx | 53 --
.../kube-object-event-status/src/resolver.tsx | 72 ---
.../kube-object-event-status/tsconfig.json | 27 -
.../webpack.config.js | 44 --
.../metrics-cluster-feature/package.json | 24 -
.../metrics-cluster-feature/renderer.tsx | 27 -
.../resources/01-namespace.yml.hb | 6 -
.../resources/02-configmap.yml.hb | 281 ----------
.../resources/02-service-account.yml | 5 -
.../resources/03-service.yml.hb | 18 -
.../resources/03-statefulset.yml.hb | 113 ----
.../resources/04-rules.yml | 514 ------------------
.../resources/05-clusterrole.yml | 18 -
.../resources/06-clusterrole-binding.yml | 12 -
.../resources/10-node-exporter-ds.yml.hb | 79 ---
.../resources/11-node-exporter-svc.yml | 18 -
.../12-kube-state-metrics-clusterrole.yml | 128 -----
.../resources/12.kube-state-metrics-sa.yml | 5 -
...kube-state-metrics-clusterrole-binding.yml | 12 -
.../14-kube-state-metrics-deployment.yml.hb | 46 --
.../resources/14-kube-state-metrics-svc.yml | 17 -
.../src/metrics-feature.ts | 108 ----
.../src/metrics-settings.tsx | 276 ----------
.../metrics-cluster-feature/tsconfig.json | 27 -
.../metrics-cluster-feature/webpack.config.js | 47 --
extensions/node-menu/package.json | 22 -
extensions/node-menu/renderer.tsx | 21 -
extensions/node-menu/src/node-menu.tsx | 122 -----
extensions/node-menu/tsconfig.json | 27 -
extensions/node-menu/webpack.config.js | 44 --
extensions/pod-menu/package.json | 22 -
extensions/pod-menu/renderer.tsx | 39 --
extensions/pod-menu/src/attach-menu.tsx | 106 ----
extensions/pod-menu/src/logs-menu.tsx | 87 ---
extensions/pod-menu/src/shell-menu.tsx | 114 ----
extensions/pod-menu/tsconfig.json | 27 -
extensions/pod-menu/webpack.config.js | 44 --
integration/__tests__/cluster-pages.tests.ts | 54 --
package.json | 14 +-
48 files changed, 5 insertions(+), 2812 deletions(-)
delete mode 100644 extensions/.eslintrc.js
delete mode 100644 extensions/.gitignore
delete mode 100644 extensions/kube-object-event-status/Makefile
delete mode 100644 extensions/kube-object-event-status/package.json
delete mode 100644 extensions/kube-object-event-status/renderer.tsx
delete mode 100644 extensions/kube-object-event-status/src/resolver.tsx
delete mode 100644 extensions/kube-object-event-status/tsconfig.json
delete mode 100644 extensions/kube-object-event-status/webpack.config.js
delete mode 100644 extensions/metrics-cluster-feature/package.json
delete mode 100644 extensions/metrics-cluster-feature/renderer.tsx
delete mode 100644 extensions/metrics-cluster-feature/resources/01-namespace.yml.hb
delete mode 100644 extensions/metrics-cluster-feature/resources/02-configmap.yml.hb
delete mode 100644 extensions/metrics-cluster-feature/resources/02-service-account.yml
delete mode 100644 extensions/metrics-cluster-feature/resources/03-service.yml.hb
delete mode 100644 extensions/metrics-cluster-feature/resources/03-statefulset.yml.hb
delete mode 100644 extensions/metrics-cluster-feature/resources/04-rules.yml
delete mode 100644 extensions/metrics-cluster-feature/resources/05-clusterrole.yml
delete mode 100644 extensions/metrics-cluster-feature/resources/06-clusterrole-binding.yml
delete mode 100644 extensions/metrics-cluster-feature/resources/10-node-exporter-ds.yml.hb
delete mode 100644 extensions/metrics-cluster-feature/resources/11-node-exporter-svc.yml
delete mode 100644 extensions/metrics-cluster-feature/resources/12-kube-state-metrics-clusterrole.yml
delete mode 100644 extensions/metrics-cluster-feature/resources/12.kube-state-metrics-sa.yml
delete mode 100644 extensions/metrics-cluster-feature/resources/13-kube-state-metrics-clusterrole-binding.yml
delete mode 100644 extensions/metrics-cluster-feature/resources/14-kube-state-metrics-deployment.yml.hb
delete mode 100644 extensions/metrics-cluster-feature/resources/14-kube-state-metrics-svc.yml
delete mode 100644 extensions/metrics-cluster-feature/src/metrics-feature.ts
delete mode 100644 extensions/metrics-cluster-feature/src/metrics-settings.tsx
delete mode 100644 extensions/metrics-cluster-feature/tsconfig.json
delete mode 100644 extensions/metrics-cluster-feature/webpack.config.js
delete mode 100644 extensions/node-menu/package.json
delete mode 100644 extensions/node-menu/renderer.tsx
delete mode 100644 extensions/node-menu/src/node-menu.tsx
delete mode 100644 extensions/node-menu/tsconfig.json
delete mode 100644 extensions/node-menu/webpack.config.js
delete mode 100644 extensions/pod-menu/package.json
delete mode 100644 extensions/pod-menu/renderer.tsx
delete mode 100644 extensions/pod-menu/src/attach-menu.tsx
delete mode 100644 extensions/pod-menu/src/logs-menu.tsx
delete mode 100644 extensions/pod-menu/src/shell-menu.tsx
delete mode 100644 extensions/pod-menu/tsconfig.json
delete mode 100644 extensions/pod-menu/webpack.config.js
diff --git a/.eslintrc.js b/.eslintrc.js
index 52ba26dcb3..09a06987c4 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -11,7 +11,6 @@ module.exports = {
"**/dist/**/*",
"**/static/**/*",
"**/site/**/*",
- "extensions/*/*.tgz",
"build/webpack/**/*",
],
settings: {
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ee1ab58970..e71bfb0be8 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -57,10 +57,6 @@ jobs:
name: Run tests
if: ${{ matrix.type == 'unit' }}
- - run: make test-extensions
- name: Run In-tree Extension tests
- if: ${{ matrix.type == 'unit' }}
-
- run: make ci-validate-dev
if: ${{ contains(github.event.pull_request.labels.*.name, 'dependencies') && matrix.type == 'unit' }}
name: Validate dev mode will work
diff --git a/.gitignore b/.gitignore
index 0a79ea77c1..57139f691b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,7 +14,6 @@ src/extensions/*/*.js
src/extensions/*/*.d.ts
types/extension-api.d.ts
types/extension-renderer-api.d.ts
-extensions/*/dist
docs/extensions/api
site/
build/webpack/
diff --git a/.idea/lens.iml b/.idea/lens.iml
index 88175e2aaa..3bef0f9888 100644
--- a/.idea/lens.iml
+++ b/.idea/lens.iml
@@ -6,10 +6,6 @@
-
-
-
-
@@ -20,4 +16,4 @@
-
\ No newline at end of file
+
diff --git a/Makefile b/Makefile
index 1a21ef0e02..07caefd5d2 100644
--- a/Makefile
+++ b/Makefile
@@ -5,10 +5,6 @@ CMD_ARGS = $(filter-out $@,$(MAKECMDGOALS))
NPM_RELEASE_TAG ?= latest
ELECTRON_BUILDER_EXTRA_ARGS ?=
-EXTENSIONS_DIR = ./extensions
-extensions = $(foreach dir, $(wildcard $(EXTENSIONS_DIR)/*), ${dir})
-extension_node_modules = $(foreach dir, $(wildcard $(EXTENSIONS_DIR)/*), ${dir}/node_modules)
-extension_dists = $(foreach dir, $(wildcard $(EXTENSIONS_DIR)/*), ${dir}/dist)
ifeq ($(OS),Windows_NT)
DETECTED_OS := Windows
@@ -28,10 +24,10 @@ compile-dev: node_modules
yarn compile:renderer --cache
.PHONY: validate-dev
-ci-validate-dev: binaries/client build-extensions compile-dev
+ci-validate-dev: binaries/client compile-dev
.PHONY: dev
-dev: binaries/client build-extensions
+dev: binaries/client
rm -rf static/build/
yarn run build:tray-icons
yarn dev
@@ -54,7 +50,6 @@ integration: build
.PHONY: build
build: node_modules binaries/client
- $(MAKE) build-extensions -B
yarn run build:tray-icons
yarn run compile
ifeq "$(DETECTED_OS)" "Windows"
@@ -63,26 +58,6 @@ ifeq "$(DETECTED_OS)" "Windows"
endif
yarn run electron-builder --publish onTag $(ELECTRON_BUILDER_EXTRA_ARGS)
-.NOTPARALLEL: $(extension_node_modules)
-$(extension_node_modules): node_modules
- cd $(@:/node_modules=) && ../../node_modules/.bin/npm install --no-audit --no-fund --no-save
-
-$(extension_dists): src/extensions/npm/extensions/dist $(extension_node_modules)
- cd $(@:/dist=) && ../../node_modules/.bin/npm run build
- rm -rf ./node_modules/$(shell basename $(@:/dist=))
-
-.PHONY: clean-old-extensions
-clean-old-extensions:
- find ./extensions -mindepth 1 -maxdepth 1 -type d '!' -exec test -e '{}/package.json' \; -exec rm -rf {} \;
-
-.PHONY: build-extensions
-build-extensions: node_modules clean-old-extensions $(extension_dists)
- yarn install --check-files --frozen-lockfile --network-timeout=100000
-
-.PHONY: test-extensions
-test-extensions: $(extension_node_modules)
- $(foreach dir, $(extensions), (cd $(dir) && npm run test || exit $?);)
-
src/extensions/npm/extensions/__mocks__:
cp -r __mocks__ src/extensions/npm/extensions/
@@ -113,16 +88,12 @@ build-docs:
docs: build-docs
yarn mkdocs-serve-local
-.PHONY: clean-extensions
-clean-extensions:
- rm -rf $(EXTENSIONS_DIR)/*/{dist,node_modules,*.tgz}
-
.PHONY: clean-npm
clean-npm:
rm -rf src/extensions/npm/extensions/{dist,__mocks__,node_modules}
.PHONY: clean
-clean: clean-npm clean-extensions
+clean: clean-npm
rm -rf binaries/client
rm -rf dist
rm -rf static/build
diff --git a/extensions/.eslintrc.js b/extensions/.eslintrc.js
deleted file mode 100644
index 9d7b71763d..0000000000
--- a/extensions/.eslintrc.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-module.exports = {
- "overrides": [
- {
- files: [
- "**/*.ts",
- "**/*.tsx",
- ],
- rules: {
- "import/no-unresolved": ["error", {
- ignore: ["@k8slens/extensions"],
- }],
- },
- },
- ],
-};
diff --git a/extensions/.gitignore b/extensions/.gitignore
deleted file mode 100644
index 193cfa4791..0000000000
--- a/extensions/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*/*.tgz
diff --git a/extensions/kube-object-event-status/Makefile b/extensions/kube-object-event-status/Makefile
deleted file mode 100644
index 1c9223e184..0000000000
--- a/extensions/kube-object-event-status/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-install-deps:
- npm install
-
-build: install-deps
- npm run build
-
-test:
- npm run test
diff --git a/extensions/kube-object-event-status/package.json b/extensions/kube-object-event-status/package.json
deleted file mode 100644
index 4e65471429..0000000000
--- a/extensions/kube-object-event-status/package.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "name": "kube-object-event-status",
- "version": "6.1.1",
- "description": "Adds kube object status from events",
- "renderer": "dist/renderer.js",
- "lens": {
- "metadata": {},
- "styles": []
- },
- "scripts": {
- "build": "npx webpack",
- "dev": "npx webpack -- --watch",
- "test": "echo NO TESTS"
- },
- "files": [
- "dist/**/*"
- ],
- "devDependencies": {
- "@k8slens/extensions": "file:../../src/extensions/npm/extensions"
- }
-}
diff --git a/extensions/kube-object-event-status/renderer.tsx b/extensions/kube-object-event-status/renderer.tsx
deleted file mode 100644
index 65b92a2658..0000000000
--- a/extensions/kube-object-event-status/renderer.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import { Renderer } from "@k8slens/extensions";
-import { resolveStatus, resolveStatusForCronJobs, resolveStatusForPods } from "./src/resolver";
-
-export default class EventResourceStatusRendererExtension extends Renderer.LensExtension {
- kubeObjectStatusTexts = [
- {
- kind: "Pod",
- apiVersions: ["v1"],
- resolve: (pod: Renderer.K8sApi.Pod) => resolveStatusForPods(pod),
- },
- {
- kind: "ReplicaSet",
- apiVersions: ["v1"],
- resolve: (replicaSet: Renderer.K8sApi.ReplicaSet) => resolveStatus(replicaSet),
- },
- {
- kind: "Deployment",
- apiVersions: ["apps/v1"],
- resolve: (deployment: Renderer.K8sApi.Deployment) => resolveStatus(deployment),
- },
- {
- kind: "StatefulSet",
- apiVersions: ["apps/v1"],
- resolve: (statefulSet: Renderer.K8sApi.StatefulSet) => resolveStatus(statefulSet),
- },
- {
- kind: "DaemonSet",
- apiVersions: ["apps/v1"],
- resolve: (daemonSet: Renderer.K8sApi.DaemonSet) => resolveStatus(daemonSet),
- },
- {
- kind: "Job",
- apiVersions: [
- "batch/v1",
- "batch/v1beta1",
- ],
- resolve: (job: Renderer.K8sApi.Job) => resolveStatus(job),
- },
- {
- kind: "CronJob",
- apiVersions: [
- "batch/v1",
- "batch/v1beta1",
- ],
- resolve: (cronJob: Renderer.K8sApi.CronJob) => resolveStatusForCronJobs(cronJob),
- },
- ];
-}
diff --git a/extensions/kube-object-event-status/src/resolver.tsx b/extensions/kube-object-event-status/src/resolver.tsx
deleted file mode 100644
index fa98290c49..0000000000
--- a/extensions/kube-object-event-status/src/resolver.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import { Renderer } from "@k8slens/extensions";
-
-const { apiManager, eventApi, KubeObjectStatusLevel } = Renderer.K8sApi;
-
-type KubeObject = Renderer.K8sApi.KubeObject;
-type Pod = Renderer.K8sApi.Pod;
-type CronJob = Renderer.K8sApi.CronJob;
-type KubeObjectStatus = Renderer.K8sApi.KubeObjectStatus;
-type EventStore = Renderer.K8sApi.EventStore;
-
-export function resolveStatus(object: KubeObject): KubeObjectStatus {
- const eventStore = apiManager.getStore(eventApi);
- const events = (eventStore as EventStore).getEventsByObject(object);
- const warnings = events.filter(evt => evt.isWarning());
-
- if (!events.length || !warnings.length) {
- return null;
- }
- const event = [...warnings, ...events][0]; // get latest event
-
- return {
- level: KubeObjectStatusLevel.WARNING,
- text: `${event.message}`,
- timestamp: event.metadata.creationTimestamp,
- };
-}
-
-export function resolveStatusForPods(pod: Pod): KubeObjectStatus {
- if (!pod.hasIssues()) {
- return null;
- }
- const eventStore = apiManager.getStore(eventApi);
- const events = (eventStore as EventStore).getEventsByObject(pod);
- const warnings = events.filter(evt => evt.isWarning());
-
- if (!events.length || !warnings.length) {
- return null;
- }
- const event = [...warnings, ...events][0]; // get latest event
-
- return {
- level: KubeObjectStatusLevel.WARNING,
- text: `${event.message}`,
- timestamp: event.metadata.creationTimestamp,
- };
-}
-
-export function resolveStatusForCronJobs(cronJob: CronJob): KubeObjectStatus {
- const eventStore = apiManager.getStore(eventApi);
- let events = (eventStore as EventStore).getEventsByObject(cronJob);
- const warnings = events.filter(evt => evt.isWarning());
-
- if (cronJob.isNeverRun()) {
- events = events.filter(event => event.reason != "FailedNeedsStart");
- }
-
- if (!events.length || !warnings.length) {
- return null;
- }
- const event = [...warnings, ...events][0]; // get latest event
-
- return {
- level: KubeObjectStatusLevel.WARNING,
- text: `${event.message}`,
- timestamp: event.metadata.creationTimestamp,
- };
-}
diff --git a/extensions/kube-object-event-status/tsconfig.json b/extensions/kube-object-event-status/tsconfig.json
deleted file mode 100644
index 5b6c61577e..0000000000
--- a/extensions/kube-object-event-status/tsconfig.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "compilerOptions": {
- "outDir": "dist",
- "module": "CommonJS",
- "target": "ES2017",
- "lib": ["ESNext", "DOM", "DOM.Iterable"],
- "moduleResolution": "Node",
- "sourceMap": false,
- "declaration": false,
- "strict": false,
- "noImplicitAny": true,
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "experimentalDecorators": true,
- "useDefineForClassFields": true,
- "jsx": "react"
- },
- "include": [
- "./*.ts",
- "./*.tsx"
- ],
- "exclude": [
- "node_modules",
- "*.js"
- ]
-}
diff --git a/extensions/kube-object-event-status/webpack.config.js b/extensions/kube-object-event-status/webpack.config.js
deleted file mode 100644
index 8fe82e48a7..0000000000
--- a/extensions/kube-object-event-status/webpack.config.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-const path = require("path");
-
-module.exports = [
- {
- entry: "./renderer.tsx",
- context: __dirname,
- target: "electron-renderer",
- mode: "production",
- optimization: {
- minimize: false,
- },
- module: {
- rules: [
- {
- test: /\.tsx?$/,
- use: "ts-loader",
- exclude: /node_modules/,
- },
- ],
- },
- externals: [
- {
- "@k8slens/extensions": "var global.LensExtensions",
- "react": "var global.React",
- "react-dom": "var global.ReactDOM",
- "mobx": "var global.Mobx",
- "mobx-react": "var global.MobxReact",
- },
- ],
- resolve: {
- extensions: [ ".tsx", ".ts", ".js" ],
- },
- output: {
- libraryTarget: "commonjs2",
- globalObject: "this",
- filename: "renderer.js",
- path: path.resolve(__dirname, "dist"),
- },
- },
-];
diff --git a/extensions/metrics-cluster-feature/package.json b/extensions/metrics-cluster-feature/package.json
deleted file mode 100644
index 3be7b58d58..0000000000
--- a/extensions/metrics-cluster-feature/package.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "name": "lens-metrics-cluster-feature",
- "version": "6.1.0",
- "description": "Lens metrics cluster feature",
- "renderer": "dist/renderer.js",
- "lens": {
- "metadata": {},
- "styles": []
- },
- "scripts": {
- "build": "npx webpack",
- "dev": "npx webpack -- --watch",
- "test": "npx jest --passWithNoTests --env=jsdom src $@",
- "clean": "rm -rf dist/ && rm *.tgz"
- },
- "files": [
- "dist/**/*",
- "resources/**/*"
- ],
- "devDependencies": {
- "@k8slens/extensions": "file:../../src/extensions/npm/extensions",
- "semver": "^7.3.2"
- }
-}
diff --git a/extensions/metrics-cluster-feature/renderer.tsx b/extensions/metrics-cluster-feature/renderer.tsx
deleted file mode 100644
index 8b04ca0b8f..0000000000
--- a/extensions/metrics-cluster-feature/renderer.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import React from "react";
-import type { Common } from "@k8slens/extensions";
-import { Renderer } from "@k8slens/extensions";
-import { MetricsSettings } from "./src/metrics-settings";
-
-export default class ClusterMetricsFeatureExtension extends Renderer.LensExtension {
- entitySettings = [
- {
- apiVersions: ["entity.k8slens.dev/v1alpha1"],
- kind: "KubernetesCluster",
- title: "Lens Metrics",
- priority: 5,
- components: {
- View: ({ entity = null }: { entity: Common.Catalog.KubernetesCluster }) => {
- return (
-
- );
- },
- },
- },
- ];
-}
diff --git a/extensions/metrics-cluster-feature/resources/01-namespace.yml.hb b/extensions/metrics-cluster-feature/resources/01-namespace.yml.hb
deleted file mode 100644
index dd3816fdff..0000000000
--- a/extensions/metrics-cluster-feature/resources/01-namespace.yml.hb
+++ /dev/null
@@ -1,6 +0,0 @@
-apiVersion: v1
-kind: Namespace
-metadata:
- name: lens-metrics
- annotations:
- extensionVersion: "{{ version }}"
diff --git a/extensions/metrics-cluster-feature/resources/02-configmap.yml.hb b/extensions/metrics-cluster-feature/resources/02-configmap.yml.hb
deleted file mode 100644
index 582052bd87..0000000000
--- a/extensions/metrics-cluster-feature/resources/02-configmap.yml.hb
+++ /dev/null
@@ -1,281 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: prometheus-config
- namespace: lens-metrics
-data:
- prometheus.yaml: |-
- # Global config
- global:
- scrape_interval: 15s
-
- {{#if alertManagers}}
- # AlertManager
- alerting:
- alertmanagers:
- - static_configs:
- - targets:
- {{#each alertManagers}}
- - {{this}}
- {{/each}}
- {{/if}}
-
- # Scrape configs for running Prometheus on a Kubernetes cluster.
- # This uses separate scrape configs for cluster components (i.e. API server, node)
- # and services to allow each to use different authentication configs.
- #
- # Kubernetes labels will be added as Prometheus labels on metrics via the
- # `labelmap` relabeling action.
- scrape_configs:
-
- # Scrape config for API servers.
- #
- # Kubernetes exposes API servers as endpoints to the default/kubernetes
- # service so this uses `endpoints` role and uses relabelling to only keep
- # the endpoints associated with the default/kubernetes service using the
- # default named port `https`. This works for single API server deployments as
- # well as HA API server deployments.
- - job_name: 'kubernetes-apiservers'
- kubernetes_sd_configs:
- - role: endpoints
-
- scheme: https
- tls_config:
- ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
- # Using endpoints to discover kube-apiserver targets finds the pod IP
- # (host IP since apiserver uses host network) which is not used in
- # the server certificate.
- insecure_skip_verify: true
- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
-
- # Keep only the default/kubernetes service endpoints for the https port. This
- # will add targets for each API server which Kubernetes adds an endpoint to
- # the default/kubernetes service.
- relabel_configs:
- - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
- action: keep
- regex: default;kubernetes;https
- - replacement: apiserver
- action: replace
- target_label: job
-
- # Scrape config for node (i.e. kubelet) /metrics (e.g. 'kubelet_'). Explore
- # metrics from a node by scraping kubelet (127.0.0.1:10250/metrics).
- - job_name: 'kubelet'
- kubernetes_sd_configs:
- - role: node
-
- scheme: https
- tls_config:
- ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
- # Kubelet certs don't have any fixed IP SANs
- insecure_skip_verify: true
- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
-
- relabel_configs:
- - action: labelmap
- regex: __meta_kubernetes_node_label_(.+)
- - replacement: 'lens-metrics'
- target_label: kubernetes_namespace
-
- metric_relabel_configs:
- - source_labels:
- - namespace
- action: replace
- regex: (.+)
- target_label: kubernetes_namespace
-
- # Scrape config for Kubelet cAdvisor. Explore metrics from a node by
- # scraping kubelet (127.0.0.1:10250/metrics/cadvisor).
- - job_name: 'kubernetes-cadvisor'
- kubernetes_sd_configs:
- - role: node
-
- scheme: https
- metrics_path: /metrics/cadvisor
- tls_config:
- # Kubelet certs don't have any fixed IP SANs
- insecure_skip_verify: true
- ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
-
- relabel_configs:
- - action: labelmap
- regex: __meta_kubernetes_node_label_(.+)
- metric_relabel_configs:
- - source_labels:
- - namespace
- action: replace
- target_label: kubernetes_namespace
- - source_labels:
- - pod
- regex: (.*)
- replacement: $1
- action: replace
- target_label: pod_name
- - source_labels:
- - container
- regex: (.*)
- replacement: $1
- action: replace
- target_label: container_name
-
- # Scrap etcd metrics from masters via etcd-scraper-proxy
- - job_name: 'etcd'
- kubernetes_sd_configs:
- - role: pod
- scheme: http
- relabel_configs:
- - source_labels: [__meta_kubernetes_namespace]
- action: keep
- regex: 'kube-system'
- - source_labels: [__meta_kubernetes_pod_label_component]
- action: keep
- regex: 'etcd-scraper-proxy'
- - action: labelmap
- regex: __meta_kubernetes_pod_label_(.+)
-
- # Scrape config for service endpoints.
- #
- # The relabeling allows the actual service scrape endpoint to be configured
- # via the following annotations:
- #
- # * `prometheus.io/scrape`: Only scrape services that have a value of `true`
- # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need
- # to set this to `https` & most likely set the `tls_config` of the scrape config.
- # * `prometheus.io/path`: If the metrics path is not `/metrics` override this.
- # * `prometheus.io/port`: If the metrics are exposed on a different port to the
- # service then set this appropriately.
- - job_name: 'kubernetes-service-endpoints'
-
- kubernetes_sd_configs:
- - role: endpoints
- namespaces:
- names:
- - lens-metrics
-
- relabel_configs:
- - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
- action: keep
- regex: true
- - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
- action: replace
- target_label: __scheme__
- regex: (https?)
- - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
- action: replace
- target_label: __metrics_path__
- regex: (.+)
- - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
- action: replace
- target_label: __address__
- regex: ([^:]+)(?::\d+)?;(\d+)
- replacement: $1:$2
- - action: labelmap
- regex: __meta_kubernetes_service_label_(.+)
- - source_labels: [__meta_kubernetes_service_name]
- action: replace
- target_label: job
- - action: replace
- source_labels:
- - __meta_kubernetes_pod_node_name
- target_label: kubernetes_node
- - source_labels: [__meta_kubernetes_namespace]
- action: replace
- target_label: kubernetes_namespace
- metric_relabel_configs:
- - source_labels:
- - namespace
- action: replace
- regex: (.+)
- target_label: kubernetes_namespace
-
- # Example scrape config for probing services via the Blackbox Exporter.
- #
- # The relabeling allows the actual service scrape endpoint to be configured
- # via the following annotations:
- #
- # * `prometheus.io/probe`: Only probe services that have a value of `true`
- - job_name: 'kubernetes-services'
-
- metrics_path: /probe
- params:
- module: [http_2xx]
-
- kubernetes_sd_configs:
- - role: service
- namespaces:
- names:
- - lens-metrics
-
- relabel_configs:
- - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
- action: keep
- regex: true
- - source_labels: [__address__]
- target_label: __param_target
- - target_label: __address__
- replacement: blackbox
- - source_labels: [__param_target]
- target_label: instance
- - action: labelmap
- regex: __meta_kubernetes_service_label_(.+)
- - source_labels: [__meta_kubernetes_service_name]
- target_label: job
- metric_relabel_configs:
- - source_labels:
- - namespace
- action: replace
- regex: (.+)
- target_label: kubernetes_namespace
-
- # Example scrape config for pods
- #
- # The relabeling allows the actual pod scrape endpoint to be configured via the
- # following annotations:
- #
- # * `prometheus.io/scrape`: Only scrape pods that have a value of `true`
- # * `prometheus.io/path`: If the metrics path is not `/metrics` override this.
- # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the
- # pod's declared ports (default is a port-free target if none are declared).
- - job_name: 'kubernetes-pods'
-
- kubernetes_sd_configs:
- - role: pod
- namespaces:
- names:
- - lens-metrics
-
- relabel_configs:
- - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
- action: keep
- regex: true
- - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
- action: replace
- target_label: __metrics_path__
- regex: (.+)
- - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
- action: replace
- regex: ([^:]+)(?::\d+)?;(\d+)
- replacement: $1:$2
- target_label: __address__
- - action: labelmap
- regex: __meta_kubernetes_pod_label_(.+)
- - source_labels: [__meta_kubernetes_namespace]
- action: replace
- target_label: kubernetes_namespace
- - source_labels: [__meta_kubernetes_pod_name]
- action: replace
- target_label: kubernetes_pod_name
- metric_relabel_configs:
- - source_labels:
- - namespace
- action: replace
- regex: (.+)
- target_label: kubernetes_namespace
-
- # Rule files
- rule_files:
- - "/etc/prometheus/rules/*.rules"
- - "/etc/prometheus/rules/*.yaml"
- - "/etc/prometheus/rules/*.yml"
diff --git a/extensions/metrics-cluster-feature/resources/02-service-account.yml b/extensions/metrics-cluster-feature/resources/02-service-account.yml
deleted file mode 100644
index 5cb45a352f..0000000000
--- a/extensions/metrics-cluster-feature/resources/02-service-account.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: prometheus
- namespace: lens-metrics
diff --git a/extensions/metrics-cluster-feature/resources/03-service.yml.hb b/extensions/metrics-cluster-feature/resources/03-service.yml.hb
deleted file mode 100644
index 3cdcdbc260..0000000000
--- a/extensions/metrics-cluster-feature/resources/03-service.yml.hb
+++ /dev/null
@@ -1,18 +0,0 @@
-{{#if prometheus.enabled}}
-apiVersion: v1
-kind: Service
-metadata:
- name: prometheus
- namespace: lens-metrics
- annotations:
- prometheus.io/scrape: 'true'
-spec:
- type: ClusterIP
- selector:
- name: prometheus
- ports:
- - name: web
- protocol: TCP
- port: 80
- targetPort: 9090
-{{/if}}
diff --git a/extensions/metrics-cluster-feature/resources/03-statefulset.yml.hb b/extensions/metrics-cluster-feature/resources/03-statefulset.yml.hb
deleted file mode 100644
index 288cd553b1..0000000000
--- a/extensions/metrics-cluster-feature/resources/03-statefulset.yml.hb
+++ /dev/null
@@ -1,113 +0,0 @@
-{{#if prometheus.enabled}}
-apiVersion: apps/v1
-kind: StatefulSet
-metadata:
- name: prometheus
- namespace: lens-metrics
-spec:
- replicas: {{replicas}}
- serviceName: prometheus
- selector:
- matchLabels:
- name: prometheus
- template:
- metadata:
- labels:
- name: prometheus
- spec:
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: kubernetes.io/os
- operator: In
- values:
- - linux
- # <%- if config.node_selector -%>
- # nodeSelector:
- # <%- node_selector.to_h.each do |key, value| -%>
- # <%= key %>: <%= value %>
- # <%- end -%>
- # <%- end -%>
- # <%- unless config.tolerations.empty? -%>
- # tolerations:
- # <%- config.tolerations.each do |t| -%>
- # -
- # <%- t.each do |k,v| -%>
- # <%= k %>: <%= v %>
- # <%- end -%>
- # <%- end -%>
- # <%- end -%>
- serviceAccountName: prometheus
- initContainers:
- - name: chown
- image: docker.io/alpine:3.12
- command: ["chown", "-R", "65534:65534", "/var/lib/prometheus"]
- volumeMounts:
- - name: data
- mountPath: /var/lib/prometheus
- containers:
- - name: prometheus
- image: quay.io/prometheus/prometheus:v2.27.1
- args:
- - --web.listen-address=0.0.0.0:9090
- - --config.file=/etc/prometheus/prometheus.yaml
- - --storage.tsdb.path=/var/lib/prometheus
- - --storage.tsdb.retention.time={{retention.time}}
- - --storage.tsdb.retention.size={{retention.size}}
- - --storage.tsdb.min-block-duration=2h
- - --storage.tsdb.max-block-duration=2h
- ports:
- - name: web
- containerPort: 9090
- volumeMounts:
- - name: config
- mountPath: /etc/prometheus
- - name: rules
- mountPath: /etc/prometheus/rules
- - name: data
- mountPath: /var/lib/prometheus
- readinessProbe:
- httpGet:
- path: /-/ready
- port: 9090
- initialDelaySeconds: 10
- timeoutSeconds: 10
- livenessProbe:
- httpGet:
- path: /-/healthy
- port: 9090
- initialDelaySeconds: 10
- timeoutSeconds: 10
- resources:
- requests:
- cpu: 100m
- memory: 512Mi
- terminationGracePeriodSeconds: 30
- volumes:
- - name: config
- configMap:
- name: prometheus-config
- - name: rules
- configMap:
- name: prometheus-rules
- {{#unless persistence.enabled}}
- - name: data
- emptyDir: {}
- {{/unless}}
- {{#if persistence.enabled}}
- volumeClaimTemplates:
- - metadata:
- name: data
- spec:
- accessModes:
- - ReadWriteOnce
- {{#if persistence.storageClass}}
- storageClassName: "{{persistence.storageClass}}"
- {{/if}}
- resources:
- requests:
- storage: {{persistence.size}}
- {{/if}}
-{{/if}}
diff --git a/extensions/metrics-cluster-feature/resources/04-rules.yml b/extensions/metrics-cluster-feature/resources/04-rules.yml
deleted file mode 100644
index b7f088a003..0000000000
--- a/extensions/metrics-cluster-feature/resources/04-rules.yml
+++ /dev/null
@@ -1,514 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: prometheus-rules
- namespace: lens-metrics
-data:
- alertmanager.rules.yaml: |
- groups:
- - name: alertmanager.rules
- rules:
- - alert: AlertmanagerConfigInconsistent
- expr: count_values("config_hash", alertmanager_config_hash) BY (service) / ON(service)
- GROUP_LEFT() label_replace(prometheus_operator_alertmanager_spec_replicas, "service",
- "alertmanager-$1", "alertmanager", "(.*)") != 1
- for: 5m
- labels:
- severity: critical
- annotations:
- description: The configuration of the instances of the Alertmanager cluster
- `{{$labels.service}}` are out of sync.
- - alert: AlertmanagerDownOrMissing
- expr: label_replace(prometheus_operator_alertmanager_spec_replicas, "job", "alertmanager-$1",
- "alertmanager", "(.*)") / ON(job) GROUP_RIGHT() sum(up) BY (job) != 1
- for: 5m
- labels:
- severity: warning
- annotations:
- description: An unexpected number of Alertmanagers are scraped or Alertmanagers
- disappeared from discovery.
- - alert: AlertmanagerFailedReload
- expr: alertmanager_config_last_reload_successful == 0
- for: 10m
- labels:
- severity: warning
- annotations:
- description: Reloading Alertmanager's configuration has failed for {{ $labels.namespace
- }}/{{ $labels.pod}}.
- etcd3.rules.yaml: |
- groups:
- - name: ./etcd3.rules
- rules:
- - alert: InsufficientMembers
- expr: count(up{job="etcd"} == 0) > (count(up{job="etcd"}) / 2 - 1)
- for: 3m
- labels:
- severity: critical
- annotations:
- description: If one more etcd member goes down the cluster will be unavailable
- summary: etcd cluster insufficient members
- - alert: NoLeader
- expr: etcd_server_has_leader{job="etcd"} == 0
- for: 1m
- labels:
- severity: critical
- annotations:
- description: etcd member {{ $labels.instance }} has no leader
- summary: etcd member has no leader
- - alert: HighNumberOfLeaderChanges
- expr: increase(etcd_server_leader_changes_seen_total{job="etcd"}[1h]) > 3
- labels:
- severity: warning
- annotations:
- description: etcd instance {{ $labels.instance }} has seen {{ $value }} leader
- changes within the last hour
- summary: a high number of leader changes within the etcd cluster are happening
- - alert: GRPCRequestsSlow
- expr: histogram_quantile(0.99, sum(rate(grpc_server_handling_seconds_bucket{job="etcd",grpc_type="unary"}[5m])) by (grpc_service, grpc_method, le))
- > 0.15
- for: 10m
- labels:
- severity: critical
- annotations:
- description: on etcd instance {{ $labels.instance }} gRPC requests to {{ $labels.grpc_method
- }} are slow
- summary: slow gRPC requests
- - alert: HighNumberOfFailedHTTPRequests
- expr: sum(rate(etcd_http_failed_total{job="etcd"}[5m])) BY (method) / sum(rate(etcd_http_received_total{job="etcd"}[5m]))
- BY (method) > 0.01
- for: 10m
- labels:
- severity: warning
- annotations:
- description: '{{ $value }}% of requests for {{ $labels.method }} failed on etcd
- instance {{ $labels.instance }}'
- summary: a high number of HTTP requests are failing
- - alert: HighNumberOfFailedHTTPRequests
- expr: sum(rate(etcd_http_failed_total{job="etcd"}[5m])) BY (method) / sum(rate(etcd_http_received_total{job="etcd"}[5m]))
- BY (method) > 0.05
- for: 5m
- labels:
- severity: critical
- annotations:
- description: '{{ $value }}% of requests for {{ $labels.method }} failed on etcd
- instance {{ $labels.instance }}'
- summary: a high number of HTTP requests are failing
- - alert: HTTPRequestsSlow
- expr: histogram_quantile(0.99, rate(etcd_http_successful_duration_seconds_bucket[5m]))
- > 0.15
- for: 10m
- labels:
- severity: warning
- annotations:
- description: on etcd instance {{ $labels.instance }} HTTP requests to {{ $labels.method
- }} are slow
- summary: slow HTTP requests
- - alert: EtcdMemberCommunicationSlow
- expr: histogram_quantile(0.99, rate(etcd_network_peer_round_trip_time_seconds_bucket[5m]))
- > 0.15
- for: 10m
- labels:
- severity: warning
- annotations:
- description: etcd instance {{ $labels.instance }} member communication with
- {{ $labels.To }} is slow
- summary: etcd member communication is slow
- - alert: HighNumberOfFailedProposals
- expr: increase(etcd_server_proposals_failed_total{job="etcd"}[1h]) > 5
- labels:
- severity: warning
- annotations:
- description: etcd instance {{ $labels.instance }} has seen {{ $value }} proposal
- failures within the last hour
- summary: a high number of proposals within the etcd cluster are failing
- - alert: HighFsyncDurations
- expr: histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m]))
- > 0.5
- for: 10m
- labels:
- severity: warning
- annotations:
- description: etcd instance {{ $labels.instance }} fync durations are high
- summary: high fsync durations
- - alert: HighCommitDurations
- expr: histogram_quantile(0.99, rate(etcd_disk_backend_commit_duration_seconds_bucket[5m]))
- > 0.25
- for: 10m
- labels:
- severity: warning
- annotations:
- description: etcd instance {{ $labels.instance }} commit durations are high
- summary: high commit durations
- general.rules.yaml: |
- groups:
- - name: general.rules
- rules:
- - alert: TargetDown
- expr: 100 * (count(up == 0) BY (job) / count(up) BY (job)) > 10
- for: 10m
- labels:
- severity: warning
- annotations:
- description: '{{ $value }}% of {{ $labels.job }} targets are down.'
- summary: Targets are down
- - record: fd_utilization
- expr: process_open_fds / process_max_fds
- - alert: FdExhaustionClose
- expr: predict_linear(fd_utilization[1h], 3600 * 4) > 1
- for: 10m
- labels:
- severity: warning
- annotations:
- description: '{{ $labels.job }}: {{ $labels.namespace }}/{{ $labels.pod }} instance
- will exhaust in file/socket descriptors within the next 4 hours'
- summary: file descriptors soon exhausted
- - alert: FdExhaustionClose
- expr: predict_linear(fd_utilization[10m], 3600) > 1
- for: 10m
- labels:
- severity: critical
- annotations:
- description: '{{ $labels.job }}: {{ $labels.namespace }}/{{ $labels.pod }} instance
- will exhaust in file/socket descriptors within the next hour'
- summary: file descriptors soon exhausted
- kube-state-metrics.rules.yaml: |
- groups:
- - name: kube-state-metrics.rules
- rules:
- - alert: DeploymentGenerationMismatch
- expr: kube_deployment_status_observed_generation != kube_deployment_metadata_generation
- for: 15m
- labels:
- severity: warning
- annotations:
- description: Observed deployment generation does not match expected one for
- deployment {{$labels.namespaces}}/{{$labels.deployment}}
- summary: Deployment is outdated
- - alert: DeploymentReplicasNotUpdated
- expr: ((kube_deployment_status_replicas_updated != kube_deployment_spec_replicas)
- or (kube_deployment_status_replicas_available != kube_deployment_spec_replicas))
- unless (kube_deployment_spec_paused == 1)
- for: 15m
- labels:
- severity: warning
- annotations:
- description: Replicas are not updated and available for deployment {{$labels.namespaces}}/{{$labels.deployment}}
- summary: Deployment replicas are outdated
- - alert: DaemonSetRolloutStuck
- expr: kube_daemonset_status_number_ready / kube_daemonset_status_desired_number_scheduled
- * 100 < 100
- for: 15m
- labels:
- severity: warning
- annotations:
- description: Only {{$value}}% of desired pods scheduled and ready for daemon
- set {{$labels.namespaces}}/{{$labels.daemonset}}
- summary: DaemonSet is missing pods
- - alert: K8SDaemonSetsNotScheduled
- expr: kube_daemonset_status_desired_number_scheduled - kube_daemonset_status_current_number_scheduled
- > 0
- for: 10m
- labels:
- severity: warning
- annotations:
- description: A number of daemonsets are not scheduled.
- summary: Daemonsets are not scheduled correctly
- - alert: DaemonSetsMissScheduled
- expr: kube_daemonset_status_number_misscheduled > 0
- for: 10m
- labels:
- severity: warning
- annotations:
- description: A number of daemonsets are running where they are not supposed
- to run.
- summary: Daemonsets are not scheduled correctly
- - alert: PodFrequentlyRestarting
- expr: increase(kube_pod_container_status_restarts_total[1h]) > 5
- for: 10m
- labels:
- severity: warning
- annotations:
- description: Pod {{$labels.namespaces}}/{{$labels.pod}} restarted {{$value}}
- times within the last hour
- summary: Pod is restarting frequently
- kubelet.rules.yaml: |
- groups:
- - name: kubelet.rules
- rules:
- - alert: K8SNodeNotReady
- expr: kube_node_status_condition{condition="Ready",status="true"} == 0
- for: 1h
- labels:
- severity: warning
- annotations:
- description: The Kubelet on {{ $labels.node }} has not checked in with the API,
- or has set itself to NotReady, for more than an hour
- summary: Node status is NotReady
- - alert: K8SManyNodesNotReady
- expr: count(kube_node_status_condition{condition="Ready",status="true"} == 0)
- > 1 and (count(kube_node_status_condition{condition="Ready",status="true"} ==
- 0) / count(kube_node_status_condition{condition="Ready",status="true"})) > 0.2
- for: 1m
- labels:
- severity: critical
- annotations:
- description: '{{ $value }}% of Kubernetes nodes are not ready'
- - alert: K8SKubeletDown
- expr: count(up{job="kubelet"} == 0) / count(up{job="kubelet"}) * 100 > 3
- for: 1h
- labels:
- severity: warning
- annotations:
- description: Prometheus failed to scrape {{ $value }}% of kubelets.
- - alert: K8SKubeletDown
- expr: (absent(up{job="kubelet"} == 1) or count(up{job="kubelet"} == 0) / count(up{job="kubelet"}))
- * 100 > 10
- for: 1h
- labels:
- severity: critical
- annotations:
- description: Prometheus failed to scrape {{ $value }}% of kubelets, or all Kubelets
- have disappeared from service discovery.
- summary: Many Kubelets cannot be scraped
- - alert: K8SKubeletTooManyPods
- expr: kubelet_running_pod_count > 100
- for: 10m
- labels:
- severity: warning
- annotations:
- description: Kubelet {{$labels.instance}} is running {{$value}} pods, close
- to the limit of 110
- summary: Kubelet is close to pod limit
- kubernetes.rules.yaml: |
- groups:
- - name: kubernetes.rules
- rules:
- - record: pod_name:container_memory_usage_bytes:sum
- expr: sum(container_memory_usage_bytes{container_name!="POD",pod_name!=""}) BY
- (pod_name)
- - record: pod_name:container_spec_cpu_shares:sum
- expr: sum(container_spec_cpu_shares{container_name!="POD",pod_name!=""}) BY (pod_name)
- - record: pod_name:container_cpu_usage:sum
- expr: sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name!=""}[5m]))
- BY (pod_name)
- - record: pod_name:container_fs_usage_bytes:sum
- expr: sum(container_fs_usage_bytes{container_name!="POD",pod_name!=""}) BY (pod_name)
- - record: namespace:container_memory_usage_bytes:sum
- expr: sum(container_memory_usage_bytes{container_name!=""}) BY (namespace)
- - record: namespace:container_spec_cpu_shares:sum
- expr: sum(container_spec_cpu_shares{container_name!=""}) BY (namespace)
- - record: namespace:container_cpu_usage:sum
- expr: sum(rate(container_cpu_usage_seconds_total{container_name!="POD"}[5m]))
- BY (namespace)
- - record: cluster:memory_usage:ratio
- expr: sum(container_memory_usage_bytes{container_name!="POD",pod_name!=""}) BY
- (cluster) / sum(machine_memory_bytes) BY (cluster)
- - record: cluster:container_spec_cpu_shares:ratio
- expr: sum(container_spec_cpu_shares{container_name!="POD",pod_name!=""}) / 1000
- / sum(machine_cpu_cores)
- - record: cluster:container_cpu_usage:ratio
- expr: sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name!=""}[5m]))
- / sum(machine_cpu_cores)
- - record: apiserver_latency_seconds:quantile
- expr: histogram_quantile(0.99, rate(apiserver_request_latencies_bucket[5m])) /
- 1e+06
- labels:
- quantile: "0.99"
- - record: apiserver_latency:quantile_seconds
- expr: histogram_quantile(0.9, rate(apiserver_request_latencies_bucket[5m])) /
- 1e+06
- labels:
- quantile: "0.9"
- - record: apiserver_latency_seconds:quantile
- expr: histogram_quantile(0.5, rate(apiserver_request_latencies_bucket[5m])) /
- 1e+06
- labels:
- quantile: "0.5"
- - alert: APIServerLatencyHigh
- expr: apiserver_latency_seconds:quantile{quantile="0.99",subresource!="log",verb!~"^(?:WATCH|WATCHLIST|PROXY|CONNECT)$"}
- > 1
- for: 10m
- labels:
- severity: warning
- annotations:
- description: the API server has a 99th percentile latency of {{ $value }} seconds
- for {{$labels.verb}} {{$labels.resource}}
- - alert: APIServerLatencyHigh
- expr: apiserver_latency_seconds:quantile{quantile="0.99",subresource!="log",verb!~"^(?:WATCH|WATCHLIST|PROXY|CONNECT)$"}
- > 4
- for: 10m
- labels:
- severity: critical
- annotations:
- description: the API server has a 99th percentile latency of {{ $value }} seconds
- for {{$labels.verb}} {{$labels.resource}}
- - alert: APIServerErrorsHigh
- expr: rate(apiserver_request_count{code=~"^(?:5..)$"}[5m]) / rate(apiserver_request_count[5m])
- * 100 > 2
- for: 10m
- labels:
- severity: warning
- annotations:
- description: API server returns errors for {{ $value }}% of requests
- - alert: APIServerErrorsHigh
- expr: rate(apiserver_request_count{code=~"^(?:5..)$"}[5m]) / rate(apiserver_request_count[5m])
- * 100 > 5
- for: 10m
- labels:
- severity: critical
- annotations:
- description: API server returns errors for {{ $value }}% of requests
- - alert: K8SApiserverDown
- expr: absent(up{job="apiserver"} == 1)
- for: 20m
- labels:
- severity: critical
- annotations:
- description: No API servers are reachable or all have disappeared from service
- discovery
-
- - alert: K8sCertificateExpirationNotice
- labels:
- severity: warning
- annotations:
- description: Kubernetes API Certificate is expiring soon (less than 7 days)
- expr: sum(apiserver_client_certificate_expiration_seconds_bucket{le="604800"}) > 0
-
- - alert: K8sCertificateExpirationNotice
- labels:
- severity: critical
- annotations:
- description: Kubernetes API Certificate is expiring in less than 1 day
- expr: sum(apiserver_client_certificate_expiration_seconds_bucket{le="86400"}) > 0
- node.rules.yaml: |
- groups:
- - name: node.rules
- rules:
- - record: instance:node_cpu:rate:sum
- expr: sum(rate(node_cpu{mode!="idle",mode!="iowait",mode!~"^(?:guest.*)$"}[3m]))
- BY (instance)
- - record: instance:node_filesystem_usage:sum
- expr: sum((node_filesystem_size{mountpoint="/"} - node_filesystem_free{mountpoint="/"}))
- BY (instance)
- - record: instance:node_network_receive_bytes:rate:sum
- expr: sum(rate(node_network_receive_bytes[3m])) BY (instance)
- - record: instance:node_network_transmit_bytes:rate:sum
- expr: sum(rate(node_network_transmit_bytes[3m])) BY (instance)
- - record: instance:node_cpu:ratio
- expr: sum(rate(node_cpu{mode!="idle"}[5m])) WITHOUT (cpu, mode) / ON(instance)
- GROUP_LEFT() count(sum(node_cpu) BY (instance, cpu)) BY (instance)
- - record: cluster:node_cpu:sum_rate5m
- expr: sum(rate(node_cpu{mode!="idle"}[5m]))
- - record: cluster:node_cpu:ratio
- expr: cluster:node_cpu:rate5m / count(sum(node_cpu) BY (instance, cpu))
- - alert: NodeExporterDown
- expr: absent(up{job="node-exporter"} == 1)
- for: 10m
- labels:
- severity: warning
- annotations:
- description: Prometheus could not scrape a node-exporter for more than 10m,
- or node-exporters have disappeared from discovery
- - alert: NodeDiskRunningFull
- expr: predict_linear(node_filesystem_free[6h], 3600 * 24) < 0
- for: 30m
- labels:
- severity: warning
- annotations:
- description: device {{$labels.device}} on node {{$labels.instance}} is running
- full within the next 24 hours (mounted at {{$labels.mountpoint}})
- - alert: NodeDiskRunningFull
- expr: predict_linear(node_filesystem_free[30m], 3600 * 2) < 0
- for: 10m
- labels:
- severity: critical
- annotations:
- description: device {{$labels.device}} on node {{$labels.instance}} is running
- full within the next 2 hours (mounted at {{$labels.mountpoint}})
- - alert: InactiveRAIDDisk
- expr: node_md_disks - node_md_disks_active > 0
- for: 10m
- labels:
- severity: warning
- annotations:
- description: '{{$value}} RAID disk(s) on node {{$labels.instance}} are inactive'
- prometheus.rules.yaml: |
- groups:
- - name: prometheus.rules
- rules:
- - alert: PrometheusConfigReloadFailed
- expr: prometheus_config_last_reload_successful == 0
- for: 10m
- labels:
- severity: warning
- annotations:
- description: Reloading Prometheus' configuration has failed for {{$labels.namespace}}/{{$labels.pod}}
- - alert: PrometheusNotificationQueueRunningFull
- expr: predict_linear(prometheus_notifications_queue_length[5m], 60 * 30) > prometheus_notifications_queue_capacity
- for: 10m
- labels:
- severity: warning
- annotations:
- description: Prometheus' alert notification queue is running full for {{$labels.namespace}}/{{
- $labels.pod}}
- - alert: PrometheusErrorSendingAlerts
- expr: rate(prometheus_notifications_errors_total[5m]) / rate(prometheus_notifications_sent_total[5m])
- > 0.01
- for: 10m
- labels:
- severity: warning
- annotations:
- description: Errors while sending alerts from Prometheus {{$labels.namespace}}/{{
- $labels.pod}} to Alertmanager {{$labels.Alertmanager}}
- - alert: PrometheusErrorSendingAlerts
- expr: rate(prometheus_notifications_errors_total[5m]) / rate(prometheus_notifications_sent_total[5m])
- > 0.03
- for: 10m
- labels:
- severity: critical
- annotations:
- description: Errors while sending alerts from Prometheus {{$labels.namespace}}/{{
- $labels.pod}} to Alertmanager {{$labels.Alertmanager}}
- - alert: PrometheusNotConnectedToAlertmanagers
- expr: prometheus_notifications_alertmanagers_discovered < 1
- for: 10m
- labels:
- severity: warning
- annotations:
- description: Prometheus {{ $labels.namespace }}/{{ $labels.pod}} is not connected
- to any Alertmanagers
- - alert: PrometheusTSDBReloadsFailing
- expr: increase(prometheus_tsdb_reloads_failures_total[2h]) > 0
- for: 12h
- labels:
- severity: warning
- annotations:
- description: '{{$labels.job}} at {{$labels.instance}} had {{$value | humanize}}
- reload failures over the last four hours.'
- summary: Prometheus has issues reloading data blocks from disk
- - alert: PrometheusTSDBCompactionsFailing
- expr: increase(prometheus_tsdb_compactions_failed_total[2h]) > 0
- for: 12h
- labels:
- severity: warning
- annotations:
- description: '{{$labels.job}} at {{$labels.instance}} had {{$value | humanize}}
- compaction failures over the last four hours.'
- summary: Prometheus has issues compacting sample blocks
- - alert: PrometheusTSDBWALCorruptions
- expr: tsdb_wal_corruptions_total > 0
- for: 4h
- labels:
- severity: warning
- annotations:
- description: '{{$labels.job}} at {{$labels.instance}} has a corrupted write-ahead
- log (WAL).'
- summary: Prometheus write-ahead log is corrupted
- - alert: PrometheusNotIngestingSamples
- expr: rate(prometheus_tsdb_head_samples_appended_total[5m]) <= 0
- for: 10m
- labels:
- severity: warning
- annotations:
- description: "Prometheus {{ $labels.namespace }}/{{ $labels.pod}} isn't ingesting samples."
- summary: "Prometheus isn't ingesting samples"
diff --git a/extensions/metrics-cluster-feature/resources/05-clusterrole.yml b/extensions/metrics-cluster-feature/resources/05-clusterrole.yml
deleted file mode 100644
index 9b23edc84b..0000000000
--- a/extensions/metrics-cluster-feature/resources/05-clusterrole.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: lens-prometheus
-rules:
-- apiGroups: [""]
- resources:
- - nodes
- - nodes/proxy
- - nodes/metrics
- - services
- - endpoints
- - pods
- - ingresses
- - configmaps
- verbs: ["get", "list", "watch"]
-- nonResourceURLs: ["/metrics"]
- verbs: ["get"]
diff --git a/extensions/metrics-cluster-feature/resources/06-clusterrole-binding.yml b/extensions/metrics-cluster-feature/resources/06-clusterrole-binding.yml
deleted file mode 100644
index 37fc605f05..0000000000
--- a/extensions/metrics-cluster-feature/resources/06-clusterrole-binding.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: lens-prometheus
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: lens-prometheus
-subjects:
-- kind: ServiceAccount
- name: prometheus
- namespace: lens-metrics
diff --git a/extensions/metrics-cluster-feature/resources/10-node-exporter-ds.yml.hb b/extensions/metrics-cluster-feature/resources/10-node-exporter-ds.yml.hb
deleted file mode 100644
index c02fb93321..0000000000
--- a/extensions/metrics-cluster-feature/resources/10-node-exporter-ds.yml.hb
+++ /dev/null
@@ -1,79 +0,0 @@
-{{#if nodeExporter.enabled}}
-apiVersion: apps/v1
-kind: DaemonSet
-metadata:
- name: node-exporter
- namespace: lens-metrics
-spec:
- updateStrategy:
- type: RollingUpdate
- rollingUpdate:
- maxUnavailable: 1
- selector:
- matchLabels:
- name: node-exporter
- phase: prod
- template:
- metadata:
- labels:
- name: node-exporter
- phase: prod
- annotations:
- seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
- spec:
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: kubernetes.io/os
- operator: In
- values:
- - linux
- securityContext:
- runAsNonRoot: true
- runAsUser: 65534
- hostPID: true
- containers:
- - name: node-exporter
- image: quay.io/prometheus/node-exporter:v1.1.2
- args:
- - --path.procfs=/host/proc
- - --path.sysfs=/host/sys
- - --path.rootfs=/host/root
- - --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker|var/lib/containerd|var/lib/containers/.+)($|/)
- - --collector.filesystem.ignored-fs-types=^(autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|sysfs|tracefs)$
- ports:
- - name: metrics
- containerPort: 9100
- resources:
- requests:
- cpu: 10m
- memory: 24Mi
- limits:
- cpu: 200m
- memory: 100Mi
- volumeMounts:
- - name: proc
- mountPath: /host/proc
- readOnly: true
- - name: sys
- mountPath: /host/sys
- readOnly: true
- - name: root
- mountPath: /host/root
- readOnly: true
- tolerations:
- - effect: NoSchedule
- operator: Exists
- volumes:
- - name: proc
- hostPath:
- path: /proc
- - name: sys
- hostPath:
- path: /sys
- - name: root
- hostPath:
- path: /
-{{/if}}
diff --git a/extensions/metrics-cluster-feature/resources/11-node-exporter-svc.yml b/extensions/metrics-cluster-feature/resources/11-node-exporter-svc.yml
deleted file mode 100644
index f85e878e06..0000000000
--- a/extensions/metrics-cluster-feature/resources/11-node-exporter-svc.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- name: node-exporter
- namespace: lens-metrics
- annotations:
- prometheus.io/scrape: 'true'
-spec:
- type: ClusterIP
- clusterIP: None
- selector:
- name: node-exporter
- phase: prod
- ports:
- - name: metrics
- protocol: TCP
- port: 80
- targetPort: 9100
diff --git a/extensions/metrics-cluster-feature/resources/12-kube-state-metrics-clusterrole.yml b/extensions/metrics-cluster-feature/resources/12-kube-state-metrics-clusterrole.yml
deleted file mode 100644
index 8101bcc05d..0000000000
--- a/extensions/metrics-cluster-feature/resources/12-kube-state-metrics-clusterrole.yml
+++ /dev/null
@@ -1,128 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: lens-kube-state-metrics
-rules:
- - apiGroups:
- - ""
- resources:
- - configmaps
- - secrets
- - nodes
- - pods
- - services
- - resourcequotas
- - replicationcontrollers
- - limitranges
- - persistentvolumeclaims
- - persistentvolumes
- - namespaces
- - endpoints
- verbs:
- - list
- - watch
- - apiGroups:
- - extensions
- resources:
- - daemonsets
- - deployments
- - replicasets
- - ingresses
- verbs:
- - list
- - watch
- - apiGroups:
- - networking.k8s.io
- resources:
- - ingresses
- verbs:
- - list
- - watch
- - apiGroups:
- - apps
- resources:
- - statefulsets
- - daemonsets
- - deployments
- - replicasets
- verbs:
- - list
- - watch
- - apiGroups:
- - batch
- resources:
- - cronjobs
- - jobs
- verbs:
- - list
- - watch
- - apiGroups:
- - autoscaling
- resources:
- - horizontalpodautoscalers
- verbs:
- - list
- - watch
- - apiGroups:
- - authentication.k8s.io
- resources:
- - tokenreviews
- verbs:
- - create
- - apiGroups:
- - authorization.k8s.io
- resources:
- - subjectaccessreviews
- verbs:
- - create
- - apiGroups:
- - policy
- resources:
- - poddisruptionbudgets
- verbs:
- - list
- - watch
- - apiGroups:
- - certificates.k8s.io
- resources:
- - certificatesigningrequests
- verbs:
- - list
- - watch
- - apiGroups:
- - storage.k8s.io
- resources:
- - storageclasses
- - volumeattachments
- verbs:
- - list
- - watch
- - apiGroups:
- - admissionregistration.k8s.io
- resources:
- - mutatingwebhookconfigurations
- - validatingwebhookconfigurations
- verbs:
- - list
- - watch
- - apiGroups:
- - networking.k8s.io
- resources:
- - networkpolicies
- verbs:
- - list
- - watch
- - apiGroups:
- - coordination.k8s.io
- resources:
- - leases
- verbs:
- - list
- - watch
- - apiGroups:
- - scheduling.k8s.io
- resources:
- - priorityclasses
- verbs:
- - list
- - watch
diff --git a/extensions/metrics-cluster-feature/resources/12.kube-state-metrics-sa.yml b/extensions/metrics-cluster-feature/resources/12.kube-state-metrics-sa.yml
deleted file mode 100644
index 2b3c22f8da..0000000000
--- a/extensions/metrics-cluster-feature/resources/12.kube-state-metrics-sa.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: kube-state-metrics
- namespace: lens-metrics
diff --git a/extensions/metrics-cluster-feature/resources/13-kube-state-metrics-clusterrole-binding.yml b/extensions/metrics-cluster-feature/resources/13-kube-state-metrics-clusterrole-binding.yml
deleted file mode 100644
index e60dedae19..0000000000
--- a/extensions/metrics-cluster-feature/resources/13-kube-state-metrics-clusterrole-binding.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: lens-kube-state-metrics
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: lens-kube-state-metrics
-subjects:
-- kind: ServiceAccount
- name: kube-state-metrics
- namespace: lens-metrics
diff --git a/extensions/metrics-cluster-feature/resources/14-kube-state-metrics-deployment.yml.hb b/extensions/metrics-cluster-feature/resources/14-kube-state-metrics-deployment.yml.hb
deleted file mode 100644
index 0174d5c8f4..0000000000
--- a/extensions/metrics-cluster-feature/resources/14-kube-state-metrics-deployment.yml.hb
+++ /dev/null
@@ -1,46 +0,0 @@
-{{#if kubeStateMetrics.enabled}}
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: kube-state-metrics
- namespace: lens-metrics
-spec:
- selector:
- matchLabels:
- name: kube-state-metrics
- replicas: 1
- template:
- metadata:
- labels:
- name: kube-state-metrics
- spec:
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: kubernetes.io/os
- operator: In
- values:
- - linux
- serviceAccountName: kube-state-metrics
- containers:
- - name: kube-state-metrics
- image: k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0
- ports:
- - name: metrics
- containerPort: 8080
- readinessProbe:
- httpGet:
- path: /healthz
- port: 8080
- initialDelaySeconds: 5
- timeoutSeconds: 5
- resources:
- requests:
- cpu: 10m
- memory: 32Mi
- limits:
- cpu: 200m
- memory: 150Mi
-{{/if}}
diff --git a/extensions/metrics-cluster-feature/resources/14-kube-state-metrics-svc.yml b/extensions/metrics-cluster-feature/resources/14-kube-state-metrics-svc.yml
deleted file mode 100644
index be6168ab7a..0000000000
--- a/extensions/metrics-cluster-feature/resources/14-kube-state-metrics-svc.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- name: kube-state-metrics
- namespace: lens-metrics
- labels:
- name: kube-state-metrics
- annotations:
- prometheus.io/scrape: 'true'
-spec:
- ports:
- - name: metrics
- port: 8080
- targetPort: 8080
- protocol: TCP
- selector:
- name: kube-state-metrics
diff --git a/extensions/metrics-cluster-feature/src/metrics-feature.ts b/extensions/metrics-cluster-feature/src/metrics-feature.ts
deleted file mode 100644
index c9d4275abb..0000000000
--- a/extensions/metrics-cluster-feature/src/metrics-feature.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import type { Common } from "@k8slens/extensions";
-import { Renderer } from "@k8slens/extensions";
-import semver from "semver";
-import * as path from "path";
-
-const { ResourceStack, forCluster, StorageClass, Namespace } = Renderer.K8sApi;
-
-type ResourceStack = Renderer.K8sApi.ResourceStack;
-
-export interface MetricsConfiguration {
- // Placeholder for Metrics config structure
- prometheus: {
- enabled: boolean;
- };
- persistence: {
- enabled: boolean;
- storageClass: string;
- size: string;
- };
- nodeExporter: {
- enabled: boolean;
- };
- kubeStateMetrics: {
- enabled: boolean;
- };
- retention: {
- time: string;
- size: string;
- };
- alertManagers: string[];
- replicas: number;
- storageClass: string;
- version?: string;
-}
-
-export interface MetricsStatus {
- installed: boolean;
- canUpgrade: boolean;
-}
-
-export class MetricsFeature {
- name = "lens-metrics";
- latestVersion = "v2.26.0-lens1";
-
- protected stack: ResourceStack;
-
- constructor(protected cluster: Common.Catalog.KubernetesCluster) {
- this.stack = new ResourceStack(cluster, this.name);
- }
-
- get resourceFolder() {
- return path.join(__dirname, "../resources/");
- }
-
- async install(config: MetricsConfiguration): Promise {
- // Check if there are storageclasses
- const storageClassApi = forCluster(this.cluster, StorageClass);
- const scs = await storageClassApi.list();
-
- config.persistence.enabled = scs.some(sc => (
- sc.metadata?.annotations?.["storageclass.kubernetes.io/is-default-class"] === "true" ||
- sc.metadata?.annotations?.["storageclass.beta.kubernetes.io/is-default-class"] === "true"
- ));
-
- config.version = this.latestVersion;
-
- return this.stack.kubectlApplyFolder(this.resourceFolder, config, ["--prune"]);
- }
-
- async upgrade(config: MetricsConfiguration): Promise {
- return this.install(config);
- }
-
- async getStatus(): Promise {
- const status: MetricsStatus = { installed: false, canUpgrade: false };
-
- try {
- const namespaceApi = forCluster(this.cluster, Namespace);
- const namespace = await namespaceApi.get({ name: "lens-metrics" });
-
- if (namespace?.kind) {
- const currentVersion = namespace.metadata.annotations?.extensionVersion || "0.0.0";
-
- status.installed = true;
- status.canUpgrade = semver.lt(currentVersion, this.latestVersion, true);
- } else {
- status.installed = false;
- }
- } catch(e) {
- if (e?.error?.code === 404) {
- status.installed = false;
- } else {
- console.warn("[LENS-METRICS] failed to resolve install state", e);
- }
- }
-
- return status;
- }
-
- async uninstall(config: MetricsConfiguration): Promise {
- return this.stack.kubectlDeleteFolder(this.resourceFolder, config);
- }
-}
diff --git a/extensions/metrics-cluster-feature/src/metrics-settings.tsx b/extensions/metrics-cluster-feature/src/metrics-settings.tsx
deleted file mode 100644
index 4ae4235780..0000000000
--- a/extensions/metrics-cluster-feature/src/metrics-settings.tsx
+++ /dev/null
@@ -1,276 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-import React from "react";
-import type { Common } from "@k8slens/extensions";
-import { Renderer } from "@k8slens/extensions";
-import { observer } from "mobx-react";
-import { computed, observable, makeObservable } from "mobx";
-import type { MetricsConfiguration } from "./metrics-feature";
-import { MetricsFeature } from "./metrics-feature";
-
-const {
- K8sApi: {
- forCluster, StatefulSet, DaemonSet, Deployment,
- },
- Component: {
- SubTitle, Switch, Button,
- },
-} = Renderer;
-
-export interface MetricsSettingsProps {
- cluster: Common.Catalog.KubernetesCluster;
-}
-
-@observer
-export class MetricsSettings extends React.Component {
- constructor(props: MetricsSettingsProps) {
- super(props);
- makeObservable(this);
- }
-
- @observable featureStates = {
- prometheus: false,
- kubeStateMetrics: false,
- nodeExporter: false,
- };
- @observable canUpgrade = false;
- @observable upgrading = false;
- @observable changed = false;
- @observable inProgress = false;
-
- config: MetricsConfiguration = {
- prometheus: {
- enabled: false,
- },
- persistence: {
- enabled: false,
- storageClass: null,
- size: "20Gi", // kubernetes yaml value (no B suffix)
- },
- nodeExporter: {
- enabled: false,
- },
- retention: {
- time: "2d",
- size: "5GiB", // argument for prometheus (requires B suffix)
- },
- kubeStateMetrics: {
- enabled: false,
- },
- alertManagers: null,
- replicas: 1,
- storageClass: null,
- };
- feature: MetricsFeature;
-
- @computed get isTogglable() {
- if (this.inProgress) return false;
- if (this.props.cluster.status.phase !== "connected") return false;
- if (this.canUpgrade) return false;
- if (!this.isActiveMetricsProvider) return false;
-
- return true;
- }
-
- get metricsProvider() {
- return this.props.cluster.spec?.metrics?.prometheus?.type || "";
- }
-
- get isActiveMetricsProvider() {
- return (!this.metricsProvider || this.metricsProvider === "lens");
- }
-
- async componentDidMount() {
- this.feature = new MetricsFeature(this.props.cluster);
-
- await this.updateFeatureStates();
- }
-
- async updateFeatureStates() {
- const status = await this.feature.getStatus();
-
- this.canUpgrade = status.canUpgrade;
-
- if (this.canUpgrade) {
- this.changed = true;
- }
-
- const statefulSet = forCluster(this.props.cluster, StatefulSet);
-
- try {
- await statefulSet.get({ name: "prometheus", namespace: "lens-metrics" });
- this.featureStates.prometheus = true;
- } catch(e) {
- if (e?.error?.code === 404) {
- this.featureStates.prometheus = false;
- } else {
- this.featureStates.prometheus = undefined;
- }
- }
-
- const deployment = forCluster(this.props.cluster, Deployment);
-
- try {
- await deployment.get({ name: "kube-state-metrics", namespace: "lens-metrics" });
- this.featureStates.kubeStateMetrics = true;
- } catch(e) {
- if (e?.error?.code === 404) {
- this.featureStates.kubeStateMetrics = false;
- } else {
- this.featureStates.kubeStateMetrics = undefined;
- }
- }
-
- const daemonSet = forCluster(this.props.cluster, DaemonSet);
-
- try {
- await daemonSet.get({ name: "node-exporter", namespace: "lens-metrics" });
- this.featureStates.nodeExporter = true;
- } catch(e) {
- if (e?.error?.code === 404) {
- this.featureStates.nodeExporter = false;
- } else {
- this.featureStates.nodeExporter = undefined;
- }
- }
- }
-
- async save() {
- this.config.prometheus.enabled = !!this.featureStates.prometheus;
- this.config.kubeStateMetrics.enabled = !!this.featureStates.kubeStateMetrics;
- this.config.nodeExporter.enabled = !!this.featureStates.nodeExporter;
-
- this.inProgress = true;
-
- try {
- if (!this.config.prometheus.enabled && !this.config.kubeStateMetrics.enabled && !this.config.nodeExporter.enabled) {
- await this.feature.uninstall(this.config);
- } else {
- await this.feature.install(this.config);
- }
- } finally {
- this.inProgress = false;
- this.changed = false;
-
- await this.updateFeatureStates();
- }
- }
-
- async togglePrometheus(enabled: boolean) {
- this.featureStates.prometheus = enabled;
- this.changed = true;
- }
-
- async toggleKubeStateMetrics(enabled: boolean) {
- this.featureStates.kubeStateMetrics = enabled;
- this.changed = true;
- }
-
- async toggleNodeExporter(enabled: boolean) {
- this.featureStates.nodeExporter = enabled;
- this.changed = true;
- }
-
- @computed get buttonLabel() {
- const allDisabled = !this.featureStates.kubeStateMetrics && !this.featureStates.nodeExporter && !this.featureStates.prometheus;
-
- if (this.inProgress && this.canUpgrade) return "Upgrading ...";
- if (this.inProgress && allDisabled) return "Uninstalling ...";
- if (this.inProgress) return "Applying ...";
- if (this.canUpgrade) return "Upgrade";
-
- if (this.changed && allDisabled) {
- return "Uninstall";
- }
-
- return "Apply";
- }
-
- render() {
- return (
-
- { this.props.cluster.status.phase !== "connected" && (
-
-
- Lens Metrics settings requires established connection to the cluster.
-
-
- )}
- { !this.isActiveMetricsProvider && (
-
-
- Other metrics provider is currently active. See "Metrics" tab for details.
-
-
- )}
-
-
- this.togglePrometheus(checked)}
- name="prometheus"
- >
- Enable bundled Prometheus metrics stack
-
-
- Enable timeseries data visualization (Prometheus stack) for your cluster.
-
-
-
-
-
- this.toggleKubeStateMetrics(checked)}
- name="kube-state-metrics"
- >
- Enable bundled kube-state-metrics stack
-
-
- Enable Kubernetes API object metrics for your cluster.
- Enable this only if you don't have existing kube-state-metrics stack installed.
-
-
-
-
-
- this.toggleNodeExporter(checked)}
- name="node-exporter"
- >
- Enable bundled node-exporter stack
-
-
- Enable node level metrics for your cluster.
- Enable this only if you don't have existing node-exporter stack installed.
-
-
-
-
-
- this.save()}
- disabled={!this.changed}
- style={{ width: "20ch", padding: "0.5rem" }}
- />
-
- {this.canUpgrade && (
-
- An update is available for enabled metrics components.
-
- )}
-
-
-
- );
- }
-}
diff --git a/extensions/metrics-cluster-feature/tsconfig.json b/extensions/metrics-cluster-feature/tsconfig.json
deleted file mode 100644
index f60a98c9ad..0000000000
--- a/extensions/metrics-cluster-feature/tsconfig.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "compilerOptions": {
- "outDir": "dist",
- "module": "CommonJS",
- "target": "ES2017",
- "lib": ["ESNext", "DOM", "DOM.Iterable"],
- "moduleResolution": "Node",
- "sourceMap": false,
- "declaration": false,
- "strict": false,
- "noImplicitAny": true,
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "experimentalDecorators": true,
- "useDefineForClassFields": true,
- "jsx": "react"
- },
- "include": [
- "./**/*.ts",
- "./**/*.tsx"
- ],
- "exclude": [
- "node_modules",
- "*.js"
- ]
-}
diff --git a/extensions/metrics-cluster-feature/webpack.config.js b/extensions/metrics-cluster-feature/webpack.config.js
deleted file mode 100644
index 951cffdabc..0000000000
--- a/extensions/metrics-cluster-feature/webpack.config.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-const path = require("path");
-
-module.exports = [
- {
- entry: "./renderer.tsx",
- context: __dirname,
- target: "electron-renderer",
- mode: "production",
- optimization: {
- minimize: false,
- },
- module: {
- rules: [
- {
- test: /\.tsx?$/,
- use: "ts-loader",
- exclude: /node_modules/,
- },
- ],
- },
- externals: [
- {
- "@k8slens/extensions": "var global.LensExtensions",
- "react": "var global.React",
- "react-dom": "var global.ReactDOM",
- "mobx": "var global.Mobx",
- "mobx-react": "var global.MobxReact",
- },
- ],
- resolve: {
- extensions: [ ".tsx", ".ts", ".js" ],
- },
- output: {
- libraryTarget: "commonjs2",
- globalObject: "this",
- filename: "renderer.js",
- path: path.resolve(__dirname, "dist"),
- },
- node: {
- __dirname: false,
- },
- },
-];
diff --git a/extensions/node-menu/package.json b/extensions/node-menu/package.json
deleted file mode 100644
index df2d490ee0..0000000000
--- a/extensions/node-menu/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "name": "lens-node-menu",
- "version": "6.1.0",
- "description": "Lens node menu",
- "renderer": "dist/renderer.js",
- "lens": {
- "metadata": {},
- "styles": []
- },
- "scripts": {
- "build": "npx webpack",
- "dev": "npx webpack -- --watch",
- "test": "npx jest --passWithNoTests --env=jsdom src $@"
- },
- "files": [
- "dist/**/*"
- ],
- "dependencies": {},
- "devDependencies": {
- "@k8slens/extensions": "file:../../src/extensions/npm/extensions"
- }
-}
diff --git a/extensions/node-menu/renderer.tsx b/extensions/node-menu/renderer.tsx
deleted file mode 100644
index 31557c908d..0000000000
--- a/extensions/node-menu/renderer.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import { Renderer } from "@k8slens/extensions";
-import React from "react";
-import type { NodeMenuProps } from "./src/node-menu";
-import { NodeMenu } from "./src/node-menu";
-
-export default class NodeMenuRendererExtension extends Renderer.LensExtension {
- kubeObjectMenuItems = [
- {
- kind: "Node",
- apiVersions: ["v1"],
- components: {
- MenuItem: (props: NodeMenuProps) => ,
- },
- },
- ];
-}
diff --git a/extensions/node-menu/src/node-menu.tsx b/extensions/node-menu/src/node-menu.tsx
deleted file mode 100644
index adc7576206..0000000000
--- a/extensions/node-menu/src/node-menu.tsx
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import React from "react";
-import { Common, Renderer } from "@k8slens/extensions";
-
-type Node = Renderer.K8sApi.Node;
-
-const {
- Component: {
- terminalStore,
- createTerminalTab,
- ConfirmDialog,
- MenuItem,
- Icon,
- },
- Navigation,
-} = Renderer;
-const {
- App,
-} = Common;
-
-
-export interface NodeMenuProps extends Renderer.Component.KubeObjectMenuProps {
-}
-
-export function NodeMenu(props: NodeMenuProps) {
- const { object: node, toolbar } = props;
-
- if (!node) {
- return null;
- }
-
- const nodeName = node.getName();
- const kubectlPath = App.Preferences.getKubectlPath() || "kubectl";
-
- const sendToTerminal = (command: string) => {
- terminalStore.sendCommand(command, {
- enter: true,
- newTab: true,
- });
- Navigation.hideDetails();
- };
-
- const shell = () => {
- createTerminalTab({
- title: `Node: ${nodeName}`,
- node: nodeName,
- });
- Navigation.hideDetails();
- };
-
- const cordon = () => {
- sendToTerminal(`${kubectlPath} cordon ${nodeName}`);
- };
-
- const unCordon = () => {
- sendToTerminal(`${kubectlPath} uncordon ${nodeName}`);
- };
-
- const drain = () => {
- const command = `${kubectlPath} drain ${nodeName} --delete-local-data --ignore-daemonsets --force`;
-
- ConfirmDialog.open({
- ok: () => sendToTerminal(command),
- labelOk: `Drain Node`,
- message: (
-
- {"Are you sure you want to drain "}
- {nodeName}
- ?
-
- ),
- });
- };
-
- return (
- <>
-
-
- Shell
-
- {
- node.isUnschedulable()
- ? (
-
-
- Uncordon
-
- )
- : (
-
-
- Cordon
-
- )
- }
-
-
- Drain
-
- >
- );
-}
diff --git a/extensions/node-menu/tsconfig.json b/extensions/node-menu/tsconfig.json
deleted file mode 100644
index 5b6c61577e..0000000000
--- a/extensions/node-menu/tsconfig.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "compilerOptions": {
- "outDir": "dist",
- "module": "CommonJS",
- "target": "ES2017",
- "lib": ["ESNext", "DOM", "DOM.Iterable"],
- "moduleResolution": "Node",
- "sourceMap": false,
- "declaration": false,
- "strict": false,
- "noImplicitAny": true,
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "experimentalDecorators": true,
- "useDefineForClassFields": true,
- "jsx": "react"
- },
- "include": [
- "./*.ts",
- "./*.tsx"
- ],
- "exclude": [
- "node_modules",
- "*.js"
- ]
-}
diff --git a/extensions/node-menu/webpack.config.js b/extensions/node-menu/webpack.config.js
deleted file mode 100644
index 8fe82e48a7..0000000000
--- a/extensions/node-menu/webpack.config.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-const path = require("path");
-
-module.exports = [
- {
- entry: "./renderer.tsx",
- context: __dirname,
- target: "electron-renderer",
- mode: "production",
- optimization: {
- minimize: false,
- },
- module: {
- rules: [
- {
- test: /\.tsx?$/,
- use: "ts-loader",
- exclude: /node_modules/,
- },
- ],
- },
- externals: [
- {
- "@k8slens/extensions": "var global.LensExtensions",
- "react": "var global.React",
- "react-dom": "var global.ReactDOM",
- "mobx": "var global.Mobx",
- "mobx-react": "var global.MobxReact",
- },
- ],
- resolve: {
- extensions: [ ".tsx", ".ts", ".js" ],
- },
- output: {
- libraryTarget: "commonjs2",
- globalObject: "this",
- filename: "renderer.js",
- path: path.resolve(__dirname, "dist"),
- },
- },
-];
diff --git a/extensions/pod-menu/package.json b/extensions/pod-menu/package.json
deleted file mode 100644
index 3b44d3c44d..0000000000
--- a/extensions/pod-menu/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "name": "lens-pod-menu",
- "version": "6.1.0",
- "description": "Lens pod menu",
- "renderer": "dist/renderer.js",
- "lens": {
- "metadata": {},
- "styles": []
- },
- "scripts": {
- "build": "npx webpack",
- "dev": "npx webpack -- --watch",
- "test": "npx jest --passWithNoTests --env=jsdom src $@"
- },
- "files": [
- "dist/**/*"
- ],
- "dependencies": {},
- "devDependencies": {
- "@k8slens/extensions": "file:../../src/extensions/npm/extensions"
- }
-}
diff --git a/extensions/pod-menu/renderer.tsx b/extensions/pod-menu/renderer.tsx
deleted file mode 100644
index 4788da9707..0000000000
--- a/extensions/pod-menu/renderer.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import { Renderer } from "@k8slens/extensions";
-import type { PodAttachMenuProps } from "./src/attach-menu";
-import { PodAttachMenu } from "./src/attach-menu";
-import type { PodShellMenuProps } from "./src/shell-menu";
-import { PodShellMenu } from "./src/shell-menu";
-import type { PodLogsMenuProps } from "./src/logs-menu";
-import { PodLogsMenu } from "./src/logs-menu";
-import React from "react";
-
-export default class PodMenuRendererExtension extends Renderer.LensExtension {
- kubeObjectMenuItems = [
- {
- kind: "Pod",
- apiVersions: ["v1"],
- components: {
- MenuItem: (props: PodAttachMenuProps) => ,
- },
- },
- {
- kind: "Pod",
- apiVersions: ["v1"],
- components: {
- MenuItem: (props: PodShellMenuProps) => ,
- },
- },
- {
- kind: "Pod",
- apiVersions: ["v1"],
- components: {
- MenuItem: (props: PodLogsMenuProps) => ,
- },
- },
- ];
-}
diff --git a/extensions/pod-menu/src/attach-menu.tsx b/extensions/pod-menu/src/attach-menu.tsx
deleted file mode 100644
index fd6250bd30..0000000000
--- a/extensions/pod-menu/src/attach-menu.tsx
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-
-
-import React from "react";
-import { Renderer, Common } from "@k8slens/extensions";
-
-type Pod = Renderer.K8sApi.Pod;
-
-const {
- Component: {
- createTerminalTab,
- terminalStore,
- MenuItem,
- Icon,
- SubMenu,
- StatusBrick,
- },
- Navigation,
-} = Renderer;
-const {
- Util,
- App,
-} = Common;
-
-export interface PodAttachMenuProps extends Renderer.Component.KubeObjectMenuProps {
-}
-
-export class PodAttachMenu extends React.Component {
- async attachToPod(container?: string) {
- const { object: pod } = this.props;
-
- const kubectlPath = App.Preferences.getKubectlPath() || "kubectl";
- const commandParts = [
- kubectlPath,
- "attach",
- "-i",
- "-t",
- "-n", pod.getNs(),
- pod.getName(),
- ];
-
- if (window.navigator.platform !== "Win32") {
- commandParts.unshift("exec");
- }
-
- if (container) {
- commandParts.push("-c", container);
- }
-
- const shell = createTerminalTab({
- title: `Pod: ${pod.getName()} (namespace: ${pod.getNs()}) [Attached]`,
- });
-
- terminalStore.sendCommand(commandParts.join(" "), {
- enter: true,
- tabId: shell.id,
- });
-
- Navigation.hideDetails();
- }
-
- render() {
- const { object, toolbar } = this.props;
- const containers = object.getRunningContainers();
-
- if (!containers.length) return null;
-
- return (
- this.attachToPod(containers[0].name))}>
-
- Attach Pod
- {containers.length > 1 && (
- <>
-
-
- {
- containers.map(container => {
- const { name } = container;
-
- return (
- this.attachToPod(name))}
- className="flex align-center"
- >
-
- {name}
-
- );
- })
- }
-
- >
- )}
-
- );
- }
-}
diff --git a/extensions/pod-menu/src/logs-menu.tsx b/extensions/pod-menu/src/logs-menu.tsx
deleted file mode 100644
index e5c8496d3d..0000000000
--- a/extensions/pod-menu/src/logs-menu.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import React from "react";
-import { Renderer, Common } from "@k8slens/extensions";
-
-type Pod = Renderer.K8sApi.Pod;
-type IPodContainer = Renderer.K8sApi.IPodContainer;
-
-const {
- Component: {
- logTabStore,
- MenuItem,
- Icon,
- SubMenu,
- StatusBrick,
- },
- Navigation,
-} = Renderer;
-const {
- Util,
-} = Common;
-
-export interface PodLogsMenuProps extends Renderer.Component.KubeObjectMenuProps {
-}
-
-export class PodLogsMenu extends React.Component {
- showLogs(container: IPodContainer) {
- Navigation.hideDetails();
- const pod = this.props.object;
-
- logTabStore.createPodTab({
- selectedPod: pod,
- selectedContainer: container,
- });
- }
-
- render() {
- const { object: pod, toolbar } = this.props;
- const containers = pod.getAllContainers();
- const statuses = pod.getContainerStatuses();
-
- if (!containers.length) return null;
-
- return (
- this.showLogs(containers[0]))}>
-
- Logs
- {containers.length > 1 && (
- <>
-
-
- {
- containers.map(container => {
- const { name } = container;
- const status = statuses.find(status => status.name === name);
- const brick = status ? (
-
- ) : null;
-
- return (
- this.showLogs(container))}
- className="flex align-center"
- >
- {brick}
- {name}
-
- );
- })
- }
-
- >
- )}
-
- );
- }
-}
diff --git a/extensions/pod-menu/src/shell-menu.tsx b/extensions/pod-menu/src/shell-menu.tsx
deleted file mode 100644
index 36be7c470b..0000000000
--- a/extensions/pod-menu/src/shell-menu.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-
-
-import React from "react";
-import { Renderer, Common } from "@k8slens/extensions";
-
-type Pod = Renderer.K8sApi.Pod;
-
-const {
- Component: {
- createTerminalTab,
- terminalStore,
- MenuItem,
- Icon,
- SubMenu,
- StatusBrick,
- },
- Navigation,
-} = Renderer;
-const {
- Util,
- App,
-} = Common;
-
-export interface PodShellMenuProps extends Renderer.Component.KubeObjectMenuProps {
-}
-
-export class PodShellMenu extends React.Component {
- async execShell(container?: string) {
- const { object: pod } = this.props;
-
- const kubectlPath = App.Preferences.getKubectlPath() || "kubectl";
- const commandParts = [
- kubectlPath,
- "exec",
- "-i",
- "-t",
- "-n", pod.getNs(),
- pod.getName(),
- ];
-
- if (window.navigator.platform !== "Win32") {
- commandParts.unshift("exec");
- }
-
- if (container) {
- commandParts.push("-c", container);
- }
-
- commandParts.push("--");
-
- if (pod.getSelectedNodeOs() === "windows") {
- commandParts.push("powershell");
- } else {
- commandParts.push('sh -c "clear; (bash || ash || sh)"');
- }
-
- const shell = createTerminalTab({
- title: `Pod: ${pod.getName()} (namespace: ${pod.getNs()})`,
- });
-
- terminalStore.sendCommand(commandParts.join(" "), {
- enter: true,
- tabId: shell.id,
- });
-
- Navigation.hideDetails();
- }
-
- render() {
- const { object, toolbar } = this.props;
- const containers = object.getRunningContainers();
-
- if (!containers.length) return null;
-
- return (
- this.execShell(containers[0].name))}>
-
- Shell
- {containers.length > 1 && (
- <>
-
-
- {
- containers.map(container => {
- const { name } = container;
-
- return (
- this.execShell(name))}
- className="flex align-center"
- >
-
- {name}
-
- );
- })
- }
-
- >
- )}
-
- );
- }
-}
diff --git a/extensions/pod-menu/tsconfig.json b/extensions/pod-menu/tsconfig.json
deleted file mode 100644
index 5b6c61577e..0000000000
--- a/extensions/pod-menu/tsconfig.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "compilerOptions": {
- "outDir": "dist",
- "module": "CommonJS",
- "target": "ES2017",
- "lib": ["ESNext", "DOM", "DOM.Iterable"],
- "moduleResolution": "Node",
- "sourceMap": false,
- "declaration": false,
- "strict": false,
- "noImplicitAny": true,
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "experimentalDecorators": true,
- "useDefineForClassFields": true,
- "jsx": "react"
- },
- "include": [
- "./*.ts",
- "./*.tsx"
- ],
- "exclude": [
- "node_modules",
- "*.js"
- ]
-}
diff --git a/extensions/pod-menu/webpack.config.js b/extensions/pod-menu/webpack.config.js
deleted file mode 100644
index 8fe82e48a7..0000000000
--- a/extensions/pod-menu/webpack.config.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-const path = require("path");
-
-module.exports = [
- {
- entry: "./renderer.tsx",
- context: __dirname,
- target: "electron-renderer",
- mode: "production",
- optimization: {
- minimize: false,
- },
- module: {
- rules: [
- {
- test: /\.tsx?$/,
- use: "ts-loader",
- exclude: /node_modules/,
- },
- ],
- },
- externals: [
- {
- "@k8slens/extensions": "var global.LensExtensions",
- "react": "var global.React",
- "react-dom": "var global.ReactDOM",
- "mobx": "var global.Mobx",
- "mobx-react": "var global.MobxReact",
- },
- ],
- resolve: {
- extensions: [ ".tsx", ".ts", ".js" ],
- },
- output: {
- libraryTarget: "commonjs2",
- globalObject: "this",
- filename: "renderer.js",
- path: path.resolve(__dirname, "dist"),
- },
- },
-];
diff --git a/integration/__tests__/cluster-pages.tests.ts b/integration/__tests__/cluster-pages.tests.ts
index 842a38da88..e0b865d5af 100644
--- a/integration/__tests__/cluster-pages.tests.ts
+++ b/integration/__tests__/cluster-pages.tests.ts
@@ -76,60 +76,6 @@ describeIf(minikubeReady(TEST_NAMESPACE))("Minikube based tests", () => {
10 * 60 * 1000,
);
- it(
- "show logs and highlight the log search entries",
- async () => {
- await navigateToPods(frame);
-
- const namespacesSelector = await frame.waitForSelector(
- ".NamespaceSelect",
- );
-
- await namespacesSelector.click();
- await namespacesSelector.type("kube-system");
- await namespacesSelector.press("Enter");
- await namespacesSelector.click();
-
- const kubeApiServerRow = await frame.waitForSelector(
- "div.TableCell >> text=kube-apiserver",
- );
-
- await kubeApiServerRow.click();
- await frame.waitForSelector(".Drawer", { state: "visible" });
-
- const showPodLogsIcon = await frame.waitForSelector(
- ".Drawer .drawer-title .Icon >> text=subject",
- );
-
- showPodLogsIcon.click();
-
- // Check if controls are available
- await frame.waitForSelector(".Dock.isOpen");
- await frame.waitForSelector(".LogList .VirtualList");
- await frame.waitForSelector(".LogResourceSelector");
-
- const logSearchInput = await frame.waitForSelector(
- ".LogSearch .SearchInput input",
- );
-
- await logSearchInput.type(":");
- await frame.waitForSelector(".LogList .list span.active");
-
- const showTimestampsButton = await frame.waitForSelector(
- "[data-testid='log-controls'] .show-timestamps",
- );
-
- await showTimestampsButton.click();
-
- const showPreviousButton = await frame.waitForSelector(
- "[data-testid='log-controls'] .show-previous",
- );
-
- await showPreviousButton.click();
- },
- 10 * 60 * 1000,
- );
-
it(
"should show the default namespaces",
async () => {
diff --git a/package.json b/package.json
index 232a4395ad..99fdec1759 100644
--- a/package.json
+++ b/package.json
@@ -59,12 +59,7 @@
"sentryDsn": "",
"contentSecurityPolicy": "script-src 'unsafe-eval' 'self'; frame-src http://*.localhost:*/; img-src * data:",
"welcomeRoute": "/welcome",
- "extensions": [
- "kube-object-event-status",
- "metrics-cluster-feature",
- "node-menu",
- "pod-menu"
- ]
+ "extensions": []
},
"engines": {
"node": ">=16 <17"
@@ -234,14 +229,9 @@
"joi": "^17.7.0",
"js-yaml": "^4.1.0",
"jsdom": "^16.7.0",
- "kube-object-event-status": "file:./extensions/kube-object-event-status",
- "lens-metrics-cluster-feature": "file:./extensions/metrics-cluster-feature",
- "lens-node-menu": "file:./extensions/node-menu",
- "lens-pod-menu": "file:./extensions/pod-menu",
"lodash": "^4.17.15",
"marked": "^4.2.4",
"md5-file": "^5.0.0",
- "metrics-cluster-feature": "file:./extensions/metrics-cluster-feature",
"mobx": "^6.7.0",
"mobx-observable-history": "^2.0.3",
"mobx-react": "^7.6.0",
@@ -252,12 +242,10 @@
"monaco-editor": "^0.29.1",
"monaco-editor-webpack-plugin": "^5.0.0",
"node-fetch": "^3.3.0",
- "node-menu": "file:./extensions/node-menu",
"node-pty": "0.10.1",
"npm": "^8.19.3",
"p-limit": "^3.1.0",
"path-to-regexp": "^6.2.0",
- "pod-menu": "file:./extensions/pod-menu",
"proper-lockfile": "^4.1.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
From ed26e245e6b5f1a4ab717969a743936715ff201e Mon Sep 17 00:00:00 2001
From: Sebastian Malton
Date: Tue, 20 Dec 2022 05:33:48 -0800
Subject: [PATCH 18/26] Prevent shell sync commands from polluting history
(#6668)
* Prevent shell sync commands from polluting history
Signed-off-by: Sebastian Malton
* Fix tests
Signed-off-by: Sebastian Malton
Signed-off-by: Sebastian Malton
---
.../main/compute-unix-shell-environment.injectable.ts | 1 +
.../shell-sync/main/compute-unix-shell-environment.test.ts | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/features/shell-sync/main/compute-unix-shell-environment.injectable.ts b/src/features/shell-sync/main/compute-unix-shell-environment.injectable.ts
index e0f2b2aeb1..fa6de94b57 100644
--- a/src/features/shell-sync/main/compute-unix-shell-environment.injectable.ts
+++ b/src/features/shell-sync/main/compute-unix-shell-environment.injectable.ts
@@ -84,6 +84,7 @@ const computeUnixShellEnvironmentInjectable = getInjectable({
} else if (!cshLikeShellName.test(shellName)) {
// zsh (at least, maybe others) don't load RC files when in non-interactive mode, even when using -l (login) option
shellArgs.push("-i");
+ command = ` ${command}`; // This prevents the command from being added to the history
} else {
// Some shells don't support any other options when providing the -l (login) shell option
}
diff --git a/src/features/shell-sync/main/compute-unix-shell-environment.test.ts b/src/features/shell-sync/main/compute-unix-shell-environment.test.ts
index 55766fbb8a..a540824286 100644
--- a/src/features/shell-sync/main/compute-unix-shell-environment.test.ts
+++ b/src/features/shell-sync/main/compute-unix-shell-environment.test.ts
@@ -218,7 +218,7 @@ describe("computeUnixShellEnvironment technical tests", () => {
});
it("should send the command via stdin", () => {
- expect(stdinValue).toBe(`'/some/process/exec/path' -p '"deadbeef" + JSON.stringify(process.env) + "deadbeef"'`);
+ expect(stdinValue).toBe(` '/some/process/exec/path' -p '"deadbeef" + JSON.stringify(process.env) + "deadbeef"'`);
});
it("should close stdin", () => {
From 5dde02733bb8142b7466bf65bf805bde597733dd Mon Sep 17 00:00:00 2001
From: Alex Andreev
Date: Tue, 20 Dec 2022 16:34:43 +0300
Subject: [PATCH 19/26] Fix: load pods from all namespaces in node details
(#6794)
* Load pods from all namespaces in Node details
Signed-off-by: Alex Andreev
* Lint fixes
Signed-off-by: Alex Andreev
Signed-off-by: Alex Andreev
---
src/renderer/components/+nodes/details.tsx | 5 ++++
...oad-pods-from-all-namespaces.injectable.ts | 28 +++++++++++++++++++
2 files changed, 33 insertions(+)
create mode 100644 src/renderer/components/+workloads-pods/load-pods-from-all-namespaces.injectable.ts
diff --git a/src/renderer/components/+nodes/details.tsx b/src/renderer/components/+nodes/details.tsx
index 4e1eeddb65..622f9f1b69 100644
--- a/src/renderer/components/+nodes/details.tsx
+++ b/src/renderer/components/+nodes/details.tsx
@@ -23,6 +23,7 @@ import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.inj
import type { PodStore } from "../+workloads-pods/store";
import podStoreInjectable from "../+workloads-pods/store.injectable";
import loggerInjectable from "../../../common/logger.injectable";
+import loadPodsFromAllNamespacesInjectable from "../+workloads-pods/load-pods-from-all-namespaces.injectable";
export interface NodeDetailsProps extends KubeObjectDetailsProps {
}
@@ -31,6 +32,7 @@ interface Dependencies {
subscribeStores: SubscribeStores;
podStore: PodStore;
logger: Logger;
+ loadPodsFromAllNamespaces: () => void;
}
@observer
@@ -41,6 +43,8 @@ class NonInjectedNodeDetails extends React.Component(NonIn
subscribeStores: di.inject(subscribeStoresInjectable),
podStore: di.inject(podStoreInjectable),
logger: di.inject(loggerInjectable),
+ loadPodsFromAllNamespaces: di.inject(loadPodsFromAllNamespacesInjectable),
}),
});
diff --git a/src/renderer/components/+workloads-pods/load-pods-from-all-namespaces.injectable.ts b/src/renderer/components/+workloads-pods/load-pods-from-all-namespaces.injectable.ts
new file mode 100644
index 0000000000..f6e96d5b79
--- /dev/null
+++ b/src/renderer/components/+workloads-pods/load-pods-from-all-namespaces.injectable.ts
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+
+import { getInjectable } from "@ogre-tools/injectable";
+import namespaceStoreInjectable from "../+namespaces/store.injectable";
+import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable";
+import podStoreInjectable from "./store.injectable";
+
+const loadPodsFromAllNamespacesInjectable = getInjectable({
+ id: "load-pods-from-all-namespaces",
+ instantiate: (di) => {
+ const podStore = di.inject(podStoreInjectable);
+ const namespaceStore = di.inject(namespaceStoreInjectable);
+ const showErrorNotification = di.inject(showErrorNotificationInjectable);
+
+ return () => {
+ podStore.loadAll({
+ namespaces: [...namespaceStore.getItems().map(ns => ns.getName())],
+ onLoadFailure: error =>
+ showErrorNotification(`Can not load Pods. ${String(error)}`),
+ });
+ };
+ },
+});
+
+export default loadPodsFromAllNamespacesInjectable;
From e762d07cf87035d1fbee8b74c8e9d7ae0956591f Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 20 Dec 2022 08:37:32 -0500
Subject: [PATCH 20/26] Bump esbuild from 0.16.9 to 0.16.10 (#6790)
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.16.9 to 0.16.10.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.16.9...v0.16.10)
---
updated-dependencies:
- dependency-name: esbuild
dependency-type: direct:development
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 | 228 +++++++++++++++++++++++++--------------------------
2 files changed, 115 insertions(+), 115 deletions(-)
diff --git a/package.json b/package.json
index 99fdec1759..3429716034 100644
--- a/package.json
+++ b/package.json
@@ -353,7 +353,7 @@
"electron": "^19.1.9",
"electron-builder": "^23.6.0",
"electron-notarize": "^0.3.0",
- "esbuild": "^0.16.9",
+ "esbuild": "^0.16.10",
"esbuild-loader": "^2.20.0",
"eslint": "^8.30.0",
"eslint-import-resolver-typescript": "^3.5.2",
diff --git a/yarn.lock b/yarn.lock
index 3d971d840a..06411f098e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -598,125 +598,125 @@
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
-"@esbuild/android-arm64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.9.tgz#474da719599f99d820ec010c92846a4f685fa28a"
- integrity sha512-ndIAZJUeLx4O+4AJbFQCurQW4VRUXjDsUvt1L+nP8bVELOWdmdCEOtlIweCUE6P+hU0uxYbEK2AEP0n5IVQvhg==
+"@esbuild/android-arm64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.10.tgz#d784d8f13dbef50492ea55456fb50651e4036fbf"
+ integrity sha512-47Y+NwVKTldTlDhSgJHZ/RpvBQMUDG7eKihqaF/u6g7s0ZPz4J1vy8A3rwnnUOF2CuDn7w7Gj/QcMoWz3U3SJw==
"@esbuild/android-arm@0.15.18":
version "0.15.18"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz#266d40b8fdcf87962df8af05b76219bc786b4f80"
integrity sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==
-"@esbuild/android-arm@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.9.tgz#b0747ec074bba3ca652bfa8de3f55acfbb2d259e"
- integrity sha512-kW5ccqWHVOOTGUkkJbtfoImtqu3kA1PFkivM+9QPFSHphPfPBlBalX9eDRqPK+wHCqKhU48/78T791qPgC9e9A==
+"@esbuild/android-arm@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.10.tgz#becf6b5647c091b039121db8c17300a7dfd1ab4a"
+ integrity sha512-RmJjQTRrO6VwUWDrzTBLmV4OJZTarYsiepLGlF2rYTVB701hSorPywPGvP6d8HCuuRibyXa5JX4s3jN2kHEtjQ==
-"@esbuild/android-x64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.9.tgz#1cd75e8ed7d6d7eb5f9896f623df63882bd8e887"
- integrity sha512-UbMcJB4EHrAVOnknQklREPgclNU2CPet2h+sCBCXmF2mfoYWopBn/CfTfeyOkb/JglOcdEADqAljFndMKnFtOw==
+"@esbuild/android-x64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.10.tgz#648cacbb13a5047380a038e5d6d895015e31b525"
+ integrity sha512-C4PfnrBMcuAcOurQzpF1tTtZz94IXO5JmICJJ3NFJRHbXXsQUg9RFG45KvydKqtFfBaFLCHpduUkUfXwIvGnRg==
-"@esbuild/darwin-arm64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.9.tgz#820c88738cd97621737abcd5f05400ae5e0c66e6"
- integrity sha512-d7D7/nrt4CxPul98lx4PXhyNZwTYtbdaHhOSdXlZuu5zZIznjqtMqLac8Bv+IuT6SVHiHUwrkL6ywD7mOgLW+A==
+"@esbuild/darwin-arm64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.10.tgz#3ca7fd9a456d11752df77df6c030f2d08f27bda9"
+ integrity sha512-bH/bpFwldyOKdi9HSLCLhhKeVgRYr9KblchwXgY2NeUHBB/BzTUHtUSBgGBmpydB1/4E37m+ggXXfSrnD7/E7g==
-"@esbuild/darwin-x64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.9.tgz#5a19c00781595e0dfeef1826b3512d04c37b98ff"
- integrity sha512-LZc+Wlz06AkJYtwWsBM3x2rSqTG8lntDuftsUNQ3fCx9ZttYtvlDcVtgb+NQ6t9s6K5No5zutN3pcjZEC2a4iQ==
+"@esbuild/darwin-x64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.10.tgz#7eb71b8da4106627f01553def517d3c5e5942592"
+ integrity sha512-OXt7ijoLuy+AjDSKQWu+KdDFMBbdeaL6wtgMKtDUXKWHiAMKHan5+R1QAG6HD4+K0nnOvEJXKHeA9QhXNAjOTQ==
-"@esbuild/freebsd-arm64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.9.tgz#2b7c16f5d15c259ed279b293b97c28c4a4bb107f"
- integrity sha512-gIj0UQZlQo93CHYouHKkpzP7AuruSaMIm1etcWIxccFEVqCN1xDr6BWlN9bM+ol/f0W9w3hx3HDuEwcJVtGneQ==
+"@esbuild/freebsd-arm64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.10.tgz#c69c78ee1d17d35ad2cf76a1bb67788000a84b43"
+ integrity sha512-shSQX/3GHuspE3Uxtq5kcFG/zqC+VuMnJkqV7LczO41cIe6CQaXHD3QdMLA4ziRq/m0vZo7JdterlgbmgNIAlQ==
-"@esbuild/freebsd-x64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.9.tgz#2db48ffeeab149c2b970494a60b82bf3004b8630"
- integrity sha512-GNors4vaMJ7lzGOuhzNc7jvgsQZqErGA8rsW+nck8N1nYu86CvsJW2seigVrQQWOV4QzEP8Zf3gm+QCjA2hnBQ==
+"@esbuild/freebsd-x64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.10.tgz#a9804ab1b9366f915812af24ad5cfc1c0db01441"
+ integrity sha512-5YVc1zdeaJGASijZmTzSO4h6uKzsQGG3pkjI6fuXvolhm3hVRhZwnHJkforaZLmzvNv5Tb7a3QL2FAVmrgySIA==
-"@esbuild/linux-arm64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.9.tgz#4c63c9f8ddd690d140ac3e0f360226d3fcdd75d8"
- integrity sha512-YPxQunReYp8RQ1FvexFrOEqqf+nLbS3bKVZF5FRT2uKM7Wio7BeATqAwO02AyrdSEntt3I5fhFsujUChIa8CZg==
+"@esbuild/linux-arm64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.10.tgz#d9a9ddfcb28ed8cced688bc112ef66283d6fa77f"
+ integrity sha512-2aqeNVxIaRfPcIaMZIFoblLh588sWyCbmj1HHCCs9WmeNWm+EIN0SmvsmPvTa/TsNZFKnxTcvkX2eszTcCqIrA==
-"@esbuild/linux-arm@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.9.tgz#7704de1c2a30bc68d8f615d3ecb1cf68f001256a"
- integrity sha512-cNx1EF99c2t1Ztn0lk9N+MuwBijGF8mH6nx9GFsB3e0lpUpPkCE/yt5d+7NP9EwJf5uzqdjutgVYoH1SNqzudA==
+"@esbuild/linux-arm@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.10.tgz#f32cdac1d3319c83ae7f9f31238dd1284ee6bba2"
+ integrity sha512-c360287ZWI2miBnvIj23bPyVctgzeMT2kQKR+x94pVqIN44h3GF8VMEs1SFPH1UgyDr3yBbx3vowDS1SVhyVhA==
-"@esbuild/linux-ia32@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.9.tgz#bf0fda9f046e6c8332d7c8350b8a94d63acb4ceb"
- integrity sha512-zb12ixDIKNwFpIqR00J88FFitVwOEwO78EiUi8wi8FXlmSc3GtUuKV/BSO+730Kglt0B47+ZrJN1BhhOxZaVrw==
+"@esbuild/linux-ia32@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.10.tgz#1e023478e42f3a01cad48f4af50120d4b639af03"
+ integrity sha512-sqMIEWeyrLGU7J5RB5fTkLRIFwsgsQ7ieWXlDLEmC2HblPYGb3AucD7inw2OrKFpRPKsec1l+lssiM3+NV5aOw==
"@esbuild/linux-loong64@0.15.18":
version "0.15.18"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz#128b76ecb9be48b60cf5cfc1c63a4f00691a3239"
integrity sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==
-"@esbuild/linux-loong64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.9.tgz#c16378b898fa38f5f788f76fbce16a45c49c8793"
- integrity sha512-X8te4NLxtHiNT6H+4Pfm5RklzItA1Qy4nfyttihGGX+Koc53Ar20ViC+myY70QJ8PDEOehinXZj/F7QK3A+MKQ==
+"@esbuild/linux-loong64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.10.tgz#f9098865a69d1d6e2f8bda51c7f9d4240f20b771"
+ integrity sha512-O7Pd5hLEtTg37NC73pfhUOGTjx/+aXu5YoSq3ahCxcN7Bcr2F47mv+kG5t840thnsEzrv0oB70+LJu3gUgchvg==
-"@esbuild/linux-mips64el@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.9.tgz#492605f13f19dc06c350d94e4048c21478b9dec4"
- integrity sha512-ZqyMDLt02c5smoS3enlF54ndK5zK4IpClLTxF0hHfzHJlfm4y8IAkIF8LUW0W7zxcKy7oAwI7BRDqeVvC120SA==
+"@esbuild/linux-mips64el@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.10.tgz#574725ad2ea81b7783b7ba7d1ab3475f8fdd8d32"
+ integrity sha512-FN8mZOH7531iPHM0kaFhAOqqNHoAb6r/YHW2ZIxNi0a85UBi2DO4Vuyn7t1p4UN8a4LoAnLOT1PqNgHkgBJgbA==
-"@esbuild/linux-ppc64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.9.tgz#ccaf759fc4f7a5fe72bdac05b4f5bf18ef1fe01b"
- integrity sha512-k+ca5W5LDBEF3lfDwMV6YNXwm4wEpw9krMnNvvlNz3MrKSD2Eb2c861O0MaKrZkG/buTQAP4vkavbLwgIe6xjg==
+"@esbuild/linux-ppc64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.10.tgz#11da658c54514a693813af56bb28951d563a90c3"
+ integrity sha512-Dg9RiqdvHOAWnOKIOTsIx8dFX9EDlY2IbPEY7YFzchrCiTZmMkD7jWA9UdZbNUygPjdmQBVPRCrLydReFlX9yg==
-"@esbuild/linux-riscv64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.9.tgz#542d0e68bc99fb658fe732b0917931c09775f1a3"
- integrity sha512-GuInVdogjmg9DhgkEmNipHkC+3tzkanPJzgzTC2ihsvrruLyFoR1YrTGixblNSMPudQLpiqkcwGwwe0oqfrvfA==
+"@esbuild/linux-riscv64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.10.tgz#3af4600adbd6c5a4a6f1da05771f4aa6774baab2"
+ integrity sha512-XMqtpjwzbmlar0BJIxmzu/RZ7EWlfVfH68Vadrva0Wj5UKOdKvqskuev2jY2oPV3aoQUyXwnMbMrFmloO2GfAw==
-"@esbuild/linux-s390x@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.9.tgz#4398f9d9d64dba4cfa6eed267476eaa9c9b7f214"
- integrity sha512-49wQ0aYkvwXonGsxc7LuuLNICMX8XtO92Iqmug5Qau0kpnV6SP34jk+jIeu4suHwAbSbRhVFtDv75yRmyfQcHw==
+"@esbuild/linux-s390x@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.10.tgz#9e3377aaf0191a9d6628e806a279085ec4391f3e"
+ integrity sha512-fu7XtnoeRNFMx8DjK3gPWpFBDM2u5ba+FYwg27SjMJwKvJr4bDyKz5c+FLXLUSSAkMAt/UL+cUbEbra+rYtUgw==
-"@esbuild/linux-x64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.9.tgz#67c6b418ef36addbca17af0d7a2274c37ddffba2"
- integrity sha512-Nx4oKEAJ6EcQlt4dK7qJyuZUoXZG7CAeY22R7rqZijFzwFfMOD+gLP56uV7RrV86jGf8PeRY8TBsRmOcZoG42w==
+"@esbuild/linux-x64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.10.tgz#7c41d4d697ce674e0083e7baa6231468f4650d85"
+ integrity sha512-61lcjVC/RldNNMUzQQdyCWjCxp9YLEQgIxErxU9XluX7juBdGKb0pvddS0vPNuCvotRbzijZ1pzII+26haWzbA==
-"@esbuild/netbsd-x64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.9.tgz#22ed58e404ebeb2475b821bc4e25f1027eb0c912"
- integrity sha512-d0WnpgJ+FTiMZXEQ1NOv9+0gvEhttbgKEvVqWWAtl1u9AvlspKXbodKHzQ5MLP6YV1y52Xp+p8FMYqj8ykTahg==
+"@esbuild/netbsd-x64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.10.tgz#ebac59e3986834af04bbafcee7b0c1f31cd477c6"
+ integrity sha512-JeZXCX3viSA9j4HqSoygjssdqYdfHd6yCFWyfSekLbz4Ef+D2EjvsN02ZQPwYl5a5gg/ehdHgegHhlfOFP0HCA==
-"@esbuild/openbsd-x64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.9.tgz#2b2597b4edd4d26946f7c56838680fbeb4d455eb"
- integrity sha512-jccK11278dvEscHFfMk5EIPjF4wv1qGD0vps7mBV1a6TspdR36O28fgPem/SA/0pcsCPHjww5ouCLwP+JNAFlw==
+"@esbuild/openbsd-x64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.10.tgz#9eaa6cac3b80db45090c0946e62de5b5689c61d1"
+ integrity sha512-3qpxQKuEVIIg8SebpXsp82OBrqjPV/OwNWmG+TnZDr3VGyChNnGMHccC1xkbxCHDQNnnXjxhMQNyHmdFJbmbRA==
-"@esbuild/sunos-x64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.9.tgz#c132603a19ef79c0d7bd95afb09f41618ea8dda2"
- integrity sha512-OetwTSsv6mIDLqN7I7I2oX9MmHGwG+AP+wKIHvq+6sIHwcPPJqRx+DJB55jy9JG13CWcdcQno/7V5MTJ5a0xfQ==
+"@esbuild/sunos-x64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.10.tgz#31e5e4b814ef43d300e26511e486a4716a390d5f"
+ integrity sha512-z+q0xZ+et/7etz7WoMyXTHZ1rB8PMSNp/FOqURLJLOPb3GWJ2aj4oCqFCjPwEbW1rsT7JPpxeH/DwGAWk/I1Bg==
-"@esbuild/win32-arm64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.9.tgz#bf74d007d7f0fe1fe32c4fff82d27b271b3e1d58"
- integrity sha512-tKSSSK6unhxbGbHg+Cc+JhRzemkcsX0tPBvG0m5qsWbkShDK9c+/LSb13L18LWVdOQZwuA55Vbakxmt6OjBDOQ==
+"@esbuild/win32-arm64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.10.tgz#ca58472dc03ca79e6d03f8a31113979ff253d94f"
+ integrity sha512-+YYu5sbQ9npkNT9Dec+tn1F/kjg6SMgr6bfi/6FpXYZvCRfu2YFPZGb+3x8K30s8eRxFpoG4sGhiSUkr1xbHEw==
-"@esbuild/win32-ia32@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.9.tgz#e46478e77431bca1a8b80f6260fc6b0020aa8127"
- integrity sha512-ZTQ5vhNS5gli0KK8I6/s6+LwXmNEfq1ftjnSVyyNm33dBw8zDpstqhGXYUbZSWWLvkqiRRjgxgmoncmi6Yy7Ng==
+"@esbuild/win32-ia32@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.10.tgz#c572df2c65ab118feed0a5da5a4a193846d74e43"
+ integrity sha512-Aw7Fupk7XNehR1ftHGYwUteyJ2q+em/aE+fVU3YMTBN2V5A7Z4aVCSV+SvCp9HIIHZavPFBpbdP3VfjQpdf6Xg==
-"@esbuild/win32-x64@0.16.9":
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.9.tgz#4595a29c2930c5157aa1be0963abbbac989647c9"
- integrity sha512-C4ZX+YFIp6+lPrru3tpH6Gaapy8IBRHw/e7l63fzGDhn/EaiGpQgbIlT5paByyy+oMvRFQoxxyvC4LE0AjJMqQ==
+"@esbuild/win32-x64@0.16.10":
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.10.tgz#0e9c6a5e69c10d96aff2386b7ee9646138c2a831"
+ integrity sha512-qddWullt3sC1EIpfHvCRBq3H4g3L86DZpD6n8k2XFjFVyp01D++uNbN1hT/JRsHxTbyyemZcpwL5aRlJwc/zFw==
"@eslint/eslintrc@^1.4.0":
version "1.4.0"
@@ -5584,33 +5584,33 @@ esbuild@^0.15.6:
esbuild-windows-64 "0.15.18"
esbuild-windows-arm64 "0.15.18"
-esbuild@^0.16.9:
- version "0.16.9"
- resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.9.tgz#01b6c3a6cbc072108253ac160a0734229bf8c921"
- integrity sha512-gkH83yHyijMSZcZFs1IWew342eMdFuWXmQo3zkDPTre25LIPBJsXryg02M3u8OpTwCJdBkdaQwqKkDLnAsAeLQ==
+esbuild@^0.16.10:
+ version "0.16.10"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.10.tgz#d485c28f1626a3f9c1796c952e4cd0561f0031bb"
+ integrity sha512-z5dIViHoVnw2l+NCJ3zj5behdXjYvXne9gL18OOivCadXDUhyDkeSvEtLcGVAJW2fNmh33TDUpsi704XYlDodw==
optionalDependencies:
- "@esbuild/android-arm" "0.16.9"
- "@esbuild/android-arm64" "0.16.9"
- "@esbuild/android-x64" "0.16.9"
- "@esbuild/darwin-arm64" "0.16.9"
- "@esbuild/darwin-x64" "0.16.9"
- "@esbuild/freebsd-arm64" "0.16.9"
- "@esbuild/freebsd-x64" "0.16.9"
- "@esbuild/linux-arm" "0.16.9"
- "@esbuild/linux-arm64" "0.16.9"
- "@esbuild/linux-ia32" "0.16.9"
- "@esbuild/linux-loong64" "0.16.9"
- "@esbuild/linux-mips64el" "0.16.9"
- "@esbuild/linux-ppc64" "0.16.9"
- "@esbuild/linux-riscv64" "0.16.9"
- "@esbuild/linux-s390x" "0.16.9"
- "@esbuild/linux-x64" "0.16.9"
- "@esbuild/netbsd-x64" "0.16.9"
- "@esbuild/openbsd-x64" "0.16.9"
- "@esbuild/sunos-x64" "0.16.9"
- "@esbuild/win32-arm64" "0.16.9"
- "@esbuild/win32-ia32" "0.16.9"
- "@esbuild/win32-x64" "0.16.9"
+ "@esbuild/android-arm" "0.16.10"
+ "@esbuild/android-arm64" "0.16.10"
+ "@esbuild/android-x64" "0.16.10"
+ "@esbuild/darwin-arm64" "0.16.10"
+ "@esbuild/darwin-x64" "0.16.10"
+ "@esbuild/freebsd-arm64" "0.16.10"
+ "@esbuild/freebsd-x64" "0.16.10"
+ "@esbuild/linux-arm" "0.16.10"
+ "@esbuild/linux-arm64" "0.16.10"
+ "@esbuild/linux-ia32" "0.16.10"
+ "@esbuild/linux-loong64" "0.16.10"
+ "@esbuild/linux-mips64el" "0.16.10"
+ "@esbuild/linux-ppc64" "0.16.10"
+ "@esbuild/linux-riscv64" "0.16.10"
+ "@esbuild/linux-s390x" "0.16.10"
+ "@esbuild/linux-x64" "0.16.10"
+ "@esbuild/netbsd-x64" "0.16.10"
+ "@esbuild/openbsd-x64" "0.16.10"
+ "@esbuild/sunos-x64" "0.16.10"
+ "@esbuild/win32-arm64" "0.16.10"
+ "@esbuild/win32-ia32" "0.16.10"
+ "@esbuild/win32-x64" "0.16.10"
escalade@^3.1.1:
version "3.1.1"
From 6ce7e8ee532f7680d6fe6a8d1ab163c4f58308a4 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 20 Dec 2022 08:37:43 -0500
Subject: [PATCH 21/26] Bump sass from 1.57.0 to 1.57.1 (#6793)
Bumps [sass](https://github.com/sass/dart-sass) from 1.57.0 to 1.57.1.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.57.0...1.57.1)
---
updated-dependencies:
- dependency-name: sass
dependency-type: direct:development
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 3429716034..cb37a0685e 100644
--- a/package.json
+++ b/package.json
@@ -392,7 +392,7 @@
"react-select-event": "^5.5.1",
"react-table": "^7.8.0",
"react-window": "^1.8.8",
- "sass": "^1.57.0",
+ "sass": "^1.57.1",
"sass-loader": "^12.6.0",
"sharp": "^0.31.2",
"style-loader": "^3.3.1",
diff --git a/yarn.lock b/yarn.lock
index 06411f098e..b94098bb0b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -11299,10 +11299,10 @@ sass-loader@^12.6.0:
klona "^2.0.4"
neo-async "^2.6.2"
-sass@^1.32.13, sass@^1.57.0:
- version "1.57.0"
- resolved "https://registry.yarnpkg.com/sass/-/sass-1.57.0.tgz#64c4144ed4e1c0ccb96dc18aef2c424cdbc0c12b"
- integrity sha512-IZNEJDTK1cF5B1cGA593TPAV/1S0ysUDxq9XHjX/+SMy0QfUny+nfUsq5ZP7wWSl4eEf7wDJcEZ8ABYFmh3m/w==
+sass@^1.32.13, sass@^1.57.1:
+ version "1.57.1"
+ resolved "https://registry.yarnpkg.com/sass/-/sass-1.57.1.tgz#dfafd46eb3ab94817145e8825208ecf7281119b5"
+ integrity sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==
dependencies:
chokidar ">=3.0.0 <4.0.0"
immutable "^4.0.0"
From 257582df76be60034c738af2271f20b8eaad141f Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 20 Dec 2022 08:38:04 -0500
Subject: [PATCH 22/26] Bump typedoc from 0.23.22 to 0.23.23 (#6792)
Bumps [typedoc](https://github.com/TypeStrong/TypeDoc) from 0.23.22 to 0.23.23.
- [Release notes](https://github.com/TypeStrong/TypeDoc/releases)
- [Changelog](https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TypeStrong/TypeDoc/compare/v0.23.22...v0.23.23)
---
updated-dependencies:
- dependency-name: typedoc
dependency-type: direct:development
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 | 22 +++++++++++-----------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/package.json b/package.json
index cb37a0685e..b0b341bd64 100644
--- a/package.json
+++ b/package.json
@@ -402,7 +402,7 @@
"ts-node": "^10.9.1",
"type-fest": "^2.14.0",
"typed-emitter": "^1.4.0",
- "typedoc": "0.23.22",
+ "typedoc": "0.23.23",
"typedoc-plugin-markdown": "^3.13.6",
"typescript": "^4.9.4",
"typescript-plugin-css-modules": "^3.4.0",
diff --git a/yarn.lock b/yarn.lock
index b94098bb0b..9a876289b3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8922,7 +8922,7 @@ markdown@^0.5.0:
dependencies:
nopt "~2.1.1"
-marked@^4.0.19, marked@^4.2.4:
+marked@^4.2.4:
version "4.2.4"
resolved "https://registry.yarnpkg.com/marked/-/marked-4.2.4.tgz#5a4ce6c7a1ae0c952601fce46376ee4cf1797e1c"
integrity sha512-Wcc9ikX7Q5E4BYDPvh1C6QNSxrjC9tBgz+A/vAhp59KXUgachw++uMvMKiSW8oA85nopmPZcEvBoex/YLMsiyA==
@@ -9088,10 +9088,10 @@ minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatc
dependencies:
brace-expansion "^1.1.7"
-minimatch@^5.0.0, minimatch@^5.0.1, minimatch@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7"
- integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==
+minimatch@^5.0.0, minimatch@^5.0.1, minimatch@^5.1.0, minimatch@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.1.tgz#6c9dffcf9927ff2a31e74b5af11adf8b9604b022"
+ integrity sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==
dependencies:
brace-expansion "^2.0.1"
@@ -12592,14 +12592,14 @@ typedoc-plugin-markdown@^3.13.6:
dependencies:
handlebars "^4.7.7"
-typedoc@0.23.22:
- version "0.23.22"
- resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.23.22.tgz#e25281ca816cd92ecfdaf3ec336d27e7bebb69ac"
- integrity sha512-5sJkjK60xp8A7YpcYniu3+Wf0QcgojEnhzHuCN+CkdpQkKRhOspon/9+sGTkGI8kjVkZs3KHrhltpQyVhRMVfw==
+typedoc@0.23.23:
+ version "0.23.23"
+ resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.23.23.tgz#9cf95b03d2d40031d8978b55e88b0b968d69f512"
+ integrity sha512-cg1YQWj+/BU6wq74iott513U16fbrPCbyYs04PHZgvoKJIc6EY4xNobyDZh4KMfRGW8Yjv6wwIzQyoqopKOUGw==
dependencies:
lunr "^2.3.9"
- marked "^4.0.19"
- minimatch "^5.1.0"
+ marked "^4.2.4"
+ minimatch "^5.1.1"
shiki "^0.11.1"
typescript-plugin-css-modules@^3.4.0:
From e36f3d2d7043dc60d78cfcbca93aa67cab6bb3d2 Mon Sep 17 00:00:00 2001
From: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>
Date: Tue, 20 Dec 2022 15:38:20 +0200
Subject: [PATCH 23/26] Navigation logging injectable (#6797)
Move navigation logging to `setupLoggingForNavigationInjectable` to prevent cycle of injectables from occurring. Wasn't eventually needed for #6795 but still an improvement.
Credit for the implementation goes to @Nokel81 , thanks!
Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>
Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>
---
.../observable-history.injectable.ts | 9 -----
...setup-logging-for-navigation.injectable.ts | 33 +++++++++++++++++++
2 files changed, 33 insertions(+), 9 deletions(-)
create mode 100644 src/renderer/navigation/setup-logging-for-navigation.injectable.ts
diff --git a/src/renderer/navigation/observable-history.injectable.ts b/src/renderer/navigation/observable-history.injectable.ts
index 81d9df2dd1..c813c675fd 100644
--- a/src/renderer/navigation/observable-history.injectable.ts
+++ b/src/renderer/navigation/observable-history.injectable.ts
@@ -4,7 +4,6 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import { createObservableHistory } from "mobx-observable-history";
-import loggerInjectable from "../../common/logger.injectable";
import { searchParamsOptions } from "./search-params";
import historyInjectable from "./history.injectable";
@@ -13,18 +12,10 @@ const observableHistoryInjectable = getInjectable({
instantiate: (di) => {
const history = di.inject(historyInjectable);
- const logger = di.inject(loggerInjectable);
const navigation = createObservableHistory(history, {
searchParams: searchParamsOptions,
});
- navigation.listen((location, action) => {
- const isClusterView = !process.isMainFrame;
- const domain = global.location.href;
-
- logger.debug(`[NAVIGATION]: ${action}-ing. Current is now:`, { isClusterView, domain, location });
- });
-
return navigation;
},
});
diff --git a/src/renderer/navigation/setup-logging-for-navigation.injectable.ts b/src/renderer/navigation/setup-logging-for-navigation.injectable.ts
new file mode 100644
index 0000000000..b769b92db1
--- /dev/null
+++ b/src/renderer/navigation/setup-logging-for-navigation.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 loggerInjectable from "../../common/logger.injectable";
+import { beforeFrameStartsInjectionToken } from "../before-frame-starts/tokens";
+import observableHistoryInjectable from "./observable-history.injectable";
+
+const setupLoggingForNavigationInjectable = getInjectable({
+ id: "setup-logging-for-navigation",
+ instantiate: (di) => ({
+ id: "setup-logging-for-navigation",
+ run: () => {
+ const logger = di.inject(loggerInjectable);
+ const observableHistory = di.inject(observableHistoryInjectable);
+
+ observableHistory.listen((location, action) => {
+ const isClusterView = !process.isMainFrame;
+ const domain = global.location.href;
+
+ logger.debug(`[NAVIGATION]: ${action}-ing. Current is now:`, {
+ isClusterView,
+ domain,
+ location,
+ });
+ });
+ },
+ }),
+ injectionToken: beforeFrameStartsInjectionToken,
+});
+
+export default setupLoggingForNavigationInjectable;
From 443081493b2146d168438cdb2961504ce41e3114 Mon Sep 17 00:00:00 2001
From: Sebastian Malton
Date: Tue, 20 Dec 2022 07:20:27 -0800
Subject: [PATCH 24/26] Fix allowed resources checks on GKE (#6657)
* Add check for incomplete SelfSubjectRulesReview to fix GKE
Signed-off-by: Sebastian Malton
* Adding namespaced for KubeApiResource
Signed-off-by: Sebastian Malton
* Refactoring of AuthorizationNamespaceReview
Signed-off-by: Sebastian Malton
* Removing dead code
Signed-off-by: Sebastian Malton
* Refactoring ListApiResources
Signed-off-by: Sebastian Malton
* Extract ClusterContext into deps for KubeObjectStore to fix circular import
Signed-off-by: Sebastian Malton
* Fix remaining type errors
Signed-off-by: Sebastian Malton
* Fix crash in frame by consolidating setup into runnables
Signed-off-by: Sebastian Malton
* Fix type errors and remove dead code
Signed-off-by: Sebastian Malton
* Fix core resources not showing up
Signed-off-by: Sebastian Malton
* Fix namespaces not being shown
Signed-off-by: Sebastian Malton
* Simplify ClusterContext to remove something only NamespaceStore needs
Signed-off-by: Sebastian Malton
* Make sure the public API doesn't change
Signed-off-by: Sebastian Malton
* Fix lint
Signed-off-by: Sebastian Malton
* Fixing namespace-select-filter tests
Signed-off-by: Sebastian Malton
* Fix other tests requiring overrides
Signed-off-by: Sebastian Malton
* Fix kludge in cluster-frame tests
Signed-off-by: Sebastian Malton
* Fix remaining test failures
Signed-off-by: Sebastian Malton
* Fix integration test due to incorrect casting
Signed-off-by: Sebastian Malton
* Fix integration test and kube watches not working at all
Signed-off-by: Sebastian Malton
* Fix secret details test
Signed-off-by: Sebastian Malton
* Fix lint
Signed-off-by: Sebastian Malton
* Fix non-ApplicationBuilder tests by adding overrides
Signed-off-by: Sebastian Malton
* Fix crash due to trying to read hostedCluster too soon
Signed-off-by: Sebastian Malton
* Fix crash due to timing issues
- Make injectable phases more explicit for renderer
Signed-off-by: Sebastian Malton
Signed-off-by: Sebastian Malton
---
.../allowed-resources-injection-token.ts | 5 +-
...thorization-namespace-review.injectable.ts | 87 --
src/common/cluster/cluster.ts | 129 +--
src/common/cluster/is-allowed-resource.ts | 20 -
.../cluster/list-api-resources.injectable.ts | 91 --
.../request-api-resources.injectable.ts | 83 ++
...t-namespace-list-permissions.injectable.ts | 78 ++
src/common/configure-packages.ts | 27 -
.../config-maps-route.injectable.ts | 21 +-
...zontal-pod-autoscalers-route.injectable.ts | 19 +-
.../config/leases/leases-route.injectable.ts | 19 +-
.../limit-ranges-route.injectable.ts | 22 +-
...pod-disruption-budgets-route.injectable.ts | 19 +-
.../priority-classes-route.injectable.ts | 19 +-
.../resource-quotas-route.injectable.ts | 19 +-
.../runtime-classes-route.injectable.ts | 19 +-
.../secrets/secrets-route.injectable.ts | 19 +-
.../cluster/events/events-route.injectable.ts | 19 +-
.../namespaces/namespaces-route.injectable.ts | 19 +-
.../endpoints/endpoints-route.injectable.ts | 19 +-
.../ingresses/ingresses-route.injectable.ts | 26 +-
.../network-policies-route.injectable.ts | 19 +-
.../services/services-route.injectable.ts | 19 +-
.../cluster/nodes/nodes-route.injectable.ts | 19 +-
.../cluster-overview-route.injectable.ts | 19 +-
...rsistent-volume-claims-route.injectable.ts | 19 +-
.../persistent-volumes-route.injectable.ts | 19 +-
.../storage-classes-route.injectable.ts | 19 +-
.../cluster-role-bindings-route.injectable.ts | 19 +-
.../cluster-roles-route.injectable.ts | 19 +-
.../pod-security-policies-route.injectable.ts | 9 +-
.../role-bindings-route.injectable.ts | 9 +-
.../roles/roles-route.injectable.ts | 19 +-
.../service-accounts-route.injectable.ts | 19 +-
.../cron-jobs/cron-jobs-route.injectable.ts | 19 +-
.../daemonsets/daemonsets-route.injectable.ts | 19 +-
.../deployments-route.injectable.ts | 19 +-
.../workloads/jobs/jobs-route.injectable.ts | 19 +-
.../workloads/pods/pods-route.injectable.ts | 19 +-
.../replicasets-route.injectable.ts | 19 +-
.../statefulsets-route.injectable.ts | 19 +-
.../k8s-api/__tests__/api-manager.test.ts | 28 +-
.../kube-api-version-detection.test.ts | 52 +-
src/common/k8s-api/__tests__/kube-api.test.ts | 97 +--
.../__tests__/kube-object.store.test.ts | 23 +-
.../auto-registration.injectable.ts | 74 --
.../k8s-api/api-manager/resource.store.ts | 5 +-
src/common/k8s-api/cluster-context.ts | 13 -
.../request-patch.injectable.ts | 29 +-
.../request-update.injectable.ts | 25 +-
src/common/k8s-api/json-api.ts | 4 +-
src/common/k8s-api/kube-api.ts | 27 +-
src/common/k8s-api/kube-object.store.ts | 106 +--
src/common/k8s-api/kube-object.ts | 15 +-
src/common/logger.injectable.ts | 24 +-
src/common/logger.ts | 4 +-
src/common/rbac.ts | 219 ++++-
src/common/utils/computed-or.ts | 11 +
.../utils/is-allowed-resource.injectable.ts | 26 -
src/common/utils/wait.ts | 13 +-
src/common/vars.ts | 20 -
src/extensions/common-api/k8s-api.ts | 44 +-
src/extensions/renderer-api/k8s-api.ts | 20 +-
.../catalog/opening-entity-details.test.tsx | 2 +-
.../delete-cluster-dialog.test.tsx | 2 -
.../edit-namespace-from-new-tab.test.tsx | 5 +-
...espace-from-previously-opened-tab.test.tsx | 5 +-
.../renderer/setup-sync.injectable.ts | 4 +-
.../cluster/store/renderer/init.injectable.ts | 4 +-
.../visibility-of-sidebar-items.test.tsx | 29 +-
.../cluster/workload-overview.test.tsx | 5 +-
...owing-settings-for-correct-entity.test.tsx | 2 +-
.../renderer/init-store.injectable.ts | 4 +-
.../hotbar/store/renderer/init.injectable.ts | 4 +-
.../renderer/initialize.injectable.ts | 4 +-
src/jest.setup.ts | 9 +-
src/main/__test__/cluster.test.ts | 7 +-
src/main/cluster/manager.ts | 2 +-
.../allowed-resources.injectable.ts | 13 +-
.../create-cluster.injectable.ts | 8 +-
.../create-lens-window.injectable.ts | 5 +-
.../load-monaco-themes.injectable.ts | 4 +-
.../setup-auto-registration.injectable.ts | 12 +-
...up-current-cluster-broadcast.injectable.ts | 4 +-
...tes-cluster-catalog-add-menu.injectable.ts | 4 +-
...es-cluster-context-menu-open.injectable.ts | 4 +-
.../setup-root-mac-class.injectable.ts | 4 +-
.../runnables/setup-sentry.injectable.ts | 4 +-
...p-weblink-context-menu-open.injectable.tsx | 4 +-
src/renderer/before-frame-starts/tokens.ts | 24 +-
.../allowed-resources.injectable.ts | 25 -
.../cluster-frame-context.injectable.ts | 25 -
.../cluster-frame-context.ts | 48 +-
...for-cluster-scoped-resources.injectable.ts | 21 +
.../for-namespaced-resources.injectable.ts | 64 ++
.../should-show-resource.injectable.ts | 27 +
.../accessible-namespaces.injectable.ts | 18 +
.../create-cluster.injectable.ts | 4 +-
.../cluster-overview-store.injectable.ts | 2 +
.../cluster-overview-store.ts | 5 +-
.../+config-autoscalers/store.injectable.ts | 5 +-
.../+config-leases/store.injectable.ts | 5 +-
.../+config-limit-ranges/store.injectable.ts | 5 +-
.../+config-maps/store.injectable.ts | 5 +-
.../store.injectable.ts | 5 +-
.../store.injectable.ts | 5 +-
.../store.injectable.ts | 5 +-
.../store.injectable.ts | 5 +-
.../__tests__/secret-details.test.tsx | 16 +
.../+config-secrets/store.injectable.ts | 5 +-
.../definition.store.injectable.ts | 2 +
.../+custom-resources/definition.store.ts | 6 +-
.../components/+events/store.injectable.ts | 2 +
src/renderer/components/+events/store.ts | 8 +-
.../+helm-releases/releases.injectable.ts | 4 +-
.../namespace-select-filter.test.tsx.snap | 806 +++++++++---------
.../namespace-select-filter.test.tsx | 273 +++---
.../+namespaces/store.injectable.ts | 4 +
src/renderer/components/+namespaces/store.ts | 74 +-
.../+network-endpoints/store.injectable.ts | 5 +-
.../+network-ingresses/store.injectable.ts | 5 +-
.../+network-policies/store.injectable.ts | 5 +-
.../+network-services/store.injectable.ts | 5 +-
.../components/+nodes/store.injectable.ts | 5 +-
src/renderer/components/+nodes/store.ts | 6 +-
.../store.injectable.ts | 5 +-
.../+storage-classes/store.injectable.ts | 2 +
.../components/+storage-classes/store.ts | 6 +-
.../store.injectable.ts | 5 +-
.../+storage-volumes/store.injectable.ts | 5 +-
.../__tests__/dialog.test.tsx | 16 +-
.../store.injectable.ts | 5 +-
.../+cluster-roles/store.injectable.ts | 5 +-
.../+role-bindings/__tests__/dialog.test.tsx | 16 +-
.../+role-bindings/store.injectable.ts | 5 +-
.../+roles/store.injectable.ts | 5 +-
.../+service-accounts/store.injectable.ts | 5 +-
.../+workloads-cronjobs/store.injectable.ts | 2 +
.../components/+workloads-cronjobs/store.ts | 6 +-
.../+workloads-daemonsets/store.injectable.ts | 2 +
.../components/+workloads-daemonsets/store.ts | 6 +-
.../store.injectable.ts | 2 +
.../+workloads-deployments/store.ts | 6 +-
.../+workloads-jobs/store.injectable.ts | 2 +
.../components/+workloads-jobs/store.ts | 6 +-
.../+workloads-overview/overview-statuses.tsx | 3 +-
.../+workloads-overview/overview.tsx | 8 +-
.../cron-jobs-workload.injectable.ts | 8 +-
.../daemonsets-workload.injectable.ts | 5 +-
.../deployments-workload.injectable.ts | 5 +-
.../jobs-workload.injectable.ts | 5 +-
.../pods-workload.injectable.ts | 5 +-
.../replicasets-workload.injectable.ts | 5 +-
.../statefulsets-workload.injectable.ts | 5 +-
.../workloads/workload-injection-token.ts | 3 +-
.../workloads/workloads.injectable.ts | 32 +-
.../+workloads-pods/store.injectable.ts | 2 +
.../components/+workloads-pods/store.ts | 6 +-
.../store.injectable.ts | 2 +
.../+workloads-replicasets/store.ts | 8 +-
.../store.injectable.ts | 2 +
.../+workloads-statefulsets/store.ts | 6 +-
.../__tests__/cronjob.store.test.ts | 16 +
.../__tests__/daemonset.store.test.ts | 16 +
.../__tests__/deployments.store.test.ts | 16 +
.../components/__tests__/job.store.test.ts | 16 +
.../components/__tests__/pods.store.test.ts | 16 +
.../__tests__/replicaset.store.test.ts | 16 +
.../__tests__/statefulset.store.test.ts | 16 +
.../accessible-namespaces.tsx | 4 +-
.../components/dock/create-resource/view.tsx | 62 +-
.../components/input/search-input.tsx | 22 +-
.../kube-object-list-layout.tsx | 8 +-
.../top-bar/start-state-sync.injectable.ts | 4 +-
.../monaco-themes/clouds-midnight.json | 128 ---
.../test-utils/get-application-builder.tsx | 38 +-
.../cluster-frame/cluster-frame.test.tsx | 8 +-
.../init-cluster-frame.injectable.ts | 6 +-
.../init-cluster-frame/init-cluster-frame.ts | 22 +-
.../root-frame/setup-system-ca.injectable.ts | 4 +-
src/renderer/initializers/workload-events.tsx | 7 +-
.../kube-watch-api.injectable.ts | 4 +-
src/renderer/kube-watch-api/kube-watch-api.ts | 10 +-
.../subscribe-stores.injectable.ts | 1 -
src/renderer/navigation/events.ts | 32 +-
.../start-frame/start-frame.injectable.ts | 24 +-
.../stores/init-user-store.injectable.ts | 4 +-
.../setup-apply-active-theme.injectable.ts | 4 +-
.../start-listening-of-channels.injectable.ts | 4 +-
src/renderer/utils/rbac.ts | 7 +-
...nitial-values-for-sync-boxes.injectable.ts | 4 +-
.../vars/build-version/init.injectable.ts | 4 +-
.../default-update-channel/init.injectable.ts | 4 +-
.../vars/release-channel/init.injectable.ts | 4 +-
.../semantic-build-version/init.injectable.ts | 4 +-
src/test-utils/mock-responses.ts | 62 ++
196 files changed, 2379 insertions(+), 2146 deletions(-)
delete mode 100644 src/common/cluster/authorization-namespace-review.injectable.ts
delete mode 100644 src/common/cluster/is-allowed-resource.ts
delete mode 100644 src/common/cluster/list-api-resources.injectable.ts
create mode 100644 src/common/cluster/request-api-resources.injectable.ts
create mode 100644 src/common/cluster/request-namespace-list-permissions.injectable.ts
delete mode 100644 src/common/configure-packages.ts
delete mode 100644 src/common/k8s-api/api-manager/auto-registration.injectable.ts
delete mode 100644 src/common/k8s-api/cluster-context.ts
create mode 100644 src/common/utils/computed-or.ts
delete mode 100644 src/common/utils/is-allowed-resource.injectable.ts
delete mode 100644 src/renderer/cluster-frame-context/allowed-resources.injectable.ts
delete mode 100644 src/renderer/cluster-frame-context/cluster-frame-context.injectable.ts
create mode 100644 src/renderer/cluster-frame-context/for-cluster-scoped-resources.injectable.ts
create mode 100644 src/renderer/cluster-frame-context/for-namespaced-resources.injectable.ts
create mode 100644 src/renderer/cluster-frame-context/should-show-resource.injectable.ts
create mode 100644 src/renderer/cluster/accessible-namespaces.injectable.ts
rename src/renderer/{create-cluster => cluster}/create-cluster.injectable.ts (92%)
delete mode 100644 src/renderer/components/monaco-editor/monaco-themes/clouds-midnight.json
create mode 100644 src/test-utils/mock-responses.ts
diff --git a/src/common/cluster-store/allowed-resources-injection-token.ts b/src/common/cluster-store/allowed-resources-injection-token.ts
index 353d0b309c..5b71038d04 100644
--- a/src/common/cluster-store/allowed-resources-injection-token.ts
+++ b/src/common/cluster-store/allowed-resources-injection-token.ts
@@ -5,7 +5,8 @@
import { getInjectionToken } from "@ogre-tools/injectable";
import type { IComputedValue } from "mobx";
+import type { KubeApiResourceDescriptor } from "../rbac";
-export const allowedResourcesInjectionToken = getInjectionToken>>({
- id: "allowed-resources",
+export const shouldShowResourceInjectionToken = getInjectionToken, KubeApiResourceDescriptor>({
+ id: "should-show-resource",
});
diff --git a/src/common/cluster/authorization-namespace-review.injectable.ts b/src/common/cluster/authorization-namespace-review.injectable.ts
deleted file mode 100644
index aa78453569..0000000000
--- a/src/common/cluster/authorization-namespace-review.injectable.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import type { KubeConfig } from "@kubernetes/client-node";
-import { AuthorizationV1Api } from "@kubernetes/client-node";
-import { getInjectable } from "@ogre-tools/injectable";
-import type { Logger } from "../logger";
-import loggerInjectable from "../logger.injectable";
-import type { KubeApiResource } from "../rbac";
-
-/**
- * Requests the permissions for actions on the kube cluster
- * @param namespace The namespace of the resources
- * @param availableResources List of available resources in the cluster to resolve glob values fir api groups
- * @returns list of allowed resources names
- */
-export type RequestNamespaceResources = (namespace: string, availableResources: KubeApiResource[]) => Promise;
-
-/**
- * @param proxyConfig This config's `currentContext` field must be set, and will be used as the target cluster
- */
-export type AuthorizationNamespaceReview = (proxyConfig: KubeConfig) => RequestNamespaceResources;
-
-interface Dependencies {
- logger: Logger;
-}
-
-const authorizationNamespaceReview = ({ logger }: Dependencies): AuthorizationNamespaceReview => {
- return (proxyConfig) => {
-
- const api = proxyConfig.makeApiClient(AuthorizationV1Api);
-
- return async (namespace, availableResources) => {
- try {
- const { body } = await api.createSelfSubjectRulesReview({
- apiVersion: "authorization.k8s.io/v1",
- kind: "SelfSubjectRulesReview",
- spec: { namespace },
- });
-
- const resources = new Set();
-
- body.status?.resourceRules.forEach(resourceRule => {
- if (!resourceRule.verbs.some(verb => ["*", "list"].includes(verb)) || !resourceRule.resources) {
- return;
- }
-
- const apiGroups = resourceRule.apiGroups;
-
- if (resourceRule.resources.length === 1 && resourceRule.resources[0] === "*" && apiGroups) {
- if (apiGroups[0] === "*") {
- availableResources.forEach(resource => resources.add(resource.apiName));
- } else {
- availableResources.forEach((apiResource)=> {
- if (apiGroups.includes(apiResource.group || "")) {
- resources.add(apiResource.apiName);
- }
- });
- }
- } else {
- resourceRule.resources.forEach(resource => resources.add(resource));
- }
-
- });
-
- return [...resources];
- } catch (error) {
- logger.error(`[AUTHORIZATION-NAMESPACE-REVIEW]: failed to create subject rules review: ${error}`, { namespace });
-
- return [];
- }
- };
- };
-};
-
-const authorizationNamespaceReviewInjectable = getInjectable({
- id: "authorization-namespace-review",
- instantiate: (di) => {
- const logger = di.inject(loggerInjectable);
-
- return authorizationNamespaceReview({ logger });
- },
-});
-
-export default authorizationNamespaceReviewInjectable;
diff --git a/src/common/cluster/cluster.ts b/src/common/cluster/cluster.ts
index fe66c9fe1b..303ee89361 100644
--- a/src/common/cluster/cluster.ts
+++ b/src/common/cluster/cluster.ts
@@ -9,8 +9,8 @@ import type { KubeConfig } from "@kubernetes/client-node";
import { HttpError } from "@kubernetes/client-node";
import type { Kubectl } from "../../main/kubectl/kubectl";
import type { KubeconfigManager } from "../../main/kubeconfig-manager/kubeconfig-manager";
-import type { KubeApiResource, KubeResource } from "../rbac";
-import { apiResourceRecord, apiResources } from "../rbac";
+import type { KubeApiResource, KubeApiResourceDescriptor } from "../rbac";
+import { formatKubeApiResource } from "../rbac";
import type { VersionDetector } from "../../main/cluster-detectors/version-detector";
import type { DetectorRegistry } from "../../main/cluster-detectors/detector-registry";
import plimit from "p-limit";
@@ -25,8 +25,8 @@ import assert from "assert";
import type { Logger } from "../logger";
import type { BroadcastMessage } from "../ipc/broadcast-message.injectable";
import type { LoadConfigfromFile } from "../kube-helpers/load-config-from-file.injectable";
-import type { RequestNamespaceResources } from "./authorization-namespace-review.injectable";
-import type { RequestListApiResources } from "./list-api-resources.injectable";
+import type { CanListResource, RequestNamespaceListPermissions, RequestNamespaceListPermissionsFor } from "./request-namespace-list-permissions.injectable";
+import type { RequestApiResources } from "./request-api-resources.injectable";
export interface ClusterDependencies {
readonly directoryForKubeConfigs: string;
@@ -36,8 +36,8 @@ export interface ClusterDependencies {
createContextHandler: (cluster: Cluster) => ClusterContextHandler;
createKubectl: (clusterVersion: string) => Kubectl;
createAuthorizationReview: (config: KubeConfig) => CanI;
- createAuthorizationNamespaceReview: (config: KubeConfig) => RequestNamespaceResources;
- createListApiResources: (cluster: Cluster) => RequestListApiResources;
+ requestApiResources: RequestApiResources;
+ requestNamespaceListPermissionsFor: RequestNamespaceListPermissionsFor;
createListNamespaces: (config: KubeConfig) => ListNamespaces;
createVersionDetector: (cluster: Cluster) => VersionDetector;
broadcastMessage: BroadcastMessage;
@@ -49,7 +49,7 @@ export interface ClusterDependencies {
*
* @beta
*/
-export class Cluster implements ClusterModel, ClusterState {
+export class Cluster implements ClusterModel {
/** Unique id for a cluster */
public readonly id: ClusterId;
private kubeCtl: Kubectl | undefined;
@@ -62,7 +62,6 @@ export class Cluster implements ClusterModel, ClusterState {
protected readonly _proxyKubeconfigManager: KubeconfigManager | undefined;
protected readonly eventsDisposer = disposer();
protected activated = false;
- private readonly resourceAccessStatuses = new Map();
public get contextHandler() {
// TODO: remove these once main/renderer are seperate classes
@@ -163,25 +162,21 @@ export class Cluster implements ClusterModel, ClusterState {
* @observable
*/
@observable metadata: ClusterMetadata = {};
+
/**
* List of allowed namespaces verified via K8S::SelfSubjectAccessReview api
- *
- * @observable
*/
- @observable allowedNamespaces: string[] = [];
- /**
- * List of allowed resources
- *
- * @observable
- * @internal
- */
- @observable allowedResources: string[] = [];
+ readonly allowedNamespaces = observable.array();
+
/**
* List of accessible namespaces provided by user in the Cluster Settings
- *
- * @observable
*/
- @observable accessibleNamespaces: string[] = [];
+ readonly accessibleNamespaces = observable.array();
+
+ private readonly knownResources = observable.array();
+
+ // The formatting of this is `group.name` or `name` (if in core)
+ private readonly allowedResources = observable.set();
/**
* Labels for the catalog entity
@@ -299,7 +294,7 @@ export class Cluster implements ClusterModel, ClusterState {
}
if (model.accessibleNamespaces) {
- this.accessibleNamespaces = model.accessibleNamespaces;
+ this.accessibleNamespaces.replace(model.accessibleNamespaces);
}
if (model.labels) {
@@ -433,8 +428,7 @@ export class Cluster implements ClusterModel, ClusterState {
this.accessible = false;
this.ready = false;
this.activated = false;
- this.allowedNamespaces = [];
- this.resourceAccessStatuses.clear();
+ this.allowedNamespaces.clear();
this.dependencies.logger.info(`[CLUSTER]: disconnected`, { id: this.id });
}
@@ -474,8 +468,7 @@ export class Cluster implements ClusterModel, ClusterState {
this.dependencies.logger.info(`[CLUSTER]: refreshAccessibility`, this.getMeta());
const proxyConfig = await this.getProxyKubeconfig();
const canI = this.dependencies.createAuthorizationReview(proxyConfig);
- const requestNamespaceResources = this.dependencies.createAuthorizationNamespaceReview(proxyConfig);
- const listApiResources = this.dependencies.createListApiResources(this);
+ const requestNamespaceListPermissions = this.dependencies.requestNamespaceListPermissionsFor(proxyConfig);
this.isAdmin = await canI({
namespace: "kube-system",
@@ -486,8 +479,9 @@ export class Cluster implements ClusterModel, ClusterState {
verb: "watch",
resource: "*",
});
- this.allowedNamespaces = await this.getAllowedNamespaces(proxyConfig);
- this.allowedResources = await this.getAllowedResources(listApiResources, requestNamespaceResources);
+ this.allowedNamespaces.replace(await this.requestAllowedNamespaces(proxyConfig));
+ this.knownResources.replace(await this.dependencies.requestApiResources(this));
+ this.allowedResources.replace(await this.getAllowedResources(requestNamespaceListPermissions));
this.ready = true;
}
@@ -600,7 +594,7 @@ export class Cluster implements ClusterModel, ClusterState {
accessible: this.accessible,
isAdmin: this.isAdmin,
allowedNamespaces: this.allowedNamespaces,
- allowedResources: this.allowedResources,
+ allowedResources: [...this.allowedResources],
isGlobalWatchEnabled: this.isGlobalWatchEnabled,
});
}
@@ -611,8 +605,8 @@ export class Cluster implements ClusterModel, ClusterState {
*/
@action setState(state: ClusterState) {
this.accessible = state.accessible;
- this.allowedNamespaces = state.allowedNamespaces;
- this.allowedResources = state.allowedResources;
+ this.allowedNamespaces.replace(state.allowedNamespaces);
+ this.allowedResources.replace(state.allowedResources);
this.apiUrl = state.apiUrl;
this.disconnected = state.disconnected;
this.isAdmin = state.isAdmin;
@@ -644,7 +638,7 @@ export class Cluster implements ClusterModel, ClusterState {
this.dependencies.broadcastMessage(`cluster:${this.id}:connection-update`, update);
}
- protected async getAllowedNamespaces(proxyConfig: KubeConfig) {
+ protected async requestAllowedNamespaces(proxyConfig: KubeConfig) {
if (this.accessibleNamespaces.length) {
return this.accessibleNamespaces;
}
@@ -668,69 +662,28 @@ export class Cluster implements ClusterModel, ClusterState {
}
}
- protected async getAllowedResources(listApiResources:RequestListApiResources, requestNamespaceResources: RequestNamespaceResources) {
+ protected async getAllowedResources(requestNamespaceListPermissions: RequestNamespaceListPermissions) {
+ if (!this.allowedNamespaces.length) {
+ return [];
+ }
+
try {
- if (!this.allowedNamespaces.length) {
- return [];
- }
+ const apiLimit = plimit(5); // 5 concurrent api requests
+ const canListResourceCheckers = await Promise.all((
+ this.allowedNamespaces.map(namespace => apiLimit(() => requestNamespaceListPermissions(namespace)))
+ ));
+ const canListNamespacedResource: CanListResource = (resource) => canListResourceCheckers.some(fn => fn(resource));
- const unknownResources = new Map(apiResources.map(resource => ([resource.apiName, resource])));
-
- const availableResources = await listApiResources();
- const availableResourcesNames = new Set(availableResources.map(apiResource => apiResource.apiName));
-
- [...unknownResources.values()].map(unknownResource => {
- if (!availableResourcesNames.has(unknownResource.apiName)) {
- this.resourceAccessStatuses.set(unknownResource, false);
- unknownResources.delete(unknownResource.apiName);
- }
- });
-
- if (unknownResources.size > 0) {
- const apiLimit = plimit(5); // 5 concurrent api requests
-
- await Promise.all(this.allowedNamespaces.map(namespace => apiLimit(async () => {
- if (unknownResources.size === 0) {
- return;
- }
-
- const namespaceResources = await requestNamespaceResources(namespace, availableResources);
-
- for (const resourceName of namespaceResources) {
- const unknownResource = unknownResources.get(resourceName);
-
- if (unknownResource) {
- this.resourceAccessStatuses.set(unknownResource, true);
- unknownResources.delete(resourceName);
- }
- }
- })));
-
- for (const forbiddenResource of unknownResources.values()) {
- this.resourceAccessStatuses.set(forbiddenResource, false);
- }
- }
-
- return apiResources
- .filter((resource) => this.resourceAccessStatuses.get(resource))
- .map(apiResource => apiResource.apiName);
+ return this.knownResources
+ .filter(canListNamespacedResource)
+ .map(formatKubeApiResource);
} catch (error) {
return [];
}
}
- isAllowedResource(kind: string): boolean {
- if ((kind as KubeResource) in apiResourceRecord) {
- return this.allowedResources.includes(kind);
- }
-
- const apiResource = apiResources.find(resource => resource.kind === kind);
-
- if (apiResource) {
- return this.allowedResources.includes(apiResource.apiName);
- }
-
- return true; // allowed by default for other resources
+ shouldShowResource(resource: KubeApiResourceDescriptor): boolean {
+ return this.allowedResources.has(formatKubeApiResource(resource));
}
isMetricHidden(resource: ClusterMetricsResourceType): boolean {
diff --git a/src/common/cluster/is-allowed-resource.ts b/src/common/cluster/is-allowed-resource.ts
deleted file mode 100644
index 7a6a392f78..0000000000
--- a/src/common/cluster/is-allowed-resource.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-import type { KubeResource } from "../rbac";
-import { apiResourceRecord, apiResources } from "../rbac";
-
-export const isAllowedResource = (allowedResources: string[]) => (kind: string): boolean => {
- if ((kind as KubeResource) in apiResourceRecord) {
- return allowedResources.includes(kind);
- }
-
- const apiResource = apiResources.find(resource => resource.kind === kind);
-
- if (apiResource) {
- return allowedResources.includes(apiResource.apiName);
- }
-
- return true; // allowed by default for other resources
-};
diff --git a/src/common/cluster/list-api-resources.injectable.ts b/src/common/cluster/list-api-resources.injectable.ts
deleted file mode 100644
index ed9d5c9c39..0000000000
--- a/src/common/cluster/list-api-resources.injectable.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import type {
- V1APIGroupList,
- V1APIResourceList,
- V1APIVersions,
-} from "@kubernetes/client-node";
-import { getInjectable } from "@ogre-tools/injectable";
-import type { K8sRequest } from "../../main/k8s-request.injectable";
-import k8SRequestInjectable from "../../main/k8s-request.injectable";
-import type { Logger } from "../logger";
-import loggerInjectable from "../logger.injectable";
-import type { KubeApiResource, KubeResource } from "../rbac";
-import type { Cluster } from "./cluster";
-import plimit from "p-limit";
-
-export type RequestListApiResources = () => Promise;
-
-/**
- * @param proxyConfig This config's `currentContext` field must be set, and will be used as the target cluster
- */
-export type ListApiResources = (cluster: Cluster) => RequestListApiResources;
-
-interface Dependencies {
- logger: Logger;
- k8sRequest: K8sRequest;
-}
-
-const listApiResources = ({ k8sRequest, logger }: Dependencies): ListApiResources => {
- return (cluster) => {
- const clusterRequest = (path: string) => k8sRequest(cluster, path);
- const apiLimit = plimit(5);
-
- return async () => {
- const resources: KubeApiResource[] = [];
-
- try {
- const resourceListGroups:{ group:string;path:string }[] = [];
-
- await Promise.all(
- [
- clusterRequest("/api").then((response:V1APIVersions)=>response.versions.forEach(version => resourceListGroups.push({ group:version, path:`/api/${version}` }))),
- clusterRequest("/apis").then((response:V1APIGroupList) => response.groups.forEach(group => {
- const preferredVersion = group.preferredVersion?.groupVersion;
-
- if (preferredVersion) {
- resourceListGroups.push({ group:group.name, path:`/apis/${preferredVersion}` });
- }
- })),
- ],
- );
-
- await Promise.all(
- resourceListGroups.map(({ group, path }) => apiLimit(async () => {
- const apiResources:V1APIResourceList = await clusterRequest(path);
-
- if (apiResources.resources) {
- resources.push(
- ...apiResources.resources.filter(resource => resource.verbs.includes("list")).map((resource) => ({
- apiName: resource.name as KubeResource,
- kind: resource.kind,
- group,
- })),
- );
- }
- }),
- ),
- );
- } catch (error) {
- logger.error(`[LIST-API-RESOURCES]: failed to list api resources: ${error}`);
- }
-
- return resources;
- };
- };
-};
-
-const listApiResourcesInjectable = getInjectable({
- id: "list-api-resources",
- instantiate: (di) => {
- const k8sRequest = di.inject(k8SRequestInjectable);
- const logger = di.inject(loggerInjectable);
-
- return listApiResources({ k8sRequest, logger });
- },
-});
-
-export default listApiResourcesInjectable;
diff --git a/src/common/cluster/request-api-resources.injectable.ts b/src/common/cluster/request-api-resources.injectable.ts
new file mode 100644
index 0000000000..3e1a621f39
--- /dev/null
+++ b/src/common/cluster/request-api-resources.injectable.ts
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+
+import type { V1APIGroupList, V1APIResourceList, V1APIVersions } from "@kubernetes/client-node";
+import { getInjectable } from "@ogre-tools/injectable";
+import k8SRequestInjectable from "../../main/k8s-request.injectable";
+import loggerInjectable from "../logger.injectable";
+import type { KubeApiResource } from "../rbac";
+import type { Cluster } from "./cluster";
+import plimit from "p-limit";
+
+export type RequestApiResources = (cluster: Cluster) => Promise;
+
+interface KubeResourceListGroup {
+ group: string;
+ path: string;
+}
+
+const requestApiResourcesInjectable = getInjectable({
+ id: "request-api-resources",
+ instantiate: (di): RequestApiResources => {
+ const k8sRequest = di.inject(k8SRequestInjectable);
+ const logger = di.inject(loggerInjectable);
+
+ return async (cluster) => {
+ const apiLimit = plimit(5);
+ const kubeApiResources: KubeApiResource[] = [];
+ const resourceListGroups: KubeResourceListGroup[] = [];
+
+ try {
+ await Promise.all([
+ (async () => {
+ const { versions } = await k8sRequest(cluster, "/api") as V1APIVersions;
+
+ for (const version of versions) {
+ resourceListGroups.push({
+ group: version,
+ path: `/api/${version}`,
+ });
+ }
+ })(),
+ (async () => {
+ const { groups } = await k8sRequest(cluster, "/apis") as V1APIGroupList;
+
+ for (const { preferredVersion, name } of groups) {
+ const { groupVersion } = preferredVersion ?? {};
+
+ if (groupVersion) {
+ resourceListGroups.push({
+ group: name,
+ path: `/apis/${groupVersion}`,
+ });
+ }
+ }
+ })(),
+ ]);
+
+ await Promise.all(
+ resourceListGroups.map(({ group, path }) => apiLimit(async () => {
+ const { resources } = await k8sRequest(cluster, path) as V1APIResourceList;
+
+ for (const resource of resources) {
+ kubeApiResources.push({
+ apiName: resource.name,
+ kind: resource.kind,
+ group,
+ namespaced: resource.namespaced,
+ });
+ }
+ })),
+ );
+ } catch (error) {
+ logger.error(`[LIST-API-RESOURCES]: failed to list api resources: ${error}`);
+ }
+
+ return kubeApiResources;
+ };
+ },
+});
+
+export default requestApiResourcesInjectable;
diff --git a/src/common/cluster/request-namespace-list-permissions.injectable.ts b/src/common/cluster/request-namespace-list-permissions.injectable.ts
new file mode 100644
index 0000000000..62d2477e42
--- /dev/null
+++ b/src/common/cluster/request-namespace-list-permissions.injectable.ts
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+
+import type { KubeConfig } from "@kubernetes/client-node";
+import { AuthorizationV1Api } from "@kubernetes/client-node";
+import { getInjectable } from "@ogre-tools/injectable";
+import loggerInjectable from "../logger.injectable";
+import type { KubeApiResource } from "../rbac";
+
+export type CanListResource = (resource: KubeApiResource) => boolean;
+
+/**
+ * Requests the permissions for actions on the kube cluster
+ * @param namespace The namespace of the resources
+ */
+export type RequestNamespaceListPermissions = (namespace: string) => Promise;
+
+/**
+ * @param proxyConfig This config's `currentContext` field must be set, and will be used as the target cluster
+ */
+export type RequestNamespaceListPermissionsFor = (proxyConfig: KubeConfig) => RequestNamespaceListPermissions;
+
+const requestNamespaceListPermissionsForInjectable = getInjectable({
+ id: "request-namespace-list-permissions-for",
+ instantiate: (di): RequestNamespaceListPermissionsFor => {
+ const logger = di.inject(loggerInjectable);
+
+ return (proxyConfig) => {
+ const api = proxyConfig.makeApiClient(AuthorizationV1Api);
+
+ return async (namespace) => {
+ try {
+ const { body: { status }} = await api.createSelfSubjectRulesReview({
+ apiVersion: "authorization.k8s.io/v1",
+ kind: "SelfSubjectRulesReview",
+ spec: { namespace },
+ });
+
+ if (!status || status.incomplete) {
+ logger.warn(`[AUTHORIZATION-NAMESPACE-REVIEW]: allowing all resources in namespace="${namespace}" due to incomplete SelfSubjectRulesReview: ${status?.evaluationError}`);
+
+ return () => true;
+ }
+
+ const { resourceRules } = status;
+
+ return (resource) => {
+ const resourceRule = resourceRules.find(({
+ apiGroups = [],
+ resources = [],
+ }) => {
+ const isAboutRelevantApiGroup = apiGroups.includes("*") || apiGroups.includes(resource.group);
+ const isAboutResource = resources.includes("*") || resources.includes(resource.apiName);
+
+ return isAboutRelevantApiGroup && isAboutResource;
+ });
+
+ if (!resourceRule) {
+ return false;
+ }
+
+ const { verbs } = resourceRule;
+
+ return verbs.includes("*") || verbs.includes("list");
+ };
+ } catch (error) {
+ logger.error(`[AUTHORIZATION-NAMESPACE-REVIEW]: failed to create subject rules review`, { namespace, error });
+
+ return () => true;
+ }
+ };
+ };
+ },
+});
+
+export default requestNamespaceListPermissionsForInjectable;
diff --git a/src/common/configure-packages.ts b/src/common/configure-packages.ts
deleted file mode 100644
index ec48be44ce..0000000000
--- a/src/common/configure-packages.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import * as Mobx from "mobx";
-import * as Immer from "immer";
-
-/**
- * Setup default configuration for external npm-packages
- */
-export default function configurePackages() {
- // Docs: https://mobx.js.org/configuration.html
- Mobx.configure({
- enforceActions: "never",
-
- // TODO: enable later (read more: https://mobx.js.org/migrating-from-4-or-5.html)
- // computedRequiresReaction: true,
- // reactionRequiresObservable: true,
- // observableRequiresReaction: true,
- });
-
- // Docs: https://immerjs.github.io/immer/
- // Required in `utils/storage-helper.ts`
- Immer.setAutoFreeze(false); // allow to merge mobx observables
- Immer.enableMapSet(); // allow to merge maps and sets
-}
diff --git a/src/common/front-end-routing/routes/cluster/config/config-maps/config-maps-route.injectable.ts b/src/common/front-end-routing/routes/cluster/config/config-maps/config-maps-route.injectable.ts
index 3ab2bc515c..6ea03fff08 100644
--- a/src/common/front-end-routing/routes/cluster/config/config-maps/config-maps-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/config/config-maps/config-maps-route.injectable.ts
@@ -3,22 +3,19 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const configMapsRouteInjectable = getInjectable({
id: "config-maps-route",
-
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "configmaps");
-
- return {
- path: "/configmaps",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
-
+ instantiate: (di) => ({
+ path: "/configmaps",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "configmaps",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/config/horizontal-pod-autoscalers/horizontal-pod-autoscalers-route.injectable.ts b/src/common/front-end-routing/routes/cluster/config/horizontal-pod-autoscalers/horizontal-pod-autoscalers-route.injectable.ts
index fe1814734f..00002620ee 100644
--- a/src/common/front-end-routing/routes/cluster/config/horizontal-pod-autoscalers/horizontal-pod-autoscalers-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/config/horizontal-pod-autoscalers/horizontal-pod-autoscalers-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const horizontalPodAutoscalersRouteInjectable = getInjectable({
id: "horizontal-pod-autoscalers-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "horizontalpodautoscalers");
-
- return {
- path: "/hpa",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/hpa",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "horizontalpodautoscalers",
+ group: "autoscaling",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/config/leases/leases-route.injectable.ts b/src/common/front-end-routing/routes/cluster/config/leases/leases-route.injectable.ts
index 65ee0e3ffa..ea4eb2ae59 100644
--- a/src/common/front-end-routing/routes/cluster/config/leases/leases-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/config/leases/leases-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const leasesRouteInjectable = getInjectable({
id: "leases",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "leases");
-
- return {
- path: "/leases",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/leases",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "leases",
+ group: "coordination.k8s.io",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/config/limit-ranges/limit-ranges-route.injectable.ts b/src/common/front-end-routing/routes/cluster/config/limit-ranges/limit-ranges-route.injectable.ts
index bcf740113b..8623f3520e 100644
--- a/src/common/front-end-routing/routes/cluster/config/limit-ranges/limit-ranges-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/config/limit-ranges/limit-ranges-route.injectable.ts
@@ -3,24 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const limitRangesRouteInjectable = getInjectable({
id: "limit-ranges-route",
- instantiate: (di) => {
- const limitRangesIsAllowed = di.inject(
- isAllowedResourceInjectable,
- "limitranges",
- );
-
- return {
- path: "/limitranges",
- clusterFrame: true,
- isEnabled: limitRangesIsAllowed,
- };
- },
+ instantiate: (di) => ({
+ path: "/limitranges",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "limitranges",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/config/pod-disruption-budgets/pod-disruption-budgets-route.injectable.ts b/src/common/front-end-routing/routes/cluster/config/pod-disruption-budgets/pod-disruption-budgets-route.injectable.ts
index df6d89fb06..12ce0a2138 100644
--- a/src/common/front-end-routing/routes/cluster/config/pod-disruption-budgets/pod-disruption-budgets-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/config/pod-disruption-budgets/pod-disruption-budgets-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const podDisruptionBudgetsRouteInjectable = getInjectable({
id: "pod-disruption-budgets-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "poddisruptionbudgets");
-
- return {
- path: "/poddisruptionbudgets",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/poddisruptionbudgets",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "poddisruptionbudgets",
+ group: "policy",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/config/priority-classes/priority-classes-route.injectable.ts b/src/common/front-end-routing/routes/cluster/config/priority-classes/priority-classes-route.injectable.ts
index 1c3632c261..75194b0541 100644
--- a/src/common/front-end-routing/routes/cluster/config/priority-classes/priority-classes-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/config/priority-classes/priority-classes-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const priorityClassesRouteInjectable = getInjectable({
id: "priority-classes-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "priorityclasses");
-
- return {
- path: "/priorityclasses",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/priorityclasses",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "priorityclasses",
+ group: "scheduling.k8s.io",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/config/resource-quotas/resource-quotas-route.injectable.ts b/src/common/front-end-routing/routes/cluster/config/resource-quotas/resource-quotas-route.injectable.ts
index 496a42ed0c..209f77e19a 100644
--- a/src/common/front-end-routing/routes/cluster/config/resource-quotas/resource-quotas-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/config/resource-quotas/resource-quotas-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const resourceQuotasRouteInjectable = getInjectable({
id: "resource-quotas-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "resourcequotas");
-
- return {
- path: "/resourcequotas",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/resourcequotas",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "resourcequotas",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/config/runtime-classes/runtime-classes-route.injectable.ts b/src/common/front-end-routing/routes/cluster/config/runtime-classes/runtime-classes-route.injectable.ts
index 72934f9158..beab83754f 100644
--- a/src/common/front-end-routing/routes/cluster/config/runtime-classes/runtime-classes-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/config/runtime-classes/runtime-classes-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const runtimeClassesRouteInjectable = getInjectable({
id: "runtime-classes-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "runtimeclasses");
-
- return {
- path: "/runtimeclasses",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/runtimeclasses",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "runtimeclasses",
+ group: "node.k8s.io",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/config/secrets/secrets-route.injectable.ts b/src/common/front-end-routing/routes/cluster/config/secrets/secrets-route.injectable.ts
index f451f51d0c..079ddcbf83 100644
--- a/src/common/front-end-routing/routes/cluster/config/secrets/secrets-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/config/secrets/secrets-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const secretsRouteInjectable = getInjectable({
id: "secrets-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "secrets");
-
- return {
- path: "/secrets",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/secrets",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "secrets",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/events/events-route.injectable.ts b/src/common/front-end-routing/routes/cluster/events/events-route.injectable.ts
index a53cb5d1f8..b3df358ad8 100644
--- a/src/common/front-end-routing/routes/cluster/events/events-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/events/events-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../front-end-route-injection-token";
const eventsRouteInjectable = getInjectable({
id: "events-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "events");
-
- return {
- path: "/events",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/events",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "events",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/namespaces/namespaces-route.injectable.ts b/src/common/front-end-routing/routes/cluster/namespaces/namespaces-route.injectable.ts
index 395c128682..2aa6c23efe 100644
--- a/src/common/front-end-routing/routes/cluster/namespaces/namespaces-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/namespaces/namespaces-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../front-end-route-injection-token";
const namespacesRouteInjectable = getInjectable({
id: "namespaces-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "namespaces");
-
- return {
- path: "/namespaces",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/namespaces",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "namespaces",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/network/endpoints/endpoints-route.injectable.ts b/src/common/front-end-routing/routes/cluster/network/endpoints/endpoints-route.injectable.ts
index e30df3123b..c88ec04714 100644
--- a/src/common/front-end-routing/routes/cluster/network/endpoints/endpoints-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/network/endpoints/endpoints-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const endpointsRouteInjectable = getInjectable({
id: "endpoints-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "endpoints");
-
- return {
- path: "/endpoints",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/endpoints",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "endpoints",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/network/ingresses/ingresses-route.injectable.ts b/src/common/front-end-routing/routes/cluster/network/ingresses/ingresses-route.injectable.ts
index 12565deeaf..8e01646b82 100644
--- a/src/common/front-end-routing/routes/cluster/network/ingresses/ingresses-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/network/ingresses/ingresses-route.injectable.ts
@@ -3,21 +3,27 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
+import { computedOr } from "../../../../../utils/computed-or";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const ingressesRouteInjectable = getInjectable({
id: "ingresses-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "ingresses");
-
- return {
- path: "/ingresses",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/ingresses",
+ clusterFrame: true,
+ isEnabled: computedOr(
+ di.inject(shouldShowResourceInjectionToken, {
+ apiName: "ingresses",
+ group: "networking.k8s.io",
+ }),
+ di.inject(shouldShowResourceInjectionToken, {
+ apiName: "ingresses",
+ group: "extensions",
+ }),
+ ),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/network/network-policies/network-policies-route.injectable.ts b/src/common/front-end-routing/routes/cluster/network/network-policies/network-policies-route.injectable.ts
index ead62ee435..38a1b8a7e2 100644
--- a/src/common/front-end-routing/routes/cluster/network/network-policies/network-policies-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/network/network-policies/network-policies-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const networkPoliciesRouteInjectable = getInjectable({
id: "network-policies-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "networkpolicies");
-
- return {
- path: "/network-policies",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/network-policies",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "networkpolicies",
+ group: "networking.k8s.io",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/network/services/services-route.injectable.ts b/src/common/front-end-routing/routes/cluster/network/services/services-route.injectable.ts
index 033c95673b..53300ee241 100644
--- a/src/common/front-end-routing/routes/cluster/network/services/services-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/network/services/services-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const servicesRouteInjectable = getInjectable({
id: "services-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "services");
-
- return {
- path: "/services",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/services",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "services",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/nodes/nodes-route.injectable.ts b/src/common/front-end-routing/routes/cluster/nodes/nodes-route.injectable.ts
index febd733343..81323843d5 100644
--- a/src/common/front-end-routing/routes/cluster/nodes/nodes-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/nodes/nodes-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../front-end-route-injection-token";
const nodesRouteInjectable = getInjectable({
id: "nodes-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "nodes");
-
- return {
- path: "/nodes",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/nodes",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "nodes",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/overview/cluster-overview-route.injectable.ts b/src/common/front-end-routing/routes/cluster/overview/cluster-overview-route.injectable.ts
index 209fc113d8..8315fd7773 100644
--- a/src/common/front-end-routing/routes/cluster/overview/cluster-overview-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/overview/cluster-overview-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../front-end-route-injection-token";
const clusterOverviewRouteInjectable = getInjectable({
id: "cluster-overview-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "nodes");
-
- return {
- path: "/overview",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/overview",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "nodes",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/storage/persistent-volume-claims/persistent-volume-claims-route.injectable.ts b/src/common/front-end-routing/routes/cluster/storage/persistent-volume-claims/persistent-volume-claims-route.injectable.ts
index 8879541355..1b96933136 100644
--- a/src/common/front-end-routing/routes/cluster/storage/persistent-volume-claims/persistent-volume-claims-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/storage/persistent-volume-claims/persistent-volume-claims-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const persistentVolumeClaimsRouteInjectable = getInjectable({
id: "persistent-volume-claims-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "persistentvolumeclaims");
-
- return {
- path: "/persistent-volume-claims",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/persistent-volume-claims",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "persistentvolumeclaims",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/storage/persistent-volumes/persistent-volumes-route.injectable.ts b/src/common/front-end-routing/routes/cluster/storage/persistent-volumes/persistent-volumes-route.injectable.ts
index e6549ea45b..52f95b32c6 100644
--- a/src/common/front-end-routing/routes/cluster/storage/persistent-volumes/persistent-volumes-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/storage/persistent-volumes/persistent-volumes-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const persistentVolumesRouteInjectable = getInjectable({
id: "persistent-volumes-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "persistentvolumes");
-
- return {
- path: "/persistent-volumes",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/persistent-volumes",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "persistentvolumes",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/storage/storage-classes/storage-classes-route.injectable.ts b/src/common/front-end-routing/routes/cluster/storage/storage-classes/storage-classes-route.injectable.ts
index 69f2b5d4ee..8702ab1602 100644
--- a/src/common/front-end-routing/routes/cluster/storage/storage-classes/storage-classes-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/storage/storage-classes/storage-classes-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const storageClassesRouteInjectable = getInjectable({
id: "storage-classes-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "storageclasses");
-
- return {
- path: "/storage-classes",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/storage-classes",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "storageclasses",
+ group: "storage.k8s.io",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/user-management/cluster-role-bindings/cluster-role-bindings-route.injectable.ts b/src/common/front-end-routing/routes/cluster/user-management/cluster-role-bindings/cluster-role-bindings-route.injectable.ts
index f19491ee72..0903d5fced 100644
--- a/src/common/front-end-routing/routes/cluster/user-management/cluster-role-bindings/cluster-role-bindings-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/user-management/cluster-role-bindings/cluster-role-bindings-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const clusterRoleBindingsRouteInjectable = getInjectable({
id: "cluster-role-bindings-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "clusterrolebindings");
-
- return {
- path: "/cluster-role-bindings",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/cluster-role-bindings",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "clusterrolebindings",
+ group: "rbac.authorization.k8s.io",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/user-management/cluster-roles/cluster-roles-route.injectable.ts b/src/common/front-end-routing/routes/cluster/user-management/cluster-roles/cluster-roles-route.injectable.ts
index d21c2c33a4..9fce206667 100644
--- a/src/common/front-end-routing/routes/cluster/user-management/cluster-roles/cluster-roles-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/user-management/cluster-roles/cluster-roles-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const clusterRolesRouteInjectable = getInjectable({
id: "cluster-roles-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "clusterroles");
-
- return {
- path: "/cluster-roles",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/cluster-roles",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "clusterroles",
+ group: "rbac.authorization.k8s.io",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/user-management/pod-security-policies/pod-security-policies-route.injectable.ts b/src/common/front-end-routing/routes/cluster/user-management/pod-security-policies/pod-security-policies-route.injectable.ts
index 14cfcbedc5..2f35986916 100644
--- a/src/common/front-end-routing/routes/cluster/user-management/pod-security-policies/pod-security-policies-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/user-management/pod-security-policies/pod-security-policies-route.injectable.ts
@@ -3,19 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const podSecurityPoliciesRouteInjectable = getInjectable({
id: "pod-security-policies-route",
instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "podsecuritypolicies");
-
return {
path: "/pod-security-policies",
clusterFrame: true,
- isEnabled: isAllowedResource,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "podsecuritypolicies",
+ group: "policy",
+ }),
};
},
diff --git a/src/common/front-end-routing/routes/cluster/user-management/role-bindings/role-bindings-route.injectable.ts b/src/common/front-end-routing/routes/cluster/user-management/role-bindings/role-bindings-route.injectable.ts
index 0f908e5876..759c1b8eda 100644
--- a/src/common/front-end-routing/routes/cluster/user-management/role-bindings/role-bindings-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/user-management/role-bindings/role-bindings-route.injectable.ts
@@ -3,19 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const roleBindingsRouteInjectable = getInjectable({
id: "role-bindings-route",
instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "rolebindings");
-
return {
path: "/role-bindings",
clusterFrame: true,
- isEnabled: isAllowedResource,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "rolebindings",
+ group: "rbac.authorization.k8s.io",
+ }),
};
},
diff --git a/src/common/front-end-routing/routes/cluster/user-management/roles/roles-route.injectable.ts b/src/common/front-end-routing/routes/cluster/user-management/roles/roles-route.injectable.ts
index 94db156fa4..efe4cad810 100644
--- a/src/common/front-end-routing/routes/cluster/user-management/roles/roles-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/user-management/roles/roles-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const rolesRouteInjectable = getInjectable({
id: "roles-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "roles");
-
- return {
- path: "/roles",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/roles",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "roles",
+ group: "rbac.authorization.k8s.io",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/user-management/service-accounts/service-accounts-route.injectable.ts b/src/common/front-end-routing/routes/cluster/user-management/service-accounts/service-accounts-route.injectable.ts
index 4d79258c54..3bf6c1ec00 100644
--- a/src/common/front-end-routing/routes/cluster/user-management/service-accounts/service-accounts-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/user-management/service-accounts/service-accounts-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const serviceAccountsRouteInjectable = getInjectable({
id: "service-accounts-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "serviceaccounts");
-
- return {
- path: "/service-accounts",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/service-accounts",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "serviceaccounts",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/workloads/cron-jobs/cron-jobs-route.injectable.ts b/src/common/front-end-routing/routes/cluster/workloads/cron-jobs/cron-jobs-route.injectable.ts
index 735ea94642..33453a2247 100644
--- a/src/common/front-end-routing/routes/cluster/workloads/cron-jobs/cron-jobs-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/workloads/cron-jobs/cron-jobs-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const cronJobsRouteInjectable = getInjectable({
id: "cron-jobs-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "cronjobs");
-
- return {
- path: "/cronjobs",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/cronjobs",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "cronjobs",
+ group: "batch",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/workloads/daemonsets/daemonsets-route.injectable.ts b/src/common/front-end-routing/routes/cluster/workloads/daemonsets/daemonsets-route.injectable.ts
index 55729813e8..f1ec2008fa 100644
--- a/src/common/front-end-routing/routes/cluster/workloads/daemonsets/daemonsets-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/workloads/daemonsets/daemonsets-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const daemonsetsRouteInjectable = getInjectable({
id: "daemonsets-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "daemonsets");
-
- return {
- path: "/daemonsets",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/daemonsets",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "daemonsets",
+ group: "apps",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/workloads/deployments/deployments-route.injectable.ts b/src/common/front-end-routing/routes/cluster/workloads/deployments/deployments-route.injectable.ts
index b9ff072e66..84c059780f 100644
--- a/src/common/front-end-routing/routes/cluster/workloads/deployments/deployments-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/workloads/deployments/deployments-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const deploymentsRouteInjectable = getInjectable({
id: "deployments-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "deployments");
-
- return {
- path: "/deployments",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/deployments",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "deployments",
+ group: "apps",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/workloads/jobs/jobs-route.injectable.ts b/src/common/front-end-routing/routes/cluster/workloads/jobs/jobs-route.injectable.ts
index d9190a7ea8..39cc89e88f 100644
--- a/src/common/front-end-routing/routes/cluster/workloads/jobs/jobs-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/workloads/jobs/jobs-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const jobsRouteInjectable = getInjectable({
id: "jobs-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "jobs");
-
- return {
- path: "/jobs",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/jobs",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "jobs",
+ group: "batch",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/workloads/pods/pods-route.injectable.ts b/src/common/front-end-routing/routes/cluster/workloads/pods/pods-route.injectable.ts
index e9fb2a2b16..577f1c1a91 100644
--- a/src/common/front-end-routing/routes/cluster/workloads/pods/pods-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/workloads/pods/pods-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const podsRouteInjectable = getInjectable({
id: "pods-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "pods");
-
- return {
- path: "/pods",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/pods",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "pods",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/workloads/replicasets/replicasets-route.injectable.ts b/src/common/front-end-routing/routes/cluster/workloads/replicasets/replicasets-route.injectable.ts
index 0319d27550..b790ce13ec 100644
--- a/src/common/front-end-routing/routes/cluster/workloads/replicasets/replicasets-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/workloads/replicasets/replicasets-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const replicasetsRouteInjectable = getInjectable({
id: "replicasets-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "replicasets");
-
- return {
- path: "/replicasets",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/replicasets",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "replicasets",
+ group: "apps",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/front-end-routing/routes/cluster/workloads/statefulsets/statefulsets-route.injectable.ts b/src/common/front-end-routing/routes/cluster/workloads/statefulsets/statefulsets-route.injectable.ts
index a3089fa62f..72c81b3bee 100644
--- a/src/common/front-end-routing/routes/cluster/workloads/statefulsets/statefulsets-route.injectable.ts
+++ b/src/common/front-end-routing/routes/cluster/workloads/statefulsets/statefulsets-route.injectable.ts
@@ -3,21 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
-import isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
+import { shouldShowResourceInjectionToken } from "../../../../../cluster-store/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const statefulsetsRouteInjectable = getInjectable({
id: "statefulsets-route",
- instantiate: (di) => {
- const isAllowedResource = di.inject(isAllowedResourceInjectable, "statefulsets");
-
- return {
- path: "/statefulsets",
- clusterFrame: true,
- isEnabled: isAllowedResource,
- };
- },
+ instantiate: (di) => ({
+ path: "/statefulsets",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "statefulsets",
+ group: "apps",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/common/k8s-api/__tests__/api-manager.test.ts b/src/common/k8s-api/__tests__/api-manager.test.ts
index 3e411b6584..e99ac62018 100644
--- a/src/common/k8s-api/__tests__/api-manager.test.ts
+++ b/src/common/k8s-api/__tests__/api-manager.test.ts
@@ -3,7 +3,14 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
+import type { DiContainer } from "@ogre-tools/injectable";
+import createClusterInjectable from "../../../main/create-cluster/create-cluster.injectable";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../../renderer/cluster-frame-context/for-namespaced-resources.injectable";
+import hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting";
+import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
+import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
+import directoryForUserDataInjectable from "../../app-paths/directory-for-user-data/directory-for-user-data.injectable";
import type { ApiManager } from "../api-manager";
import apiManagerInjectable from "../api-manager/manager.injectable";
import { KubeApi } from "../kube-api";
@@ -22,9 +29,24 @@ class TestStore extends KubeObjectStore {
describe("ApiManager", () => {
let apiManager: ApiManager;
+ let di: DiContainer;
beforeEach(() => {
- const di = getDiForUnitTesting({ doGeneralOverrides: true });
+ 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",
+ }));
apiManager = di.inject(apiManagerInjectable);
});
@@ -40,7 +62,9 @@ describe("ApiManager", () => {
fallbackApiBases: [fallbackApiBase],
checkPreferredVersion: true,
});
- const kubeStore = new TestStore(kubeApi);
+ const kubeStore = new TestStore({
+ context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
+ }, kubeApi);
apiManager.registerApi(apiBase, kubeApi);
diff --git a/src/common/k8s-api/__tests__/kube-api-version-detection.test.ts b/src/common/k8s-api/__tests__/kube-api-version-detection.test.ts
index eb13464716..e2caef39fa 100644
--- a/src/common/k8s-api/__tests__/kube-api-version-detection.test.ts
+++ b/src/common/k8s-api/__tests__/kube-api-version-detection.test.ts
@@ -3,43 +3,23 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { KubeJsonApi } from "../kube-json-api";
-import { PassThrough } from "stream";
import type { ApiManager } from "../api-manager";
import { Ingress, IngressApi } from "../endpoints";
import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting";
import apiManagerInjectable from "../api-manager/manager.injectable";
-import autoRegistrationInjectable from "../api-manager/auto-registration.injectable";
import type { Fetch } from "../../fetch/fetch.injectable";
import fetchInjectable from "../../fetch/fetch.injectable";
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import { flushPromises } from "../../test-utils/flush-promises";
import createKubeJsonApiInjectable from "../create-kube-json-api.injectable";
-import type { Response, Headers as NodeFetchHeaders } from "node-fetch";
-
-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;
-};
+import setupAutoRegistrationInjectable from "../../../renderer/before-frame-starts/runnables/setup-auto-registration.injectable";
+import { createMockResponseFromString } from "../../../test-utils/mock-responses";
+import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
+import directoryForUserDataInjectable from "../../app-paths/directory-for-user-data/directory-for-user-data.injectable";
+import createClusterInjectable from "../../../main/create-cluster/create-cluster.injectable";
+import hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
+import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
describe("KubeApi", () => {
let request: KubeJsonApi;
@@ -52,6 +32,20 @@ describe("KubeApi", () => {
fetchMock = asyncFn();
di.override(fetchInjectable, () => fetchMock);
+ 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 createKubeJsonApi = di.inject(createKubeJsonApiInjectable);
request = createKubeJsonApi({
@@ -60,7 +54,9 @@ describe("KubeApi", () => {
});
registerApiSpy = jest.spyOn(di.inject(apiManagerInjectable), "registerApi");
- di.inject(autoRegistrationInjectable);
+ const setupAutoRegistration = di.inject(setupAutoRegistrationInjectable);
+
+ setupAutoRegistration.run();
});
describe("on first call to IngressApi.get()", () => {
diff --git a/src/common/k8s-api/__tests__/kube-api.test.ts b/src/common/k8s-api/__tests__/kube-api.test.ts
index 4f67ed1401..a4f9fd5b21 100644
--- a/src/common/k8s-api/__tests__/kube-api.test.ts
+++ b/src/common/k8s-api/__tests__/kube-api.test.ts
@@ -8,7 +8,6 @@ import type { KubeJsonApi, KubeJsonApiData } from "../kube-json-api";
import { PassThrough } from "stream";
import { Deployment, DeploymentApi, NamespaceApi, Pod, PodApi } from "../endpoints";
import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting";
-import autoRegistrationInjectable from "../api-manager/auto-registration.injectable";
import type { Fetch } from "../../fetch/fetch.injectable";
import fetchInjectable from "../../fetch/fetch.injectable";
import type { CreateKubeApiForRemoteCluster } from "../create-kube-api-for-remote-cluster.injectable";
@@ -19,64 +18,14 @@ import { flushPromises } from "../../test-utils/flush-promises";
import createKubeJsonApiInjectable from "../create-kube-json-api.injectable";
import type { IKubeWatchEvent } from "../kube-watch-event";
import type { KubeJsonApiDataFor } from "../kube-object";
-import type { Response, Headers as NodeFetchHeaders } from "node-fetch";
import AbortController from "abort-controller";
-
-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;
-};
-
-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;
-};
+import setupAutoRegistrationInjectable from "../../../renderer/before-frame-starts/runnables/setup-auto-registration.injectable";
+import { createMockResponseFromStream, createMockResponseFromString } from "../../../test-utils/mock-responses";
+import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
+import directoryForUserDataInjectable from "../../app-paths/directory-for-user-data/directory-for-user-data.injectable";
+import createClusterInjectable from "../../../main/create-cluster/create-cluster.injectable";
+import hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
+import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
describe("createKubeApiForRemoteCluster", () => {
let createKubeApiForRemoteCluster: CreateKubeApiForRemoteCluster;
@@ -85,6 +34,20 @@ describe("createKubeApiForRemoteCluster", () => {
beforeEach(async () => {
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",
+ }));
+
fetchMock = asyncFn();
di.override(fetchInjectable, () => fetchMock);
@@ -174,6 +137,20 @@ describe("KubeApi", () => {
beforeEach(async () => {
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",
+ }));
+
fetchMock = asyncFn();
di.override(fetchInjectable, () => fetchMock);
@@ -184,7 +161,9 @@ describe("KubeApi", () => {
apiBase: "/api-kube",
});
- di.inject(autoRegistrationInjectable);
+ const setupAutoRegistration = di.inject(setupAutoRegistrationInjectable);
+
+ setupAutoRegistration.run();
});
describe("patching deployments", () => {
diff --git a/src/common/k8s-api/__tests__/kube-object.store.test.ts b/src/common/k8s-api/__tests__/kube-object.store.test.ts
index 91ed80fbde..afe755a6ba 100644
--- a/src/common/k8s-api/__tests__/kube-object.store.test.ts
+++ b/src/common/k8s-api/__tests__/kube-object.store.test.ts
@@ -3,27 +3,22 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
-import type { Cluster } from "../../cluster/cluster";
-import type { ClusterContext } from "../cluster-context";
import type { KubeApi } from "../kube-api";
import { KubeObject } from "../kube-object";
import type { KubeObjectStoreLoadingParams } from "../kube-object.store";
import { KubeObjectStore } from "../kube-object.store";
class FakeKubeObjectStore extends KubeObjectStore {
- _context = {
- allNamespaces: [],
- contextNamespaces: [],
- hasSelectedAll: false,
- cluster: {} as Cluster,
- } as ClusterContext;
-
- get context() {
- return this._context;
- }
-
constructor(private readonly _loadItems: (params: KubeObjectStoreLoadingParams) => KubeObject[], api: Partial>) {
- super(api as KubeApi);
+ super({
+ context: {
+ allNamespaces: [],
+ contextNamespaces: [],
+ hasSelectedAll: false,
+ isGlobalWatchEnabled: () => true,
+ isLoadingAll: () => true,
+ },
+ }, api as KubeApi);
}
async loadItems(params: KubeObjectStoreLoadingParams) {
diff --git a/src/common/k8s-api/api-manager/auto-registration.injectable.ts b/src/common/k8s-api/api-manager/auto-registration.injectable.ts
deleted file mode 100644
index 0cf1a3055d..0000000000
--- a/src/common/k8s-api/api-manager/auto-registration.injectable.ts
+++ /dev/null
@@ -1,74 +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 { CustomResourceDefinition } from "../endpoints";
-import { KubeApi } from "../kube-api";
-import { KubeObject } from "../kube-object";
-import autoRegistrationEmitterInjectable from "./auto-registration-emitter.injectable";
-import apiManagerInjectable from "./manager.injectable";
-import { CustomResourceStore } from "./resource.store";
-
-const autoRegistrationInjectable = getInjectable({
- id: "api-manager-auto-registration",
- instantiate: (di) => {
- const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable);
- const beforeApiManagerInitializationCrds: CustomResourceDefinition[] = [];
- const beforeApiManagerInitializationApis: KubeApi[] = [];
- let initialized = false;
-
- const autoInitCustomResourceStore = (crd: CustomResourceDefinition) => {
- const objectConstructor = class extends KubeObject {
- static readonly kind = crd.getResourceKind();
- static readonly namespaced = crd.isNamespaced();
- static readonly apiBase = crd.getResourceApiBase();
- };
-
- const api = (() => {
- const rawApi = apiManager.getApi(objectConstructor.apiBase);
-
- if (rawApi) {
- return rawApi;
- }
-
- const api = new KubeApi({ objectConstructor });
-
- apiManager.registerApi(api);
-
- return api;
- })();
-
- if (!apiManager.getStore(api)) {
- apiManager.registerStore(new CustomResourceStore(api));
- }
- };
- const autoInitKubeApi = (api: KubeApi) => {
- apiManager.registerApi(api);
- };
-
- autoRegistrationEmitter
- .on("customResourceDefinition", (crd) => {
- if (initialized) {
- autoInitCustomResourceStore(crd);
- } else {
- beforeApiManagerInitializationCrds.push(crd);
- }
- })
- .on("kubeApi", (api) => {
- if (initialized) {
- autoInitKubeApi(api);
- } else {
- beforeApiManagerInitializationApis.push(api);
- }
- });
-
- const apiManager = di.inject(apiManagerInjectable);
-
- beforeApiManagerInitializationCrds.forEach(autoInitCustomResourceStore);
- beforeApiManagerInitializationApis.forEach(autoInitKubeApi);
- initialized = true;
- },
-});
-
-export default autoRegistrationInjectable;
diff --git a/src/common/k8s-api/api-manager/resource.store.ts b/src/common/k8s-api/api-manager/resource.store.ts
index 63ccdcf93d..c81ce7daec 100644
--- a/src/common/k8s-api/api-manager/resource.store.ts
+++ b/src/common/k8s-api/api-manager/resource.store.ts
@@ -4,11 +4,12 @@
*/
import type { KubeApi } from "../kube-api";
+import type { KubeObjectStoreDependencies } from "../kube-object.store";
import { KubeObjectStore } from "../kube-object.store";
import type { KubeObject } from "../kube-object";
export class CustomResourceStore extends KubeObjectStore> {
- constructor(api: KubeApi) {
- super(api);
+ constructor(deps: KubeObjectStoreDependencies, api: KubeApi) {
+ super(deps, api);
}
}
diff --git a/src/common/k8s-api/cluster-context.ts b/src/common/k8s-api/cluster-context.ts
deleted file mode 100644
index 098d92642d..0000000000
--- a/src/common/k8s-api/cluster-context.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import type { Cluster } from "../cluster/cluster";
-
-export interface ClusterContext {
- cluster: Cluster;
- allNamespaces: string[]; // available / allowed namespaces from cluster.ts
- contextNamespaces: string[]; // selected by user (see: namespace-select.tsx)
- hasSelectedAll: boolean;
-}
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 7290263a41..49271fb6d2 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
@@ -5,25 +5,44 @@
import { getInjectable } from "@ogre-tools/injectable";
import type { Patch } from "rfc6902";
import apiBaseInjectable from "../../api-base.injectable";
+import type { AsyncResult } from "../../../utils/async-result";
import type { KubeJsonApiData } from "../../kube-json-api";
-export type RequestKubeObjectPatch = (name: string, kind: string, ns: string | undefined, patch: Patch) => Promise;
+export type RequestKubeObjectPatch = (name: string, kind: string, ns: string | undefined, patch: Patch) => Promise>;
const requestKubeObjectPatchInjectable = getInjectable({
id: "request-kube-object-patch",
instantiate: (di): RequestKubeObjectPatch => {
const apiBase = di.inject(apiBaseInjectable);
- return (name, kind, ns, patch) => (
- apiBase.patch("/stack", {
+ return async (name, kind, ns, patch) => {
+ const result = await apiBase.patch("/stack", {
data: {
name,
kind,
ns,
patch,
},
- })
- );
+ }) as AsyncResult;
+
+ if (!result.callWasSuccessful) {
+ return result;
+ }
+
+ try {
+ const response = JSON.parse(result.response);
+
+ return {
+ callWasSuccessful: true,
+ response,
+ };
+ } catch (error) {
+ return {
+ callWasSuccessful: false,
+ error: String(error),
+ };
+ }
+ };
},
});
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 7d996253ee..1891a779cf 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
@@ -4,16 +4,37 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import apiBaseInjectable from "../../api-base.injectable";
+import type { AsyncResult } from "../../../utils/async-result";
import type { KubeJsonApiData } from "../../kube-json-api";
-export type RequestKubeObjectCreation = (resourceDescriptor: string) => Promise;
+export type RequestKubeObjectCreation = (resourceDescriptor: string) => Promise>;
const requestKubeObjectCreationInjectable = getInjectable({
id: "request-kube-object-creation",
instantiate: (di): RequestKubeObjectCreation => {
const apiBase = di.inject(apiBaseInjectable);
- return (data) => apiBase.post("/stack", { data });
+ return async (data) => {
+ const result = await apiBase.post("/stack", { data }) as AsyncResult;
+
+ if (!result.callWasSuccessful) {
+ return result;
+ }
+
+ try {
+ const response = JSON.parse(result.response);
+
+ return {
+ callWasSuccessful: true,
+ response,
+ };
+ } catch (error) {
+ return {
+ callWasSuccessful: false,
+ error: String(error),
+ };
+ }
+ };
},
});
diff --git a/src/common/k8s-api/json-api.ts b/src/common/k8s-api/json-api.ts
index c3e07bfa94..988378641c 100644
--- a/src/common/k8s-api/json-api.ts
+++ b/src/common/k8s-api/json-api.ts
@@ -104,7 +104,7 @@ export class JsonApi = Js
);
const { query } = params ?? {};
- if (query) {
+ if (query && Object.keys(query).length > 0) {
const queryString = stringify(query as unknown as QueryParams);
reqUrl += (reqUrl.includes("?") ? "&" : "?") + queryString;
@@ -171,7 +171,7 @@ export class JsonApi = Js
reqInit.body = JSON.stringify(data);
}
- if (query) {
+ if (query && Object.keys(query).length > 0) {
const queryString = stringify(query as unknown as QueryParams);
reqUrl += (reqUrl.includes("?") ? "&" : "?") + queryString;
diff --git a/src/common/k8s-api/kube-api.ts b/src/common/k8s-api/kube-api.ts
index 7ca2995906..6e3ad4a72a 100644
--- a/src/common/k8s-api/kube-api.ts
+++ b/src/common/k8s-api/kube-api.ts
@@ -403,10 +403,11 @@ export class KubeApi<
/**
* This method differs from {@link formatUrlForNotListing} because this treats `""` as "all namespaces"
+ * NOTE: This is also useful for watching
* @param namespace The namespace to list in or `""` for all namespaces
*/
- formatUrlForListing(namespace: string) {
- return createKubeApiURL({
+ formatUrlForListing(namespace: string | undefined, query?: Partial) {
+ const resourcePath = createKubeApiURL({
apiPrefix: this.apiPrefix,
apiVersion: this.apiVersionWithGroup,
resource: this.apiResource,
@@ -414,15 +415,15 @@ export class KubeApi<
? namespace ?? "default"
: undefined,
});
+
+ return resourcePath + (query ? `?${stringify(this.normalizeQuery(query))}` : "");
}
/**
* Format a URL pathname and query for acting upon a specific resource.
*/
- formatUrlForNotListing(resource?: Partial, query?: Partial): string;
-
- formatUrlForNotListing({ name, namespace }: Partial = {}, query?: Partial) {
- const resourcePath = createKubeApiURL({
+ formatUrlForNotListing({ name, namespace }: Partial = {}) {
+ return createKubeApiURL({
apiPrefix: this.apiPrefix,
apiVersion: this.apiVersionWithGroup,
resource: this.apiResource,
@@ -431,15 +432,17 @@ export class KubeApi<
: undefined,
name,
});
-
- return resourcePath + (query ? `?${stringify(this.normalizeQuery(query))}` : "");
}
/**
- * @deprecated use {@link formatUrlForNotListing} instead
+ * @deprecated use {@link formatUrlForNotListing} or {@link formatUrlForListing} instead
*/
getUrl(resource?: Partial, query?: Partial) {
- return this.formatUrlForNotListing(resource, query);
+ if (query) {
+ return this.formatUrlForListing(resource?.namespace, query);
+ }
+
+ return this.formatUrlForNotListing(resource);
}
protected normalizeQuery(query: Partial = {}) {
@@ -625,14 +628,14 @@ export class KubeApi<
}
getWatchUrl(namespace?: string, query: KubeApiQueryParams = {}) {
- return this.formatUrlForNotListing({ namespace }, {
+ return this.formatUrlForListing(namespace, {
watch: 1,
resourceVersion: this.getResourceVersion(namespace),
...query,
});
}
- watch(opts?: KubeApiWatchOptions): () => void {
+ watch(opts?: KubeApiWatchOptions): Disposer {
let errorReceived = false;
let timedRetry: NodeJS.Timeout;
const {
diff --git a/src/common/k8s-api/kube-object.store.ts b/src/common/k8s-api/kube-object.store.ts
index 309c183e42..9e7c541b58 100644
--- a/src/common/k8s-api/kube-object.store.ts
+++ b/src/common/k8s-api/kube-object.store.ts
@@ -3,11 +3,9 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
-import type { ClusterContext } from "./cluster-context";
-
-import { action, computed, makeObservable, observable, reaction, when } from "mobx";
+import { action, computed, makeObservable, observable, reaction } from "mobx";
import type { Disposer } from "../utils";
-import { waitUntilDefined, autoBind, includes, noop, rejectPromiseBy } from "../utils";
+import { waitUntilDefined, autoBind, includes, rejectPromiseBy } from "../utils";
import type { KubeJsonApiDataFor, KubeObject } from "./kube-object";
import { KubeStatus } from "./kube-object";
import type { IKubeWatchEvent } from "./kube-watch-event";
@@ -21,6 +19,7 @@ import assert from "assert";
import type { PartialDeep } from "type-fest";
import { entries } from "../utils/objects";
import AbortController from "abort-controller";
+import type { ClusterContext } from "../../renderer/cluster-frame-context/cluster-frame-context";
export type OnLoadFailure = (error: unknown) => void;
@@ -85,38 +84,26 @@ export type KubeApiDataFrom = A extends KubeApi = KubeApi>,
D extends KubeJsonApiDataFor = KubeApiDataFrom,
> extends ItemStore {
- static readonly defaultContext = observable.box(); // TODO: support multiple cluster contexts
-
- public readonly api!: A;
public readonly limit: number | undefined;
public readonly bufferSize: number;
- @observable private loadedNamespaces: string[] | undefined = undefined;
- get contextReady() {
- return when(() => Boolean(this.context));
- }
+ private readonly loadedNamespaces = observable.box();
- get namespacesReady() {
- return when(() => Boolean(this.loadedNamespaces));
- }
-
- constructor(api: A, opts?: KubeObjectStoreOptions);
- /**
- * @deprecated Supply API instance through constructor
- */
- constructor();
- constructor(api?: A, opts?: KubeObjectStoreOptions) {
+ constructor(
+ protected readonly dependencies: KubeObjectStoreDependencies,
+ public readonly api: A,
+ opts?: KubeObjectStoreOptions,
+ ) {
super();
-
- if (api) {
- this.api = api;
- }
-
this.limit = opts?.limit;
this.bufferSize = opts?.bufferSize ?? 50_000;
@@ -125,13 +112,9 @@ export abstract class KubeObjectStore<
this.bindWatchEventsUpdater();
}
- get context(): ClusterContext | undefined {
- return KubeObjectStore.defaultContext.get();
- }
-
// TODO: Circular dependency: KubeObjectStore -> ClusterFrameContext -> NamespaceStore -> KubeObjectStore
@computed get contextItems(): K[] {
- const namespaces = this.context?.contextNamespaces ?? [];
+ const namespaces = this.dependencies.context.contextNamespaces;
return this.items.filter(item => {
const itemNamespace = item.getNs();
@@ -202,17 +185,11 @@ export abstract class KubeObjectStore<
}
protected async loadItems({ namespaces, reqInit, onLoadFailure }: KubeObjectStoreLoadingParams): Promise {
- if (!this.context?.cluster?.isAllowedResource(this.api.kind)) {
- return [];
- }
-
- const isLoadingAll = this.context.allNamespaces?.length > 1
- && this.context.cluster.accessibleNamespaces.length === 0
- && this.context.allNamespaces.every(ns => namespaces.includes(ns));
+ const isLoadingAll = this.dependencies.context.isLoadingAll(namespaces);
if (!this.api.isNamespaced || isLoadingAll) {
if (this.api.isNamespaced) {
- this.loadedNamespaces = [];
+ this.loadedNamespaces.set([]);
}
const res = this.api.list({ reqInit }, this.query);
@@ -234,7 +211,7 @@ export abstract class KubeObjectStore<
return await res ?? [];
}
- this.loadedNamespaces = namespaces;
+ this.loadedNamespaces.set(namespaces);
const results = await Promise.allSettled(
namespaces.map(namespace => this.api.list({ namespace, reqInit }, this.query)),
@@ -266,9 +243,7 @@ export abstract class KubeObjectStore<
@action
async loadAll({ namespaces, merge = true, reqInit, onLoadFailure }: KubeObjectStoreLoadAllParams = {}): Promise {
- const context = await waitUntilDefined(() => this.context);
-
- namespaces ??= context.contextNamespaces;
+ namespaces ??= this.dependencies.context.contextNamespaces;
this.isLoading = true;
try {
@@ -425,7 +400,7 @@ export abstract class KubeObjectStore<
}
// collect items from watch-api events to avoid UI blowing up with huge streams of data
- protected eventsBuffer = observable.array>([], { deep: false });
+ protected readonly eventsBuffer = observable.array>([], { deep: false });
protected bindWatchEventsUpdater(delay = 1000) {
reaction(() => [...this.eventsBuffer], this.updateFromEventsBuffer, {
@@ -435,25 +410,24 @@ export abstract class KubeObjectStore<
subscribe({ onLoadFailure, abortController = new AbortController() }: KubeObjectStoreSubscribeParams = {}): Disposer {
if (this.api.isNamespaced) {
- Promise.race([
- rejectPromiseBy(abortController.signal),
- Promise.all([
- waitUntilDefined(() => this.context),
- this.namespacesReady,
- ] as const),
- ])
- .then(([context]) => {
- assert(this.loadedNamespaces);
+ void (async () => {
+ try {
+ const loadedNamespaces = await Promise.race([
+ rejectPromiseBy(abortController.signal),
+ waitUntilDefined(() => this.loadedNamespaces.get()),
+ ]);
- if (context.cluster?.isGlobalWatchEnabled && this.loadedNamespaces.length === 0) {
- return this.watchNamespace("", abortController, { onLoadFailure });
+ if (this.dependencies.context.isGlobalWatchEnabled() && loadedNamespaces.length === 0) {
+ this.watchNamespace("", abortController, { onLoadFailure });
+ } else {
+ for (const namespace of loadedNamespaces) {
+ this.watchNamespace(namespace, abortController, { onLoadFailure });
+ }
}
-
- for (const namespace of this.loadedNamespaces) {
- this.watchNamespace(namespace, abortController, { onLoadFailure });
- }
- })
- .catch(noop); // ignore DOMExceptions
+ } catch (error) {
+ console.error(`[KUBE-OBJECT-STORE]: failed to subscribe to ${this.api.apiBase}`, error);
+ }
+ })();
} else {
this.watchNamespace("", abortController, { onLoadFailure });
}
@@ -467,7 +441,7 @@ export abstract class KubeObjectStore<
}
let timedRetry: NodeJS.Timeout;
- const watch = () => this.api.watch({
+ const startNewWatch = () => this.api.watch({
namespace,
abortController,
callback,
@@ -486,7 +460,7 @@ export abstract class KubeObjectStore<
// not sure what to do, best to retry
clearTimeout(timedRetry);
- timedRetry = setTimeout(watch, 5000);
+ timedRetry = setTimeout(startNewWatch, 5000);
} else if (error instanceof KubeStatus && error.code === 410) {
clearTimeout(timedRetry);
// resourceVersion has gone, let's try to reload
@@ -495,11 +469,11 @@ export abstract class KubeObjectStore<
namespace
? this.loadAll({ namespaces: [namespace], reqInit: { signal }, ...opts })
: this.loadAll({ merge: false, reqInit: { signal }, ...opts })
- ).then(watch);
+ ).then(startNewWatch);
}, 1000);
} else if (error) { // not sure what to do, best to retry
clearTimeout(timedRetry);
- timedRetry = setTimeout(watch, 5000);
+ timedRetry = setTimeout(startNewWatch, 5000);
}
if (data) {
@@ -508,7 +482,7 @@ export abstract class KubeObjectStore<
};
signal.addEventListener("abort", () => clearTimeout(timedRetry));
- watch();
+ startNewWatch();
}
@action
diff --git a/src/common/k8s-api/kube-object.ts b/src/common/k8s-api/kube-object.ts
index 24e34eff4b..53bc6defdf 100644
--- a/src/common/k8s-api/kube-object.ts
+++ b/src/common/k8s-api/kube-object.ts
@@ -645,8 +645,13 @@ export class KubeObject<
}
const requestKubeObjectPatch = asLegacyGlobalFunctionForExtensionApi(requestKubeObjectPatchInjectable);
+ const result = await requestKubeObjectPatch(this.getName(), this.kind, this.getNs(), patch);
- return requestKubeObjectPatch(this.getName(), this.kind, this.getNs(), patch);
+ if (!result.callWasSuccessful) {
+ throw new Error(result.error);
+ }
+
+ return result.response;
}
/**
@@ -665,7 +670,13 @@ export class KubeObject<
...data,
});
- return requestKubeObjectCreation(descriptor);
+ const result = await requestKubeObjectCreation(descriptor);
+
+ if (!result.callWasSuccessful) {
+ throw new Error(result.error);
+ }
+
+ return result.response;
}
/**
diff --git a/src/common/logger.injectable.ts b/src/common/logger.injectable.ts
index e1a085f199..8e9dd2a6a7 100644
--- a/src/common/logger.injectable.ts
+++ b/src/common/logger.injectable.ts
@@ -9,13 +9,23 @@ import { loggerTransportInjectionToken } from "./logger/transports";
const loggerInjectable = getInjectable({
id: "logger",
- instantiate: (di): Logger => createLogger({
- format: format.combine(
- format.splat(),
- format.simple(),
- ),
- transports: di.injectMany(loggerTransportInjectionToken),
- }),
+ instantiate: (di): Logger => {
+ const baseLogger = createLogger({
+ format: format.combine(
+ format.splat(),
+ format.simple(),
+ ),
+ transports: di.injectMany(loggerTransportInjectionToken),
+ });
+
+ return {
+ debug: (message, ...data) => baseLogger.debug(message, ...data),
+ info: (message, ...data) => baseLogger.info(message, ...data),
+ warn: (message, ...data) => baseLogger.warn(message, ...data),
+ error: (message, ...data) => baseLogger.error(message, ...data),
+ silly: (message, ...data) => baseLogger.silly(message, ...data),
+ };
+ },
});
export default loggerInjectable;
diff --git a/src/common/logger.ts b/src/common/logger.ts
index 948404a6b9..0b460a48ff 100644
--- a/src/common/logger.ts
+++ b/src/common/logger.ts
@@ -17,4 +17,6 @@ export interface Logger {
/**
* @deprecated use `di.inject(loggerInjectable)` instead
*/
-export default asLegacyGlobalForExtensionApi(loggerInjectable);
+const logger = asLegacyGlobalForExtensionApi(loggerInjectable);
+
+export default logger;
diff --git a/src/common/rbac.ts b/src/common/rbac.ts
index bfa04ef46b..99e564a377 100644
--- a/src/common/rbac.ts
+++ b/src/common/rbac.ts
@@ -11,51 +11,190 @@ export type KubeResource =
"priorityclasses" | "runtimeclasses" |
"roles" | "clusterroles" | "rolebindings" | "clusterrolebindings" | "serviceaccounts";
-export interface KubeApiResource extends KubeApiResourceData {
- apiName: KubeResource; // valid api resource name (e.g. "namespaces")
+export interface KubeApiResource {
+ kind: string;
+ group: string;
+ apiName: string;
+ namespaced: boolean;
}
+export interface KubeApiResourceDescriptor {
+ apiName: string;
+ group: string;
+}
+
+export const formatKubeApiResource = (res: KubeApiResourceDescriptor) => `${res.group}/${res.apiName}`;
+
export interface KubeApiResourceData {
kind: string; // resource type (e.g. "Namespace")
- group?: string; // api-group
+ group: string; // api-group, if empty then "core"
+ namespaced: boolean;
}
export const apiResourceRecord: Record = {
- "clusterroles": { kind: "ClusterRole", group: "rbac.authorization.k8s.io" },
- "clusterrolebindings": { kind: "ClusterRoleBinding", group: "rbac.authorization.k8s.io" },
- "configmaps": { kind: "ConfigMap" }, //empty group means "core"
- "cronjobs": { kind: "CronJob", group: "batch" },
- "customresourcedefinitions": { kind: "CustomResourceDefinition", group: "apiextensions.k8s.io" },
- "daemonsets": { kind: "DaemonSet", group: "apps" },
- "deployments": { kind: "Deployment", group: "apps" },
- "endpoints": { kind: "Endpoint" },
- "events": { kind: "Event" },
- "horizontalpodautoscalers": { kind: "HorizontalPodAutoscaler", group: "autoscaling" },
- "ingresses": { kind: "Ingress", group: "networking.k8s.io" },
- "jobs": { kind: "Job", group: "batch" },
- "namespaces": { kind: "Namespace" },
- "limitranges": { kind: "LimitRange" },
- "leases": { kind: "Lease" },
- "networkpolicies": { kind: "NetworkPolicy", group: "networking.k8s.io" },
- "nodes": { kind: "Node" },
- "persistentvolumes": { kind: "PersistentVolume" },
- "persistentvolumeclaims": { kind: "PersistentVolumeClaim" },
- "pods": { kind: "Pod" },
- "poddisruptionbudgets": { kind: "PodDisruptionBudget", group: "policy" },
- "podsecuritypolicies": { kind: "PodSecurityPolicy", group: "policy" },
- "priorityclasses": { kind: "PriorityClass", group: "scheduling.k8s.io" },
- "runtimeclasses": { kind: "RuntimeClass", group: "node.k8s.io" },
- "resourcequotas": { kind: "ResourceQuota" },
- "replicasets": { kind: "ReplicaSet", group: "apps" },
- "roles": { kind: "Role", group: "rbac.authorization.k8s.io" },
- "rolebindings": { kind: "RoleBinding", group: "rbac.authorization.k8s.io" },
- "secrets": { kind: "Secret" },
- "serviceaccounts": { kind: "ServiceAccount" },
- "services": { kind: "Service" },
- "statefulsets": { kind: "StatefulSet", group: "apps" },
- "storageclasses": { kind: "StorageClass", group: "storage.k8s.io" },
+ clusterroles: {
+ kind: "ClusterRole",
+ group: "rbac.authorization.k8s.io",
+ namespaced: false,
+ },
+ clusterrolebindings: {
+ kind: "ClusterRoleBinding",
+ group: "rbac.authorization.k8s.io",
+ namespaced: false,
+ },
+ configmaps: {
+ kind: "ConfigMap",
+ group: "v1",
+ namespaced: true,
+ },
+ cronjobs: {
+ kind: "CronJob",
+ group: "batch",
+ namespaced: true,
+ },
+ customresourcedefinitions: {
+ kind: "CustomResourceDefinition",
+ group: "apiextensions.k8s.io",
+ namespaced: false,
+ },
+ daemonsets: {
+ kind: "DaemonSet",
+ group: "apps",
+ namespaced: true,
+ },
+ deployments: {
+ kind: "Deployment",
+ group: "apps",
+ namespaced: true,
+ },
+ endpoints: {
+ kind: "Endpoint",
+ group: "v1",
+ namespaced: true,
+ },
+ events: {
+ kind: "Event",
+ group: "v1",
+ namespaced: true,
+ },
+ horizontalpodautoscalers: {
+ kind: "HorizontalPodAutoscaler",
+ group: "autoscaling",
+ namespaced: true,
+ },
+ ingresses: {
+ kind: "Ingress",
+ group: "networking.k8s.io",
+ namespaced: true,
+ },
+ jobs: {
+ kind: "Job",
+ group: "batch",
+ namespaced: true,
+ },
+ namespaces: {
+ kind: "Namespace",
+ group: "v1",
+ namespaced: false,
+ },
+ limitranges: {
+ kind: "LimitRange",
+ group: "v1",
+ namespaced: true,
+ },
+ leases: {
+ kind: "Lease",
+ group: "v1",
+ namespaced: true,
+ },
+ networkpolicies: {
+ kind: "NetworkPolicy",
+ group: "networking.k8s.io",
+ namespaced: true,
+ },
+ nodes: {
+ kind: "Node",
+ group: "v1",
+ namespaced: false,
+ },
+ persistentvolumes: {
+ kind: "PersistentVolume",
+ group: "v1",
+ namespaced: false,
+ },
+ persistentvolumeclaims: {
+ kind: "PersistentVolumeClaim",
+ group: "v1",
+ namespaced: true,
+ },
+ pods: {
+ kind: "Pod",
+ group: "v1",
+ namespaced: true,
+ },
+ poddisruptionbudgets: {
+ kind: "PodDisruptionBudget",
+ group: "policy",
+ namespaced: true,
+ },
+ podsecuritypolicies: {
+ kind: "PodSecurityPolicy",
+ group: "policy",
+ namespaced: false,
+ },
+ priorityclasses: {
+ kind: "PriorityClass",
+ group: "scheduling.k8s.io",
+ namespaced: false,
+ },
+ runtimeclasses: {
+ kind: "RuntimeClass",
+ group: "node.k8s.io",
+ namespaced: false,
+ },
+ resourcequotas: {
+ kind: "ResourceQuota",
+ group: "v1",
+ namespaced: true,
+ },
+ replicasets: {
+ kind: "ReplicaSet",
+ group: "apps",
+ namespaced: true,
+ },
+ roles: {
+ kind: "Role",
+ group: "rbac.authorization.k8s.io",
+ namespaced: true,
+ },
+ rolebindings: {
+ kind: "RoleBinding",
+ group: "rbac.authorization.k8s.io",
+ namespaced: true,
+ },
+ secrets: {
+ kind: "Secret",
+ group: "v1",
+ namespaced: true,
+ },
+ serviceaccounts: {
+ kind: "ServiceAccount",
+ group: "v1",
+ namespaced: true,
+ },
+ services: {
+ kind: "Service",
+ group: "v1",
+ namespaced: true,
+ },
+ statefulsets: {
+ kind: "StatefulSet",
+ group: "apps",
+ namespaced: true,
+ },
+ storageclasses: {
+ kind: "StorageClass",
+ group: "storage.k8s.io",
+ namespaced: false,
+ },
};
-
-// TODO: auto-populate all resources dynamically (see: kubectl api-resources -o=wide -v=7)
-export const apiResources: KubeApiResource[] = Object.entries(apiResourceRecord)
- .map(([apiName, data]) => ({ apiName: apiName as KubeResource, ...data }));
diff --git a/src/common/utils/computed-or.ts b/src/common/utils/computed-or.ts
new file mode 100644
index 0000000000..4e93394924
--- /dev/null
+++ b/src/common/utils/computed-or.ts
@@ -0,0 +1,11 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+
+import type { IComputedValue } from "mobx";
+import { computed } from "mobx";
+
+export const computedOr = (...values: IComputedValue[]) => computed((
+ () => values.some(value => value.get())
+));
diff --git a/src/common/utils/is-allowed-resource.injectable.ts b/src/common/utils/is-allowed-resource.injectable.ts
deleted file mode 100644
index 8841a8f0cc..0000000000
--- a/src/common/utils/is-allowed-resource.injectable.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * 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 { computed } from "mobx";
-import type { KubeResource } from "../rbac";
-import { allowedResourcesInjectionToken } from "../cluster-store/allowed-resources-injection-token";
-
-export type IsAllowedResource = (resource: KubeResource) => boolean;
-
-const isAllowedResourceInjectable = getInjectable({
- id: "is-allowed-resource",
-
- instantiate: (di, resourceName: string) => {
- const allowedResources = di.inject(allowedResourcesInjectionToken);
-
- return computed(() => allowedResources.get().has(resourceName));
- },
-
- lifecycle: lifecycleEnum.keyedSingleton({
- getInstanceKey: (di, resource: string) => resource,
- }),
-});
-
-export default isAllowedResourceInjectable;
diff --git a/src/common/utils/wait.ts b/src/common/utils/wait.ts
index 7bcbd1688b..402d556b5d 100644
--- a/src/common/utils/wait.ts
+++ b/src/common/utils/wait.ts
@@ -8,26 +8,23 @@ import type { Disposer } from "./disposer";
export async function waitUntilDefined(getter: (() => T | null | undefined) | IComputedValue, opts?: { timeout?: number }): Promise {
return new Promise((resolve, reject) => {
- let res: T | null | undefined;
-
when(
() => {
- res = typeof getter === "function"
+ const res = typeof getter === "function"
? getter()
: getter.get();
+ const isDefined = res != null;
- if (res != null) {
+ if (isDefined) {
resolve(res);
-
- return true;
}
- return false;
+ return isDefined;
},
() => {},
{
onError: reject,
- ...opts,
+ ...(opts ?? {}),
},
);
});
diff --git a/src/common/vars.ts b/src/common/vars.ts
index cbde12ff5d..d58e0871e6 100644
--- a/src/common/vars.ts
+++ b/src/common/vars.ts
@@ -6,26 +6,6 @@
// App's common configuration for any process (main, renderer, build pipeline, etc.)
import type { ThemeId } from "../renderer/themes/lens-theme";
-/**
- * @deprecated Switch to using isMacInjectable
- */
-export const isMac = process.platform === "darwin";
-
-/**
- * @deprecated Switch to using isWindowsInjectable
- */
-export const isWindows = process.platform === "win32";
-
-/**
- * @deprecated Switch to using isLinuxInjectable
- */
-export const isLinux = process.platform === "linux";
-
-/**
- * @deprecated switch to using `isDebuggingInjectable`
- */
-export const isDebugging = ["true", "1", "yes", "y", "on"].includes((process.env.DEBUG ?? "").toLowerCase());
-
/**
* @deprecated Switch to using isTestEnvInjectable
*/
diff --git a/src/extensions/common-api/k8s-api.ts b/src/extensions/common-api/k8s-api.ts
index e5c7013bc7..9b62af7551 100644
--- a/src/extensions/common-api/k8s-api.ts
+++ b/src/extensions/common-api/k8s-api.ts
@@ -15,6 +15,12 @@ import type { ResourceApplyingStack } from "../../common/k8s/resource-stack";
import { asLegacyGlobalFunctionForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
import type { KubernetesCluster } from "./catalog";
+import type { KubeApiDataFrom, KubeObjectStoreOptions } from "../../common/k8s-api/kube-object.store";
+import { KubeObjectStore as InternalKubeObjectStore } from "../../common/k8s-api/kube-object.store";
+import type { KubeJsonApiDataFor, KubeObject } from "../../common/k8s-api/kube-object";
+import type { KubeApi } from "../../common/k8s-api/kube-api";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../renderer/cluster-frame-context/for-namespaced-resources.injectable";
+import type { ClusterContext } from "../../renderer/cluster-frame-context/cluster-frame-context";
export const apiManager = asLegacyGlobalForExtensionApi(apiManagerInjectable);
export const forCluster = asLegacyGlobalFunctionForExtensionApi(createKubeApiForClusterInjectable);
@@ -72,8 +78,44 @@ export {
type KubeJsonApiData,
} from "../../common/k8s-api/kube-json-api";
+export abstract class KubeObjectStore<
+ K extends KubeObject = KubeObject,
+ A extends KubeApi = KubeApi>,
+ D extends KubeJsonApiDataFor = KubeApiDataFrom,
+> extends InternalKubeObjectStore {
+ /**
+ * @deprecated This is no longer used and shouldn't have been every really used
+ */
+ static readonly context = {
+ set: (ctx: ClusterContext) => {
+ console.warn("Setting KubeObjectStore.context is no longer supported");
+ void ctx;
+ },
+ get: () => asLegacyGlobalForExtensionApi(clusterFrameContextForNamespacedResourcesInjectable),
+ };
+
+ get context() {
+ return this.dependencies.context;
+ }
+
+ constructor(api: A, opts?: KubeObjectStoreOptions);
+ /**
+ * @deprecated Supply API instance through constructor
+ */
+ constructor();
+ constructor(api?: A, opts?: KubeObjectStoreOptions) {
+ super(
+ {
+ context: asLegacyGlobalForExtensionApi(clusterFrameContextForNamespacedResourcesInjectable),
+ },
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ api!,
+ opts,
+ );
+ }
+}
+
export {
- KubeObjectStore,
type JsonPatch,
type KubeObjectStoreLoadAllParams,
type KubeObjectStoreLoadingParams,
diff --git a/src/extensions/renderer-api/k8s-api.ts b/src/extensions/renderer-api/k8s-api.ts
index 3401d979f7..6335559409 100644
--- a/src/extensions/renderer-api/k8s-api.ts
+++ b/src/extensions/renderer-api/k8s-api.ts
@@ -3,8 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { KubeResource } from "../../common/rbac";
-import isAllowedResourceInjectable from "../../common/utils/is-allowed-resource.injectable";
-import { castArray } from "lodash/fp";
+import { apiResourceRecord } from "../../common/rbac";
import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import clusterRoleBindingApiInjectable from "../../common/k8s-api/endpoints/cluster-role-binding.api.injectable";
import clusterRoleApiInjectable from "../../common/k8s-api/endpoints/cluster-role.api.injectable";
@@ -37,13 +36,22 @@ import namespaceApiInjectable from "../../common/k8s-api/endpoints/namespace.api
import kubeEventApiInjectable from "../../common/k8s-api/endpoints/events.api.injectable";
import roleBindingApiInjectable from "../../common/k8s-api/endpoints/role-binding.api.injectable";
import customResourceDefinitionApiInjectable from "../../common/k8s-api/endpoints/custom-resource-definition.api.injectable";
+import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
-export function isAllowedResource(resource: KubeResource | KubeResource[]) {
- const resources = castArray(resource);
+export function isAllowedResource(resources: KubeResource | KubeResource[]) {
const di = getLegacyGlobalDiForExtensionApi();
- return resources.every((resourceName: any) => {
- const _isAllowedResource = di.inject(isAllowedResourceInjectable, resourceName);
+ return [resources].flat().every((resourceName) => {
+ const resource = apiResourceRecord[resourceName];
+
+ if (!resource) {
+ return true;
+ }
+
+ const _isAllowedResource = di.inject(shouldShowResourceInjectionToken, {
+ apiName: resourceName,
+ group: resource.group,
+ });
// Note: Legacy isAllowedResource does not advertise reactivity
return _isAllowedResource.get();
diff --git a/src/features/catalog/opening-entity-details.test.tsx b/src/features/catalog/opening-entity-details.test.tsx
index 2d548697ed..8ae49ff548 100644
--- a/src/features/catalog/opening-entity-details.test.tsx
+++ b/src/features/catalog/opening-entity-details.test.tsx
@@ -10,8 +10,8 @@ import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injec
import type { Cluster } from "../../common/cluster/cluster";
import navigateToCatalogInjectable from "../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
import catalogEntityRegistryInjectable from "../../renderer/api/catalog/entity/registry.injectable";
+import createClusterInjectable from "../../renderer/cluster/create-cluster.injectable";
import { type ApplicationBuilder, getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
-import createClusterInjectable from "../../renderer/create-cluster/create-cluster.injectable";
describe("opening catalog entity details panel", () => {
let builder: ApplicationBuilder;
diff --git a/src/features/cluster/delete-dialog/delete-cluster-dialog.test.tsx b/src/features/cluster/delete-dialog/delete-cluster-dialog.test.tsx
index c96f2714e1..5c527edbb4 100644
--- a/src/features/cluster/delete-dialog/delete-cluster-dialog.test.tsx
+++ b/src/features/cluster/delete-dialog/delete-cluster-dialog.test.tsx
@@ -14,7 +14,6 @@ import kubectlBinaryNameInjectable from "../../../main/kubectl/binary-name.injec
import kubectlDownloadingNormalizedArchInjectable from "../../../main/kubectl/normalized-arch.injectable";
import openDeleteClusterDialogInjectable, { type OpenDeleteClusterDialog } from "../../../renderer/components/delete-cluster-dialog/open.injectable";
import { type ApplicationBuilder, getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
-import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
import type { Cluster } from "../../../common/cluster/cluster";
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
@@ -90,7 +89,6 @@ describe("Deleting a cluster", () => {
});
builder.beforeWindowStart((windowDi) => {
- windowDi.override(storesAndApisCanBeCreatedInjectable, () => true);
openDeleteClusterDialog = windowDi.inject(openDeleteClusterDialogInjectable);
});
diff --git a/src/features/cluster/namespaces/edit-namespace-from-new-tab.test.tsx b/src/features/cluster/namespaces/edit-namespace-from-new-tab.test.tsx
index efe0cdf554..f37ada1736 100644
--- a/src/features/cluster/namespaces/edit-namespace-from-new-tab.test.tsx
+++ b/src/features/cluster/namespaces/edit-namespace-from-new-tab.test.tsx
@@ -98,7 +98,10 @@ describe("cluster/namespaces - edit namespace from new tab", () => {
});
});
- builder.allowKubeResource("namespaces");
+ builder.allowKubeResource({
+ apiName: "namespaces",
+ group: "v1",
+ });
});
describe("when navigating to namespaces", () => {
diff --git a/src/features/cluster/namespaces/edit-namespace-from-previously-opened-tab.test.tsx b/src/features/cluster/namespaces/edit-namespace-from-previously-opened-tab.test.tsx
index a5f834563b..4cf63ee353 100644
--- a/src/features/cluster/namespaces/edit-namespace-from-previously-opened-tab.test.tsx
+++ b/src/features/cluster/namespaces/edit-namespace-from-previously-opened-tab.test.tsx
@@ -42,7 +42,10 @@ describe("cluster/namespaces - edit namespaces from previously opened tab", () =
windowDi.override(callForResourceInjectable, () => callForNamespaceMock);
});
- builder.allowKubeResource("namespaces");
+ builder.allowKubeResource({
+ apiName: "namespaces",
+ group: "v1",
+ });
});
describe("given tab was previously opened, when application is started", () => {
diff --git a/src/features/cluster/state-sync/renderer/setup-sync.injectable.ts b/src/features/cluster/state-sync/renderer/setup-sync.injectable.ts
index 93005543db..e4df4c7f8e 100644
--- a/src/features/cluster/state-sync/renderer/setup-sync.injectable.ts
+++ b/src/features/cluster/state-sync/renderer/setup-sync.injectable.ts
@@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable";
-import { beforeFrameStartsInjectionToken } from "../../../../renderer/before-frame-starts/tokens";
+import { beforeFrameStartsSecondInjectionToken } from "../../../../renderer/before-frame-starts/tokens";
import initClusterStoreInjectable from "../../store/renderer/init.injectable";
import requestInitialClusterStatesInjectable from "./request-initial.injectable";
@@ -23,7 +23,7 @@ const setupClusterStateSyncInjectable = getInjectable({
},
runAfter: di.inject(initClusterStoreInjectable),
}),
- injectionToken: beforeFrameStartsInjectionToken,
+ injectionToken: beforeFrameStartsSecondInjectionToken,
});
export default setupClusterStateSyncInjectable;
diff --git a/src/features/cluster/store/renderer/init.injectable.ts b/src/features/cluster/store/renderer/init.injectable.ts
index 2c2795de5c..66d2e31e09 100644
--- a/src/features/cluster/store/renderer/init.injectable.ts
+++ b/src/features/cluster/store/renderer/init.injectable.ts
@@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable";
-import { beforeFrameStartsInjectionToken } from "../../../../renderer/before-frame-starts/tokens";
+import { beforeFrameStartsSecondInjectionToken } from "../../../../renderer/before-frame-starts/tokens";
import initUserStoreInjectable from "../../../../renderer/stores/init-user-store.injectable";
const initClusterStoreInjectable = getInjectable({
@@ -18,7 +18,7 @@ const initClusterStoreInjectable = getInjectable({
},
runAfter: di.inject(initUserStoreInjectable),
}),
- injectionToken: beforeFrameStartsInjectionToken,
+ injectionToken: beforeFrameStartsSecondInjectionToken,
});
export default initClusterStoreInjectable;
diff --git a/src/features/cluster/visibility-of-sidebar-items.test.tsx b/src/features/cluster/visibility-of-sidebar-items.test.tsx
index 0e09f0efa8..2eb42b7fdf 100644
--- a/src/features/cluster/visibility-of-sidebar-items.test.tsx
+++ b/src/features/cluster/visibility-of-sidebar-items.test.tsx
@@ -9,11 +9,11 @@ import { sidebarItemsInjectionToken } from "../../renderer/components/layout/sid
import { computed, runInAction } from "mobx";
import { routeSpecificComponentInjectionToken } from "../../renderer/routes/route-specific-component-injection-token";
import React from "react";
-import isAllowedResourceInjectable from "../../common/utils/is-allowed-resource.injectable";
import { frontEndRouteInjectionToken } from "../../common/front-end-routing/front-end-route-injection-token";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { navigateToRouteInjectionToken } from "../../common/front-end-routing/navigate-to-route-injection-token";
+import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
describe("cluster - visibility of sidebar items", () => {
let builder: ApplicationBuilder;
@@ -50,7 +50,10 @@ describe("cluster - visibility of sidebar items", () => {
describe("when kube resource becomes allowed", () => {
beforeEach(() => {
- builder.allowKubeResource("namespaces");
+ builder.allowKubeResource({
+ apiName: "namespaces",
+ group: "v1",
+ });
});
it("renders", () => {
@@ -69,20 +72,14 @@ describe("cluster - visibility of sidebar items", () => {
const testRouteInjectable = getInjectable({
id: "some-route-injectable-id",
- instantiate: (di) => {
- const someKubeResourceName = "namespaces";
-
- const kubeResourceIsAllowed = di.inject(
- isAllowedResourceInjectable,
- someKubeResourceName,
- );
-
- return {
- path: "/some-child-page",
- isEnabled: kubeResourceIsAllowed,
- clusterFrame: true,
- };
- },
+ instantiate: (di) => ({
+ path: "/some-child-page",
+ clusterFrame: true,
+ isEnabled: di.inject(shouldShowResourceInjectionToken, {
+ apiName: "namespaces",
+ group: "v1",
+ }),
+ }),
injectionToken: frontEndRouteInjectionToken,
});
diff --git a/src/features/cluster/workload-overview.test.tsx b/src/features/cluster/workload-overview.test.tsx
index 1a6750a8f9..205c837b47 100644
--- a/src/features/cluster/workload-overview.test.tsx
+++ b/src/features/cluster/workload-overview.test.tsx
@@ -13,7 +13,10 @@ describe("workload overview", () => {
beforeEach(async () => {
applicationBuilder = getApplicationBuilder().setEnvironmentToClusterFrame();
- applicationBuilder.allowKubeResource("pods");
+ applicationBuilder.allowKubeResource({
+ apiName: "pods",
+ group: "v1",
+ });
rendered = await applicationBuilder.render();
});
diff --git a/src/features/entity-settings/showing-settings-for-correct-entity.test.tsx b/src/features/entity-settings/showing-settings-for-correct-entity.test.tsx
index 306582a188..36844cb3af 100644
--- a/src/features/entity-settings/showing-settings-for-correct-entity.test.tsx
+++ b/src/features/entity-settings/showing-settings-for-correct-entity.test.tsx
@@ -11,7 +11,7 @@ import type { Cluster } from "../../common/cluster/cluster";
import navigateToEntitySettingsInjectable from "../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
import catalogEntityRegistryInjectable from "../../renderer/api/catalog/entity/registry.injectable";
import { type ApplicationBuilder, getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
-import createClusterInjectable from "../../renderer/create-cluster/create-cluster.injectable";
+import createClusterInjectable from "../../renderer/cluster/create-cluster.injectable";
describe("Showing correct entity settings", () => {
let builder: ApplicationBuilder;
diff --git a/src/features/file-system-provisioner/renderer/init-store.injectable.ts b/src/features/file-system-provisioner/renderer/init-store.injectable.ts
index d241dcad38..0e64e49fd6 100644
--- a/src/features/file-system-provisioner/renderer/init-store.injectable.ts
+++ b/src/features/file-system-provisioner/renderer/init-store.injectable.ts
@@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import fileSystemProvisionerStoreInjectable from "../../../extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable";
-import { beforeFrameStartsInjectionToken } from "../../../renderer/before-frame-starts/tokens";
+import { beforeFrameStartsSecondInjectionToken } from "../../../renderer/before-frame-starts/tokens";
const initFileSystemProvisionerStoreInjectable = getInjectable({
id: "init-file-system-provisioner-store",
@@ -16,7 +16,7 @@ const initFileSystemProvisionerStoreInjectable = getInjectable({
store.load();
},
}),
- injectionToken: beforeFrameStartsInjectionToken,
+ injectionToken: beforeFrameStartsSecondInjectionToken,
});
export default initFileSystemProvisionerStoreInjectable;
diff --git a/src/features/hotbar/store/renderer/init.injectable.ts b/src/features/hotbar/store/renderer/init.injectable.ts
index 6d341f1ee8..c17e3a4858 100644
--- a/src/features/hotbar/store/renderer/init.injectable.ts
+++ b/src/features/hotbar/store/renderer/init.injectable.ts
@@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
-import { beforeFrameStartsInjectionToken } from "../../../../renderer/before-frame-starts/tokens";
+import { beforeFrameStartsSecondInjectionToken } from "../../../../renderer/before-frame-starts/tokens";
import initClusterStoreInjectable from "../../../cluster/store/renderer/init.injectable";
const initHotbarStoreInjectable = getInjectable({
@@ -18,7 +18,7 @@ const initHotbarStoreInjectable = getInjectable({
},
runAfter: di.inject(initClusterStoreInjectable),
}),
- injectionToken: beforeFrameStartsInjectionToken,
+ injectionToken: beforeFrameStartsSecondInjectionToken,
});
export default initHotbarStoreInjectable;
diff --git a/src/features/theme/system-type/renderer/initialize.injectable.ts b/src/features/theme/system-type/renderer/initialize.injectable.ts
index e6ed81f4f1..849c8328b2 100644
--- a/src/features/theme/system-type/renderer/initialize.injectable.ts
+++ b/src/features/theme/system-type/renderer/initialize.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 "../../../../renderer/before-frame-starts/tokens";
+import { beforeFrameStartsSecondInjectionToken } from "../../../../renderer/before-frame-starts/tokens";
import initUserStoreInjectable from "../../../../renderer/stores/init-user-store.injectable";
import systemThemeConfigurationInjectable from "../../../../renderer/themes/system-theme.injectable";
import requestInitialSystemThemeTypeInjectable from "./request-initial.injectable";
@@ -20,7 +20,7 @@ const initializeSystemThemeTypeInjectable = getInjectable({
},
runAfter: di.inject(initUserStoreInjectable),
}),
- injectionToken: beforeFrameStartsInjectionToken,
+ injectionToken: beforeFrameStartsSecondInjectionToken,
});
export default initializeSystemThemeTypeInjectable;
diff --git a/src/jest.setup.ts b/src/jest.setup.ts
index b0acfba878..1e7d0a8ce3 100644
--- a/src/jest.setup.ts
+++ b/src/jest.setup.ts
@@ -3,22 +3,23 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
-import configurePackages from "./common/configure-packages";
import { configure } from "mobx";
import { setImmediate } from "timers";
import { TextEncoder, TextDecoder as TextDecoderNode } from "util";
import glob from "glob";
import path from "path";
-
-// setup default configuration for external npm-packages
-configurePackages();
+import { enableMapSet, setAutoFreeze } from "immer";
configure({
// Needed because we want to use jest.spyOn()
// ref https://github.com/mobxjs/mobx/issues/2784
safeDescriptors: false,
+ enforceActions: "never",
});
+setAutoFreeze(false); // allow to merge mobx observables
+enableMapSet(); // allow to merge maps and sets
+
// Mock __non_webpack_require__ for tests
globalThis.__non_webpack_require__ = jest.fn();
diff --git a/src/main/__test__/cluster.test.ts b/src/main/__test__/cluster.test.ts
index 4a9b257623..d9e48fb3d9 100644
--- a/src/main/__test__/cluster.test.ts
+++ b/src/main/__test__/cluster.test.ts
@@ -10,7 +10,7 @@ import { getDiForUnitTesting } from "../getDiForUnitTesting";
import type { CreateCluster } from "../../common/cluster/create-cluster-injection-token";
import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
import authorizationReviewInjectable from "../../common/cluster/authorization-review.injectable";
-import authorizationNamespaceReviewInjectable from "../../common/cluster/authorization-namespace-review.injectable";
+import requestNamespaceListPermissionsForInjectable from "../../common/cluster/request-namespace-list-permissions.injectable";
import listNamespacesInjectable from "../../common/cluster/list-namespaces.injectable";
import createContextHandlerInjectable from "../context-handler/create-context-handler.injectable";
import type { ClusterContextHandler } from "../context-handler/context-handler";
@@ -20,8 +20,6 @@ import directoryForTempInjectable from "../../common/app-paths/directory-for-tem
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
import kubectlBinaryNameInjectable from "../kubectl/binary-name.injectable";
import kubectlDownloadingNormalizedArchInjectable from "../kubectl/normalized-arch.injectable";
-import { apiResourceRecord, apiResources } from "../../common/rbac";
-import listApiResourcesInjectable from "../../common/cluster/list-api-resources.injectable";
import pathExistsSyncInjectable from "../../common/fs/path-exists-sync.injectable";
import pathExistsInjectable from "../../common/fs/path-exists.injectable";
import readJsonSyncInjectable from "../../common/fs/read-json-sync.injectable";
@@ -46,8 +44,7 @@ describe("create clusters", () => {
di.override(normalizedPlatformInjectable, () => "darwin");
di.override(broadcastMessageInjectable, () => async () => {});
di.override(authorizationReviewInjectable, () => () => () => Promise.resolve(true));
- di.override(authorizationNamespaceReviewInjectable, () => () => () => Promise.resolve(Object.keys(apiResourceRecord)));
- di.override(listApiResourcesInjectable, () => () => () => Promise.resolve(apiResources));
+ di.override(requestNamespaceListPermissionsForInjectable, () => () => async () => () => true);
di.override(listNamespacesInjectable, () => () => () => Promise.resolve([ "default" ]));
di.override(createContextHandlerInjectable, () => (cluster) => ({
restartServer: jest.fn(),
diff --git a/src/main/cluster/manager.ts b/src/main/cluster/manager.ts
index d5c06c0619..83270941d4 100644
--- a/src/main/cluster/manager.ts
+++ b/src/main/cluster/manager.ts
@@ -210,7 +210,7 @@ export class ClusterManager {
cluster.contextName = entity.spec.kubeconfigContext;
if (entity.spec.accessibleNamespaces) {
- cluster.accessibleNamespaces = entity.spec.accessibleNamespaces;
+ cluster.accessibleNamespaces.replace(entity.spec.accessibleNamespaces);
}
if (entity.spec.metrics) {
diff --git a/src/main/create-cluster/allowed-resources.injectable.ts b/src/main/create-cluster/allowed-resources.injectable.ts
index d614ca3d17..09beae9fd2 100644
--- a/src/main/create-cluster/allowed-resources.injectable.ts
+++ b/src/main/create-cluster/allowed-resources.injectable.ts
@@ -2,15 +2,20 @@
* 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 { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
import { computed } from "mobx";
-import { allowedResourcesInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
+import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
+import type { KubeApiResourceDescriptor } from "../../common/rbac";
+import { formatKubeApiResource } from "../../common/rbac";
// TODO: Figure out implementation for this later.
const allowedResourcesInjectable = getInjectable({
id: "allowed-resources",
- instantiate: () => computed(() => new Set()),
- injectionToken: allowedResourcesInjectionToken,
+ instantiate: () => computed(() => false),
+ injectionToken: shouldShowResourceInjectionToken,
+ lifecycle: lifecycleEnum.keyedSingleton({
+ getInstanceKey: (di, resource: KubeApiResourceDescriptor) => formatKubeApiResource(resource),
+ }),
});
export default allowedResourcesInjectable;
diff --git a/src/main/create-cluster/create-cluster.injectable.ts b/src/main/create-cluster/create-cluster.injectable.ts
index e1782ec6c9..f5b302300c 100644
--- a/src/main/create-cluster/create-cluster.injectable.ts
+++ b/src/main/create-cluster/create-cluster.injectable.ts
@@ -11,14 +11,14 @@ import createKubectlInjectable from "../kubectl/create-kubectl.injectable";
import createContextHandlerInjectable from "../context-handler/create-context-handler.injectable";
import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
import authorizationReviewInjectable from "../../common/cluster/authorization-review.injectable";
-import createAuthorizationNamespaceReview from "../../common/cluster/authorization-namespace-review.injectable";
import listNamespacesInjectable from "../../common/cluster/list-namespaces.injectable";
-import createListApiResourcesInjectable from "../../common/cluster/list-api-resources.injectable";
+import createListApiResourcesInjectable from "../../common/cluster/request-api-resources.injectable";
import loggerInjectable from "../../common/logger.injectable";
import detectorRegistryInjectable from "../cluster-detectors/detector-registry.injectable";
import createVersionDetectorInjectable from "../cluster-detectors/create-version-detector.injectable";
import broadcastMessageInjectable from "../../common/ipc/broadcast-message.injectable";
import loadConfigfromFileInjectable from "../../common/kube-helpers/load-config-from-file.injectable";
+import requestNamespaceListPermissionsForInjectable from "../../common/cluster/request-namespace-list-permissions.injectable";
const createClusterInjectable = getInjectable({
id: "create-cluster",
@@ -30,8 +30,8 @@ const createClusterInjectable = getInjectable({
createKubectl: di.inject(createKubectlInjectable),
createContextHandler: di.inject(createContextHandlerInjectable),
createAuthorizationReview: di.inject(authorizationReviewInjectable),
- createAuthorizationNamespaceReview: di.inject(createAuthorizationNamespaceReview),
- createListApiResources: di.inject(createListApiResourcesInjectable),
+ requestNamespaceListPermissionsFor: di.inject(requestNamespaceListPermissionsForInjectable),
+ requestApiResources: di.inject(createListApiResourcesInjectable),
createListNamespaces: di.inject(listNamespacesInjectable),
logger: di.inject(loggerInjectable),
detectorRegistry: di.inject(detectorRegistryInjectable),
diff --git a/src/main/start-main-application/lens-window/application-window/create-lens-window.injectable.ts b/src/main/start-main-application/lens-window/application-window/create-lens-window.injectable.ts
index 9d760a8bc2..d2d8f344eb 100644
--- a/src/main/start-main-application/lens-window/application-window/create-lens-window.injectable.ts
+++ b/src/main/start-main-application/lens-window/application-window/create-lens-window.injectable.ts
@@ -5,7 +5,6 @@
import { getInjectable } from "@ogre-tools/injectable";
import type { ContentSource, ElectronWindowTitleBarStyle } from "./create-electron-window.injectable";
import createElectronWindowForInjectable from "./create-electron-window.injectable";
-import assert from "assert";
import type { ClusterFrameInfo } from "../../../../common/cluster-frames";
export interface ElectronWindow {
@@ -69,7 +68,9 @@ const createLensWindowInjectable = getInjectable({
let windowIsStarting = false;
const showWindow = () => {
- assert(browserWindow);
+ if (!browserWindow) {
+ throw new Error("Cannot show browserWindow, does not exist");
+ }
browserWindow.show();
windowIsShown = true;
diff --git a/src/renderer/before-frame-starts/runnables/load-monaco-themes.injectable.ts b/src/renderer/before-frame-starts/runnables/load-monaco-themes.injectable.ts
index 02a00523ad..ef85a84cd0 100644
--- a/src/renderer/before-frame-starts/runnables/load-monaco-themes.injectable.ts
+++ b/src/renderer/before-frame-starts/runnables/load-monaco-themes.injectable.ts
@@ -5,7 +5,7 @@
import { getInjectable } from "@ogre-tools/injectable";
import { customMonacoThemeInjectionToken } from "../../components/monaco-editor";
import addNewMonacoThemeInjectable from "../../monaco/add-new-theme.injectable";
-import { beforeFrameStartsInjectionToken } from "../tokens";
+import { beforeFrameStartsSecondInjectionToken } from "../tokens";
const loadMonacoThemesInjectable = getInjectable({
id: "load-monaco-themes",
@@ -18,7 +18,7 @@ const loadMonacoThemesInjectable = getInjectable({
customThemes.forEach(addNewMonacoTheme);
},
}),
- injectionToken: beforeFrameStartsInjectionToken,
+ injectionToken: beforeFrameStartsSecondInjectionToken,
});
export default loadMonacoThemesInjectable;
diff --git a/src/renderer/before-frame-starts/runnables/setup-auto-registration.injectable.ts b/src/renderer/before-frame-starts/runnables/setup-auto-registration.injectable.ts
index c2c58c22b0..ecfac3136a 100644
--- a/src/renderer/before-frame-starts/runnables/setup-auto-registration.injectable.ts
+++ b/src/renderer/before-frame-starts/runnables/setup-auto-registration.injectable.ts
@@ -9,7 +9,9 @@ import { CustomResourceStore } from "../../../common/k8s-api/api-manager/resourc
import type { CustomResourceDefinition } from "../../../common/k8s-api/endpoints";
import { KubeApi } from "../../../common/k8s-api/kube-api";
import { KubeObject } from "../../../common/k8s-api/kube-object";
-import { beforeClusterFrameStartsInjectionToken } from "../tokens";
+import { beforeClusterFrameStartsSecondInjectionToken } from "../tokens";
+import type { KubeObjectStoreDependencies } from "../../../common/k8s-api/kube-object.store";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
const setupAutoRegistrationInjectable = getInjectable({
id: "setup-auto-registration",
@@ -19,6 +21,9 @@ const setupAutoRegistrationInjectable = getInjectable({
const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable);
const beforeApiManagerInitializationCrds: CustomResourceDefinition[] = [];
const beforeApiManagerInitializationApis: KubeApi[] = [];
+ const deps: KubeObjectStoreDependencies = {
+ context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
+ };
let initialized = false;
const autoInitCustomResourceStore = (crd: CustomResourceDefinition) => {
@@ -43,7 +48,7 @@ const setupAutoRegistrationInjectable = getInjectable({
})();
if (!apiManager.getStore(api)) {
- apiManager.registerStore(new CustomResourceStore(api));
+ apiManager.registerStore(new CustomResourceStore(deps, api));
}
};
const autoInitKubeApi = (api: KubeApi) => {
@@ -66,6 +71,7 @@ const setupAutoRegistrationInjectable = getInjectable({
}
});
+ // NOTE: this MUST happen after the event emitter listeners are registered
const apiManager = di.inject(apiManagerInjectable);
beforeApiManagerInitializationCrds.forEach(autoInitCustomResourceStore);
@@ -73,7 +79,7 @@ const setupAutoRegistrationInjectable = getInjectable({
initialized = true;
},
}),
- injectionToken: beforeClusterFrameStartsInjectionToken,
+ injectionToken: beforeClusterFrameStartsSecondInjectionToken,
});
export default setupAutoRegistrationInjectable;
diff --git a/src/renderer/before-frame-starts/runnables/setup-current-cluster-broadcast.injectable.ts b/src/renderer/before-frame-starts/runnables/setup-current-cluster-broadcast.injectable.ts
index 978eae3d95..a89ba58ec2 100644
--- a/src/renderer/before-frame-starts/runnables/setup-current-cluster-broadcast.injectable.ts
+++ b/src/renderer/before-frame-starts/runnables/setup-current-cluster-broadcast.injectable.ts
@@ -7,7 +7,7 @@ import { reaction } from "mobx";
import { currentClusterMessageChannel } from "../../../common/cluster/current-cluster-channel";
import { sendMessageToChannelInjectionToken } from "../../../common/utils/channel/message-to-channel-injection-token";
import matchedClusterIdInjectable from "../../navigation/matched-cluster-id.injectable";
-import { beforeMainFrameStartsInjectionToken } from "../tokens";
+import { beforeMainFrameStartsFirstInjectionToken } from "../tokens";
const setupCurrentClusterBroadcastInjectable = getInjectable({
id: "setup-current-cluster-broadcast",
@@ -26,7 +26,7 @@ const setupCurrentClusterBroadcastInjectable = getInjectable({
);
},
}),
- injectionToken: beforeMainFrameStartsInjectionToken,
+ injectionToken: beforeMainFrameStartsFirstInjectionToken,
});
export default setupCurrentClusterBroadcastInjectable;
diff --git a/src/renderer/before-frame-starts/runnables/setup-kubernetes-cluster-catalog-add-menu.injectable.ts b/src/renderer/before-frame-starts/runnables/setup-kubernetes-cluster-catalog-add-menu.injectable.ts
index 406b1641af..20566b5dac 100644
--- a/src/renderer/before-frame-starts/runnables/setup-kubernetes-cluster-catalog-add-menu.injectable.ts
+++ b/src/renderer/before-frame-starts/runnables/setup-kubernetes-cluster-catalog-add-menu.injectable.ts
@@ -9,7 +9,7 @@ import isLinuxInjectable from "../../../common/vars/is-linux.injectable";
import isWindowsInjectable from "../../../common/vars/is-windows.injectable";
import openPathPickingDialogInjectable from "../../../features/path-picking-dialog/renderer/pick-paths.injectable";
import addSyncEntriesInjectable from "../../initializers/add-sync-entries.injectable";
-import { beforeFrameStartsInjectionToken } from "../tokens";
+import { beforeFrameStartsSecondInjectionToken } from "../tokens";
const setupKubernetesClusterCatalogAddMenuListenerInjectable = getInjectable({
id: "setup-kubernetes-cluster-catalog-add-menu-listener",
@@ -75,7 +75,7 @@ const setupKubernetesClusterCatalogAddMenuListenerInjectable = getInjectable({
});
},
}),
- injectionToken: beforeFrameStartsInjectionToken,
+ injectionToken: beforeFrameStartsSecondInjectionToken,
});
export default setupKubernetesClusterCatalogAddMenuListenerInjectable;
diff --git a/src/renderer/before-frame-starts/runnables/setup-kubernetes-cluster-context-menu-open.injectable.ts b/src/renderer/before-frame-starts/runnables/setup-kubernetes-cluster-context-menu-open.injectable.ts
index 150620c22a..73cc988e2c 100644
--- a/src/renderer/before-frame-starts/runnables/setup-kubernetes-cluster-context-menu-open.injectable.ts
+++ b/src/renderer/before-frame-starts/runnables/setup-kubernetes-cluster-context-menu-open.injectable.ts
@@ -9,7 +9,7 @@ import readFileInjectable from "../../../common/fs/read-file.injectable";
import { loadConfigFromString } from "../../../common/kube-helpers";
import loggerInjectable from "../../../common/logger.injectable";
import openDeleteClusterDialogInjectable from "../../components/delete-cluster-dialog/open.injectable";
-import { beforeFrameStartsInjectionToken } from "../tokens";
+import { beforeFrameStartsSecondInjectionToken } from "../tokens";
const setupKubernetesClusterContextMenuOpenInjectable = getInjectable({
id: "setup-kubernetes-cluster-context-menu-open",
@@ -50,7 +50,7 @@ const setupKubernetesClusterContextMenuOpenInjectable = getInjectable({
});
},
}),
- injectionToken: beforeFrameStartsInjectionToken,
+ injectionToken: beforeFrameStartsSecondInjectionToken,
});
export default setupKubernetesClusterContextMenuOpenInjectable;
diff --git a/src/renderer/before-frame-starts/runnables/setup-root-mac-class.injectable.ts b/src/renderer/before-frame-starts/runnables/setup-root-mac-class.injectable.ts
index 59a684ccc9..56b9ce66fa 100644
--- a/src/renderer/before-frame-starts/runnables/setup-root-mac-class.injectable.ts
+++ b/src/renderer/before-frame-starts/runnables/setup-root-mac-class.injectable.ts
@@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import isMacInjectable from "../../../common/vars/is-mac.injectable";
-import { beforeFrameStartsInjectionToken } from "../tokens";
+import { beforeFrameStartsSecondInjectionToken } from "../tokens";
const setupRootMacClassnameInjectable = getInjectable({
id: "setup-root-mac-classname",
@@ -17,7 +17,7 @@ const setupRootMacClassnameInjectable = getInjectable({
rootElem?.classList.toggle("is-mac", isMac);
},
}),
- injectionToken: beforeFrameStartsInjectionToken,
+ injectionToken: beforeFrameStartsSecondInjectionToken,
});
export default setupRootMacClassnameInjectable;
diff --git a/src/renderer/before-frame-starts/runnables/setup-sentry.injectable.ts b/src/renderer/before-frame-starts/runnables/setup-sentry.injectable.ts
index 401cec99d5..c6af3b7614 100644
--- a/src/renderer/before-frame-starts/runnables/setup-sentry.injectable.ts
+++ b/src/renderer/before-frame-starts/runnables/setup-sentry.injectable.ts
@@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import initializeSentryReportingWithInjectable from "../../../common/error-reporting/initialize-sentry-reporting.injectable";
-import { beforeMainFrameStartsInjectionToken } from "../tokens";
+import { beforeMainFrameStartsFirstInjectionToken } from "../tokens";
import { init } from "@sentry/electron/renderer";
const setupSentryInjectable = getInjectable({
@@ -17,7 +17,7 @@ const setupSentryInjectable = getInjectable({
initializeSentryReportingWith(init);
},
}),
- injectionToken: beforeMainFrameStartsInjectionToken,
+ injectionToken: beforeMainFrameStartsFirstInjectionToken,
});
export default setupSentryInjectable;
diff --git a/src/renderer/before-frame-starts/runnables/setup-weblink-context-menu-open.injectable.tsx b/src/renderer/before-frame-starts/runnables/setup-weblink-context-menu-open.injectable.tsx
index 4c027d6047..7bf8f29422 100644
--- a/src/renderer/before-frame-starts/runnables/setup-weblink-context-menu-open.injectable.tsx
+++ b/src/renderer/before-frame-starts/runnables/setup-weblink-context-menu-open.injectable.tsx
@@ -7,7 +7,7 @@ import React from "react";
import catalogCategoryRegistryInjectable from "../../../common/catalog/category-registry.injectable";
import { WeblinkAddCommand } from "../../components/catalog-entities/weblink-add-command";
import commandOverlayInjectable from "../../components/command-palette/command-overlay.injectable";
-import { beforeFrameStartsInjectionToken } from "../tokens";
+import { beforeFrameStartsSecondInjectionToken } from "../tokens";
const setupWeblickContextMenuOpenInjectable = getInjectable({
id: "setup-weblick-context-menu-open",
@@ -28,7 +28,7 @@ const setupWeblickContextMenuOpenInjectable = getInjectable({
});
},
}),
- injectionToken: beforeFrameStartsInjectionToken,
+ injectionToken: beforeFrameStartsSecondInjectionToken,
});
export default setupWeblickContextMenuOpenInjectable;
diff --git a/src/renderer/before-frame-starts/tokens.ts b/src/renderer/before-frame-starts/tokens.ts
index 77b0350315..460c44cde9 100644
--- a/src/renderer/before-frame-starts/tokens.ts
+++ b/src/renderer/before-frame-starts/tokens.ts
@@ -7,20 +7,30 @@ import type { Runnable } from "../../common/runnable/run-many-for";
// NOTE: these are run before any other token, mostly to set up things that all other runnables need
export const beforeFrameStartsFirstInjectionToken = getInjectionToken({
- id: "even-before-frame-starts",
+ id: "before-frame-starts-first",
});
// NOTE: these are only run when process.isMainFrame === true
-export const beforeMainFrameStartsInjectionToken = getInjectionToken({
- id: "even-before-main-frame-starts",
+export const beforeMainFrameStartsFirstInjectionToken = getInjectionToken({
+ id: "before-main-frame-starts-first",
});
// NOTE: these are only run when process.isMainFrame === false
-export const beforeClusterFrameStartsInjectionToken = getInjectionToken({
- id: "even-before-cluster-frame-starts",
+export const beforeClusterFrameStartsFirstInjectionToken = getInjectionToken({
+ id: "before-cluster-frame-starts-first",
});
-export const beforeFrameStartsInjectionToken = getInjectionToken({
- id: "before-frame-starts",
+export const beforeFrameStartsSecondInjectionToken = getInjectionToken({
+ id: "before-frame-starts-second",
+});
+
+// NOTE: these are only run when process.isMainFrame === true
+export const beforeMainFrameStartsSecondInjectionToken = getInjectionToken({
+ id: "before-main-frame-starts-second",
+});
+
+// NOTE: these are only run when process.isMainFrame === false
+export const beforeClusterFrameStartsSecondInjectionToken = getInjectionToken({
+ id: "before-cluster-frame-starts-second",
});
diff --git a/src/renderer/cluster-frame-context/allowed-resources.injectable.ts b/src/renderer/cluster-frame-context/allowed-resources.injectable.ts
deleted file mode 100644
index 646d931367..0000000000
--- a/src/renderer/cluster-frame-context/allowed-resources.injectable.ts
+++ /dev/null
@@ -1,25 +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 { comparer, computed } from "mobx";
-import hostedClusterInjectable from "./hosted-cluster.injectable";
-import { allowedResourcesInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
-
-const allowedResourcesInjectable = getInjectable({
- id: "allowed-resources",
-
- instantiate: (di) => {
- const cluster = di.inject(hostedClusterInjectable);
-
- return computed(() => new Set(cluster?.allowedResources), {
- // This needs to be here so that during refresh changes are only propogated when necessary
- equals: (cur, prev) => comparer.structural(cur, prev),
- });
- },
-
- injectionToken: allowedResourcesInjectionToken,
-});
-
-export default allowedResourcesInjectable;
diff --git a/src/renderer/cluster-frame-context/cluster-frame-context.injectable.ts b/src/renderer/cluster-frame-context/cluster-frame-context.injectable.ts
deleted file mode 100644
index a353a30b40..0000000000
--- a/src/renderer/cluster-frame-context/cluster-frame-context.injectable.ts
+++ /dev/null
@@ -1,25 +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 { ClusterFrameContext } from "./cluster-frame-context";
-import namespaceStoreInjectable from "../components/+namespaces/store.injectable";
-import hostedClusterInjectable from "./hosted-cluster.injectable";
-import assert from "assert";
-
-const clusterFrameContextInjectable = getInjectable({
- id: "cluster-frame-context",
-
- instantiate: (di) => {
- const cluster = di.inject(hostedClusterInjectable);
-
- assert(cluster, "This can only be injected within a cluster frame");
-
- return new ClusterFrameContext(cluster, {
- namespaceStore: di.inject(namespaceStoreInjectable),
- });
- },
-});
-
-export default clusterFrameContextInjectable;
diff --git a/src/renderer/cluster-frame-context/cluster-frame-context.ts b/src/renderer/cluster-frame-context/cluster-frame-context.ts
index 1f1625e9e1..e23bac5fd4 100755
--- a/src/renderer/cluster-frame-context/cluster-frame-context.ts
+++ b/src/renderer/cluster-frame-context/cluster-frame-context.ts
@@ -3,44 +3,14 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
-import type { Cluster } from "../../common/cluster/cluster";
-import type { NamespaceStore } from "../components/+namespaces/store";
-import type { ClusterContext } from "../../common/k8s-api/cluster-context";
-import { computed, makeObservable } from "mobx";
+/**
+ * This type is used for KubeObjectStores
+ */
+export interface ClusterContext {
+ readonly allNamespaces: string[]; // available / allowed namespaces from cluster.ts
+ readonly contextNamespaces: string[]; // selected by user (see: namespace-select.tsx)
+ readonly hasSelectedAll: boolean;
-interface Dependencies {
- namespaceStore: NamespaceStore;
-}
-
-export class ClusterFrameContext implements ClusterContext {
- constructor(public cluster: Cluster, private dependencies: Dependencies) {
- makeObservable(this);
- }
-
- @computed get allNamespaces(): string[] {
- // user given list of namespaces
- if (this.cluster.accessibleNamespaces.length) {
- return this.cluster.accessibleNamespaces;
- }
-
- if (this.dependencies.namespaceStore.items.length > 0) {
- // namespaces from kubernetes api
- return this.dependencies.namespaceStore.items.map((namespace) => namespace.getName());
- } else {
- // fallback to cluster resolved namespaces because we could not load list
- return this.cluster.allowedNamespaces || [];
- }
- }
-
- @computed get contextNamespaces(): string[] {
- return this.dependencies.namespaceStore.contextNamespaces;
- }
-
- @computed get hasSelectedAll(): boolean {
- const namespaces = new Set(this.contextNamespaces);
-
- return this.allNamespaces?.length > 1
- && this.cluster.accessibleNamespaces.length === 0
- && this.allNamespaces.every(ns => namespaces.has(ns));
- }
+ isLoadingAll(namespaces: string[]): boolean;
+ isGlobalWatchEnabled(): boolean;
}
diff --git a/src/renderer/cluster-frame-context/for-cluster-scoped-resources.injectable.ts b/src/renderer/cluster-frame-context/for-cluster-scoped-resources.injectable.ts
new file mode 100644
index 0000000000..12e74cdc1f
--- /dev/null
+++ b/src/renderer/cluster-frame-context/for-cluster-scoped-resources.injectable.ts
@@ -0,0 +1,21 @@
+/**
+ * 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 { ClusterContext } from "./cluster-frame-context";
+
+const clusterFrameContextForClusterScopedResourcesInjectable = getInjectable({
+ id: "cluster-frame-context-for-cluster-scoped-resources",
+ instantiate: (): ClusterContext => ({
+ // This doesn't matter as it is an optimization for namespaced resources only
+ isGlobalWatchEnabled: () => true,
+ // This is always the case for cluster scoped resources
+ isLoadingAll: () => true,
+ allNamespaces: [],
+ contextNamespaces: [],
+ hasSelectedAll: true,
+ }),
+});
+
+export default clusterFrameContextForClusterScopedResourcesInjectable;
diff --git a/src/renderer/cluster-frame-context/for-namespaced-resources.injectable.ts b/src/renderer/cluster-frame-context/for-namespaced-resources.injectable.ts
new file mode 100644
index 0000000000..1eb85b3a43
--- /dev/null
+++ b/src/renderer/cluster-frame-context/for-namespaced-resources.injectable.ts
@@ -0,0 +1,64 @@
+/**
+ * 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 { ClusterContext } from "./cluster-frame-context";
+import namespaceStoreInjectable from "../components/+namespaces/store.injectable";
+import hostedClusterInjectable from "./hosted-cluster.injectable";
+import assert from "assert";
+import { computed } from "mobx";
+
+const clusterFrameContextForNamespacedResourcesInjectable = getInjectable({
+ id: "cluster-frame-context-for-namespaced-resources",
+
+ instantiate: (di): ClusterContext => {
+ const cluster = di.inject(hostedClusterInjectable);
+ const namespaceStore = di.inject(namespaceStoreInjectable);
+
+ assert(cluster, "This can only be injected within a cluster frame");
+
+ const allNamespaces = computed(() => {
+ // user given list of namespaces
+ if (cluster.accessibleNamespaces.length) {
+ return cluster.accessibleNamespaces.slice();
+ }
+
+ if (namespaceStore.items.length > 0) {
+ // namespaces from kubernetes api
+ return namespaceStore.items.map((namespace) => namespace.getName());
+ }
+
+ // fallback to cluster resolved namespaces because we could not load list
+ return cluster.allowedNamespaces.slice();
+ });
+ const contextNamespaces = computed(() => namespaceStore.contextNamespaces);
+ const hasSelectedAll = computed(() => {
+ const namespaces = new Set(contextNamespaces.get());
+
+ return allNamespaces.get().length > 1
+ && cluster.accessibleNamespaces.length === 0
+ && allNamespaces.get().every(ns => namespaces.has(ns));
+ });
+
+ return {
+ isLoadingAll: (namespaces) => (
+ allNamespaces.get().length > 1
+ && cluster.accessibleNamespaces.length === 0
+ && allNamespaces.get().every(ns => namespaces.includes(ns))
+ ),
+ isGlobalWatchEnabled: () => cluster.isGlobalWatchEnabled,
+ get allNamespaces() {
+ return allNamespaces.get();
+ },
+ get contextNamespaces() {
+ return contextNamespaces.get();
+ },
+ get hasSelectedAll() {
+ return hasSelectedAll.get();
+ },
+ };
+ },
+});
+
+export default clusterFrameContextForNamespacedResourcesInjectable;
diff --git a/src/renderer/cluster-frame-context/should-show-resource.injectable.ts b/src/renderer/cluster-frame-context/should-show-resource.injectable.ts
new file mode 100644
index 0000000000..2ec4132045
--- /dev/null
+++ b/src/renderer/cluster-frame-context/should-show-resource.injectable.ts
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import hostedClusterInjectable from "./hosted-cluster.injectable";
+import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
+import type { KubeApiResourceDescriptor } from "../../common/rbac";
+import { formatKubeApiResource } from "../../common/rbac";
+
+const shouldShowResourceInjectable = getInjectable({
+ id: "should-show-resource",
+ instantiate: (di, resource) => {
+ const cluster = di.inject(hostedClusterInjectable);
+
+ return cluster
+ ? computed(() => cluster.shouldShowResource(resource))
+ : computed(() => false);
+ },
+ injectionToken: shouldShowResourceInjectionToken,
+ lifecycle: lifecycleEnum.keyedSingleton({
+ getInstanceKey: (di, resource: KubeApiResourceDescriptor) => formatKubeApiResource(resource),
+ }),
+});
+
+export default shouldShowResourceInjectable;
diff --git a/src/renderer/cluster/accessible-namespaces.injectable.ts b/src/renderer/cluster/accessible-namespaces.injectable.ts
new file mode 100644
index 0000000000..50743cfa83
--- /dev/null
+++ b/src/renderer/cluster/accessible-namespaces.injectable.ts
@@ -0,0 +1,18 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import hostedClusterInjectable from "../cluster-frame-context/hosted-cluster.injectable";
+
+const clusterConfiguredAccessibleNamespacesInjectable = getInjectable({
+ id: "cluster-configured-accessible-namespaces",
+ instantiate: (di) => {
+ const hostedCluster = di.inject(hostedClusterInjectable);
+
+ return computed(() => [...hostedCluster?.accessibleNamespaces ?? []]);
+ },
+});
+
+export default clusterConfiguredAccessibleNamespacesInjectable;
diff --git a/src/renderer/create-cluster/create-cluster.injectable.ts b/src/renderer/cluster/create-cluster.injectable.ts
similarity index 92%
rename from src/renderer/create-cluster/create-cluster.injectable.ts
rename to src/renderer/cluster/create-cluster.injectable.ts
index e0a9f51656..385dfe8d66 100644
--- a/src/renderer/create-cluster/create-cluster.injectable.ts
+++ b/src/renderer/cluster/create-cluster.injectable.ts
@@ -27,9 +27,9 @@ const createClusterInjectable = getInjectable({
createKubectl: () => { throw new Error("Tried to access back-end feature in front-end.");},
createContextHandler: () => undefined as never,
createAuthorizationReview: () => { throw new Error("Tried to access back-end feature in front-end."); },
- createAuthorizationNamespaceReview: () => { throw new Error("Tried to access back-end feature in front-end."); },
+ requestNamespaceListPermissionsFor: () => { throw new Error("Tried to access back-end feature in front-end."); },
createListNamespaces: () => { throw new Error("Tried to access back-end feature in front-end."); },
- createListApiResources: ()=> { throw new Error("Tried to access back-end feature in front-end."); },
+ requestApiResources: ()=> { throw new Error("Tried to access back-end feature in front-end."); },
detectorRegistry: undefined as never,
createVersionDetector: () => { throw new Error("Tried to access back-end feature in front-end."); },
};
diff --git a/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.injectable.ts b/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.injectable.ts
index 6389009785..a4666adcef 100644
--- a/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.injectable.ts
+++ b/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.injectable.ts
@@ -13,6 +13,7 @@ import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-cre
import assert from "assert";
import nodeStoreInjectable from "../../+nodes/store.injectable";
import requestClusterMetricsByNodeNamesInjectable from "../../../../common/k8s-api/endpoints/metrics.api/request-cluster-metrics-by-node-names.injectable";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable";
const clusterOverviewStoreInjectable = getInjectable({
id: "cluster-overview-store",
@@ -32,6 +33,7 @@ const clusterOverviewStoreInjectable = getInjectable({
),
nodeStore: di.inject(nodeStoreInjectable),
requestClusterMetricsByNodeNames: di.inject(requestClusterMetricsByNodeNamesInjectable),
+ context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
}, clusterApi);
},
injectionToken: kubeObjectStoreInjectionToken,
diff --git a/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.ts b/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.ts
index 2669cb71a6..943b14dbf9 100644
--- a/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.ts
+++ b/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.ts
@@ -4,6 +4,7 @@
*/
import { action, observable, reaction, when, makeObservable } from "mobx";
+import type { KubeObjectStoreDependencies } from "../../../../common/k8s-api/kube-object.store";
import { KubeObjectStore } from "../../../../common/k8s-api/kube-object.store";
import type { Cluster, ClusterApi } from "../../../../common/k8s-api/endpoints";
import type { StorageLayer } from "../../../utils";
@@ -28,7 +29,7 @@ export interface ClusterOverviewStorageState {
metricNodeRole: MetricNodeRole;
}
-interface ClusterOverviewStoreDependencies {
+interface ClusterOverviewStoreDependencies extends KubeObjectStoreDependencies {
readonly storage: StorageLayer;
readonly nodeStore: NodeStore;
requestClusterMetricsByNodeNames: RequestClusterMetricsByNodeNames;
@@ -58,7 +59,7 @@ export class ClusterOverviewStore extends KubeObjectStore i
}
constructor(protected readonly dependencies: ClusterOverviewStoreDependencies, api: ClusterApi) {
- super(api);
+ super(dependencies, api);
makeObservable(this);
autoBind(this);
diff --git a/src/renderer/components/+config-autoscalers/store.injectable.ts b/src/renderer/components/+config-autoscalers/store.injectable.ts
index a2d271df5d..4d4a3adc21 100644
--- a/src/renderer/components/+config-autoscalers/store.injectable.ts
+++ b/src/renderer/components/+config-autoscalers/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 horizontalPodAutoscalerApiInjectable from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api.injectable";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { HorizontalPodAutoscalerStore } from "./store";
@@ -16,7 +17,9 @@ const horizontalPodAutoscalerStoreInjectable = getInjectable({
const api = di.inject(horizontalPodAutoscalerApiInjectable);
- return new HorizontalPodAutoscalerStore(api);
+ return new HorizontalPodAutoscalerStore({
+ context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
+ }, api);
},
injectionToken: kubeObjectStoreInjectionToken,
});
diff --git a/src/renderer/components/+config-leases/store.injectable.ts b/src/renderer/components/+config-leases/store.injectable.ts
index b9dda24b07..eb9676ce90 100644
--- a/src/renderer/components/+config-leases/store.injectable.ts
+++ b/src/renderer/components/+config-leases/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 leaseApiInjectable from "../../../common/k8s-api/endpoints/lease.api.injectable";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { LeaseStore } from "./store";
@@ -16,7 +17,9 @@ const leaseStoreInjectable = getInjectable({
const api = di.inject(leaseApiInjectable);
- return new LeaseStore(api);
+ return new LeaseStore({
+ context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
+ }, api);
},
injectionToken: kubeObjectStoreInjectionToken,
});
diff --git a/src/renderer/components/+config-limit-ranges/store.injectable.ts b/src/renderer/components/+config-limit-ranges/store.injectable.ts
index 4f1224131a..494968b60c 100644
--- a/src/renderer/components/+config-limit-ranges/store.injectable.ts
+++ b/src/renderer/components/+config-limit-ranges/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 limitRangeApiInjectable from "../../../common/k8s-api/endpoints/limit-range.api.injectable";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { LimitRangeStore } from "./store";
@@ -16,7 +17,9 @@ const limitRangeStoreInjectable = getInjectable({
const api = di.inject(limitRangeApiInjectable);
- return new LimitRangeStore(api);
+ return new LimitRangeStore({
+ context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
+ }, api);
},
injectionToken: kubeObjectStoreInjectionToken,
});
diff --git a/src/renderer/components/+config-maps/store.injectable.ts b/src/renderer/components/+config-maps/store.injectable.ts
index d16da8318e..7cbd59e4a5 100644
--- a/src/renderer/components/+config-maps/store.injectable.ts
+++ b/src/renderer/components/+config-maps/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 configMapApiInjectable from "../../../common/k8s-api/endpoints/config-map.api.injectable";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { ConfigMapStore } from "./store";
@@ -16,7 +17,9 @@ const configMapStoreInjectable = getInjectable({
const api = di.inject(configMapApiInjectable);
- return new ConfigMapStore(api);
+ return new ConfigMapStore({
+ context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
+ }, api);
},
injectionToken: kubeObjectStoreInjectionToken,
});
diff --git a/src/renderer/components/+config-pod-disruption-budgets/store.injectable.ts b/src/renderer/components/+config-pod-disruption-budgets/store.injectable.ts
index 5314584274..697fd5c444 100644
--- a/src/renderer/components/+config-pod-disruption-budgets/store.injectable.ts
+++ b/src/renderer/components/+config-pod-disruption-budgets/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 podDisruptionBudgetApiInjectable from "../../../common/k8s-api/endpoints/pod-disruption-budget.api.injectable";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { PodDisruptionBudgetStore } from "./store";
@@ -16,7 +17,9 @@ const podDisruptionBudgetStoreInjectable = getInjectable({
const api = di.inject(podDisruptionBudgetApiInjectable);
- return new PodDisruptionBudgetStore(api);
+ return new PodDisruptionBudgetStore({
+ context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
+ }, api);
},
injectionToken: kubeObjectStoreInjectionToken,
});
diff --git a/src/renderer/components/+config-priority-classes/store.injectable.ts b/src/renderer/components/+config-priority-classes/store.injectable.ts
index 68677a3b5f..b01e69602c 100644
--- a/src/renderer/components/+config-priority-classes/store.injectable.ts
+++ b/src/renderer/components/+config-priority-classes/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 priorityClassApiInjectable from "../../../common/k8s-api/endpoints/priority-class.api.injectable";
+import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { PriorityClassStore } from "./store";
@@ -16,7 +17,9 @@ const priorityClassStoreInjectable = getInjectable({
const api = di.inject(priorityClassApiInjectable);
- return new PriorityClassStore(api);
+ return new PriorityClassStore({
+ context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
+ }, api);
},
injectionToken: kubeObjectStoreInjectionToken,
});
diff --git a/src/renderer/components/+config-resource-quotas/store.injectable.ts b/src/renderer/components/+config-resource-quotas/store.injectable.ts
index d8294c8132..4999ca9517 100644
--- a/src/renderer/components/+config-resource-quotas/store.injectable.ts
+++ b/src/renderer/components/+config-resource-quotas/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 resourceQuotaApiInjectable from "../../../common/k8s-api/endpoints/resource-quota.api.injectable";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { ResourceQuotaStore } from "./store";
@@ -16,7 +17,9 @@ const resourceQuotaStoreInjectable = getInjectable({
const api = di.inject(resourceQuotaApiInjectable);
- return new ResourceQuotaStore(api);
+ return new ResourceQuotaStore({
+ context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
+ }, api);
},
injectionToken: kubeObjectStoreInjectionToken,
});
diff --git a/src/renderer/components/+config-runtime-classes/store.injectable.ts b/src/renderer/components/+config-runtime-classes/store.injectable.ts
index 0a4a21d716..63e8d82526 100644
--- a/src/renderer/components/+config-runtime-classes/store.injectable.ts
+++ b/src/renderer/components/+config-runtime-classes/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 runtimeClassApiInjectable from "../../../common/k8s-api/endpoints/runtime-class.api.injectable";
+import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { RuntimeClassStore } from "./store";
@@ -16,7 +17,9 @@ const runtimeClassStoreInjectable = getInjectable({
const api = di.inject(runtimeClassApiInjectable);
- return new RuntimeClassStore(api);
+ return new RuntimeClassStore({
+ context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
+ }, api);
},
injectionToken: kubeObjectStoreInjectionToken,
});
diff --git a/src/renderer/components/+config-secrets/__tests__/secret-details.test.tsx b/src/renderer/components/+config-secrets/__tests__/secret-details.test.tsx
index f1e3aad2b4..6a586bdd0c 100644
--- a/src/renderer/components/+config-secrets/__tests__/secret-details.test.tsx
+++ b/src/renderer/components/+config-secrets/__tests__/secret-details.test.tsx
@@ -9,6 +9,10 @@ import { Secret, SecretType } from "../../../../common/k8s-api/endpoints";
import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
import { renderFor } from "../../test-utils/renderFor";
import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable";
+import directoryForUserDataInjectable from "../../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
+import hostedClusterInjectable from "../../../cluster-frame-context/hosted-cluster.injectable";
+import createClusterInjectable from "../../../cluster/create-cluster.injectable";
+import directoryForKubeConfigsInjectable from "../../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
jest.mock("../../kube-object-meta/kube-object-meta", () => ({
KubeObjectMeta: () => null,
@@ -19,8 +23,20 @@ describe("SecretDetails tests", () => {
const di = getDiForUnitTesting({ doGeneralOverrides: true });
const render = renderFor(di);
+ di.override(directoryForUserDataInjectable, () => "/some-user-data");
+ 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 secret = new Secret({
apiVersion: "v1",
kind: "secret",
diff --git a/src/renderer/components/+config-secrets/store.injectable.ts b/src/renderer/components/+config-secrets/store.injectable.ts
index 9e84f20696..2af7bf13f6 100644
--- a/src/renderer/components/+config-secrets/store.injectable.ts
+++ b/src/renderer/components/+config-secrets/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 secretApiInjectable from "../../../common/k8s-api/endpoints/secret.api.injectable";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { SecretStore } from "./store";
@@ -16,7 +17,9 @@ const secretStoreInjectable = getInjectable({
const api = di.inject(secretApiInjectable);
- return new SecretStore(api);
+ return new SecretStore({
+ context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
+ }, api);
},
injectionToken: kubeObjectStoreInjectionToken,
});
diff --git a/src/renderer/components/+custom-resources/definition.store.injectable.ts b/src/renderer/components/+custom-resources/definition.store.injectable.ts
index ee4719cc97..b93f656df9 100644
--- a/src/renderer/components/+custom-resources/definition.store.injectable.ts
+++ b/src/renderer/components/+custom-resources/definition.store.injectable.ts
@@ -7,6 +7,7 @@ import assert from "assert";
import autoRegistrationEmitterInjectable from "../../../common/k8s-api/api-manager/auto-registration-emitter.injectable";
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
import customResourceDefinitionApiInjectable from "../../../common/k8s-api/endpoints/custom-resource-definition.api.injectable";
+import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import { CustomResourceDefinitionStore } from "./definition.store";
@@ -19,6 +20,7 @@ const customResourceDefinitionStoreInjectable = getInjectable({
return new CustomResourceDefinitionStore({
autoRegistration: di.inject(autoRegistrationEmitterInjectable),
+ context: di.inject(clusterFrameContextForClusterScopedResourcesInjectable),
}, api);
},
injectionToken: kubeObjectStoreInjectionToken,
diff --git a/src/renderer/components/+custom-resources/definition.store.ts b/src/renderer/components/+custom-resources/definition.store.ts
index 778f895214..bef5c2323e 100644
--- a/src/renderer/components/+custom-resources/definition.store.ts
+++ b/src/renderer/components/+custom-resources/definition.store.ts
@@ -4,7 +4,7 @@
*/
import { computed, reaction, makeObservable } 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 { autoBind } from "../../utils";
import type { CustomResourceDefinition, CustomResourceDefinitionApi } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
@@ -12,7 +12,7 @@ import type { KubeObject } from "../../../common/k8s-api/kube-object";
import type TypedEventEmitter from "typed-emitter";
import type { LegacyAutoRegistration } from "../../../common/k8s-api/api-manager/auto-registration-emitter.injectable";
-export interface CustomResourceDefinitionStoreDependencies {
+export interface CustomResourceDefinitionStoreDependencies extends KubeObjectStoreDependencies {
readonly autoRegistration: TypedEventEmitter;
}
@@ -22,7 +22,7 @@ export class CustomResourceDefinitionStore extends KubeObjectStore {
constructor(
- protected readonly dependencies: Dependencies,
+ protected readonly dependencies: EventStoreDependencies,
api: KubeEventApi,
opts: KubeObjectStoreOptions = {},
) {
- super(api, { limit: 1000, ...opts });
+ super(dependencies, api, { limit: 1000, ...opts });
autoBind(this);
}
diff --git a/src/renderer/components/+helm-releases/releases.injectable.ts b/src/renderer/components/+helm-releases/releases.injectable.ts
index ed3d8d6b8e..7f4d2d286b 100644
--- a/src/renderer/components/+helm-releases/releases.injectable.ts
+++ b/src/renderer/components/+helm-releases/releases.injectable.ts
@@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import { asyncComputed } from "@ogre-tools/injectable-react";
-import clusterFrameContextInjectable from "../../cluster-frame-context/cluster-frame-context.injectable";
+import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
import releaseSecretsInjectable from "./release-secrets.injectable";
import requestHelmReleasesInjectable from "../../../common/k8s-api/endpoints/helm-releases.api/request-releases.injectable";
import toHelmReleaseInjectable from "./to-helm-release.injectable";
@@ -13,7 +13,7 @@ const releasesInjectable = getInjectable({
id: "releases",
instantiate: (di) => {
- const clusterContext = di.inject(clusterFrameContextInjectable);
+ const clusterContext = di.inject(clusterFrameContextForNamespacedResourcesInjectable);
const releaseSecrets = di.inject(releaseSecretsInjectable);
const requestHelmReleases = di.inject(requestHelmReleasesInjectable);
const toHelmRelease = di.inject(toHelmReleaseInjectable);
diff --git a/src/renderer/components/+namespaces/__snapshots__/namespace-select-filter.test.tsx.snap b/src/renderer/components/+namespaces/__snapshots__/namespace-select-filter.test.tsx.snap
index 664b0daece..335cc1d159 100644
--- a/src/renderer/components/+namespaces/__snapshots__/namespace-select-filter.test.tsx.snap
+++ b/src/renderer/components/+namespaces/__snapshots__/namespace-select-filter.test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[` renders 1`] = `
+exports[` once the subscribe resolves renders 1`] = `
renders 1`] = `
`;
-exports[`
when clicked renders 1`] = `
+exports[`
once the subscribe resolves when clicked renders 1`] = `
when clicked renders 1`] = `
class="Select__option Select__option--is-selected css-tr4s17-option"
id="react-select-namespace-select-filter-option-2"
tabindex="-1"
- >
-
-
-
- layers
-
-
-
- test-2
-
-
-
- check
-
-
-
-
-
-
-
-
- layers
-
-
-
- test-3
-
-
-
- check
-
-
-
-
-
-
-
-
- layers
-
-
-
- test-4
-
-
-
- check
-
-
-
-
-
-
-
-
- layers
-
-
-
- test-5
-
-
-
- check
-
-
-
-
-
-
-
-
- layers
-
-
-
- test-6
-
-
-
- check
-
-
-
-
-
-
-
-
- layers
-
-
-
- test-7
-
-
-
- check
-
-
-
-
-
-
-
-
- layers
-
-
-
- test-8
-
-
-
- check
-
-
-
-
-
-
-
-
- layers
-
-
-
- test-9
-
-
-
- check
-
-
-
-
-
when clicked renders 1`] = `
when clicked renders 1`] = `
when clicked renders 1`] = `
when clicked renders 1`] = `
+
+
+
+
+ layers
+
+
+
+ test-2
+
+
+
+ check
+
+
+
+
+
+
+
+
+ layers
+
+
+
+ test-3
+
+
+
+ check
+
+
+
+
+
+
+
+
+ layers
+
+
+
+ test-4
+
+
+
+ check
+
+
+
+
+
+
+
+
+ layers
+
+
+
+ test-5
+
+
+
+ check
+
+
+
+
+
+
+
+
+ layers
+
+
+
+ test-6
+
+
+
+ check
+
+
+
+
+
+
+
+
+ layers
+
+
+
+ test-7
+
+
+
+ check
+
+
+
+
+
+
+
+
+ layers
+
+
+
+ test-8
+
+
+
+ check
+
+
+
+
+
+
+
+
+ layers
+
+
+
+ test-9
+
+
+
+ check
+
+
+
+
`;
-exports[` when clicked when 'test-2' is clicked renders 1`] = `
+exports[` once the subscribe resolves when clicked when 'test-2' is clicked renders 1`] = `
when clicked when 'test-2' is clicked renders
`;
-exports[`
when clicked when 'test-2' is clicked when clicked again renders 1`] = `
+exports[`
once the subscribe resolves when clicked when 'test-2' is clicked when clicked again renders 1`] = `
when clicked when 'test-2' is clicked when cl
- test-3
+ test-10
@@ -942,7 +942,7 @@ exports[` when clicked when 'test-2' is clicked when cl
- test-4
+ test-11
@@ -966,7 +966,7 @@ exports[` when clicked when 'test-2' is clicked when cl
- test-5
+ test-12
@@ -990,7 +990,7 @@ exports[` when clicked when 'test-2' is clicked when cl
- test-6
+ test-13
@@ -1014,7 +1014,7 @@ exports[` when clicked when 'test-2' is clicked when cl
- test-7
+ test-3
@@ -1038,7 +1038,7 @@ exports[` when clicked when 'test-2' is clicked when cl
- test-8
+ test-4
@@ -1062,7 +1062,7 @@ exports[` when clicked when 'test-2' is clicked when cl
- test-9
+ test-5
@@ -1086,7 +1086,7 @@ exports[` when clicked when 'test-2' is clicked when cl
- test-10
+ test-6
@@ -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(