diff --git a/.github/workflows/bump-master-version.yaml b/.github/workflows/bump-master-version.yaml index 2fc558db28..b8c0622dd2 100644 --- a/.github/workflows/bump-master-version.yaml +++ b/.github/workflows/bump-master-version.yaml @@ -22,13 +22,25 @@ jobs: yarn install --frozen-lockfile yarn lerna bootstrap - name: Bump version to first alpha of next minor version + id: bump run: | + CURRENT_VERSION=$(cat lerna.json | jq .version --raw-output) + + if ! [[ "${CURRENT_VERSION}" =~ ^\d+\.\d+\.0$ ]]; then + echo "Not a minor release" + echo "status=skip" >> $GITHUB_OUTPUT + exit 0 + fi + yarn bump-version preminor + + echo "status=create" >> $GITHUB_OUTPUT - uses: peter-evans/create-pull-request@v4 + if: ${{ steps.bump.outputs.status == 'create' }} with: add-paths: lerna.json,packages/*/package.json commit-message: Update package.json version to next preminor because of recent release signoff: true delete-branch: true title: Update version to next preminor - labels: chore + labels: skip-changelog diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2c5d84bf0e..4fc05cd5d3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,5 +34,6 @@ jobs: uses: ./.github/workflows/publish-release-npm.yml needs: release if: ${{ needs.release.outputs.version != '' }} + secrets: inherit with: version: ${{ needs.release.outputs.version }} diff --git a/lerna.json b/lerna.json index 55838d653a..5ad0e4f6da 100644 --- a/lerna.json +++ b/lerna.json @@ -4,6 +4,6 @@ "packages": [ "packages/*" ], - "version": "6.4.0-alpha.0", + "version": "6.4.0-alpha.2", "npmClient": "yarn" } diff --git a/packages/core/package.json b/packages/core/package.json index 21a89fb682..77c90c1cbe 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -3,7 +3,7 @@ "productName": "OpenLens", "description": "OpenLens - Open Source IDE for Kubernetes", "homepage": "https://github.com/lensapp/lens", - "version": "6.4.0-alpha.0", + "version": "6.4.0-alpha.2", "repository": { "type": "git", "url": "git+https://github.com/lensapp/lens.git" @@ -191,7 +191,7 @@ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", "@sentry/types": "^6.19.7", "@swc/cli": "^0.1.59", - "@swc/core": "^1.3.25", + "@swc/core": "^1.3.26", "@swc/jest": "^0.2.24", "@testing-library/dom": "^7.31.2", "@testing-library/jest-dom": "^5.16.5", @@ -266,13 +266,13 @@ "electron": "^19.1.9", "electron-builder": "^23.6.0", "electron-notarize": "^0.3.0", - "esbuild": "^0.16.14", + "esbuild": "^0.16.17", "esbuild-loader": "^2.20.0", "eslint": "^8.31.0", - "eslint-import-resolver-typescript": "^3.5.2", + "eslint-import-resolver-typescript": "^3.5.3", "eslint-plugin-header": "^3.1.1", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-react": "7.31.11", + "eslint-plugin-react": "7.32.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-unused-imports": "^2.0.0", "fork-ts-checker-webpack-plugin": "^6.5.2", @@ -286,7 +286,7 @@ "jest-environment-jsdom": "^28.1.3", "jest-mock-extended": "^2.0.9", "make-plural": "^6.2.2", - "memfs": "^3.4.12", + "memfs": "^3.4.13", "memorystream": "^0.3.1", "mini-css-extract-plugin": "^2.7.2", "mock-http": "^1.1.0", @@ -323,7 +323,7 @@ "typescript": "^4.9.4", "typescript-plugin-css-modules": "^3.4.0", "webpack": "^5.75.0", - "webpack-cli": "^5.0.1", + "webpack-cli": "^4.9.2", "webpack-dev-server": "^4.11.1", "webpack-node-externals": "^3.0.0", "xterm": "^4.19.0", diff --git a/packages/core/src/common/front-end-routing/routes/cluster/config/config-maps/config-maps-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/config/config-maps/config-maps-route.injectable.ts index 6ea03fff08..0ad7ed3d88 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/config/config-maps/config-maps-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/config/config-maps/config-maps-route.injectable.ts @@ -13,7 +13,7 @@ const configMapsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "configmaps", - group: "v1", + group: "", }), }), injectionToken: frontEndRouteInjectionToken, diff --git a/packages/core/src/common/front-end-routing/routes/cluster/config/limit-ranges/limit-ranges-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/config/limit-ranges/limit-ranges-route.injectable.ts index 8623f3520e..0536e76004 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/config/limit-ranges/limit-ranges-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/config/limit-ranges/limit-ranges-route.injectable.ts @@ -14,7 +14,7 @@ const limitRangesRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "limitranges", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/config/resource-quotas/resource-quotas-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/config/resource-quotas/resource-quotas-route.injectable.ts index 209f77e19a..4905b70890 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/config/resource-quotas/resource-quotas-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/config/resource-quotas/resource-quotas-route.injectable.ts @@ -14,7 +14,7 @@ const resourceQuotasRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "resourcequotas", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/config/secrets/secrets-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/config/secrets/secrets-route.injectable.ts index 079ddcbf83..7442de14b1 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/config/secrets/secrets-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/config/secrets/secrets-route.injectable.ts @@ -14,7 +14,7 @@ const secretsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "secrets", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/events/events-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/events/events-route.injectable.ts index b3df358ad8..728f80c21d 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/events/events-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/events/events-route.injectable.ts @@ -14,7 +14,7 @@ const eventsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "events", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/namespaces/namespaces-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/namespaces/namespaces-route.injectable.ts index 2aa6c23efe..0b57c8d573 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/namespaces/namespaces-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/namespaces/namespaces-route.injectable.ts @@ -14,7 +14,7 @@ const namespacesRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "namespaces", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/network/endpoints/endpoints-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/network/endpoints/endpoints-route.injectable.ts index c88ec04714..50b3c72e4c 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/network/endpoints/endpoints-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/network/endpoints/endpoints-route.injectable.ts @@ -14,7 +14,7 @@ const endpointsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "endpoints", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/network/services/services-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/network/services/services-route.injectable.ts index 53300ee241..223ded1e65 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/network/services/services-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/network/services/services-route.injectable.ts @@ -14,7 +14,7 @@ const servicesRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "services", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/nodes/nodes-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/nodes/nodes-route.injectable.ts index 81323843d5..e6ca61346e 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/nodes/nodes-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/nodes/nodes-route.injectable.ts @@ -14,7 +14,7 @@ const nodesRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "nodes", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/overview/cluster-overview-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/overview/cluster-overview-route.injectable.ts index 8315fd7773..e559c35079 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/overview/cluster-overview-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/overview/cluster-overview-route.injectable.ts @@ -14,7 +14,7 @@ const clusterOverviewRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "nodes", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/storage/persistent-volume-claims/persistent-volume-claims-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/storage/persistent-volume-claims/persistent-volume-claims-route.injectable.ts index 1b96933136..dbda527555 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/storage/persistent-volume-claims/persistent-volume-claims-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/storage/persistent-volume-claims/persistent-volume-claims-route.injectable.ts @@ -14,7 +14,7 @@ const persistentVolumeClaimsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "persistentvolumeclaims", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/storage/persistent-volumes/persistent-volumes-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/storage/persistent-volumes/persistent-volumes-route.injectable.ts index 52f95b32c6..7a06d9df58 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/storage/persistent-volumes/persistent-volumes-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/storage/persistent-volumes/persistent-volumes-route.injectable.ts @@ -14,7 +14,7 @@ const persistentVolumesRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "persistentvolumes", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/user-management/service-accounts/service-accounts-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/user-management/service-accounts/service-accounts-route.injectable.ts index 3bf6c1ec00..65d02135c7 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/user-management/service-accounts/service-accounts-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/user-management/service-accounts/service-accounts-route.injectable.ts @@ -14,7 +14,7 @@ const serviceAccountsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "serviceaccounts", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/front-end-routing/routes/cluster/workloads/pods/pods-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/workloads/pods/pods-route.injectable.ts index 577f1c1a91..d013f872f0 100644 --- a/packages/core/src/common/front-end-routing/routes/cluster/workloads/pods/pods-route.injectable.ts +++ b/packages/core/src/common/front-end-routing/routes/cluster/workloads/pods/pods-route.injectable.ts @@ -14,7 +14,7 @@ const podsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "pods", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/common/k8s-api/__tests__/kube-api-version-detection.test.ts b/packages/core/src/common/k8s-api/__tests__/kube-api-version-detection.test.ts index 94c6e0cd9c..cd08ef4d5c 100644 --- a/packages/core/src/common/k8s-api/__tests__/kube-api-version-detection.test.ts +++ b/packages/core/src/common/k8s-api/__tests__/kube-api-version-detection.test.ts @@ -6,13 +6,11 @@ import type { ApiManager } from "../api-manager"; import type { IngressApi } from "../endpoints"; import { Ingress } from "../endpoints"; import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting"; -import apiManagerInjectable from "../api-manager/manager.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 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"; @@ -20,14 +18,14 @@ import directoryForUserDataInjectable from "../../app-paths/directory-for-user-d 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"; -import apiKubeInjectable from "../../../renderer/k8s/api-kube.injectable"; +import apiManagerInjectable from "../api-manager/manager.injectable"; import type { DiContainer } from "@ogre-tools/injectable"; import ingressApiInjectable from "../endpoints/ingress.api.injectable"; describe("KubeApi", () => { - let di: DiContainer; - let registerApiSpy: jest.SpiedFunction; let fetchMock: AsyncFnMock; + let apiManager: ApiManager; + let di: DiContainer; beforeEach(async () => { di = getDiForUnitTesting({ doGeneralOverrides: true }); @@ -40,7 +38,6 @@ describe("KubeApi", () => { di.override(storesAndApisCanBeCreatedInjectable, () => true); const createCluster = di.inject(createClusterInjectable); - const createKubeJsonApi = di.inject(createKubeJsonApiInjectable); di.override(hostedClusterInjectable, () => createCluster({ contextName: "some-context-name", @@ -50,12 +47,7 @@ describe("KubeApi", () => { clusterServerUrl: "https://localhost:8080", })); - di.override(apiKubeInjectable, () => createKubeJsonApi({ - serverAddress: `http://127.0.0.1:9999`, - apiBase: "/api-kube", - })); - - registerApiSpy = jest.spyOn(di.inject(apiManagerInjectable), "registerApi"); + apiManager = di.inject(apiManagerInjectable); const setupAutoRegistration = di.inject(setupAutoRegistrationInjectable); @@ -79,7 +71,7 @@ describe("KubeApi", () => { it("requests version list from the api group from the initial apiBase", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io", { headers: { "content-type": "application/json", @@ -92,8 +84,8 @@ describe("KubeApi", () => { describe("when the version list from the api group resolves", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io", JSON.stringify({ apiVersion: "v1", kind: "APIGroup", name: "networking.k8s.io", @@ -117,7 +109,7 @@ describe("KubeApi", () => { it("requests resources from the versioned api group from the initial apiBase", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1", { headers: { "content-type": "application/json", @@ -130,8 +122,8 @@ describe("KubeApi", () => { describe("when resource request fufills with a resource", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1", JSON.stringify({ resources: [{ name: "ingresses", }], @@ -141,7 +133,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", { headers: { "content-type": "application/json", @@ -159,8 +151,8 @@ describe("KubeApi", () => { })); }); - it("registers the api with the changes info", () => { - expect(registerApiSpy).toBeCalledWith(ingressApi); + it("api is retrievable with the new apiBase", () => { + expect(apiManager.getApi("/apis/networking.k8s.io/v1/ingresses")).toBeDefined(); }); describe("when the request resolves with no data", () => { @@ -168,8 +160,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", JSON.stringify({})), ); result = await getCall; }); @@ -193,7 +185,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -208,8 +200,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); @@ -226,8 +218,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", JSON.stringify({ apiVersion: "v1", kind: "Ingress", metadata: { @@ -260,7 +252,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -275,8 +267,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); @@ -292,8 +284,8 @@ describe("KubeApi", () => { describe("when resource request fufills with no resource", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1", JSON.stringify({ resources: [], })), ); @@ -301,7 +293,7 @@ describe("KubeApi", () => { it("requests resources from the second versioned api group from the initial apiBase", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1", { headers: { "content-type": "application/json", @@ -316,8 +308,8 @@ describe("KubeApi", () => { describe("when resource request fufills with a resource", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1", JSON.stringify({ resources: [{ name: "ingresses", }], @@ -327,7 +319,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", { headers: { "content-type": "application/json", @@ -345,8 +337,12 @@ describe("KubeApi", () => { })); }); - it("registers the api with the changes info", () => { - expect(registerApiSpy).toBeCalledWith(ingressApi); + it("api is retrievable with the new apiBase", () => { + expect(apiManager.getApi("/apis/networking.k8s.io/v1beta1/ingresses")).toBeDefined(); + }); + + it("api is retrievable with the old apiBase", () => { + expect(apiManager.getApi("/apis/networking.k8s.io/v1/ingresses")).toBeDefined(); }); describe("when the request resolves with no data", () => { @@ -354,8 +350,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({})), ); result = await getCall; }); @@ -379,7 +375,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -394,8 +390,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); @@ -412,8 +408,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({ apiVersion: "v1", kind: "Ingress", metadata: { @@ -446,7 +442,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -461,8 +457,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); @@ -480,8 +476,8 @@ describe("KubeApi", () => { describe("when the version list from the api group resolves with no versions", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io", JSON.stringify({ "metadata": {}, "status": "Failure", "message": "the server could not find the requested resource", @@ -501,7 +497,7 @@ describe("KubeApi", () => { it("requests the resources from the base api url from the fallback api", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/extensions", + "https://127.0.0.1:12345/api-kube/apis/extensions", { headers: { "content-type": "application/json", @@ -514,8 +510,8 @@ describe("KubeApi", () => { describe("when resource request fufills with a resource", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/extensions"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions", JSON.stringify({ apiVersion: "v1", kind: "APIGroup", name: "extensions", @@ -535,7 +531,7 @@ describe("KubeApi", () => { it("requests resource versions from the versioned api group from the fallback apiBase", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1", + "https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1", { headers: { "content-type": "application/json", @@ -548,8 +544,8 @@ describe("KubeApi", () => { describe("when the preferred version request resolves to v1beta1", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions", JSON.stringify({ resources: [{ name: "ingresses", }], @@ -559,7 +555,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", + "https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", { headers: { "content-type": "application/json", @@ -577,8 +573,8 @@ describe("KubeApi", () => { })); }); - it("registers the api with the changes info", () => { - expect(registerApiSpy).toBeCalledWith(ingressApi); + it("api is retrievable with the new apiBase", () => { + expect(apiManager.getApi("/apis/extensions/v1beta1/ingresses")).toBeDefined(); }); describe("when the request resolves with no data", () => { @@ -586,8 +582,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({})), ); result = await getCall; }); @@ -611,7 +607,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -626,8 +622,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); @@ -644,8 +640,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({ apiVersion: "v1beta1", kind: "Ingress", metadata: { @@ -678,7 +674,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -693,8 +689,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); diff --git a/packages/core/src/common/k8s-api/api-manager/api-manager.ts b/packages/core/src/common/k8s-api/api-manager/api-manager.ts index 080ccb671a..81b59ef9c2 100644 --- a/packages/core/src/common/k8s-api/api-manager/api-manager.ts +++ b/packages/core/src/common/k8s-api/api-manager/api-manager.ts @@ -5,11 +5,12 @@ import type { KubeObjectStore } from "../kube-object.store"; -import { action, observable, makeObservable } from "mobx"; -import { autoBind, isDefined, iter } from "../../utils"; +import type { IComputedValue } from "mobx"; +import { autorun, action, observable } from "mobx"; import type { KubeApi } from "../kube-api"; -import type { KubeJsonApiDataFor, KubeObject, ObjectReference } from "../kube-object"; +import type { KubeObject, ObjectReference } from "../kube-object"; import { parseKubeApi, createKubeApiURL } from "../kube-api-parse"; +import { chain, find } from "../../utils/iter"; export type RegisterableStore = Store extends KubeObjectStore ? Store @@ -21,25 +22,53 @@ export type KubeObjectStoreFrom = Api extends KubeApi : never; -export class ApiManager { - private readonly apis = observable.map(); - private readonly stores = observable.map(); +export type FindApiCallback = (api: KubeApi) => boolean; - constructor() { - makeObservable(this); - autoBind(this); +interface Dependencies { + readonly apis: IComputedValue; + readonly stores: IComputedValue; +} + +export class ApiManager { + private readonly externalApis = observable.array(); + private readonly externalStores = observable.array(); + + private readonly apis = observable.map(); + + constructor(private readonly dependencies: Dependencies) { + // NOTE: this is done to preserve the old behaviour of an API being discoverable using all previous apiBases + autorun(() => { + const apis = chain(this.dependencies.apis.get().values()) + .concat(this.externalApis.values()); + const removedApis = new Set(this.apis.values()); + + for (const api of apis) { + removedApis.delete(api); + this.apis.set(api.apiBase, api); + } + + for (const api of removedApis) { + for (const [apiBase, storedApi] of this.apis) { + if (storedApi === api) { + this.apis.delete(apiBase); + } + } + } + }); } - getApi(pathOrCallback: string | ((api: KubeApi) => boolean)) { - if (typeof pathOrCallback === "string") { - return this.apis.get(pathOrCallback) || this.apis.get(parseKubeApi(pathOrCallback).apiBase); + getApi(pathOrCallback: string | FindApiCallback) { + if (typeof pathOrCallback === "function") { + return find(this.apis.values(), pathOrCallback); } - return iter.find(this.apis.values(), pathOrCallback ?? (() => true)); + const { apiBase } = parseKubeApi(pathOrCallback); + + return this.apis.get(apiBase); } getApiByKind(kind: string, apiVersion: string) { - return iter.find(this.apis.values(), api => api.kind === kind && api.apiVersionWithGroup === apiVersion); + return this.getApi(api => api.kind === kind && api.apiVersionWithGroup === apiVersion); } registerApi(api: RegisterableApi): void; @@ -47,45 +76,23 @@ export class ApiManager { * @deprecated Just register the `api` by itself */ registerApi(apiBase: string, api: RegisterableApi): void; - registerApi(apiBaseRaw: string | RegisterableApi, apiRaw?: RegisterableApi) { - const api = typeof apiBaseRaw === "string" - ? apiRaw - : apiBaseRaw; - - if (!api?.apiBase) { - return; - } - - if (!this.apis.has(api.apiBase)) { - this.stores.forEach((store) => { - if (store.api === api) { - this.stores.set(api.apiBase, store); - } - }); - - this.apis.set(api.apiBase, api); + registerApi(...args: [RegisterableApi] | [string, RegisterableApi]) { + if (args.length === 1) { + this.externalApis.push(args[0]); + } else { + this.externalApis.push(args[1]); } } - protected resolveApi(api: undefined | string | KubeApi): KubeApi | undefined { - if (!api) { - return undefined; - } + unregisterApi(apiOrBase: string | KubeApi) { + if (typeof apiOrBase === "string") { + const api = this.externalApis.find(api => api.apiBase === apiOrBase); - if (typeof api === "string") { - return this.getApi(api); - } - - return api; - } - - unregisterApi(api: string | KubeApi) { - if (typeof api === "string") this.apis.delete(api); - else { - const apis = Array.from(this.apis.entries()); - const entry = apis.find(entry => entry[1] === api); - - if (entry) this.unregisterApi(entry[0]); + if (api) { + this.externalApis.remove(api); + } + } else { + this.unregisterApi(apiOrBase.apiBase); } } @@ -93,15 +100,11 @@ export class ApiManager { /** * @deprecated KubeObjectStore's should only every be about a single KubeApi type */ - registerStore(store: KubeObjectStore, KubeJsonApiDataFor>, apis: KubeApi[]): void; + registerStore(store: RegisterableStore, apis: KubeApi[]): void; @action - registerStore(store: KubeObjectStore, KubeJsonApiDataFor>, apis: KubeApi[] = [store.api]): void { - for (const api of apis.filter(isDefined)) { - if (api.apiBase) { - this.stores.set(api.apiBase, store as never); - } - } + registerStore(store: RegisterableStore): void { + this.externalStores.push(store); } getStore(api: string | undefined): KubeObjectStore | undefined; @@ -110,14 +113,23 @@ export class ApiManager { * @deprecated use an actual cast instead of hiding it with this unused type param */ getStore(api: string | KubeApi): Store | undefined ; - getStore(api: string | KubeApi | undefined): KubeObjectStore | undefined { - const { apiBase } = this.resolveApi(api) ?? {}; - - if (apiBase) { - return this.stores.get(apiBase); + getStore(apiOrBase: string | KubeApi | undefined): KubeObjectStore | undefined { + if (!apiOrBase) { + return undefined; } - return undefined; + const { apiBase } = typeof apiOrBase === "string" + ? parseKubeApi(apiOrBase) + : apiOrBase; + const api = this.getApi(apiBase); + + if (!api) { + return undefined; + } + + return chain(this.dependencies.stores.get().values()) + .concat(this.externalStores.values()) + .find(store => store.api.apiBase === api.apiBase); } lookupApiLink(ref: ObjectReference, parentObject?: KubeObject): string { @@ -132,7 +144,7 @@ export class ApiManager { const api = this.getApi(api => api.kind === kind && api.apiVersionWithGroup == apiVersion); if (api) { - return api.getUrl({ namespace, name }); + return api.formatUrlForNotListing({ namespace, name }); } // lookup api by generated resource link @@ -151,7 +163,7 @@ export class ApiManager { const apiByKind = this.getApi(api => api.kind === kind); if (apiByKind) { - return apiByKind.getUrl({ name, namespace }); + return apiByKind.formatUrlForNotListing({ name, namespace }); } // otherwise generate link with default prefix diff --git a/packages/core/src/common/k8s-api/api-manager/kube-object-store-token.ts b/packages/core/src/common/k8s-api/api-manager/kube-object-store-token.ts new file mode 100644 index 0000000000..bbf272db24 --- /dev/null +++ b/packages/core/src/common/k8s-api/api-manager/kube-object-store-token.ts @@ -0,0 +1,10 @@ +/** + * 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"; +import type { KubeObjectStore } from "../kube-object.store"; + +export const kubeObjectStoreInjectionToken = getInjectionToken>({ + id: "kube-object-store-token", +}); diff --git a/packages/core/src/common/k8s-api/api-manager/manager.injectable.ts b/packages/core/src/common/k8s-api/api-manager/manager.injectable.ts index 45188cec7a..f0b61c28b6 100644 --- a/packages/core/src/common/k8s-api/api-manager/manager.injectable.ts +++ b/packages/core/src/common/k8s-api/api-manager/manager.injectable.ts @@ -2,29 +2,28 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { getInjectable, getInjectionToken } from "@ogre-tools/injectable"; +import { getInjectable } from "@ogre-tools/injectable"; import { storesAndApisCanBeCreatedInjectionToken } from "../stores-apis-can-be-created.token"; -import type { KubeObjectStore } from "../kube-object.store"; import { ApiManager } from "./api-manager"; - -export const kubeObjectStoreInjectionToken = getInjectionToken>({ - id: "kube-object-store-token", -}); +import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx"; +import { kubeObjectStoreInjectionToken } from "./kube-object-store-token"; +import { kubeApiInjectionToken } from "../kube-api/kube-api-injection-token"; +import { computed } from "mobx"; const apiManagerInjectable = getInjectable({ id: "api-manager", instantiate: (di) => { - const apiManager = new ApiManager(); + const computedInjectMany = di.inject(computedInjectManyInjectable); + const storesAndApisCanBeCreated = di.inject(storesAndApisCanBeCreatedInjectionToken); - if (di.inject(storesAndApisCanBeCreatedInjectionToken)) { - const stores = di.injectMany(kubeObjectStoreInjectionToken); - - for (const store of stores) { - apiManager.registerStore(store); - } - } - - return apiManager; + return new ApiManager({ + apis: storesAndApisCanBeCreated + ? computedInjectMany(kubeApiInjectionToken) + : computed(() => []), + stores: storesAndApisCanBeCreated + ? computedInjectMany(kubeObjectStoreInjectionToken) + : computed(() => []), + }); }, }); diff --git a/packages/core/src/common/k8s-api/endpoints/horizontal-pod-autoscaler.api.ts b/packages/core/src/common/k8s-api/endpoints/horizontal-pod-autoscaler.api.ts index 71863d65ad..ee4fcfc63d 100644 --- a/packages/core/src/common/k8s-api/endpoints/horizontal-pod-autoscaler.api.ts +++ b/packages/core/src/common/k8s-api/endpoints/horizontal-pod-autoscaler.api.ts @@ -72,6 +72,27 @@ export type HorizontalPodAutoscalerMetricSpec = | OptionVarient | OptionVarient; +interface HorizontalPodAutoscalerBehavior { + scaleUp?: HPAScalingRules; + scaleDown?: HPAScalingRules; +} + +interface HPAScalingRules { + stabilizationWindowSecond?: number; + selectPolicy?: ScalingPolicySelect; + policies?: HPAScalingPolicy[]; +} + +type ScalingPolicySelect = string; + +interface HPAScalingPolicy { + type: HPAScalingPolicyType; + value: number; + periodSeconds: number; +} + +type HPAScalingPolicyType = string; + export interface ContainerResourceMetricStatus { container: string; currentAverageUtilization?: number; @@ -132,6 +153,7 @@ export interface HorizontalPodAutoscalerSpec { minReplicas?: number; maxReplicas: number; metrics?: HorizontalPodAutoscalerMetricSpec[]; + behavior?: HorizontalPodAutoscalerBehavior; } export interface HorizontalPodAutoscalerStatus { @@ -153,7 +175,7 @@ export class HorizontalPodAutoscaler extends KubeObject< > { static readonly kind = "HorizontalPodAutoscaler"; static readonly namespaced = true; - static readonly apiBase = "/apis/autoscaling/v2beta1/horizontalpodautoscalers"; + static readonly apiBase = "/apis/autoscaling/v2/horizontalpodautoscalers"; getMaxPods() { return this.spec.maxReplicas ?? 0; @@ -204,8 +226,15 @@ export class HorizontalPodAutoscaler extends KubeObject< export class HorizontalPodAutoscalerApi extends KubeApi { constructor(deps: KubeApiDependencies, opts?: DerivedKubeApiOptions) { super(deps, { - objectConstructor: HorizontalPodAutoscaler, ...opts ?? {}, + objectConstructor: HorizontalPodAutoscaler, + checkPreferredVersion: true, + // Kubernetes < 1.26 + fallbackApiBases: [ + "/apis/autoscaling/v2beta2/horizontalpodautoscalers", + "/apis/autoscaling/v2beta1/horizontalpodautoscalers", + "/apis/autoscaling/v1/horizontalpodautoscalers", + ], }); } } diff --git a/packages/core/src/common/k8s-api/kube-api.ts b/packages/core/src/common/k8s-api/kube-api.ts index c2a8906400..8e6e86d7da 100644 --- a/packages/core/src/common/k8s-api/kube-api.ts +++ b/packages/core/src/common/k8s-api/kube-api.ts @@ -20,10 +20,9 @@ import type { Patch } from "rfc6902"; import assert from "assert"; import type { PartialDeep } from "type-fest"; import type { Logger } from "../logger"; -import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; -import autoRegistrationEmitterInjectable from "./api-manager/auto-registration-emitter.injectable"; import type AbortController from "abort-controller"; import { matches } from "lodash/fp"; +import { makeObservable, observable } from "mobx"; /** * The options used for creating a `KubeApi` @@ -206,30 +205,6 @@ export interface DeleteResourceDescriptor extends ResourceDescriptor { propagationPolicy?: PropagationPolicy; } -/** - * @deprecated In the new extension API, don't expose `KubeApi`'s constructor - */ -function legacyRegisterApi(api: KubeApi): void { - try { - /** - * This function throws if called in `main`, so the `try..catch` is to make sure that doesn't - * leak. - * - * However, we need this code to be run in `renderer` so that the auto registering of `KubeApi` - * instances still works. That auto registering never worked or was applicable in `main` because - * there is no "single cluster" on `main`. - * - * TODO: rearchitect this design pattern in the new extension API - */ - const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.renderer); - const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable); - - setImmediate(() => autoRegistrationEmitter.emit("kubeApi", api)); - } catch { - // ignore error - } -} - export interface KubeApiDependencies { readonly logger: Logger; readonly maybeKubeApi: KubeJsonApi | undefined; @@ -241,7 +216,9 @@ export class KubeApi< > { readonly kind: string; readonly apiVersion: string; - apiBase: string; + + @observable apiBase: string; + apiPrefix: string; apiGroup: string; apiVersionPreferred: string | undefined; @@ -288,7 +265,7 @@ export class KubeApi< this.apiResource = resource; this.request = request; this.objectConstructor = objectConstructor; - legacyRegisterApi(this); + makeObservable(this); } get apiVersionWithGroup() { @@ -347,7 +324,6 @@ export class KubeApi< this.apiGroup = apiGroup; this.apiVersionPreferred = apiVersionPreferred; this.apiBase = this.computeApiBase(); - legacyRegisterApi(this); } } diff --git a/packages/core/src/common/library copy.ts b/packages/core/src/common/library copy.ts deleted file mode 100644 index 765f70edcb..0000000000 --- a/packages/core/src/common/library copy.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import applicationInformationToken from "./vars/application-information-token"; -import type { ApplicationInformation } from "./vars/application-information-token"; -import { bundledExtensionInjectionToken } from "../extensions/extension-discovery/bundled-extension-token"; -import * as extensionApi from "../extensions/common-api"; - -// @experimental -export { - applicationInformationToken, - ApplicationInformation, - bundledExtensionInjectionToken, - extensionApi, -}; diff --git a/packages/core/src/common/library.ts b/packages/core/src/common/library.ts index 765f70edcb..ec7b96fc70 100644 --- a/packages/core/src/common/library.ts +++ b/packages/core/src/common/library.ts @@ -5,7 +5,7 @@ import applicationInformationToken from "./vars/application-information-token"; import type { ApplicationInformation } from "./vars/application-information-token"; import { bundledExtensionInjectionToken } from "../extensions/extension-discovery/bundled-extension-token"; -import * as extensionApi from "../extensions/common-api"; +import * as extensionApi from "../extensions/common-api" // @experimental export { diff --git a/packages/core/src/common/rbac.ts b/packages/core/src/common/rbac.ts index 39edc49b60..40b9f2c43c 100644 --- a/packages/core/src/common/rbac.ts +++ b/packages/core/src/common/rbac.ts @@ -13,17 +13,21 @@ export type KubeResource = export interface KubeApiResource { kind: string; - group: string; + group: string; // api-group, if empty then "core" apiName: string; namespaced: boolean; } export interface KubeApiResourceDescriptor { apiName: string; - group: string; + group: string; // api-group, if empty then "core" } -export const formatKubeApiResource = (res: KubeApiResourceDescriptor) => `${res.group}/${res.apiName}`; +export const formatKubeApiResource = (desc: KubeApiResourceDescriptor) => ( + desc.group + ? `${desc.group}/${desc.apiName}` + : desc.apiName +); export interface KubeApiResourceData { kind: string; // resource type (e.g. "Namespace") @@ -44,7 +48,7 @@ export const apiResourceRecord: Record = { }, configmaps: { kind: "ConfigMap", - group: "v1", + group: "", namespaced: true, }, cronjobs: { @@ -69,12 +73,12 @@ export const apiResourceRecord: Record = { }, endpoints: { kind: "Endpoint", - group: "v1", + group: "", namespaced: true, }, events: { kind: "Event", - group: "v1", + group: "", namespaced: true, }, horizontalpodautoscalers: { @@ -99,17 +103,17 @@ export const apiResourceRecord: Record = { }, namespaces: { kind: "Namespace", - group: "v1", + group: "", namespaced: false, }, limitranges: { kind: "LimitRange", - group: "v1", + group: "", namespaced: true, }, leases: { kind: "Lease", - group: "v1", + group: "", namespaced: true, }, networkpolicies: { @@ -119,22 +123,22 @@ export const apiResourceRecord: Record = { }, nodes: { kind: "Node", - group: "v1", + group: "", namespaced: false, }, persistentvolumes: { kind: "PersistentVolume", - group: "v1", + group: "", namespaced: false, }, persistentvolumeclaims: { kind: "PersistentVolumeClaim", - group: "v1", + group: "", namespaced: true, }, pods: { kind: "Pod", - group: "v1", + group: "", namespaced: true, }, poddisruptionbudgets: { @@ -159,7 +163,7 @@ export const apiResourceRecord: Record = { }, resourcequotas: { kind: "ResourceQuota", - group: "v1", + group: "", namespaced: true, }, replicasets: { @@ -179,17 +183,17 @@ export const apiResourceRecord: Record = { }, secrets: { kind: "Secret", - group: "v1", + group: "", namespaced: true, }, serviceaccounts: { kind: "ServiceAccount", - group: "v1", + group: "", namespaced: true, }, services: { kind: "Service", - group: "v1", + group: "", namespaced: true, }, statefulsets: { diff --git a/packages/core/src/common/utils/__tests__/iter.test.ts b/packages/core/src/common/utils/__tests__/iter.test.ts index e41894e662..2489649d90 100644 --- a/packages/core/src/common/utils/__tests__/iter.test.ts +++ b/packages/core/src/common/utils/__tests__/iter.test.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { join, nth, reduce } from "../iter"; +import { join, nth, reduce, concat } from "../iter"; describe("iter", () => { describe("reduce", () => { @@ -39,4 +39,30 @@ describe("iter", () => { expect(nth(["a", "b"], 0)).toBe("a"); }); }); + + describe("concat", () => { + it("should yield undefined for empty args", () => { + const iter = concat(); + + expect(iter.next()).toEqual({ done: true }); + }); + + it("should yield undefined for only empty args", () => { + const iter = concat([].values(), [].values(), [].values(), [].values()); + + expect(iter.next()).toEqual({ done: true }); + }); + + it("should yield all of the first and then all of the second", () => { + const iter = concat([1, 2, 3].values(), [4, 5, 6].values()); + + expect(iter.next()).toEqual({ done: false, value: 1 }); + expect(iter.next()).toEqual({ done: false, value: 2 }); + expect(iter.next()).toEqual({ done: false, value: 3 }); + expect(iter.next()).toEqual({ done: false, value: 4 }); + expect(iter.next()).toEqual({ done: false, value: 5 }); + expect(iter.next()).toEqual({ done: false, value: 6 }); + expect(iter.next()).toEqual({ done: true }); + }); + }); }); diff --git a/packages/core/src/common/utils/iter.ts b/packages/core/src/common/utils/iter.ts index 5b5593d2d4..dc1c4621fd 100644 --- a/packages/core/src/common/utils/iter.ts +++ b/packages/core/src/common/utils/iter.ts @@ -12,6 +12,7 @@ interface Iterator extends Iterable { collect(fn: (values: Iterable) => U): U; map(fn: (val: T) => U): Iterator; flatMap(fn: (val: T) => U[]): Iterator; + concat(src2: IterableIterator): Iterator; join(sep?: string): string; } @@ -24,6 +25,7 @@ export function chain(src: IterableIterator): Iterator { find: (fn) => find(src, fn), join: (sep) => join(src, sep), collect: (fn) => fn(src), + concat: (src2) => chain(concat(src, src2)), [Symbol.iterator]: () => src, }; } @@ -236,3 +238,11 @@ export function every(src: Iterable, fn: (val: T) => any): boolean { return true; } + +export function* concat(...sources: IterableIterator[]): IterableIterator { + for (const source of sources) { + for (const val of source) { + yield val; + } + } +} diff --git a/packages/core/src/extensions/common-api/k8s-api.ts b/packages/core/src/extensions/common-api/k8s-api.ts index 3856429717..c24f7d14e3 100644 --- a/packages/core/src/extensions/common-api/k8s-api.ts +++ b/packages/core/src/extensions/common-api/k8s-api.ts @@ -26,10 +26,12 @@ import loggerInjectable from "../../common/logger.injectable"; import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; import maybeKubeApiInjectable from "../../common/k8s-api/maybe-kube-api.injectable"; import { DeploymentApi as InternalDeploymentApi, IngressApi as InternalIngressApi, NodeApi, PersistentVolumeClaimApi, PodApi } from "../../common/k8s-api/endpoints"; +import { storesAndApisCanBeCreatedInjectionToken } from "../../common/k8s-api/stores-apis-can-be-created.token"; export const apiManager = asLegacyGlobalForExtensionApi(apiManagerInjectable); export const forCluster = asLegacyGlobalFunctionForExtensionApi(createKubeApiForClusterInjectable); export const forRemoteCluster = asLegacyGlobalFunctionForExtensionApi(createKubeApiForRemoteClusterInjectable); +export const createResourceStack = asLegacyGlobalFunctionForExtensionApi(createResourceStackInjectable); const getKubeApiDeps = (): KubeApiDependencies => { const di = getLegacyGlobalDiForExtensionApi(); @@ -45,7 +47,16 @@ function KubeApiCstr< Object extends KubeObject = KubeObject, Data extends KubeJsonApiDataFor = KubeJsonApiDataFor, >(opts: KubeApiOptions) { - return new InternalKubeApi(getKubeApiDeps(), opts); + const api = new InternalKubeApi(getKubeApiDeps(), opts); + + const di = getLegacyGlobalDiForExtensionApi(); + const storesAndApisCanBeCreated = di.inject(storesAndApisCanBeCreatedInjectionToken); + + if (storesAndApisCanBeCreated) { + apiManager.registerApi(api); + } + + return api; } export const KubeApi = KubeApiCstr as unknown as new< @@ -53,8 +64,6 @@ export const KubeApi = KubeApiCstr as unknown as new< Data extends KubeJsonApiDataFor = KubeJsonApiDataFor, >(opts: KubeApiOptions) => InternalKubeApi; -export const createResourceStack = asLegacyGlobalFunctionForExtensionApi(createResourceStackInjectable); - /** * @deprecated Switch to using `Common.createResourceStack` instead */ @@ -174,31 +183,31 @@ export interface IgnoredKubeApiOptions { // NOTE: these *Constructor functions MUST be `function` to work with `new X()` function PodsApiConstructor(opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) { - return new PodApi(getKubeApiDeps(), opts ?? {}); + return new PodApi(getKubeApiDeps(), opts); } export const PodsApi = PodsApiConstructor as unknown as new (opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) => PodApi; function NodesApiConstructor(opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) { - return new NodeApi(getKubeApiDeps(), opts ?? {}); + return new NodeApi(getKubeApiDeps(), opts); } export const NodesApi = NodesApiConstructor as unknown as new (opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) => NodeApi; function DeploymentApiConstructor(opts?: DerivedKubeApiOptions) { - return new InternalDeploymentApi(getKubeApiDeps(), opts ?? {}); + return new InternalDeploymentApi(getKubeApiDeps(), opts); } export const DeploymentApi = DeploymentApiConstructor as unknown as new (opts?: DerivedKubeApiOptions) => InternalDeploymentApi; function IngressApiConstructor(opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) { - return new InternalIngressApi(getKubeApiDeps(), opts ?? {}); + return new InternalIngressApi(getKubeApiDeps(), opts); } export const IngressApi = IngressApiConstructor as unknown as new (opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) => InternalIngressApi; function PersistentVolumeClaimsApiConstructor(opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) { - return new PersistentVolumeClaimApi(getKubeApiDeps(), opts ?? {}); + return new PersistentVolumeClaimApi(getKubeApiDeps(), opts); } export const PersistentVolumeClaimsApi = PersistentVolumeClaimsApiConstructor as unknown as new (opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) => PersistentVolumeClaimApi; diff --git a/packages/core/src/extensions/common-api/registrations.ts b/packages/core/src/extensions/common-api/registrations.ts index 50a9262419..3592d7950e 100644 --- a/packages/core/src/extensions/common-api/registrations.ts +++ b/packages/core/src/extensions/common-api/registrations.ts @@ -14,3 +14,4 @@ export type { CustomCategoryViewProps, CustomCategoryViewComponents, CustomCateg export type { ShellEnvModifier, ShellEnvContext } from "../../main/shell-session/shell-env-modifier/shell-env-modifier-registration"; export type { KubeObjectContextMenuItem, KubeObjectOnContextMenuOpenContext, KubeObjectOnContextMenuOpen, KubeObjectHandlers, KubeObjectHandlerRegistration } from "../../renderer/kube-object/handler"; export type { TrayMenuRegistration } from "../../main/tray/tray-menu-registration"; +export type { MenuRegistration } from "../../features/application-menu/main/menu-registration"; diff --git a/packages/core/src/extensions/lens-main-extension.ts b/packages/core/src/extensions/lens-main-extension.ts index b97d8da834..63daab9ba4 100644 --- a/packages/core/src/extensions/lens-main-extension.ts +++ b/packages/core/src/extensions/lens-main-extension.ts @@ -12,7 +12,7 @@ import type { ShellEnvModifier } from "../main/shell-session/shell-env-modifier/ import type { LensMainExtensionDependencies } from "./lens-extension-set-dependencies"; export class LensMainExtension extends LensExtension { - appMenus: MenuRegistration[] = []; + appMenus: MenuRegistration[] | IComputedValue = []; trayMenus: TrayMenuRegistration[] | IComputedValue = []; /** diff --git a/packages/core/src/features/application-menu/main/application-menu-item-registrator.injectable.ts b/packages/core/src/features/application-menu/main/application-menu-item-registrator.injectable.ts index 8c3d635db0..b2e7367bbb 100644 --- a/packages/core/src/features/application-menu/main/application-menu-item-registrator.injectable.ts +++ b/packages/core/src/features/application-menu/main/application-menu-item-registrator.injectable.ts @@ -2,6 +2,7 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ +import { computed } from "mobx"; import type { Injectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable"; import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token"; @@ -25,11 +26,15 @@ const applicationMenuItemRegistratorInjectable = getInjectable({ const toRecursedInjectables = toRecursedInjectablesFor(logError); return (ext: LensExtension) => { - const extension = ext as LensMainExtension; + const mainExtension = ext as LensMainExtension; - return extension.appMenus.flatMap( - toRecursedInjectables([extension.sanitizedExtensionId]), - ); + return computed(() => { + const appMenus = Array.isArray(mainExtension.appMenus) ? mainExtension.appMenus : mainExtension.appMenus.get(); + + return appMenus.flatMap( + toRecursedInjectables([mainExtension.sanitizedExtensionId]), + ); + }); }; }, diff --git a/packages/core/src/features/application-menu/main/menu-registration.ts b/packages/core/src/features/application-menu/main/menu-registration.ts index 8f0ba5933f..3dc75ba077 100644 --- a/packages/core/src/features/application-menu/main/menu-registration.ts +++ b/packages/core/src/features/application-menu/main/menu-registration.ts @@ -3,7 +3,9 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import type { MenuItemConstructorOptions } from "electron"; +import type { IComputedValue } from "mobx"; -export interface MenuRegistration extends MenuItemConstructorOptions { +export type MenuRegistration = { parentId: string; -} + visible?: IComputedValue | boolean; +} & Omit; diff --git a/packages/core/src/features/cluster/kube-object-details/extension-api/reactively-hide-kube-object-detail-item.test.tsx b/packages/core/src/features/cluster/kube-object-details/extension-api/reactively-hide-kube-object-detail-item.test.tsx index 1a22d5d0b0..847ad3ed11 100644 --- a/packages/core/src/features/cluster/kube-object-details/extension-api/reactively-hide-kube-object-detail-item.test.tsx +++ b/packages/core/src/features/cluster/kube-object-details/extension-api/reactively-hide-kube-object-detail-item.test.tsx @@ -13,6 +13,7 @@ import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager import type { KubeObjectStore } from "../../../../common/k8s-api/kube-object.store"; import type { KubeApi } from "../../../../common/k8s-api/kube-api"; import showDetailsInjectable from "../../../../renderer/components/kube-detail-params/show-details.injectable"; +import assert from "assert"; describe("reactively hide kube object detail item", () => { let builder: ApplicationBuilder; @@ -89,6 +90,10 @@ describe("reactively hide kube object detail item", () => { runInAction(() => { someObservable.set(true); }); + + const apiManager = builder.applicationWindow.only.di.inject(apiManagerInjectable); + + assert(apiManager.getStore("/apis/some-api-version/some-kind")); }); it("renders", () => { diff --git a/packages/core/src/features/cluster/namespaces/edit-namespace-from-new-tab.test.tsx b/packages/core/src/features/cluster/namespaces/edit-namespace-from-new-tab.test.tsx index a3761caf21..c6102f3f24 100644 --- a/packages/core/src/features/cluster/namespaces/edit-namespace-from-new-tab.test.tsx +++ b/packages/core/src/features/cluster/namespaces/edit-namespace-from-new-tab.test.tsx @@ -66,7 +66,7 @@ describe("cluster/namespaces - edit namespace from new tab", () => { builder.allowKubeResource({ apiName: "namespaces", - group: "v1", + group: "", }); }); diff --git a/packages/core/src/features/cluster/namespaces/edit-namespace-from-previously-opened-tab.test.tsx b/packages/core/src/features/cluster/namespaces/edit-namespace-from-previously-opened-tab.test.tsx index 0d49469951..c5bbd15dfc 100644 --- a/packages/core/src/features/cluster/namespaces/edit-namespace-from-previously-opened-tab.test.tsx +++ b/packages/core/src/features/cluster/namespaces/edit-namespace-from-previously-opened-tab.test.tsx @@ -37,7 +37,7 @@ describe("cluster/namespaces - edit namespaces from previously opened tab", () = builder.allowKubeResource({ apiName: "namespaces", - group: "v1", + group: "", }); }); diff --git a/packages/core/src/features/cluster/visibility-of-sidebar-items.test.tsx b/packages/core/src/features/cluster/visibility-of-sidebar-items.test.tsx index 2eb42b7fdf..8fd68044a6 100644 --- a/packages/core/src/features/cluster/visibility-of-sidebar-items.test.tsx +++ b/packages/core/src/features/cluster/visibility-of-sidebar-items.test.tsx @@ -52,7 +52,7 @@ describe("cluster - visibility of sidebar items", () => { beforeEach(() => { builder.allowKubeResource({ apiName: "namespaces", - group: "v1", + group: "", }); }); @@ -77,7 +77,7 @@ const testRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "namespaces", - group: "v1", + group: "", }), }), diff --git a/packages/core/src/features/cluster/workload-overview.test.tsx b/packages/core/src/features/cluster/workload-overview.test.tsx index 205c837b47..725ec04e90 100644 --- a/packages/core/src/features/cluster/workload-overview.test.tsx +++ b/packages/core/src/features/cluster/workload-overview.test.tsx @@ -15,7 +15,7 @@ describe("workload overview", () => { applicationBuilder = getApplicationBuilder().setEnvironmentToClusterFrame(); applicationBuilder.allowKubeResource({ apiName: "pods", - group: "v1", + group: "", }); rendered = await applicationBuilder.render(); }); diff --git a/packages/core/src/main/cluster/manager.ts b/packages/core/src/main/cluster/manager.ts index 6888a44f5f..650a3b7752 100644 --- a/packages/core/src/main/cluster/manager.ts +++ b/packages/core/src/main/cluster/manager.ts @@ -145,31 +145,31 @@ export class ClusterManager { } else { entity.status.phase = (() => { if (!cluster) { - this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="no cluster"`); + this.dependencies.logger.silly(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="no cluster"`); return LensKubernetesClusterStatus.DISCONNECTED; } if (cluster.accessible) { - this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to CONNECTED, reason="cluster is accessible"`); + this.dependencies.logger.silly(`${logPrefix} setting entity ${entity.getName()} to CONNECTED, reason="cluster is accessible"`); return LensKubernetesClusterStatus.CONNECTED; } if (!cluster.disconnected) { - this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to CONNECTING, reason="cluster is not disconnected"`); + this.dependencies.logger.silly(`${logPrefix} setting entity ${entity.getName()} to CONNECTING, reason="cluster is not disconnected"`); return LensKubernetesClusterStatus.CONNECTING; } // Extensions are not allowed to use the Lens specific status phases if (!lensSpecificClusterStatuses.has(entity?.status?.phase)) { - this.dependencies.logger.debug(`${logPrefix} not clearing entity ${entity.getName()} status, reason="custom string"`); + this.dependencies.logger.silly(`${logPrefix} not clearing entity ${entity.getName()} status, reason="custom string"`); return entity.status.phase; } - this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="fallthrough"`); + this.dependencies.logger.silly(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="fallthrough"`); return LensKubernetesClusterStatus.DISCONNECTED; })(); diff --git a/packages/core/src/main/cluster/request-core-api-versions.injectable.ts b/packages/core/src/main/cluster/request-core-api-versions.injectable.ts index e92def914e..4287eb4d3b 100644 --- a/packages/core/src/main/cluster/request-core-api-versions.injectable.ts +++ b/packages/core/src/main/cluster/request-core-api-versions.injectable.ts @@ -16,7 +16,7 @@ const requestCoreApiVersionsInjectable = getInjectable({ const { versions } = await k8sRequest(cluster, "/api") as V1APIVersions; return versions.map(version => ({ - group: version, + group: "", path: `/api/${version}`, })); }; diff --git a/packages/core/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.injectable.ts b/packages/core/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.injectable.ts index 2d6ece0dfd..1b64040d40 100644 --- a/packages/core/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.injectable.ts +++ b/packages/core/src/renderer/components/+cluster/cluster-overview-store/cluster-overview-store.injectable.ts @@ -7,7 +7,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import type { ClusterOverviewStorageState } from "./cluster-overview-store"; import { ClusterOverviewStore, MetricNodeRole, MetricType } from "./cluster-overview-store"; import createStorageInjectable from "../../../utils/create-storage/create-storage.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import clusterApiInjectable from "../../../../common/k8s-api/endpoints/cluster.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable"; import assert from "assert"; diff --git a/packages/core/src/renderer/components/+config-autoscalers/store.injectable.ts b/packages/core/src/renderer/components/+config-autoscalers/store.injectable.ts index 47a0f25680..6b09568537 100644 --- a/packages/core/src/renderer/components/+config-autoscalers/store.injectable.ts +++ b/packages/core/src/renderer/components/+config-autoscalers/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import horizontalPodAutoscalerApiInjectable from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+config-leases/store.injectable.ts b/packages/core/src/renderer/components/+config-leases/store.injectable.ts index df91a1df54..26cf598aff 100644 --- a/packages/core/src/renderer/components/+config-leases/store.injectable.ts +++ b/packages/core/src/renderer/components/+config-leases/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import leaseApiInjectable from "../../../common/k8s-api/endpoints/lease.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+config-limit-ranges/store.injectable.ts b/packages/core/src/renderer/components/+config-limit-ranges/store.injectable.ts index f22aadaec1..5109b25079 100644 --- a/packages/core/src/renderer/components/+config-limit-ranges/store.injectable.ts +++ b/packages/core/src/renderer/components/+config-limit-ranges/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import limitRangeApiInjectable from "../../../common/k8s-api/endpoints/limit-range.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+config-maps/store.injectable.ts b/packages/core/src/renderer/components/+config-maps/store.injectable.ts index 44945120f0..e282e4d121 100644 --- a/packages/core/src/renderer/components/+config-maps/store.injectable.ts +++ b/packages/core/src/renderer/components/+config-maps/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import configMapApiInjectable from "../../../common/k8s-api/endpoints/config-map.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+config-pod-disruption-budgets/store.injectable.ts b/packages/core/src/renderer/components/+config-pod-disruption-budgets/store.injectable.ts index f6bb813455..3f3b83e21f 100644 --- a/packages/core/src/renderer/components/+config-pod-disruption-budgets/store.injectable.ts +++ b/packages/core/src/renderer/components/+config-pod-disruption-budgets/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import podDisruptionBudgetApiInjectable from "../../../common/k8s-api/endpoints/pod-disruption-budget.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+config-priority-classes/store.injectable.ts b/packages/core/src/renderer/components/+config-priority-classes/store.injectable.ts index acd97aee5b..e3e22a53b9 100644 --- a/packages/core/src/renderer/components/+config-priority-classes/store.injectable.ts +++ b/packages/core/src/renderer/components/+config-priority-classes/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import priorityClassApiInjectable from "../../../common/k8s-api/endpoints/priority-class.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/packages/core/src/renderer/components/+config-resource-quotas/store.injectable.ts b/packages/core/src/renderer/components/+config-resource-quotas/store.injectable.ts index 77708a1bf4..cbbb014d05 100644 --- a/packages/core/src/renderer/components/+config-resource-quotas/store.injectable.ts +++ b/packages/core/src/renderer/components/+config-resource-quotas/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import resourceQuotaApiInjectable from "../../../common/k8s-api/endpoints/resource-quota.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+config-runtime-classes/store.injectable.ts b/packages/core/src/renderer/components/+config-runtime-classes/store.injectable.ts index 03d4e50a1a..70c0efa6c4 100644 --- a/packages/core/src/renderer/components/+config-runtime-classes/store.injectable.ts +++ b/packages/core/src/renderer/components/+config-runtime-classes/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import runtimeClassApiInjectable from "../../../common/k8s-api/endpoints/runtime-class.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/packages/core/src/renderer/components/+config-secrets/store.injectable.ts b/packages/core/src/renderer/components/+config-secrets/store.injectable.ts index d98f3677c1..a18fff90b2 100644 --- a/packages/core/src/renderer/components/+config-secrets/store.injectable.ts +++ b/packages/core/src/renderer/components/+config-secrets/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import secretApiInjectable from "../../../common/k8s-api/endpoints/secret.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+custom-resources/definition.store.injectable.ts b/packages/core/src/renderer/components/+custom-resources/definition.store.injectable.ts index 47c7652f8b..f1d8f635b8 100644 --- a/packages/core/src/renderer/components/+custom-resources/definition.store.injectable.ts +++ b/packages/core/src/renderer/components/+custom-resources/definition.store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; 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 { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import customResourceDefinitionApiInjectable from "../../../common/k8s-api/endpoints/custom-resource-definition.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/packages/core/src/renderer/components/+events/store.injectable.ts b/packages/core/src/renderer/components/+events/store.injectable.ts index 57bc98e6d2..b81a198413 100644 --- a/packages/core/src/renderer/components/+events/store.injectable.ts +++ b/packages/core/src/renderer/components/+events/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import getPodByIdInjectable from "../+workloads-pods/get-pod-by-id.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import kubeEventApiInjectable from "../../../common/k8s-api/endpoints/events.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+namespaces/store.injectable.ts b/packages/core/src/renderer/components/+namespaces/store.injectable.ts index 50164e6626..1ee9dc024f 100644 --- a/packages/core/src/renderer/components/+namespaces/store.injectable.ts +++ b/packages/core/src/renderer/components/+namespaces/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { NamespaceStore } from "./store"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import createStorageInjectable from "../../utils/create-storage/create-storage.injectable"; import namespaceApiInjectable from "../../../common/k8s-api/endpoints/namespace.api.injectable"; import assert from "assert"; diff --git a/packages/core/src/renderer/components/+network-endpoints/store.injectable.ts b/packages/core/src/renderer/components/+network-endpoints/store.injectable.ts index d376b039a0..ee8474c8a8 100644 --- a/packages/core/src/renderer/components/+network-endpoints/store.injectable.ts +++ b/packages/core/src/renderer/components/+network-endpoints/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import endpointsApiInjectable from "../../../common/k8s-api/endpoints/endpoint.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+network-ingresses/ingress-class-store.injectable.ts b/packages/core/src/renderer/components/+network-ingresses/ingress-class-store.injectable.ts index 9379b4ff59..98315f91ac 100644 --- a/packages/core/src/renderer/components/+network-ingresses/ingress-class-store.injectable.ts +++ b/packages/core/src/renderer/components/+network-ingresses/ingress-class-store.injectable.ts @@ -4,10 +4,9 @@ */ import assert from "assert"; import { getInjectable } from "@ogre-tools/injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import ingressClassApiInjectable from "../../../common/k8s-api/endpoints/ingress-class.api.injectable"; import { IngressClassStore } from "./ingress-class-store"; - import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; import loggerInjectable from "../../../common/logger.injectable"; diff --git a/packages/core/src/renderer/components/+network-ingresses/ingress-store.injectable.ts b/packages/core/src/renderer/components/+network-ingresses/ingress-store.injectable.ts index 8f5f1e6e39..ebd460664e 100644 --- a/packages/core/src/renderer/components/+network-ingresses/ingress-store.injectable.ts +++ b/packages/core/src/renderer/components/+network-ingresses/ingress-store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import ingressApiInjectable from "../../../common/k8s-api/endpoints/ingress.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+network-policies/store.injectable.ts b/packages/core/src/renderer/components/+network-policies/store.injectable.ts index b17c0918d9..b3d7cfa0bf 100644 --- a/packages/core/src/renderer/components/+network-policies/store.injectable.ts +++ b/packages/core/src/renderer/components/+network-policies/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import networkPolicyApiInjectable from "../../../common/k8s-api/endpoints/network-policy.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+network-services/store.injectable.ts b/packages/core/src/renderer/components/+network-services/store.injectable.ts index d705ca0d46..a4a2f831eb 100644 --- a/packages/core/src/renderer/components/+network-services/store.injectable.ts +++ b/packages/core/src/renderer/components/+network-services/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import serviceApiInjectable from "../../../common/k8s-api/endpoints/service.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+nodes/store.injectable.ts b/packages/core/src/renderer/components/+nodes/store.injectable.ts index a397db07e1..b12845b6a4 100644 --- a/packages/core/src/renderer/components/+nodes/store.injectable.ts +++ b/packages/core/src/renderer/components/+nodes/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import nodeApiInjectable from "../../../common/k8s-api/endpoints/node.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/packages/core/src/renderer/components/+pod-security-policies/store.injectable.ts b/packages/core/src/renderer/components/+pod-security-policies/store.injectable.ts index 2e27ad466a..0c90fa571e 100644 --- a/packages/core/src/renderer/components/+pod-security-policies/store.injectable.ts +++ b/packages/core/src/renderer/components/+pod-security-policies/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import podSecurityPolicyApiInjectable from "../../../common/k8s-api/endpoints/pod-security-policy.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/packages/core/src/renderer/components/+storage-classes/store.injectable.ts b/packages/core/src/renderer/components/+storage-classes/store.injectable.ts index 0ae16b0a92..b0508f01fd 100644 --- a/packages/core/src/renderer/components/+storage-classes/store.injectable.ts +++ b/packages/core/src/renderer/components/+storage-classes/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; 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 { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import storageClassApiInjectable from "../../../common/k8s-api/endpoints/storage-class.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/packages/core/src/renderer/components/+storage-volume-claims/store.injectable.ts b/packages/core/src/renderer/components/+storage-volume-claims/store.injectable.ts index ef9b4629fa..a9289a1fd0 100644 --- a/packages/core/src/renderer/components/+storage-volume-claims/store.injectable.ts +++ b/packages/core/src/renderer/components/+storage-volume-claims/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import persistentVolumeClaimApiInjectable from "../../../common/k8s-api/endpoints/persistent-volume-claim.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+storage-volumes/store.injectable.ts b/packages/core/src/renderer/components/+storage-volumes/store.injectable.ts index 1432c0ed6c..00a0db0c8c 100644 --- a/packages/core/src/renderer/components/+storage-volumes/store.injectable.ts +++ b/packages/core/src/renderer/components/+storage-volumes/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import persistentVolumeApiInjectable from "../../../common/k8s-api/endpoints/persistent-volume.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/packages/core/src/renderer/components/+user-management/+cluster-role-bindings/store.injectable.ts b/packages/core/src/renderer/components/+user-management/+cluster-role-bindings/store.injectable.ts index ac3eb8a07d..54250222d3 100644 --- a/packages/core/src/renderer/components/+user-management/+cluster-role-bindings/store.injectable.ts +++ b/packages/core/src/renderer/components/+user-management/+cluster-role-bindings/store.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { storesAndApisCanBeCreatedInjectionToken } from "../../../../common/k8s-api/stores-apis-can-be-created.token"; import clusterRoleBindingApiInjectable from "../../../../common/k8s-api/endpoints/cluster-role-binding.api.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import { ClusterRoleBindingStore } from "./store"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../../cluster-frame-context/for-cluster-scoped-resources.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; diff --git a/packages/core/src/renderer/components/+user-management/+cluster-roles/store.injectable.ts b/packages/core/src/renderer/components/+user-management/+cluster-roles/store.injectable.ts index c88b457b1d..d7ea148d03 100644 --- a/packages/core/src/renderer/components/+user-management/+cluster-roles/store.injectable.ts +++ b/packages/core/src/renderer/components/+user-management/+cluster-roles/store.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { storesAndApisCanBeCreatedInjectionToken } from "../../../../common/k8s-api/stores-apis-can-be-created.token"; import clusterRoleApiInjectable from "../../../../common/k8s-api/endpoints/cluster-role.api.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import { ClusterRoleStore } from "./store"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../../cluster-frame-context/for-cluster-scoped-resources.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; diff --git a/packages/core/src/renderer/components/+user-management/+role-bindings/store.injectable.ts b/packages/core/src/renderer/components/+user-management/+role-bindings/store.injectable.ts index 416223b071..e9b9154068 100644 --- a/packages/core/src/renderer/components/+user-management/+role-bindings/store.injectable.ts +++ b/packages/core/src/renderer/components/+user-management/+role-bindings/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import roleBindingApiInjectable from "../../../../common/k8s-api/endpoints/role-binding.api.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+user-management/+roles/store.injectable.ts b/packages/core/src/renderer/components/+user-management/+roles/store.injectable.ts index f0df652438..99eddcbfa0 100644 --- a/packages/core/src/renderer/components/+user-management/+roles/store.injectable.ts +++ b/packages/core/src/renderer/components/+user-management/+roles/store.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import roleApiInjectable from "../../../../common/k8s-api/endpoints/role.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import { RoleStore } from "./store"; import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; diff --git a/packages/core/src/renderer/components/+user-management/+service-accounts/store.injectable.ts b/packages/core/src/renderer/components/+user-management/+service-accounts/store.injectable.ts index fd96db2d65..a4749f7ecb 100644 --- a/packages/core/src/renderer/components/+user-management/+service-accounts/store.injectable.ts +++ b/packages/core/src/renderer/components/+user-management/+service-accounts/store.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import serviceAccountApiInjectable from "../../../../common/k8s-api/endpoints/service-account.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import { ServiceAccountStore } from "./store"; import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; diff --git a/packages/core/src/renderer/components/+workloads-cronjobs/store.injectable.ts b/packages/core/src/renderer/components/+workloads-cronjobs/store.injectable.ts index 2569e77440..98d539a9ce 100644 --- a/packages/core/src/renderer/components/+workloads-cronjobs/store.injectable.ts +++ b/packages/core/src/renderer/components/+workloads-cronjobs/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; 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 { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import cronJobApiInjectable from "../../../common/k8s-api/endpoints/cron-job.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+workloads-daemonsets/store.injectable.ts b/packages/core/src/renderer/components/+workloads-daemonsets/store.injectable.ts index 59252688bf..4b79b19bb5 100644 --- a/packages/core/src/renderer/components/+workloads-daemonsets/store.injectable.ts +++ b/packages/core/src/renderer/components/+workloads-daemonsets/store.injectable.ts @@ -7,7 +7,7 @@ import assert from "assert"; import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable"; import daemonSetApiInjectable from "../../../common/k8s-api/endpoints/daemon-set.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import { DaemonSetStore } from "./store"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import loggerInjectable from "../../../common/logger.injectable"; diff --git a/packages/core/src/renderer/components/+workloads-deployments/store.injectable.ts b/packages/core/src/renderer/components/+workloads-deployments/store.injectable.ts index 1a6a9f7df1..50ae255e21 100644 --- a/packages/core/src/renderer/components/+workloads-deployments/store.injectable.ts +++ b/packages/core/src/renderer/components/+workloads-deployments/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import podStoreInjectable from "../+workloads-pods/store.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; 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"; diff --git a/packages/core/src/renderer/components/+workloads-jobs/store.injectable.ts b/packages/core/src/renderer/components/+workloads-jobs/store.injectable.ts index 28d3806788..083b465ded 100644 --- a/packages/core/src/renderer/components/+workloads-jobs/store.injectable.ts +++ b/packages/core/src/renderer/components/+workloads-jobs/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; 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 { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import jobApiInjectable from "../../../common/k8s-api/endpoints/job.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts b/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts index 452f7903aa..246469b9e7 100644 --- a/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts +++ b/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts @@ -21,7 +21,7 @@ const podsWorkloadInjectable = getInjectable({ return { resource: { apiName: "pods", - group: "v1", + group: "", }, open: navigate, diff --git a/packages/core/src/renderer/components/+workloads-pods/store.injectable.ts b/packages/core/src/renderer/components/+workloads-pods/store.injectable.ts index 473cd80c5c..7b2bc23419 100644 --- a/packages/core/src/renderer/components/+workloads-pods/store.injectable.ts +++ b/packages/core/src/renderer/components/+workloads-pods/store.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import podApiInjectable from "../../../common/k8s-api/endpoints/pod.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import { PodStore } from "./store"; import podMetricsApiInjectable from "../../../common/k8s-api/endpoints/pod-metrics.api.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/+workloads-replicasets/store.injectable.ts b/packages/core/src/renderer/components/+workloads-replicasets/store.injectable.ts index b54fd0295d..34887a0590 100644 --- a/packages/core/src/renderer/components/+workloads-replicasets/store.injectable.ts +++ b/packages/core/src/renderer/components/+workloads-replicasets/store.injectable.ts @@ -7,7 +7,7 @@ import assert from "assert"; import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable"; import replicaSetApiInjectable from "../../../common/k8s-api/endpoints/replica-set.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import { ReplicaSetStore } from "./store"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import loggerInjectable from "../../../common/logger.injectable"; diff --git a/packages/core/src/renderer/components/+workloads-statefulsets/store.injectable.ts b/packages/core/src/renderer/components/+workloads-statefulsets/store.injectable.ts index ce8649b109..b8fef46c51 100644 --- a/packages/core/src/renderer/components/+workloads-statefulsets/store.injectable.ts +++ b/packages/core/src/renderer/components/+workloads-statefulsets/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; 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 { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import statefulSetApiInjectable from "../../../common/k8s-api/endpoints/stateful-set.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/packages/core/src/renderer/components/kube-object-list-layout/__snapshots__/kube-object-list-layout.test.tsx.snap b/packages/core/src/renderer/components/kube-object-list-layout/__snapshots__/kube-object-list-layout.test.tsx.snap new file mode 100644 index 0000000000..b450030c9c --- /dev/null +++ b/packages/core/src/renderer/components/kube-object-list-layout/__snapshots__/kube-object-list-layout.test.tsx.snap @@ -0,0 +1,121 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`kube-object-list-layout given pod store renders 1`] = ` + +
+
+
+
+
+ Pods +
+
+ 0 items +
+
+
+ + +
+
+
+ All namespaces +
+
+ +
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +`; diff --git a/packages/core/src/renderer/components/kube-object-list-layout/kube-object-list-layout.test.tsx b/packages/core/src/renderer/components/kube-object-list-layout/kube-object-list-layout.test.tsx new file mode 100644 index 0000000000..d50d70c723 --- /dev/null +++ b/packages/core/src/renderer/components/kube-object-list-layout/kube-object-list-layout.test.tsx @@ -0,0 +1,108 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { DiContainer } from "@ogre-tools/injectable"; +import "@testing-library/jest-dom/extend-expect"; +import type { RenderResult } from "@testing-library/react"; +import React from "react"; +import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable"; +import { getDiForUnitTesting } from "../../getDiForUnitTesting"; +import kubeSelectedUrlParamInjectable from "../kube-detail-params/kube-selected-url.injectable"; +import toggleKubeDetailsPaneInjectable from "../kube-detail-params/toggle-details.injectable"; +import type { DiRender } from "../test-utils/renderFor"; +import { renderFor } from "../test-utils/renderFor"; +import { KubeObjectListLayout } from "./index"; +import appPathsStateInjectable from "../../../common/app-paths/app-paths-state.injectable"; +import podStoreInjectable from "../+workloads-pods/store.injectable"; +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 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 "../../../main/create-cluster/create-cluster.injectable"; +import type { PodStore } from "../+workloads-pods/store"; + +describe("kube-object-list-layout", () => { + let di: DiContainer; + let render: DiRender; + let podStore: PodStore; + + beforeEach(() => { + 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", + })); + + render = renderFor(di); + + di.override(subscribeStoresInjectable, () => jest.fn().mockImplementation(() => jest.fn())); + di.override(kubeSelectedUrlParamInjectable, () => ({ + get: () => "path", + })); + di.override(toggleKubeDetailsPaneInjectable, () => null); + di.override(appPathsStateInjectable, () => ({ + get: () => ({}), + })); + + podStore = di.inject(podStoreInjectable); + }); + + describe("given pod store", () => { + let result: RenderResult; + + it("renders", () => { + result = render(( +
+ [ +
{pod.getName()}
, + ]} + /> +
+ )); + + expect(result.baseElement).toMatchSnapshot(); + }); + + describe("given resourcename", () => { + it("uses resourcename in search placeholder", () => { + result = render(( +
+ [ +
{pod.getName()}
, + ]} + resourceName="My Custom Items" + searchFilters={[() => null]} + /> +
+ )); + + expect(result.getByPlaceholderText("Search My Custom Items...")).toBeInTheDocument(); + }); + }); + }); +}); + + diff --git a/packages/core/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx b/packages/core/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx index 463bb8dd35..82929e788c 100644 --- a/packages/core/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx +++ b/packages/core/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx @@ -40,6 +40,12 @@ export interface KubeObjectListLayoutProps< store: KubeObjectStore; dependentStores?: SubscribableStore[]; subscribeStores?: boolean; + + /** + * Customize resource name for e.g. search input ("Search ..."") + * If not provided, ResourceNames is used instead with a fallback to resource kind. + */ + resourceName?: string; } interface Dependencies { @@ -132,7 +138,7 @@ class NonInjectedKubeObjectListLayout< onDetails, ...layoutProps } = this.props; - const placeholderString = ResourceNames[ResourceKindMap[store.api.kind]] || store.api.kind; + const resourceName = this.props.resourceName || ResourceNames[ResourceKindMap[store.api.kind]] || store.api.kind; return ( @@ -151,7 +157,7 @@ class NonInjectedKubeObjectListLayout< ), searchProps: { ...searchProps, - placeholder: `Search ${placeholderString}...`, + placeholder: `Search ${resourceName}...`, }, info: ( <> diff --git a/packages/core/src/renderer/frames/cluster-frame/cluster-frame.test.tsx b/packages/core/src/renderer/frames/cluster-frame/cluster-frame.test.tsx index 1a4cc82248..c403ad6b49 100644 --- a/packages/core/src/renderer/frames/cluster-frame/cluster-frame.test.tsx +++ b/packages/core/src/renderer/frames/cluster-frame/cluster-frame.test.tsx @@ -69,7 +69,7 @@ describe("", () => { describe("given cluster with list nodes and namespaces permissions", () => { beforeEach(() => { // TODO: replace with not using private info - (cluster as any).allowedResources.replace(["v1/nodes", "v1/namespaces"]); + (cluster as unknown as { readonly allowedResources: Cluster["allowedResources"] }).allowedResources.replace(["nodes", "namespaces"]); }); it("renders", () => { @@ -110,7 +110,7 @@ describe("", () => { describe("given cluster without list nodes, but with namespaces permissions", () => { beforeEach(() => { - (cluster as any).allowedResources.replace(["v1/namespaces"]); + (cluster as unknown as { readonly allowedResources: Cluster["allowedResources"] }).allowedResources.replace(["namespaces"]); }); it("renders", () => { diff --git a/packages/core/src/renderer/initializers/workload-events.tsx b/packages/core/src/renderer/initializers/workload-events.tsx index 735b4e2c74..73251382c8 100644 --- a/packages/core/src/renderer/initializers/workload-events.tsx +++ b/packages/core/src/renderer/initializers/workload-events.tsx @@ -34,7 +34,7 @@ export const WorkloadEvents = withInjectables getProps: (di, props) => ({ workloadEventsAreAllowed: di.inject(shouldShowResourceInjectionToken, { apiName: "events", - group: "v1", + group: "", }), ...props, }), diff --git a/packages/core/yarn.lock b/packages/core/yarn.lock index b57e5ed201..7079b6d560 100644 --- a/packages/core/yarn.lock +++ b/packages/core/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.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.14.tgz#f02c9f0d43086ddf6ed2795b881ddf7990f74456" - integrity sha512-hTqB6Iq13pW4xaydeqQrs8vPntUnMjbkq+PgGiBMi69eYk74naG2ftHWqKnxn874kNrt5Or3rQ0PJutx2doJuQ== +"@esbuild/android-arm64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz#cf91e86df127aa3d141744edafcba0abdc577d23" + integrity sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg== "@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.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.14.tgz#24e4faf569d0d6bbf9ed46f6ed395d68eb7f04fc" - integrity sha512-u0rITLxFIeYAvtJXBQNhNuV4YZe+MD1YvIWT7Nicj8hZAtRVZk2PgNH6KclcKDVHz1ChLKXRfX7d7tkbQBUfrg== +"@esbuild/android-arm@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz#025b6246d3f68b7bbaa97069144fb5fb70f2fff2" + integrity sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw== -"@esbuild/android-x64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.14.tgz#1173e706cf57c0d4dbf069d18e5d50ae6a5b0871" - integrity sha512-jir51K4J0K5Rt0KOcippjSNdOl7akKDVz5I6yrqdk4/m9y+rldGptQUF7qU4YpX8U61LtR+w2Tu2Ph+K/UaJOw== +"@esbuild/android-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.17.tgz#c820e0fef982f99a85c4b8bfdd582835f04cd96e" + integrity sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ== -"@esbuild/darwin-arm64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.14.tgz#67f05693c5b097bcb4ff656ba5839459f30f79c2" - integrity sha512-vrlaP81IuwPaw1fyX8fHCmivP3Gr73ojVEZy+oWJLAiZVcG8o8Phwun/XDnYIFUHxIoUnMFEpg9o38MIvlw8zw== +"@esbuild/darwin-arm64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz#edef4487af6b21afabba7be5132c26d22379b220" + integrity sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w== -"@esbuild/darwin-x64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.14.tgz#519c9d127c5363d4a1e73b9d954460f798b41d2a" - integrity sha512-KV1E01eC2hGYA2qzFDRCK4wdZCRUvMwCNcobgpiiOzp5QXpJBqFPdxI69j8vvzuU7oxFXDgANwEkXvpeQqyOyg== +"@esbuild/darwin-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz#42829168730071c41ef0d028d8319eea0e2904b4" + integrity sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg== -"@esbuild/freebsd-arm64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.14.tgz#2e3f5de2951a8ec732a3e4ec4f5d47a7c9626001" - integrity sha512-xRM1RQsazSvL42BNa5XC7ytD4ZDp0ZyJcH7aB0SlYUcHexJUKiDNKR7dlRVlpt6W0DvoRPU2nWK/9/QWS4u2fw== +"@esbuild/freebsd-arm64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz#1f4af488bfc7e9ced04207034d398e793b570a27" + integrity sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw== -"@esbuild/freebsd-x64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.14.tgz#d3cf84ff28357ac8d0123309bac37fcfcdd98f53" - integrity sha512-7ALTAn6YRRf1O6fw9jmn0rWmOx3XfwDo7njGtjy1LXhDGUjTY/vohEPM3ii5MQ411vJv1r498EEx2aBQTJcrEw== +"@esbuild/freebsd-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz#636306f19e9bc981e06aa1d777302dad8fddaf72" + integrity sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug== -"@esbuild/linux-arm64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.14.tgz#f44b0e3d5d470cd763a9bc4855a12b8cb73d6c12" - integrity sha512-TLh2OcbBUQcMYRH4GbiDkDZfZ4t1A3GgmeXY27dHSI6xrU7IkO00MGBiJySmEV6sH3Wa6pAN6UtaVL0DwkGW4Q== +"@esbuild/linux-arm64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz#a003f7ff237c501e095d4f3a09e58fc7b25a4aca" + integrity sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g== -"@esbuild/linux-arm@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.14.tgz#b239eb7e6cb7df9c34c6b08f4adf113da47e0e09" - integrity sha512-X6xULug66ulrr4IzrW7qq+eq9n4MtEyagdWvj4o4cmWr+JXOT47atjpDF9j5M2zHY0UQBmqnHhwl+tXpkpIb2w== +"@esbuild/linux-arm@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz#b591e6a59d9c4fe0eeadd4874b157ab78cf5f196" + integrity sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ== -"@esbuild/linux-ia32@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.14.tgz#f5f7886027cd61bed59178e981a0ef47ca5b72ef" - integrity sha512-oBZkcZ56UZDFCAfE3Fd/Jgy10EoS7Td77NzNGenM+HSY8BkdQAcI9VF9qgwdOLZ+tuftWD7UqZ26SAhtvA3XhA== +"@esbuild/linux-ia32@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz#24333a11027ef46a18f57019450a5188918e2a54" + integrity sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg== "@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.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.14.tgz#d2329371726f9778156c89ea0bed26fc1bc3cd7e" - integrity sha512-udz/aEHTcuHP+xdWOJmZ5C9RQXHfZd/EhCnTi1Hfay37zH3lBxn/fNs85LA9HlsniFw2zccgcbrrTMKk7Cn1Qg== +"@esbuild/linux-loong64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz#d5ad459d41ed42bbd4d005256b31882ec52227d8" + integrity sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ== -"@esbuild/linux-mips64el@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.14.tgz#8af86bdc6ee937c8a2803b3c197b28824f48df8e" - integrity sha512-kJ2iEnikUOdC1SiTGbH0fJUgpZwa0ITDTvj9EHf9lm3I0hZ4Yugsb3M6XSl696jVxrEocLe519/8CbSpQWFSrg== +"@esbuild/linux-mips64el@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz#4e5967a665c38360b0a8205594377d4dcf9c3726" + integrity sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw== -"@esbuild/linux-ppc64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.14.tgz#3fa3f8c6c9db3127f2ec5b2eba1cec67ff9a9b8e" - integrity sha512-kclKxvZvX5YhykwlJ/K9ljiY4THe5vXubXpWmr7q3Zu3WxKnUe1VOZmhkEZlqtnJx31GHPEV4SIG95IqTdfgfg== +"@esbuild/linux-ppc64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz#206443a02eb568f9fdf0b438fbd47d26e735afc8" + integrity sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g== -"@esbuild/linux-riscv64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.14.tgz#1bd1b631de2533106a08876295bad3a19b20f629" - integrity sha512-fdwP9Dc+Kx/cZwp9T9kNqjAE/PQjfrxbio4rZ3XnC3cVvZBjuxpkiyu/tuCwt6SbAK5th6AYNjFdEV9kGC020A== +"@esbuild/linux-riscv64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz#c351e433d009bf256e798ad048152c8d76da2fc9" + integrity sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw== -"@esbuild/linux-s390x@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.14.tgz#c87440b6522b9a36a9cafd05b0f1ca3c5bad4cca" - integrity sha512-++fw3P4fQk9nqvdzbANRqimKspL8pDCnSpXomyhV7V/ISha/BZIYvZwLBWVKp9CVWKwWPJ4ktsezuLIvlJRHqA== +"@esbuild/linux-s390x@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz#661f271e5d59615b84b6801d1c2123ad13d9bd87" + integrity sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w== -"@esbuild/linux-x64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.14.tgz#49cd974dad6042ac0141ba332df6307c44e77fed" - integrity sha512-TomtswAuzBf2NnddlrS4W01Tv85RM9YtATB3OugY6On0PLM4Ksz5qvQKVAjtzPKoLgL1FiZtfc8mkZc4IgoMEA== +"@esbuild/linux-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz#e4ba18e8b149a89c982351443a377c723762b85f" + integrity sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw== -"@esbuild/netbsd-x64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.14.tgz#53dcfb5131376feff0911adff7f01b4821706cf6" - integrity sha512-U06pfx8P5CqyoPNfqIJmnf+5/r4mJ1S62G4zE6eOjS59naQcxi6GnscUCPH3b+hRG0qdKoGX49RAyiqW+M9aSw== +"@esbuild/netbsd-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz#7d4f4041e30c5c07dd24ffa295c73f06038ec775" + integrity sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA== -"@esbuild/openbsd-x64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.14.tgz#f36888f73087bcd12c5bf9a4b18e348da9c80ad0" - integrity sha512-/Jl8XVaWEZNu9rZw+n792GIBupQwHo6GDoapHSb/2xp/Ku28eK6QpR2O9cPBkzHH4OOoMH0LB6zg/qczJ5TTGg== +"@esbuild/openbsd-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz#970fa7f8470681f3e6b1db0cc421a4af8060ec35" + integrity sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg== -"@esbuild/sunos-x64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.14.tgz#41e046bb0849ae59702a5cfa8be300431a61ee3a" - integrity sha512-2iI7D34uTbDn/TaSiUbEHz+fUa8KbN90vX5yYqo12QGpu6T8Jl+kxODsWuMCwoTVlqUpwfPV22nBbFPME9OPtw== +"@esbuild/sunos-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz#abc60e7c4abf8b89fb7a4fe69a1484132238022c" + integrity sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw== -"@esbuild/win32-arm64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.14.tgz#d6ed78742a6edd413e75796882ddaef8c1e23b93" - integrity sha512-SjlM7AHmQVTiGBJE/nqauY1aDh80UBsXZ94g4g60CDkrDMseatiqALVcIuElg4ZSYzJs8hsg5W6zS2zLpZTVgg== +"@esbuild/win32-arm64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz#7b0ff9e8c3265537a7a7b1fd9a24e7bd39fcd87a" + integrity sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw== -"@esbuild/win32-ia32@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.14.tgz#558bd53859a83fe887d7d2dcdc6cb3fc9aa9a9bc" - integrity sha512-z06t5zqk8ak0Xom5HG81z2iOQ1hNWYsFQp3sczVLVx+dctWdgl80tNRyTbwjaFfui2vFO12dfE3trCTvA+HO4g== +"@esbuild/win32-ia32@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz#e90fe5267d71a7b7567afdc403dfd198c292eb09" + integrity sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig== -"@esbuild/win32-x64@0.16.14": - version "0.16.14" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.14.tgz#90558dcb279989d92a42e5be4dfb884b2399361f" - integrity sha512-ED1UpWcM6lAbalbbQ9TrGqJh4Y9TaASUvu8bI/0mgJcxhSByJ6rbpgqRhxYMaQ682WfA71nxUreaTO7L275zrw== +"@esbuild/win32-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz#c5a1a4bfe1b57f0c3e61b29883525c6da3e5c091" + integrity sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q== "@eslint/eslintrc@^1.4.1": version "1.4.1" @@ -1745,71 +1745,71 @@ slash "3.0.0" source-map "^0.7.3" -"@swc/core-darwin-arm64@1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.25.tgz#01ce7b8a88b545a4fc5283ed6f96b22c5733d6c4" - integrity sha512-8PWAVcjTJyj2VrqPBFOIi2w2P0Z8kOCbzHW3+pe+bSXxfGMG0MKPl5U2IXhsEL0ovm4xSFlqW0yygpoP3MmRPw== +"@swc/core-darwin-arm64@1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.26.tgz#43355315f0668a6a5366208f09678349bc0f44ee" + integrity sha512-FWWflBfKRYrUJtko2xiedC5XCa31O75IZZqnTWuLpe9g3C5tnUuF3M8LSXZS/dn6wprome1MhtG9GMPkSYkhkg== -"@swc/core-darwin-x64@1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.25.tgz#9fad102c507011f42c5a5d1f84919b81ab96d7f8" - integrity sha512-5DHGiMYFEj5aa208tCjo7Sn5tiG4xPz+4gUiWVlglxqXFptkNim5xu/1G6VYm5Zk7dI5jJkjTU76GQG7IRvPug== +"@swc/core-darwin-x64@1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.26.tgz#462fc2e1377437b7c7bbdf5988f51adfeea3efa9" + integrity sha512-0uQeebAtsewqJ2b35aPZstGrylwd6oJjUyAJOfVJNbremFSJ5JzytB3NoDCIw7CT5UQrSRpvD3mU95gfdQjDGA== -"@swc/core-linux-arm-gnueabihf@1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.25.tgz#ecf3a34899fdbdc742523524caab29c0db97a6ad" - integrity sha512-YNfLxv9PhZk+jrJbpR1mMrYBUkufo0hiFv3S1OrX3l8edsIP4wPND5w9ZH0Oi898f6Jg9DBrY2zXJMQ+gWkbvA== +"@swc/core-linux-arm-gnueabihf@1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.26.tgz#fecd9c2e7d9b69c849907a83a5101a98c047d986" + integrity sha512-06T+LbVFlyciQtwrUB5/a16A1ju1jFoYvd/hq9TWhf7GrtL43U7oJIgqMOPHx2j0+Ps2R3S6R/UUN5YXu618zA== -"@swc/core-linux-arm64-gnu@1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.25.tgz#50524c9db2dbf874570e45f0a66e0283f02bc2d9" - integrity sha512-kS+spM5/xQ6QvWF1ms3byfjnhUlpjTfFwgCyHnIKgjvsYkDa+vkAIhKq6HuEdaTPaCRCjts0Zarhub1nClUU0g== +"@swc/core-linux-arm64-gnu@1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.26.tgz#82a8462212263f4e4f6691473d4c2839b73c2084" + integrity sha512-2NT/0xALPfK+U01qIlHxjkGdIj6F0txhu1U2v6B0YP2+k0whL2gCgYeg9QUvkYEXSD5r1Yx+vcb2R/vaSCSClg== -"@swc/core-linux-arm64-musl@1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.25.tgz#f04a3d3784cff14f96ad9901861485ec0fa14ebf" - integrity sha512-vM3D7LWmjotUAJ2D4F+L+dspFeWrcPNVh0o8TCoTOYCt8DPD5YsUKTpIgOsZ+gReeWUAnNTh0Btx5pGGVfajGA== +"@swc/core-linux-arm64-musl@1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.26.tgz#050b7c1aa81d6f34769eb556c3a94c61a9b69aaa" + integrity sha512-64KrTay9hC0mTvZ1AmEFmNEwV5QDjw9U7PJU5riotSc28I+Q/ZoM0qcSFW9JRRa6F2Tr+IfMtyv8+eB2//BQ5g== -"@swc/core-linux-x64-gnu@1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.25.tgz#761fb020b8a0130e4dccc9c8dce355fa06df63f4" - integrity sha512-xUCLLMDlYa/zB8BftVa4SrxuVpcDxkltCfmBg5r2pZPVskhC5ZJsQZ/AvWNChoAB11shRhjTaWDlmxJEsa7TIg== +"@swc/core-linux-x64-gnu@1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.26.tgz#e306778c2c1838350f588c8ae800e74434dc2b9a" + integrity sha512-Te8G13l3dcRM1Mf3J4JzGUngzNXLKnMYlUmBOYN/ORsx7e+VNelR3zsTLHC0+0jGqELDgqvMyzDfk+dux/C/bQ== -"@swc/core-linux-x64-musl@1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.25.tgz#f944ee48c972ebdcb3e6d6fd62d67eb98dbb1268" - integrity sha512-QzHU3BIaUVRSFNsUn3Qxx1vgtF/f5NqsFMAAPSq9Y8Yq5nrlc2t7cNuOROxHLbUqE+NPUp6+RglleJMoeWz5mA== +"@swc/core-linux-x64-musl@1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.26.tgz#531d9ec7c37f56df5c6cc121db5dd6faff5e2c38" + integrity sha512-nqQWuSM6OTKepUiQ9+rXgERq/JiO72RBOpXKO2afYppsL96sngjIRewV74v5f6IAfyzw+k+AhC5pgRA4Xu/Jkg== -"@swc/core-win32-arm64-msvc@1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.25.tgz#af63ae850ef6e7322e8a5a0959529e96096239d2" - integrity sha512-77VSVtneVOAUL4zkRyQZ6pWVpTsVVdqwly/DKnRnloglGKxYuk5DG5MUBsL72Nnfv4OCHjZ27eI3NUrpLsUb2Q== +"@swc/core-win32-arm64-msvc@1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.26.tgz#9c7f245903694484bd00c4da5142f24070094d0f" + integrity sha512-xx34mx+9IBV1sun7sxoNFiqNom9wiOuvsQFJUyQptCnZHgYwOr9OI204LBF95dCcBCZsTm2hT1wBnySJOeimYw== -"@swc/core-win32-ia32-msvc@1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.25.tgz#96a869aa4b4c41c44c9c9893ac4aad68d1233022" - integrity sha512-kz0v3K3H6OPEZR3ry72Ad/6C5GrZBRRUk69K58LORQ8tZXQD3UGl85pUbQqyHl8fR5NU76Muxgovj9CI9iTHGA== +"@swc/core-win32-ia32-msvc@1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.26.tgz#56d83cc216218d78cc578f01499777cdfc0a4eeb" + integrity sha512-48LZ/HKNuU9zl8c7qG6IQKb5rBCwmJgysGOmEGzTRBYxAf/x6Scmt0aqxCoV4J02HOs2WduCBDnhUKsSQ2kcXQ== -"@swc/core-win32-x64-msvc@1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.25.tgz#9035c11626653322a404f3f44af11a02d989094c" - integrity sha512-nmQOAzIpNRRnupWzkenJmW4i+h1M76cVNUqEU2MjmtesEkRZEGqv//jefXiyCP2zcbeLNLKiB2ptVJhpd1BvRA== +"@swc/core-win32-x64-msvc@1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.26.tgz#bb65bc0fff712c8ca3702d9c0adc59894ca54bae" + integrity sha512-UPe7S+MezD/S6cKBIc50TduGzmw6PBz1Ms5p+5wDLOKYNS/LSEM4iRmLwvePzP5X8mOyesXrsbwxLy8KHP65Yw== -"@swc/core@^1.3.25": - version "1.3.25" - resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.25.tgz#53786ea51fac319684d6822de1738eb55b73a4b7" - integrity sha512-wqzvM/wu6OsTVYPMStOpm7kIQcPX3GoZ0sC85qzDdsCxmJ1rmItLAD91sXPUmmdk0XqPYjLgT9MRDEIP5woz4g== +"@swc/core@^1.3.26": + version "1.3.26" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.26.tgz#6f7fe6ad54eac7ecffbdfa75d5c4300e2f96b8f6" + integrity sha512-U7vEsaLn3IGg0XCRLJX/GTkK9WIfFHUX5USdrp1L2QD29sWPe25HqNndXmUR9KytzKmpDMNoUuHyiuhpVrnNeQ== optionalDependencies: - "@swc/core-darwin-arm64" "1.3.25" - "@swc/core-darwin-x64" "1.3.25" - "@swc/core-linux-arm-gnueabihf" "1.3.25" - "@swc/core-linux-arm64-gnu" "1.3.25" - "@swc/core-linux-arm64-musl" "1.3.25" - "@swc/core-linux-x64-gnu" "1.3.25" - "@swc/core-linux-x64-musl" "1.3.25" - "@swc/core-win32-arm64-msvc" "1.3.25" - "@swc/core-win32-ia32-msvc" "1.3.25" - "@swc/core-win32-x64-msvc" "1.3.25" + "@swc/core-darwin-arm64" "1.3.26" + "@swc/core-darwin-x64" "1.3.26" + "@swc/core-linux-arm-gnueabihf" "1.3.26" + "@swc/core-linux-arm64-gnu" "1.3.26" + "@swc/core-linux-arm64-musl" "1.3.26" + "@swc/core-linux-x64-gnu" "1.3.26" + "@swc/core-linux-x64-musl" "1.3.26" + "@swc/core-win32-arm64-msvc" "1.3.26" + "@swc/core-win32-ia32-msvc" "1.3.26" + "@swc/core-win32-x64-msvc" "1.3.26" "@swc/jest@^0.2.24": version "0.2.24" @@ -2972,20 +2972,22 @@ "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" -"@webpack-cli/configtest@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.0.1.tgz#a69720f6c9bad6aef54a8fa6ba9c3533e7ef4c7f" - integrity sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A== +"@webpack-cli/configtest@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" + integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== -"@webpack-cli/info@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.1.tgz#eed745799c910d20081e06e5177c2b2569f166c0" - integrity sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA== +"@webpack-cli/info@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" + integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== + dependencies: + envinfo "^7.7.3" -"@webpack-cli/serve@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.1.tgz#34bdc31727a1889198855913db2f270ace6d7bf8" - integrity sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw== +"@webpack-cli/serve@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" + integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -4400,7 +4402,7 @@ commander@^5.0.0, commander@^5.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -commander@^7.1.0: +commander@^7.0.0, commander@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== @@ -4410,11 +4412,6 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== -commander@^9.4.1: - version "9.5.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" - integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== - common-ancestor-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" @@ -5765,33 +5762,33 @@ esbuild@^0.15.6: esbuild-windows-64 "0.15.18" esbuild-windows-arm64 "0.15.18" -esbuild@^0.16.14: - version "0.16.14" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.14.tgz#366249a0a0fd431d3ab706195721ef1014198919" - integrity sha512-6xAn3O6ZZyoxZAEkwfI9hw4cEqSr/o1ViJtnkvImVkblmUN65Md04o0S/7H1WNu1XGf1Cjij/on7VO4psIYjkw== +esbuild@^0.16.17: + version "0.16.17" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.17.tgz#fc2c3914c57ee750635fee71b89f615f25065259" + integrity sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg== optionalDependencies: - "@esbuild/android-arm" "0.16.14" - "@esbuild/android-arm64" "0.16.14" - "@esbuild/android-x64" "0.16.14" - "@esbuild/darwin-arm64" "0.16.14" - "@esbuild/darwin-x64" "0.16.14" - "@esbuild/freebsd-arm64" "0.16.14" - "@esbuild/freebsd-x64" "0.16.14" - "@esbuild/linux-arm" "0.16.14" - "@esbuild/linux-arm64" "0.16.14" - "@esbuild/linux-ia32" "0.16.14" - "@esbuild/linux-loong64" "0.16.14" - "@esbuild/linux-mips64el" "0.16.14" - "@esbuild/linux-ppc64" "0.16.14" - "@esbuild/linux-riscv64" "0.16.14" - "@esbuild/linux-s390x" "0.16.14" - "@esbuild/linux-x64" "0.16.14" - "@esbuild/netbsd-x64" "0.16.14" - "@esbuild/openbsd-x64" "0.16.14" - "@esbuild/sunos-x64" "0.16.14" - "@esbuild/win32-arm64" "0.16.14" - "@esbuild/win32-ia32" "0.16.14" - "@esbuild/win32-x64" "0.16.14" + "@esbuild/android-arm" "0.16.17" + "@esbuild/android-arm64" "0.16.17" + "@esbuild/android-x64" "0.16.17" + "@esbuild/darwin-arm64" "0.16.17" + "@esbuild/darwin-x64" "0.16.17" + "@esbuild/freebsd-arm64" "0.16.17" + "@esbuild/freebsd-x64" "0.16.17" + "@esbuild/linux-arm" "0.16.17" + "@esbuild/linux-arm64" "0.16.17" + "@esbuild/linux-ia32" "0.16.17" + "@esbuild/linux-loong64" "0.16.17" + "@esbuild/linux-mips64el" "0.16.17" + "@esbuild/linux-ppc64" "0.16.17" + "@esbuild/linux-riscv64" "0.16.17" + "@esbuild/linux-s390x" "0.16.17" + "@esbuild/linux-x64" "0.16.17" + "@esbuild/netbsd-x64" "0.16.17" + "@esbuild/openbsd-x64" "0.16.17" + "@esbuild/sunos-x64" "0.16.17" + "@esbuild/win32-arm64" "0.16.17" + "@esbuild/win32-ia32" "0.16.17" + "@esbuild/win32-x64" "0.16.17" escalade@^3.1.1: version "3.1.1" @@ -5850,10 +5847,10 @@ eslint-import-resolver-node@^0.3.6: debug "^3.2.7" resolve "^1.20.0" -eslint-import-resolver-typescript@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.2.tgz#9431acded7d898fd94591a08ea9eec3514c7de91" - integrity sha512-zX4ebnnyXiykjhcBvKIf5TNvt8K7yX6bllTRZ14MiurKPjDpCAZujlszTdB8pcNXhZcOf+god4s9SjQa5GnytQ== +eslint-import-resolver-typescript@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.3.tgz#db5ed9e906651b7a59dd84870aaef0e78c663a05" + integrity sha512-njRcKYBc3isE42LaTcJNVANR3R99H9bAxBDMNDr2W7yq5gYPxbU3MkdhsQukxZ/Xg9C2vcyLlDsbKfRDg0QvCQ== dependencies: debug "^4.3.4" enhanced-resolve "^5.10.0" @@ -5900,10 +5897,10 @@ eslint-plugin-react-hooks@^4.6.0: resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== -eslint-plugin-react@7.31.11: - version "7.31.11" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz#011521d2b16dcf95795df688a4770b4eaab364c8" - integrity sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw== +eslint-plugin-react@7.32.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.0.tgz#d80f794a638c5770f952ba2ae793f0a516be7c09" + integrity sha512-vSBi1+SrPiLZCGvxpiZIa28fMEUaMjXtCplrvxcIxGzmFiYdsXQDwInEjuv5/i/2CTTxbkS87tE8lsQ0Qxinbw== dependencies: array-includes "^3.1.6" array.prototype.flatmap "^1.3.1" @@ -5917,7 +5914,7 @@ eslint-plugin-react@7.31.11: object.hasown "^1.1.2" object.values "^1.1.6" prop-types "^15.8.1" - resolve "^2.0.0-next.3" + resolve "^2.0.0-next.4" semver "^6.3.0" string.prototype.matchall "^4.0.8" @@ -7587,10 +7584,10 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== -interpret@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" - integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== into-stream@^3.1.0: version "3.1.0" @@ -7688,7 +7685,7 @@ is-core-module@^2.10.0: dependencies: has "^1.0.3" -is-core-module@^2.2.0, is-core-module@^2.8.1, is-core-module@^2.9.0: +is-core-module@^2.8.1, is-core-module@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== @@ -9361,10 +9358,10 @@ memfs@^3.1.2, memfs@^3.4.1: dependencies: fs-monkey "1.0.3" -memfs@^3.4.12: - version "3.4.12" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.12.tgz#d00f8ad8dab132dc277c659dc85bfd14b07d03bd" - integrity sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw== +memfs@^3.4.13: + version "3.4.13" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.13.tgz#248a8bd239b3c240175cd5ec548de5227fc4f345" + integrity sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg== dependencies: fs-monkey "^1.0.3" @@ -10606,7 +10603,7 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.6, path-parse@^1.0.7: +path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -11437,12 +11434,12 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" -rechoir@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" - integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== dependencies: - resolve "^1.20.0" + resolve "^1.9.0" redent@^3.0.0: version "3.0.0" @@ -11619,7 +11616,7 @@ resolve.exports@^1.1.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.12.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1: +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.12.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1, resolve@^1.9.0: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -11628,13 +11625,14 @@ resolve@^1.1.6, resolve@^1.1.7, resolve@^1.12.0, resolve@^1.20.0, resolve@^1.22. path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^2.0.0-next.3: - version "2.0.0-next.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" - integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== +resolve@^2.0.0-next.4: + version "2.0.0-next.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" + integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" responselike@1.0.2, responselike@^1.0.2: version "1.0.2" @@ -13552,23 +13550,22 @@ webidl-conversions@^7.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== -webpack-cli@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.0.1.tgz#95fc0495ac4065e9423a722dec9175560b6f2d9a" - integrity sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A== +webpack-cli@^4.9.2: + version "4.10.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" + integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== dependencies: "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^2.0.1" - "@webpack-cli/info" "^2.0.1" - "@webpack-cli/serve" "^2.0.1" + "@webpack-cli/configtest" "^1.2.0" + "@webpack-cli/info" "^1.5.0" + "@webpack-cli/serve" "^1.7.0" colorette "^2.0.14" - commander "^9.4.1" + commander "^7.0.0" cross-spawn "^7.0.3" - envinfo "^7.7.3" fastest-levenshtein "^1.0.12" import-local "^3.0.2" - interpret "^3.1.1" - rechoir "^0.8.0" + interpret "^2.2.0" + rechoir "^0.7.0" webpack-merge "^5.7.3" webpack-dev-middleware@^5.3.1: diff --git a/packages/extension-api/package.json b/packages/extension-api/package.json index 74301c4cc1..82145fc8af 100644 --- a/packages/extension-api/package.json +++ b/packages/extension-api/package.json @@ -2,7 +2,7 @@ "name": "@k8slens/extensions", "productName": "OpenLens extensions", "description": "OpenLens - Open Source Kubernetes IDE: extensions", - "version": "6.4.0-alpha.0", + "version": "6.4.0-alpha.2", "copyright": "© 2022 OpenLens Authors", "license": "MIT", "main": "dist/src/extension-api.js", @@ -21,7 +21,7 @@ "clean": "rm -rf dist/" }, "dependencies": { - "@k8slens/open-lens": "^6.4.0-alpha.0" + "@k8slens/open-lens": "^6.4.0-alpha.2" }, "devDependencies": { "@types/node": "^16.18.6", diff --git a/packages/open-lens/package.json b/packages/open-lens/package.json index 095a9d1e3e..8dac22b59b 100644 --- a/packages/open-lens/package.json +++ b/packages/open-lens/package.json @@ -4,7 +4,7 @@ "productName": "OpenLens", "description": "OpenLens - Open Source IDE for Kubernetes", "homepage": "https://github.com/lensapp/lens", - "version": "6.4.0-alpha.0", + "version": "6.4.0-alpha.2", "repository": { "type": "git", "url": "git+https://github.com/lensapp/lens.git" @@ -170,7 +170,7 @@ } }, "dependencies": { - "@k8slens/open-lens": "^6.4.0-alpha.0", + "@k8slens/open-lens": "^6.4.0-alpha.2", "@ogre-tools/fp": "^12.0.1", "@ogre-tools/injectable": "^12.0.1", "@ogre-tools/injectable-extension-for-auto-registration": "^12.0.1", diff --git a/packages/release-tool/package.json b/packages/release-tool/package.json index 13c83b717f..48b982e3ff 100644 --- a/packages/release-tool/package.json +++ b/packages/release-tool/package.json @@ -1,6 +1,6 @@ { "name": "@k8slens/release-tool", - "version": "6.4.0-alpha.0", + "version": "6.4.0-alpha.2", "description": "Release tool for lens monorepo", "main": "dist/index.mjs", "license": "MIT", 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 6ea03fff08..0ad7ed3d88 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 @@ -13,7 +13,7 @@ const configMapsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "configmaps", - group: "v1", + group: "", }), }), 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 8623f3520e..0536e76004 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 @@ -14,7 +14,7 @@ const limitRangesRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "limitranges", - group: "v1", + group: "", }), }), 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 209f77e19a..4905b70890 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 @@ -14,7 +14,7 @@ const resourceQuotasRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "resourcequotas", - group: "v1", + group: "", }), }), 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 079ddcbf83..7442de14b1 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 @@ -14,7 +14,7 @@ const secretsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "secrets", - group: "v1", + group: "", }), }), 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 b3df358ad8..728f80c21d 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 @@ -14,7 +14,7 @@ const eventsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "events", - group: "v1", + group: "", }), }), 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 2aa6c23efe..0b57c8d573 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 @@ -14,7 +14,7 @@ const namespacesRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "namespaces", - group: "v1", + group: "", }), }), 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 c88ec04714..50b3c72e4c 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 @@ -14,7 +14,7 @@ const endpointsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "endpoints", - group: "v1", + group: "", }), }), 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 53300ee241..223ded1e65 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 @@ -14,7 +14,7 @@ const servicesRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "services", - group: "v1", + group: "", }), }), 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 81323843d5..e6ca61346e 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 @@ -14,7 +14,7 @@ const nodesRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "nodes", - group: "v1", + group: "", }), }), 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 8315fd7773..e559c35079 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 @@ -14,7 +14,7 @@ const clusterOverviewRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "nodes", - group: "v1", + group: "", }), }), 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 1b96933136..dbda527555 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 @@ -14,7 +14,7 @@ const persistentVolumeClaimsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "persistentvolumeclaims", - group: "v1", + group: "", }), }), 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 52f95b32c6..7a06d9df58 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 @@ -14,7 +14,7 @@ const persistentVolumesRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "persistentvolumes", - group: "v1", + group: "", }), }), 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 3bf6c1ec00..65d02135c7 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 @@ -14,7 +14,7 @@ const serviceAccountsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "serviceaccounts", - group: "v1", + group: "", }), }), 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 577f1c1a91..d013f872f0 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 @@ -14,7 +14,7 @@ const podsRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "pods", - group: "v1", + group: "", }), }), 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 94c6e0cd9c..cd08ef4d5c 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 @@ -6,13 +6,11 @@ import type { ApiManager } from "../api-manager"; import type { IngressApi } from "../endpoints"; import { Ingress } from "../endpoints"; import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting"; -import apiManagerInjectable from "../api-manager/manager.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 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"; @@ -20,14 +18,14 @@ import directoryForUserDataInjectable from "../../app-paths/directory-for-user-d 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"; -import apiKubeInjectable from "../../../renderer/k8s/api-kube.injectable"; +import apiManagerInjectable from "../api-manager/manager.injectable"; import type { DiContainer } from "@ogre-tools/injectable"; import ingressApiInjectable from "../endpoints/ingress.api.injectable"; describe("KubeApi", () => { - let di: DiContainer; - let registerApiSpy: jest.SpiedFunction; let fetchMock: AsyncFnMock; + let apiManager: ApiManager; + let di: DiContainer; beforeEach(async () => { di = getDiForUnitTesting({ doGeneralOverrides: true }); @@ -40,7 +38,6 @@ describe("KubeApi", () => { di.override(storesAndApisCanBeCreatedInjectable, () => true); const createCluster = di.inject(createClusterInjectable); - const createKubeJsonApi = di.inject(createKubeJsonApiInjectable); di.override(hostedClusterInjectable, () => createCluster({ contextName: "some-context-name", @@ -50,12 +47,7 @@ describe("KubeApi", () => { clusterServerUrl: "https://localhost:8080", })); - di.override(apiKubeInjectable, () => createKubeJsonApi({ - serverAddress: `http://127.0.0.1:9999`, - apiBase: "/api-kube", - })); - - registerApiSpy = jest.spyOn(di.inject(apiManagerInjectable), "registerApi"); + apiManager = di.inject(apiManagerInjectable); const setupAutoRegistration = di.inject(setupAutoRegistrationInjectable); @@ -79,7 +71,7 @@ describe("KubeApi", () => { it("requests version list from the api group from the initial apiBase", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io", { headers: { "content-type": "application/json", @@ -92,8 +84,8 @@ describe("KubeApi", () => { describe("when the version list from the api group resolves", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io", JSON.stringify({ apiVersion: "v1", kind: "APIGroup", name: "networking.k8s.io", @@ -117,7 +109,7 @@ describe("KubeApi", () => { it("requests resources from the versioned api group from the initial apiBase", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1", { headers: { "content-type": "application/json", @@ -130,8 +122,8 @@ describe("KubeApi", () => { describe("when resource request fufills with a resource", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1", JSON.stringify({ resources: [{ name: "ingresses", }], @@ -141,7 +133,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", { headers: { "content-type": "application/json", @@ -159,8 +151,8 @@ describe("KubeApi", () => { })); }); - it("registers the api with the changes info", () => { - expect(registerApiSpy).toBeCalledWith(ingressApi); + it("api is retrievable with the new apiBase", () => { + expect(apiManager.getApi("/apis/networking.k8s.io/v1/ingresses")).toBeDefined(); }); describe("when the request resolves with no data", () => { @@ -168,8 +160,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", JSON.stringify({})), ); result = await getCall; }); @@ -193,7 +185,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -208,8 +200,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); @@ -226,8 +218,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo", JSON.stringify({ apiVersion: "v1", kind: "Ingress", metadata: { @@ -260,7 +252,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -275,8 +267,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); @@ -292,8 +284,8 @@ describe("KubeApi", () => { describe("when resource request fufills with no resource", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1", JSON.stringify({ resources: [], })), ); @@ -301,7 +293,7 @@ describe("KubeApi", () => { it("requests resources from the second versioned api group from the initial apiBase", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1", { headers: { "content-type": "application/json", @@ -316,8 +308,8 @@ describe("KubeApi", () => { describe("when resource request fufills with a resource", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1", JSON.stringify({ resources: [{ name: "ingresses", }], @@ -327,7 +319,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", { headers: { "content-type": "application/json", @@ -345,8 +337,12 @@ describe("KubeApi", () => { })); }); - it("registers the api with the changes info", () => { - expect(registerApiSpy).toBeCalledWith(ingressApi); + it("api is retrievable with the new apiBase", () => { + expect(apiManager.getApi("/apis/networking.k8s.io/v1beta1/ingresses")).toBeDefined(); + }); + + it("api is retrievable with the old apiBase", () => { + expect(apiManager.getApi("/apis/networking.k8s.io/v1/ingresses")).toBeDefined(); }); describe("when the request resolves with no data", () => { @@ -354,8 +350,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({})), ); result = await getCall; }); @@ -379,7 +375,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -394,8 +390,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); @@ -412,8 +408,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({ apiVersion: "v1", kind: "Ingress", metadata: { @@ -446,7 +442,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -461,8 +457,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); @@ -480,8 +476,8 @@ describe("KubeApi", () => { describe("when the version list from the api group resolves with no versions", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/networking.k8s.io"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/networking.k8s.io", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/networking.k8s.io"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/networking.k8s.io", JSON.stringify({ "metadata": {}, "status": "Failure", "message": "the server could not find the requested resource", @@ -501,7 +497,7 @@ describe("KubeApi", () => { it("requests the resources from the base api url from the fallback api", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/extensions", + "https://127.0.0.1:12345/api-kube/apis/extensions", { headers: { "content-type": "application/json", @@ -514,8 +510,8 @@ describe("KubeApi", () => { describe("when resource request fufills with a resource", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/extensions"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions", JSON.stringify({ apiVersion: "v1", kind: "APIGroup", name: "extensions", @@ -535,7 +531,7 @@ describe("KubeApi", () => { it("requests resource versions from the versioned api group from the fallback apiBase", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1", + "https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1", { headers: { "content-type": "application/json", @@ -548,8 +544,8 @@ describe("KubeApi", () => { describe("when the preferred version request resolves to v1beta1", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions", JSON.stringify({ resources: [{ name: "ingresses", }], @@ -559,7 +555,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", + "https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", { headers: { "content-type": "application/json", @@ -577,8 +573,8 @@ describe("KubeApi", () => { })); }); - it("registers the api with the changes info", () => { - expect(registerApiSpy).toBeCalledWith(ingressApi); + it("api is retrievable with the new apiBase", () => { + expect(apiManager.getApi("/apis/extensions/v1beta1/ingresses")).toBeDefined(); }); describe("when the request resolves with no data", () => { @@ -586,8 +582,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({})), ); result = await getCall; }); @@ -611,7 +607,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -626,8 +622,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); @@ -644,8 +640,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({ + ["https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo", JSON.stringify({ apiVersion: "v1beta1", kind: "Ingress", metadata: { @@ -678,7 +674,7 @@ describe("KubeApi", () => { it("makes the request to get the resource", () => { expect(fetchMock.mock.lastCall).toMatchObject([ - "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", + "https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", { headers: { "content-type": "application/json", @@ -693,8 +689,8 @@ describe("KubeApi", () => { beforeEach(async () => { await fetchMock.resolveSpecific( - ["http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1"], - createMockResponseFromString("http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), + ["https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1"], + createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/extensions/v1beta1/namespaces/default/ingresses/foo1", JSON.stringify({})), ); result = await getCall; }); diff --git a/src/common/k8s-api/api-manager/api-manager.ts b/src/common/k8s-api/api-manager/api-manager.ts index 080ccb671a..81b59ef9c2 100644 --- a/src/common/k8s-api/api-manager/api-manager.ts +++ b/src/common/k8s-api/api-manager/api-manager.ts @@ -5,11 +5,12 @@ import type { KubeObjectStore } from "../kube-object.store"; -import { action, observable, makeObservable } from "mobx"; -import { autoBind, isDefined, iter } from "../../utils"; +import type { IComputedValue } from "mobx"; +import { autorun, action, observable } from "mobx"; import type { KubeApi } from "../kube-api"; -import type { KubeJsonApiDataFor, KubeObject, ObjectReference } from "../kube-object"; +import type { KubeObject, ObjectReference } from "../kube-object"; import { parseKubeApi, createKubeApiURL } from "../kube-api-parse"; +import { chain, find } from "../../utils/iter"; export type RegisterableStore = Store extends KubeObjectStore ? Store @@ -21,25 +22,53 @@ export type KubeObjectStoreFrom = Api extends KubeApi : never; -export class ApiManager { - private readonly apis = observable.map(); - private readonly stores = observable.map(); +export type FindApiCallback = (api: KubeApi) => boolean; - constructor() { - makeObservable(this); - autoBind(this); +interface Dependencies { + readonly apis: IComputedValue; + readonly stores: IComputedValue; +} + +export class ApiManager { + private readonly externalApis = observable.array(); + private readonly externalStores = observable.array(); + + private readonly apis = observable.map(); + + constructor(private readonly dependencies: Dependencies) { + // NOTE: this is done to preserve the old behaviour of an API being discoverable using all previous apiBases + autorun(() => { + const apis = chain(this.dependencies.apis.get().values()) + .concat(this.externalApis.values()); + const removedApis = new Set(this.apis.values()); + + for (const api of apis) { + removedApis.delete(api); + this.apis.set(api.apiBase, api); + } + + for (const api of removedApis) { + for (const [apiBase, storedApi] of this.apis) { + if (storedApi === api) { + this.apis.delete(apiBase); + } + } + } + }); } - getApi(pathOrCallback: string | ((api: KubeApi) => boolean)) { - if (typeof pathOrCallback === "string") { - return this.apis.get(pathOrCallback) || this.apis.get(parseKubeApi(pathOrCallback).apiBase); + getApi(pathOrCallback: string | FindApiCallback) { + if (typeof pathOrCallback === "function") { + return find(this.apis.values(), pathOrCallback); } - return iter.find(this.apis.values(), pathOrCallback ?? (() => true)); + const { apiBase } = parseKubeApi(pathOrCallback); + + return this.apis.get(apiBase); } getApiByKind(kind: string, apiVersion: string) { - return iter.find(this.apis.values(), api => api.kind === kind && api.apiVersionWithGroup === apiVersion); + return this.getApi(api => api.kind === kind && api.apiVersionWithGroup === apiVersion); } registerApi(api: RegisterableApi): void; @@ -47,45 +76,23 @@ export class ApiManager { * @deprecated Just register the `api` by itself */ registerApi(apiBase: string, api: RegisterableApi): void; - registerApi(apiBaseRaw: string | RegisterableApi, apiRaw?: RegisterableApi) { - const api = typeof apiBaseRaw === "string" - ? apiRaw - : apiBaseRaw; - - if (!api?.apiBase) { - return; - } - - if (!this.apis.has(api.apiBase)) { - this.stores.forEach((store) => { - if (store.api === api) { - this.stores.set(api.apiBase, store); - } - }); - - this.apis.set(api.apiBase, api); + registerApi(...args: [RegisterableApi] | [string, RegisterableApi]) { + if (args.length === 1) { + this.externalApis.push(args[0]); + } else { + this.externalApis.push(args[1]); } } - protected resolveApi(api: undefined | string | KubeApi): KubeApi | undefined { - if (!api) { - return undefined; - } + unregisterApi(apiOrBase: string | KubeApi) { + if (typeof apiOrBase === "string") { + const api = this.externalApis.find(api => api.apiBase === apiOrBase); - if (typeof api === "string") { - return this.getApi(api); - } - - return api; - } - - unregisterApi(api: string | KubeApi) { - if (typeof api === "string") this.apis.delete(api); - else { - const apis = Array.from(this.apis.entries()); - const entry = apis.find(entry => entry[1] === api); - - if (entry) this.unregisterApi(entry[0]); + if (api) { + this.externalApis.remove(api); + } + } else { + this.unregisterApi(apiOrBase.apiBase); } } @@ -93,15 +100,11 @@ export class ApiManager { /** * @deprecated KubeObjectStore's should only every be about a single KubeApi type */ - registerStore(store: KubeObjectStore, KubeJsonApiDataFor>, apis: KubeApi[]): void; + registerStore(store: RegisterableStore, apis: KubeApi[]): void; @action - registerStore(store: KubeObjectStore, KubeJsonApiDataFor>, apis: KubeApi[] = [store.api]): void { - for (const api of apis.filter(isDefined)) { - if (api.apiBase) { - this.stores.set(api.apiBase, store as never); - } - } + registerStore(store: RegisterableStore): void { + this.externalStores.push(store); } getStore(api: string | undefined): KubeObjectStore | undefined; @@ -110,14 +113,23 @@ export class ApiManager { * @deprecated use an actual cast instead of hiding it with this unused type param */ getStore(api: string | KubeApi): Store | undefined ; - getStore(api: string | KubeApi | undefined): KubeObjectStore | undefined { - const { apiBase } = this.resolveApi(api) ?? {}; - - if (apiBase) { - return this.stores.get(apiBase); + getStore(apiOrBase: string | KubeApi | undefined): KubeObjectStore | undefined { + if (!apiOrBase) { + return undefined; } - return undefined; + const { apiBase } = typeof apiOrBase === "string" + ? parseKubeApi(apiOrBase) + : apiOrBase; + const api = this.getApi(apiBase); + + if (!api) { + return undefined; + } + + return chain(this.dependencies.stores.get().values()) + .concat(this.externalStores.values()) + .find(store => store.api.apiBase === api.apiBase); } lookupApiLink(ref: ObjectReference, parentObject?: KubeObject): string { @@ -132,7 +144,7 @@ export class ApiManager { const api = this.getApi(api => api.kind === kind && api.apiVersionWithGroup == apiVersion); if (api) { - return api.getUrl({ namespace, name }); + return api.formatUrlForNotListing({ namespace, name }); } // lookup api by generated resource link @@ -151,7 +163,7 @@ export class ApiManager { const apiByKind = this.getApi(api => api.kind === kind); if (apiByKind) { - return apiByKind.getUrl({ name, namespace }); + return apiByKind.formatUrlForNotListing({ name, namespace }); } // otherwise generate link with default prefix diff --git a/src/common/k8s-api/api-manager/kube-object-store-token.ts b/src/common/k8s-api/api-manager/kube-object-store-token.ts new file mode 100644 index 0000000000..bbf272db24 --- /dev/null +++ b/src/common/k8s-api/api-manager/kube-object-store-token.ts @@ -0,0 +1,10 @@ +/** + * 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"; +import type { KubeObjectStore } from "../kube-object.store"; + +export const kubeObjectStoreInjectionToken = getInjectionToken>({ + id: "kube-object-store-token", +}); diff --git a/src/common/k8s-api/api-manager/manager.injectable.ts b/src/common/k8s-api/api-manager/manager.injectable.ts index 45188cec7a..f0b61c28b6 100644 --- a/src/common/k8s-api/api-manager/manager.injectable.ts +++ b/src/common/k8s-api/api-manager/manager.injectable.ts @@ -2,29 +2,28 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { getInjectable, getInjectionToken } from "@ogre-tools/injectable"; +import { getInjectable } from "@ogre-tools/injectable"; import { storesAndApisCanBeCreatedInjectionToken } from "../stores-apis-can-be-created.token"; -import type { KubeObjectStore } from "../kube-object.store"; import { ApiManager } from "./api-manager"; - -export const kubeObjectStoreInjectionToken = getInjectionToken>({ - id: "kube-object-store-token", -}); +import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx"; +import { kubeObjectStoreInjectionToken } from "./kube-object-store-token"; +import { kubeApiInjectionToken } from "../kube-api/kube-api-injection-token"; +import { computed } from "mobx"; const apiManagerInjectable = getInjectable({ id: "api-manager", instantiate: (di) => { - const apiManager = new ApiManager(); + const computedInjectMany = di.inject(computedInjectManyInjectable); + const storesAndApisCanBeCreated = di.inject(storesAndApisCanBeCreatedInjectionToken); - if (di.inject(storesAndApisCanBeCreatedInjectionToken)) { - const stores = di.injectMany(kubeObjectStoreInjectionToken); - - for (const store of stores) { - apiManager.registerStore(store); - } - } - - return apiManager; + return new ApiManager({ + apis: storesAndApisCanBeCreated + ? computedInjectMany(kubeApiInjectionToken) + : computed(() => []), + stores: storesAndApisCanBeCreated + ? computedInjectMany(kubeObjectStoreInjectionToken) + : computed(() => []), + }); }, }); diff --git a/src/common/k8s-api/endpoints/horizontal-pod-autoscaler.api.ts b/src/common/k8s-api/endpoints/horizontal-pod-autoscaler.api.ts index 71863d65ad..ee4fcfc63d 100644 --- a/src/common/k8s-api/endpoints/horizontal-pod-autoscaler.api.ts +++ b/src/common/k8s-api/endpoints/horizontal-pod-autoscaler.api.ts @@ -72,6 +72,27 @@ export type HorizontalPodAutoscalerMetricSpec = | OptionVarient | OptionVarient; +interface HorizontalPodAutoscalerBehavior { + scaleUp?: HPAScalingRules; + scaleDown?: HPAScalingRules; +} + +interface HPAScalingRules { + stabilizationWindowSecond?: number; + selectPolicy?: ScalingPolicySelect; + policies?: HPAScalingPolicy[]; +} + +type ScalingPolicySelect = string; + +interface HPAScalingPolicy { + type: HPAScalingPolicyType; + value: number; + periodSeconds: number; +} + +type HPAScalingPolicyType = string; + export interface ContainerResourceMetricStatus { container: string; currentAverageUtilization?: number; @@ -132,6 +153,7 @@ export interface HorizontalPodAutoscalerSpec { minReplicas?: number; maxReplicas: number; metrics?: HorizontalPodAutoscalerMetricSpec[]; + behavior?: HorizontalPodAutoscalerBehavior; } export interface HorizontalPodAutoscalerStatus { @@ -153,7 +175,7 @@ export class HorizontalPodAutoscaler extends KubeObject< > { static readonly kind = "HorizontalPodAutoscaler"; static readonly namespaced = true; - static readonly apiBase = "/apis/autoscaling/v2beta1/horizontalpodautoscalers"; + static readonly apiBase = "/apis/autoscaling/v2/horizontalpodautoscalers"; getMaxPods() { return this.spec.maxReplicas ?? 0; @@ -204,8 +226,15 @@ export class HorizontalPodAutoscaler extends KubeObject< export class HorizontalPodAutoscalerApi extends KubeApi { constructor(deps: KubeApiDependencies, opts?: DerivedKubeApiOptions) { super(deps, { - objectConstructor: HorizontalPodAutoscaler, ...opts ?? {}, + objectConstructor: HorizontalPodAutoscaler, + checkPreferredVersion: true, + // Kubernetes < 1.26 + fallbackApiBases: [ + "/apis/autoscaling/v2beta2/horizontalpodautoscalers", + "/apis/autoscaling/v2beta1/horizontalpodautoscalers", + "/apis/autoscaling/v1/horizontalpodautoscalers", + ], }); } } diff --git a/src/common/k8s-api/kube-api.ts b/src/common/k8s-api/kube-api.ts index c2a8906400..8e6e86d7da 100644 --- a/src/common/k8s-api/kube-api.ts +++ b/src/common/k8s-api/kube-api.ts @@ -20,10 +20,9 @@ import type { Patch } from "rfc6902"; import assert from "assert"; import type { PartialDeep } from "type-fest"; import type { Logger } from "../logger"; -import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; -import autoRegistrationEmitterInjectable from "./api-manager/auto-registration-emitter.injectable"; import type AbortController from "abort-controller"; import { matches } from "lodash/fp"; +import { makeObservable, observable } from "mobx"; /** * The options used for creating a `KubeApi` @@ -206,30 +205,6 @@ export interface DeleteResourceDescriptor extends ResourceDescriptor { propagationPolicy?: PropagationPolicy; } -/** - * @deprecated In the new extension API, don't expose `KubeApi`'s constructor - */ -function legacyRegisterApi(api: KubeApi): void { - try { - /** - * This function throws if called in `main`, so the `try..catch` is to make sure that doesn't - * leak. - * - * However, we need this code to be run in `renderer` so that the auto registering of `KubeApi` - * instances still works. That auto registering never worked or was applicable in `main` because - * there is no "single cluster" on `main`. - * - * TODO: rearchitect this design pattern in the new extension API - */ - const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.renderer); - const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable); - - setImmediate(() => autoRegistrationEmitter.emit("kubeApi", api)); - } catch { - // ignore error - } -} - export interface KubeApiDependencies { readonly logger: Logger; readonly maybeKubeApi: KubeJsonApi | undefined; @@ -241,7 +216,9 @@ export class KubeApi< > { readonly kind: string; readonly apiVersion: string; - apiBase: string; + + @observable apiBase: string; + apiPrefix: string; apiGroup: string; apiVersionPreferred: string | undefined; @@ -288,7 +265,7 @@ export class KubeApi< this.apiResource = resource; this.request = request; this.objectConstructor = objectConstructor; - legacyRegisterApi(this); + makeObservable(this); } get apiVersionWithGroup() { @@ -347,7 +324,6 @@ export class KubeApi< this.apiGroup = apiGroup; this.apiVersionPreferred = apiVersionPreferred; this.apiBase = this.computeApiBase(); - legacyRegisterApi(this); } } diff --git a/src/common/rbac.ts b/src/common/rbac.ts index 39edc49b60..40b9f2c43c 100644 --- a/src/common/rbac.ts +++ b/src/common/rbac.ts @@ -13,17 +13,21 @@ export type KubeResource = export interface KubeApiResource { kind: string; - group: string; + group: string; // api-group, if empty then "core" apiName: string; namespaced: boolean; } export interface KubeApiResourceDescriptor { apiName: string; - group: string; + group: string; // api-group, if empty then "core" } -export const formatKubeApiResource = (res: KubeApiResourceDescriptor) => `${res.group}/${res.apiName}`; +export const formatKubeApiResource = (desc: KubeApiResourceDescriptor) => ( + desc.group + ? `${desc.group}/${desc.apiName}` + : desc.apiName +); export interface KubeApiResourceData { kind: string; // resource type (e.g. "Namespace") @@ -44,7 +48,7 @@ export const apiResourceRecord: Record = { }, configmaps: { kind: "ConfigMap", - group: "v1", + group: "", namespaced: true, }, cronjobs: { @@ -69,12 +73,12 @@ export const apiResourceRecord: Record = { }, endpoints: { kind: "Endpoint", - group: "v1", + group: "", namespaced: true, }, events: { kind: "Event", - group: "v1", + group: "", namespaced: true, }, horizontalpodautoscalers: { @@ -99,17 +103,17 @@ export const apiResourceRecord: Record = { }, namespaces: { kind: "Namespace", - group: "v1", + group: "", namespaced: false, }, limitranges: { kind: "LimitRange", - group: "v1", + group: "", namespaced: true, }, leases: { kind: "Lease", - group: "v1", + group: "", namespaced: true, }, networkpolicies: { @@ -119,22 +123,22 @@ export const apiResourceRecord: Record = { }, nodes: { kind: "Node", - group: "v1", + group: "", namespaced: false, }, persistentvolumes: { kind: "PersistentVolume", - group: "v1", + group: "", namespaced: false, }, persistentvolumeclaims: { kind: "PersistentVolumeClaim", - group: "v1", + group: "", namespaced: true, }, pods: { kind: "Pod", - group: "v1", + group: "", namespaced: true, }, poddisruptionbudgets: { @@ -159,7 +163,7 @@ export const apiResourceRecord: Record = { }, resourcequotas: { kind: "ResourceQuota", - group: "v1", + group: "", namespaced: true, }, replicasets: { @@ -179,17 +183,17 @@ export const apiResourceRecord: Record = { }, secrets: { kind: "Secret", - group: "v1", + group: "", namespaced: true, }, serviceaccounts: { kind: "ServiceAccount", - group: "v1", + group: "", namespaced: true, }, services: { kind: "Service", - group: "v1", + group: "", namespaced: true, }, statefulsets: { diff --git a/src/common/utils/__tests__/iter.test.ts b/src/common/utils/__tests__/iter.test.ts index e41894e662..2489649d90 100644 --- a/src/common/utils/__tests__/iter.test.ts +++ b/src/common/utils/__tests__/iter.test.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { join, nth, reduce } from "../iter"; +import { join, nth, reduce, concat } from "../iter"; describe("iter", () => { describe("reduce", () => { @@ -39,4 +39,30 @@ describe("iter", () => { expect(nth(["a", "b"], 0)).toBe("a"); }); }); + + describe("concat", () => { + it("should yield undefined for empty args", () => { + const iter = concat(); + + expect(iter.next()).toEqual({ done: true }); + }); + + it("should yield undefined for only empty args", () => { + const iter = concat([].values(), [].values(), [].values(), [].values()); + + expect(iter.next()).toEqual({ done: true }); + }); + + it("should yield all of the first and then all of the second", () => { + const iter = concat([1, 2, 3].values(), [4, 5, 6].values()); + + expect(iter.next()).toEqual({ done: false, value: 1 }); + expect(iter.next()).toEqual({ done: false, value: 2 }); + expect(iter.next()).toEqual({ done: false, value: 3 }); + expect(iter.next()).toEqual({ done: false, value: 4 }); + expect(iter.next()).toEqual({ done: false, value: 5 }); + expect(iter.next()).toEqual({ done: false, value: 6 }); + expect(iter.next()).toEqual({ done: true }); + }); + }); }); diff --git a/src/common/utils/iter.ts b/src/common/utils/iter.ts index 5b5593d2d4..dc1c4621fd 100644 --- a/src/common/utils/iter.ts +++ b/src/common/utils/iter.ts @@ -12,6 +12,7 @@ interface Iterator extends Iterable { collect(fn: (values: Iterable) => U): U; map(fn: (val: T) => U): Iterator; flatMap(fn: (val: T) => U[]): Iterator; + concat(src2: IterableIterator): Iterator; join(sep?: string): string; } @@ -24,6 +25,7 @@ export function chain(src: IterableIterator): Iterator { find: (fn) => find(src, fn), join: (sep) => join(src, sep), collect: (fn) => fn(src), + concat: (src2) => chain(concat(src, src2)), [Symbol.iterator]: () => src, }; } @@ -236,3 +238,11 @@ export function every(src: Iterable, fn: (val: T) => any): boolean { return true; } + +export function* concat(...sources: IterableIterator[]): IterableIterator { + for (const source of sources) { + for (const val of source) { + yield val; + } + } +} diff --git a/src/extensions/common-api/k8s-api.ts b/src/extensions/common-api/k8s-api.ts index 3856429717..c24f7d14e3 100644 --- a/src/extensions/common-api/k8s-api.ts +++ b/src/extensions/common-api/k8s-api.ts @@ -26,10 +26,12 @@ import loggerInjectable from "../../common/logger.injectable"; import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; import maybeKubeApiInjectable from "../../common/k8s-api/maybe-kube-api.injectable"; import { DeploymentApi as InternalDeploymentApi, IngressApi as InternalIngressApi, NodeApi, PersistentVolumeClaimApi, PodApi } from "../../common/k8s-api/endpoints"; +import { storesAndApisCanBeCreatedInjectionToken } from "../../common/k8s-api/stores-apis-can-be-created.token"; export const apiManager = asLegacyGlobalForExtensionApi(apiManagerInjectable); export const forCluster = asLegacyGlobalFunctionForExtensionApi(createKubeApiForClusterInjectable); export const forRemoteCluster = asLegacyGlobalFunctionForExtensionApi(createKubeApiForRemoteClusterInjectable); +export const createResourceStack = asLegacyGlobalFunctionForExtensionApi(createResourceStackInjectable); const getKubeApiDeps = (): KubeApiDependencies => { const di = getLegacyGlobalDiForExtensionApi(); @@ -45,7 +47,16 @@ function KubeApiCstr< Object extends KubeObject = KubeObject, Data extends KubeJsonApiDataFor = KubeJsonApiDataFor, >(opts: KubeApiOptions) { - return new InternalKubeApi(getKubeApiDeps(), opts); + const api = new InternalKubeApi(getKubeApiDeps(), opts); + + const di = getLegacyGlobalDiForExtensionApi(); + const storesAndApisCanBeCreated = di.inject(storesAndApisCanBeCreatedInjectionToken); + + if (storesAndApisCanBeCreated) { + apiManager.registerApi(api); + } + + return api; } export const KubeApi = KubeApiCstr as unknown as new< @@ -53,8 +64,6 @@ export const KubeApi = KubeApiCstr as unknown as new< Data extends KubeJsonApiDataFor = KubeJsonApiDataFor, >(opts: KubeApiOptions) => InternalKubeApi; -export const createResourceStack = asLegacyGlobalFunctionForExtensionApi(createResourceStackInjectable); - /** * @deprecated Switch to using `Common.createResourceStack` instead */ @@ -174,31 +183,31 @@ export interface IgnoredKubeApiOptions { // NOTE: these *Constructor functions MUST be `function` to work with `new X()` function PodsApiConstructor(opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) { - return new PodApi(getKubeApiDeps(), opts ?? {}); + return new PodApi(getKubeApiDeps(), opts); } export const PodsApi = PodsApiConstructor as unknown as new (opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) => PodApi; function NodesApiConstructor(opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) { - return new NodeApi(getKubeApiDeps(), opts ?? {}); + return new NodeApi(getKubeApiDeps(), opts); } export const NodesApi = NodesApiConstructor as unknown as new (opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) => NodeApi; function DeploymentApiConstructor(opts?: DerivedKubeApiOptions) { - return new InternalDeploymentApi(getKubeApiDeps(), opts ?? {}); + return new InternalDeploymentApi(getKubeApiDeps(), opts); } export const DeploymentApi = DeploymentApiConstructor as unknown as new (opts?: DerivedKubeApiOptions) => InternalDeploymentApi; function IngressApiConstructor(opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) { - return new InternalIngressApi(getKubeApiDeps(), opts ?? {}); + return new InternalIngressApi(getKubeApiDeps(), opts); } export const IngressApi = IngressApiConstructor as unknown as new (opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) => InternalIngressApi; function PersistentVolumeClaimsApiConstructor(opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) { - return new PersistentVolumeClaimApi(getKubeApiDeps(), opts ?? {}); + return new PersistentVolumeClaimApi(getKubeApiDeps(), opts); } export const PersistentVolumeClaimsApi = PersistentVolumeClaimsApiConstructor as unknown as new (opts?: DerivedKubeApiOptions & IgnoredKubeApiOptions) => PersistentVolumeClaimApi; diff --git a/src/extensions/common-api/registrations.ts b/src/extensions/common-api/registrations.ts index 50a9262419..3592d7950e 100644 --- a/src/extensions/common-api/registrations.ts +++ b/src/extensions/common-api/registrations.ts @@ -14,3 +14,4 @@ export type { CustomCategoryViewProps, CustomCategoryViewComponents, CustomCateg export type { ShellEnvModifier, ShellEnvContext } from "../../main/shell-session/shell-env-modifier/shell-env-modifier-registration"; export type { KubeObjectContextMenuItem, KubeObjectOnContextMenuOpenContext, KubeObjectOnContextMenuOpen, KubeObjectHandlers, KubeObjectHandlerRegistration } from "../../renderer/kube-object/handler"; export type { TrayMenuRegistration } from "../../main/tray/tray-menu-registration"; +export type { MenuRegistration } from "../../features/application-menu/main/menu-registration"; diff --git a/src/extensions/lens-main-extension.ts b/src/extensions/lens-main-extension.ts index b97d8da834..63daab9ba4 100644 --- a/src/extensions/lens-main-extension.ts +++ b/src/extensions/lens-main-extension.ts @@ -12,7 +12,7 @@ import type { ShellEnvModifier } from "../main/shell-session/shell-env-modifier/ import type { LensMainExtensionDependencies } from "./lens-extension-set-dependencies"; export class LensMainExtension extends LensExtension { - appMenus: MenuRegistration[] = []; + appMenus: MenuRegistration[] | IComputedValue = []; trayMenus: TrayMenuRegistration[] | IComputedValue = []; /** diff --git a/src/features/application-menu/main/application-menu-item-registrator.injectable.ts b/src/features/application-menu/main/application-menu-item-registrator.injectable.ts index 8c3d635db0..b2e7367bbb 100644 --- a/src/features/application-menu/main/application-menu-item-registrator.injectable.ts +++ b/src/features/application-menu/main/application-menu-item-registrator.injectable.ts @@ -2,6 +2,7 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ +import { computed } from "mobx"; import type { Injectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable"; import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token"; @@ -25,11 +26,15 @@ const applicationMenuItemRegistratorInjectable = getInjectable({ const toRecursedInjectables = toRecursedInjectablesFor(logError); return (ext: LensExtension) => { - const extension = ext as LensMainExtension; + const mainExtension = ext as LensMainExtension; - return extension.appMenus.flatMap( - toRecursedInjectables([extension.sanitizedExtensionId]), - ); + return computed(() => { + const appMenus = Array.isArray(mainExtension.appMenus) ? mainExtension.appMenus : mainExtension.appMenus.get(); + + return appMenus.flatMap( + toRecursedInjectables([mainExtension.sanitizedExtensionId]), + ); + }); }; }, diff --git a/src/features/application-menu/main/menu-registration.ts b/src/features/application-menu/main/menu-registration.ts index 8f0ba5933f..3dc75ba077 100644 --- a/src/features/application-menu/main/menu-registration.ts +++ b/src/features/application-menu/main/menu-registration.ts @@ -3,7 +3,9 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import type { MenuItemConstructorOptions } from "electron"; +import type { IComputedValue } from "mobx"; -export interface MenuRegistration extends MenuItemConstructorOptions { +export type MenuRegistration = { parentId: string; -} + visible?: IComputedValue | boolean; +} & Omit; diff --git a/src/features/cluster/kube-object-details/extension-api/reactively-hide-kube-object-detail-item.test.tsx b/src/features/cluster/kube-object-details/extension-api/reactively-hide-kube-object-detail-item.test.tsx index 1a22d5d0b0..847ad3ed11 100644 --- a/src/features/cluster/kube-object-details/extension-api/reactively-hide-kube-object-detail-item.test.tsx +++ b/src/features/cluster/kube-object-details/extension-api/reactively-hide-kube-object-detail-item.test.tsx @@ -13,6 +13,7 @@ import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager import type { KubeObjectStore } from "../../../../common/k8s-api/kube-object.store"; import type { KubeApi } from "../../../../common/k8s-api/kube-api"; import showDetailsInjectable from "../../../../renderer/components/kube-detail-params/show-details.injectable"; +import assert from "assert"; describe("reactively hide kube object detail item", () => { let builder: ApplicationBuilder; @@ -89,6 +90,10 @@ describe("reactively hide kube object detail item", () => { runInAction(() => { someObservable.set(true); }); + + const apiManager = builder.applicationWindow.only.di.inject(apiManagerInjectable); + + assert(apiManager.getStore("/apis/some-api-version/some-kind")); }); it("renders", () => { 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 a3761caf21..c6102f3f24 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 @@ -66,7 +66,7 @@ describe("cluster/namespaces - edit namespace from new tab", () => { builder.allowKubeResource({ apiName: "namespaces", - group: "v1", + group: "", }); }); 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 0d49469951..c5bbd15dfc 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 @@ -37,7 +37,7 @@ describe("cluster/namespaces - edit namespaces from previously opened tab", () = builder.allowKubeResource({ apiName: "namespaces", - group: "v1", + group: "", }); }); diff --git a/src/features/cluster/visibility-of-sidebar-items.test.tsx b/src/features/cluster/visibility-of-sidebar-items.test.tsx index 2eb42b7fdf..8fd68044a6 100644 --- a/src/features/cluster/visibility-of-sidebar-items.test.tsx +++ b/src/features/cluster/visibility-of-sidebar-items.test.tsx @@ -52,7 +52,7 @@ describe("cluster - visibility of sidebar items", () => { beforeEach(() => { builder.allowKubeResource({ apiName: "namespaces", - group: "v1", + group: "", }); }); @@ -77,7 +77,7 @@ const testRouteInjectable = getInjectable({ clusterFrame: true, isEnabled: di.inject(shouldShowResourceInjectionToken, { apiName: "namespaces", - group: "v1", + group: "", }), }), diff --git a/src/features/cluster/workload-overview.test.tsx b/src/features/cluster/workload-overview.test.tsx index 205c837b47..725ec04e90 100644 --- a/src/features/cluster/workload-overview.test.tsx +++ b/src/features/cluster/workload-overview.test.tsx @@ -15,7 +15,7 @@ describe("workload overview", () => { applicationBuilder = getApplicationBuilder().setEnvironmentToClusterFrame(); applicationBuilder.allowKubeResource({ apiName: "pods", - group: "v1", + group: "", }); rendered = await applicationBuilder.render(); }); diff --git a/src/main/cluster/manager.ts b/src/main/cluster/manager.ts index 6888a44f5f..650a3b7752 100644 --- a/src/main/cluster/manager.ts +++ b/src/main/cluster/manager.ts @@ -145,31 +145,31 @@ export class ClusterManager { } else { entity.status.phase = (() => { if (!cluster) { - this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="no cluster"`); + this.dependencies.logger.silly(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="no cluster"`); return LensKubernetesClusterStatus.DISCONNECTED; } if (cluster.accessible) { - this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to CONNECTED, reason="cluster is accessible"`); + this.dependencies.logger.silly(`${logPrefix} setting entity ${entity.getName()} to CONNECTED, reason="cluster is accessible"`); return LensKubernetesClusterStatus.CONNECTED; } if (!cluster.disconnected) { - this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to CONNECTING, reason="cluster is not disconnected"`); + this.dependencies.logger.silly(`${logPrefix} setting entity ${entity.getName()} to CONNECTING, reason="cluster is not disconnected"`); return LensKubernetesClusterStatus.CONNECTING; } // Extensions are not allowed to use the Lens specific status phases if (!lensSpecificClusterStatuses.has(entity?.status?.phase)) { - this.dependencies.logger.debug(`${logPrefix} not clearing entity ${entity.getName()} status, reason="custom string"`); + this.dependencies.logger.silly(`${logPrefix} not clearing entity ${entity.getName()} status, reason="custom string"`); return entity.status.phase; } - this.dependencies.logger.debug(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="fallthrough"`); + this.dependencies.logger.silly(`${logPrefix} setting entity ${entity.getName()} to DISCONNECTED, reason="fallthrough"`); return LensKubernetesClusterStatus.DISCONNECTED; })(); diff --git a/src/main/cluster/request-core-api-versions.injectable.ts b/src/main/cluster/request-core-api-versions.injectable.ts index e92def914e..4287eb4d3b 100644 --- a/src/main/cluster/request-core-api-versions.injectable.ts +++ b/src/main/cluster/request-core-api-versions.injectable.ts @@ -16,7 +16,7 @@ const requestCoreApiVersionsInjectable = getInjectable({ const { versions } = await k8sRequest(cluster, "/api") as V1APIVersions; return versions.map(version => ({ - group: version, + group: "", path: `/api/${version}`, })); }; 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 2d6ece0dfd..1b64040d40 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 @@ -7,7 +7,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import type { ClusterOverviewStorageState } from "./cluster-overview-store"; import { ClusterOverviewStore, MetricNodeRole, MetricType } from "./cluster-overview-store"; import createStorageInjectable from "../../../utils/create-storage/create-storage.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import clusterApiInjectable from "../../../../common/k8s-api/endpoints/cluster.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable"; import assert from "assert"; diff --git a/src/renderer/components/+config-autoscalers/store.injectable.ts b/src/renderer/components/+config-autoscalers/store.injectable.ts index 47a0f25680..6b09568537 100644 --- a/src/renderer/components/+config-autoscalers/store.injectable.ts +++ b/src/renderer/components/+config-autoscalers/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import horizontalPodAutoscalerApiInjectable from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+config-leases/store.injectable.ts b/src/renderer/components/+config-leases/store.injectable.ts index df91a1df54..26cf598aff 100644 --- a/src/renderer/components/+config-leases/store.injectable.ts +++ b/src/renderer/components/+config-leases/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import leaseApiInjectable from "../../../common/k8s-api/endpoints/lease.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+config-limit-ranges/store.injectable.ts b/src/renderer/components/+config-limit-ranges/store.injectable.ts index f22aadaec1..5109b25079 100644 --- a/src/renderer/components/+config-limit-ranges/store.injectable.ts +++ b/src/renderer/components/+config-limit-ranges/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import limitRangeApiInjectable from "../../../common/k8s-api/endpoints/limit-range.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+config-maps/store.injectable.ts b/src/renderer/components/+config-maps/store.injectable.ts index 44945120f0..e282e4d121 100644 --- a/src/renderer/components/+config-maps/store.injectable.ts +++ b/src/renderer/components/+config-maps/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import configMapApiInjectable from "../../../common/k8s-api/endpoints/config-map.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; 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 f6bb813455..3f3b83e21f 100644 --- a/src/renderer/components/+config-pod-disruption-budgets/store.injectable.ts +++ b/src/renderer/components/+config-pod-disruption-budgets/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import podDisruptionBudgetApiInjectable from "../../../common/k8s-api/endpoints/pod-disruption-budget.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+config-priority-classes/store.injectable.ts b/src/renderer/components/+config-priority-classes/store.injectable.ts index acd97aee5b..e3e22a53b9 100644 --- a/src/renderer/components/+config-priority-classes/store.injectable.ts +++ b/src/renderer/components/+config-priority-classes/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import priorityClassApiInjectable from "../../../common/k8s-api/endpoints/priority-class.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/src/renderer/components/+config-resource-quotas/store.injectable.ts b/src/renderer/components/+config-resource-quotas/store.injectable.ts index 77708a1bf4..cbbb014d05 100644 --- a/src/renderer/components/+config-resource-quotas/store.injectable.ts +++ b/src/renderer/components/+config-resource-quotas/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import resourceQuotaApiInjectable from "../../../common/k8s-api/endpoints/resource-quota.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+config-runtime-classes/store.injectable.ts b/src/renderer/components/+config-runtime-classes/store.injectable.ts index 03d4e50a1a..70c0efa6c4 100644 --- a/src/renderer/components/+config-runtime-classes/store.injectable.ts +++ b/src/renderer/components/+config-runtime-classes/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import runtimeClassApiInjectable from "../../../common/k8s-api/endpoints/runtime-class.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/src/renderer/components/+config-secrets/store.injectable.ts b/src/renderer/components/+config-secrets/store.injectable.ts index d98f3677c1..a18fff90b2 100644 --- a/src/renderer/components/+config-secrets/store.injectable.ts +++ b/src/renderer/components/+config-secrets/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import secretApiInjectable from "../../../common/k8s-api/endpoints/secret.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+custom-resources/definition.store.injectable.ts b/src/renderer/components/+custom-resources/definition.store.injectable.ts index 47c7652f8b..f1d8f635b8 100644 --- a/src/renderer/components/+custom-resources/definition.store.injectable.ts +++ b/src/renderer/components/+custom-resources/definition.store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; 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 { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import customResourceDefinitionApiInjectable from "../../../common/k8s-api/endpoints/custom-resource-definition.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/src/renderer/components/+events/store.injectable.ts b/src/renderer/components/+events/store.injectable.ts index 57bc98e6d2..b81a198413 100644 --- a/src/renderer/components/+events/store.injectable.ts +++ b/src/renderer/components/+events/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import getPodByIdInjectable from "../+workloads-pods/get-pod-by-id.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import kubeEventApiInjectable from "../../../common/k8s-api/endpoints/events.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+namespaces/store.injectable.ts b/src/renderer/components/+namespaces/store.injectable.ts index 50164e6626..1ee9dc024f 100644 --- a/src/renderer/components/+namespaces/store.injectable.ts +++ b/src/renderer/components/+namespaces/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { NamespaceStore } from "./store"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import createStorageInjectable from "../../utils/create-storage/create-storage.injectable"; import namespaceApiInjectable from "../../../common/k8s-api/endpoints/namespace.api.injectable"; import assert from "assert"; diff --git a/src/renderer/components/+network-endpoints/store.injectable.ts b/src/renderer/components/+network-endpoints/store.injectable.ts index d376b039a0..ee8474c8a8 100644 --- a/src/renderer/components/+network-endpoints/store.injectable.ts +++ b/src/renderer/components/+network-endpoints/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import endpointsApiInjectable from "../../../common/k8s-api/endpoints/endpoint.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+network-ingresses/ingress-class-store.injectable.ts b/src/renderer/components/+network-ingresses/ingress-class-store.injectable.ts index 9379b4ff59..98315f91ac 100644 --- a/src/renderer/components/+network-ingresses/ingress-class-store.injectable.ts +++ b/src/renderer/components/+network-ingresses/ingress-class-store.injectable.ts @@ -4,10 +4,9 @@ */ import assert from "assert"; import { getInjectable } from "@ogre-tools/injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import ingressClassApiInjectable from "../../../common/k8s-api/endpoints/ingress-class.api.injectable"; import { IngressClassStore } from "./ingress-class-store"; - import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; import loggerInjectable from "../../../common/logger.injectable"; diff --git a/src/renderer/components/+network-ingresses/ingress-store.injectable.ts b/src/renderer/components/+network-ingresses/ingress-store.injectable.ts index 8f5f1e6e39..ebd460664e 100644 --- a/src/renderer/components/+network-ingresses/ingress-store.injectable.ts +++ b/src/renderer/components/+network-ingresses/ingress-store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import ingressApiInjectable from "../../../common/k8s-api/endpoints/ingress.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+network-policies/store.injectable.ts b/src/renderer/components/+network-policies/store.injectable.ts index b17c0918d9..b3d7cfa0bf 100644 --- a/src/renderer/components/+network-policies/store.injectable.ts +++ b/src/renderer/components/+network-policies/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import networkPolicyApiInjectable from "../../../common/k8s-api/endpoints/network-policy.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+network-services/store.injectable.ts b/src/renderer/components/+network-services/store.injectable.ts index d705ca0d46..a4a2f831eb 100644 --- a/src/renderer/components/+network-services/store.injectable.ts +++ b/src/renderer/components/+network-services/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import serviceApiInjectable from "../../../common/k8s-api/endpoints/service.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+nodes/store.injectable.ts b/src/renderer/components/+nodes/store.injectable.ts index a397db07e1..b12845b6a4 100644 --- a/src/renderer/components/+nodes/store.injectable.ts +++ b/src/renderer/components/+nodes/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import nodeApiInjectable from "../../../common/k8s-api/endpoints/node.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/src/renderer/components/+pod-security-policies/store.injectable.ts b/src/renderer/components/+pod-security-policies/store.injectable.ts index 2e27ad466a..0c90fa571e 100644 --- a/src/renderer/components/+pod-security-policies/store.injectable.ts +++ b/src/renderer/components/+pod-security-policies/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import podSecurityPolicyApiInjectable from "../../../common/k8s-api/endpoints/pod-security-policy.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/src/renderer/components/+storage-classes/store.injectable.ts b/src/renderer/components/+storage-classes/store.injectable.ts index 0ae16b0a92..b0508f01fd 100644 --- a/src/renderer/components/+storage-classes/store.injectable.ts +++ b/src/renderer/components/+storage-classes/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; 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 { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import storageClassApiInjectable from "../../../common/k8s-api/endpoints/storage-class.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; diff --git a/src/renderer/components/+storage-volume-claims/store.injectable.ts b/src/renderer/components/+storage-volume-claims/store.injectable.ts index ef9b4629fa..a9289a1fd0 100644 --- a/src/renderer/components/+storage-volume-claims/store.injectable.ts +++ b/src/renderer/components/+storage-volume-claims/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import persistentVolumeClaimApiInjectable from "../../../common/k8s-api/endpoints/persistent-volume-claim.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+storage-volumes/store.injectable.ts b/src/renderer/components/+storage-volumes/store.injectable.ts index 1432c0ed6c..00a0db0c8c 100644 --- a/src/renderer/components/+storage-volumes/store.injectable.ts +++ b/src/renderer/components/+storage-volumes/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import persistentVolumeApiInjectable from "../../../common/k8s-api/endpoints/persistent-volume.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../cluster-frame-context/for-cluster-scoped-resources.injectable"; 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 ac3eb8a07d..54250222d3 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 @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { storesAndApisCanBeCreatedInjectionToken } from "../../../../common/k8s-api/stores-apis-can-be-created.token"; import clusterRoleBindingApiInjectable from "../../../../common/k8s-api/endpoints/cluster-role-binding.api.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import { ClusterRoleBindingStore } from "./store"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../../cluster-frame-context/for-cluster-scoped-resources.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; 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 c88b457b1d..d7ea148d03 100644 --- a/src/renderer/components/+user-management/+cluster-roles/store.injectable.ts +++ b/src/renderer/components/+user-management/+cluster-roles/store.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import { storesAndApisCanBeCreatedInjectionToken } from "../../../../common/k8s-api/stores-apis-can-be-created.token"; import clusterRoleApiInjectable from "../../../../common/k8s-api/endpoints/cluster-role.api.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import { ClusterRoleStore } from "./store"; import clusterFrameContextForClusterScopedResourcesInjectable from "../../../cluster-frame-context/for-cluster-scoped-resources.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; 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 416223b071..e9b9154068 100644 --- a/src/renderer/components/+user-management/+role-bindings/store.injectable.ts +++ b/src/renderer/components/+user-management/+role-bindings/store.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import roleBindingApiInjectable from "../../../../common/k8s-api/endpoints/role-binding.api.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+user-management/+roles/store.injectable.ts b/src/renderer/components/+user-management/+roles/store.injectable.ts index f0df652438..99eddcbfa0 100644 --- a/src/renderer/components/+user-management/+roles/store.injectable.ts +++ b/src/renderer/components/+user-management/+roles/store.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import roleApiInjectable from "../../../../common/k8s-api/endpoints/role.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import { RoleStore } from "./store"; import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; 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 fd96db2d65..a4749f7ecb 100644 --- a/src/renderer/components/+user-management/+service-accounts/store.injectable.ts +++ b/src/renderer/components/+user-management/+service-accounts/store.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import serviceAccountApiInjectable from "../../../../common/k8s-api/endpoints/service-account.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../../common/k8s-api/api-manager/kube-object-store-token"; import { ServiceAccountStore } from "./store"; import clusterFrameContextForNamespacedResourcesInjectable from "../../../cluster-frame-context/for-namespaced-resources.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; diff --git a/src/renderer/components/+workloads-cronjobs/store.injectable.ts b/src/renderer/components/+workloads-cronjobs/store.injectable.ts index 2569e77440..98d539a9ce 100644 --- a/src/renderer/components/+workloads-cronjobs/store.injectable.ts +++ b/src/renderer/components/+workloads-cronjobs/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; 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 { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import cronJobApiInjectable from "../../../common/k8s-api/endpoints/cron-job.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+workloads-daemonsets/store.injectable.ts b/src/renderer/components/+workloads-daemonsets/store.injectable.ts index 59252688bf..4b79b19bb5 100644 --- a/src/renderer/components/+workloads-daemonsets/store.injectable.ts +++ b/src/renderer/components/+workloads-daemonsets/store.injectable.ts @@ -7,7 +7,7 @@ import assert from "assert"; import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable"; import daemonSetApiInjectable from "../../../common/k8s-api/endpoints/daemon-set.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import { DaemonSetStore } from "./store"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import loggerInjectable from "../../../common/logger.injectable"; diff --git a/src/renderer/components/+workloads-deployments/store.injectable.ts b/src/renderer/components/+workloads-deployments/store.injectable.ts index 1a6a9f7df1..50ae255e21 100644 --- a/src/renderer/components/+workloads-deployments/store.injectable.ts +++ b/src/renderer/components/+workloads-deployments/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import podStoreInjectable from "../+workloads-pods/store.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; 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"; diff --git a/src/renderer/components/+workloads-jobs/store.injectable.ts b/src/renderer/components/+workloads-jobs/store.injectable.ts index 28d3806788..083b465ded 100644 --- a/src/renderer/components/+workloads-jobs/store.injectable.ts +++ b/src/renderer/components/+workloads-jobs/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; 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 { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import jobApiInjectable from "../../../common/k8s-api/endpoints/job.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts b/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts index 452f7903aa..246469b9e7 100644 --- a/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts +++ b/src/renderer/components/+workloads-overview/workloads/implementations/pods-workload.injectable.ts @@ -21,7 +21,7 @@ const podsWorkloadInjectable = getInjectable({ return { resource: { apiName: "pods", - group: "v1", + group: "", }, open: navigate, diff --git a/src/renderer/components/+workloads-pods/store.injectable.ts b/src/renderer/components/+workloads-pods/store.injectable.ts index 473cd80c5c..7b2bc23419 100644 --- a/src/renderer/components/+workloads-pods/store.injectable.ts +++ b/src/renderer/components/+workloads-pods/store.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import assert from "assert"; import podApiInjectable from "../../../common/k8s-api/endpoints/pod.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import { PodStore } from "./store"; import podMetricsApiInjectable from "../../../common/k8s-api/endpoints/pod-metrics.api.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/+workloads-replicasets/store.injectable.ts b/src/renderer/components/+workloads-replicasets/store.injectable.ts index b54fd0295d..34887a0590 100644 --- a/src/renderer/components/+workloads-replicasets/store.injectable.ts +++ b/src/renderer/components/+workloads-replicasets/store.injectable.ts @@ -7,7 +7,7 @@ import assert from "assert"; import getPodsByOwnerIdInjectable from "../+workloads-pods/get-pods-by-owner-id.injectable"; import replicaSetApiInjectable from "../../../common/k8s-api/endpoints/replica-set.api.injectable"; import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; -import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import { ReplicaSetStore } from "./store"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; import loggerInjectable from "../../../common/logger.injectable"; diff --git a/src/renderer/components/+workloads-statefulsets/store.injectable.ts b/src/renderer/components/+workloads-statefulsets/store.injectable.ts index ce8649b109..b8fef46c51 100644 --- a/src/renderer/components/+workloads-statefulsets/store.injectable.ts +++ b/src/renderer/components/+workloads-statefulsets/store.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; 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 { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; import statefulSetApiInjectable from "../../../common/k8s-api/endpoints/stateful-set.api.injectable"; import loggerInjectable from "../../../common/logger.injectable"; import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; diff --git a/src/renderer/components/kube-object-list-layout/__snapshots__/kube-object-list-layout.test.tsx.snap b/src/renderer/components/kube-object-list-layout/__snapshots__/kube-object-list-layout.test.tsx.snap new file mode 100644 index 0000000000..b450030c9c --- /dev/null +++ b/src/renderer/components/kube-object-list-layout/__snapshots__/kube-object-list-layout.test.tsx.snap @@ -0,0 +1,121 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`kube-object-list-layout given pod store renders 1`] = ` + +
+
+
+
+
+ Pods +
+
+ 0 items +
+
+
+ + +
+
+
+ All namespaces +
+
+ +
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +`; diff --git a/src/renderer/components/kube-object-list-layout/kube-object-list-layout.test.tsx b/src/renderer/components/kube-object-list-layout/kube-object-list-layout.test.tsx new file mode 100644 index 0000000000..d50d70c723 --- /dev/null +++ b/src/renderer/components/kube-object-list-layout/kube-object-list-layout.test.tsx @@ -0,0 +1,108 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { DiContainer } from "@ogre-tools/injectable"; +import "@testing-library/jest-dom/extend-expect"; +import type { RenderResult } from "@testing-library/react"; +import React from "react"; +import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable"; +import { getDiForUnitTesting } from "../../getDiForUnitTesting"; +import kubeSelectedUrlParamInjectable from "../kube-detail-params/kube-selected-url.injectable"; +import toggleKubeDetailsPaneInjectable from "../kube-detail-params/toggle-details.injectable"; +import type { DiRender } from "../test-utils/renderFor"; +import { renderFor } from "../test-utils/renderFor"; +import { KubeObjectListLayout } from "./index"; +import appPathsStateInjectable from "../../../common/app-paths/app-paths-state.injectable"; +import podStoreInjectable from "../+workloads-pods/store.injectable"; +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 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 "../../../main/create-cluster/create-cluster.injectable"; +import type { PodStore } from "../+workloads-pods/store"; + +describe("kube-object-list-layout", () => { + let di: DiContainer; + let render: DiRender; + let podStore: PodStore; + + beforeEach(() => { + 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", + })); + + render = renderFor(di); + + di.override(subscribeStoresInjectable, () => jest.fn().mockImplementation(() => jest.fn())); + di.override(kubeSelectedUrlParamInjectable, () => ({ + get: () => "path", + })); + di.override(toggleKubeDetailsPaneInjectable, () => null); + di.override(appPathsStateInjectable, () => ({ + get: () => ({}), + })); + + podStore = di.inject(podStoreInjectable); + }); + + describe("given pod store", () => { + let result: RenderResult; + + it("renders", () => { + result = render(( +
+ [ +
{pod.getName()}
, + ]} + /> +
+ )); + + expect(result.baseElement).toMatchSnapshot(); + }); + + describe("given resourcename", () => { + it("uses resourcename in search placeholder", () => { + result = render(( +
+ [ +
{pod.getName()}
, + ]} + resourceName="My Custom Items" + searchFilters={[() => null]} + /> +
+ )); + + expect(result.getByPlaceholderText("Search My Custom Items...")).toBeInTheDocument(); + }); + }); + }); +}); + + diff --git a/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx b/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx index 463bb8dd35..82929e788c 100644 --- a/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx +++ b/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx @@ -40,6 +40,12 @@ export interface KubeObjectListLayoutProps< store: KubeObjectStore; dependentStores?: SubscribableStore[]; subscribeStores?: boolean; + + /** + * Customize resource name for e.g. search input ("Search ..."") + * If not provided, ResourceNames is used instead with a fallback to resource kind. + */ + resourceName?: string; } interface Dependencies { @@ -132,7 +138,7 @@ class NonInjectedKubeObjectListLayout< onDetails, ...layoutProps } = this.props; - const placeholderString = ResourceNames[ResourceKindMap[store.api.kind]] || store.api.kind; + const resourceName = this.props.resourceName || ResourceNames[ResourceKindMap[store.api.kind]] || store.api.kind; return ( @@ -151,7 +157,7 @@ class NonInjectedKubeObjectListLayout< ), searchProps: { ...searchProps, - placeholder: `Search ${placeholderString}...`, + placeholder: `Search ${resourceName}...`, }, info: ( <> diff --git a/src/renderer/frames/cluster-frame/cluster-frame.test.tsx b/src/renderer/frames/cluster-frame/cluster-frame.test.tsx index 1a4cc82248..c403ad6b49 100644 --- a/src/renderer/frames/cluster-frame/cluster-frame.test.tsx +++ b/src/renderer/frames/cluster-frame/cluster-frame.test.tsx @@ -69,7 +69,7 @@ describe("", () => { describe("given cluster with list nodes and namespaces permissions", () => { beforeEach(() => { // TODO: replace with not using private info - (cluster as any).allowedResources.replace(["v1/nodes", "v1/namespaces"]); + (cluster as unknown as { readonly allowedResources: Cluster["allowedResources"] }).allowedResources.replace(["nodes", "namespaces"]); }); it("renders", () => { @@ -110,7 +110,7 @@ describe("", () => { describe("given cluster without list nodes, but with namespaces permissions", () => { beforeEach(() => { - (cluster as any).allowedResources.replace(["v1/namespaces"]); + (cluster as unknown as { readonly allowedResources: Cluster["allowedResources"] }).allowedResources.replace(["namespaces"]); }); it("renders", () => { diff --git a/src/renderer/initializers/workload-events.tsx b/src/renderer/initializers/workload-events.tsx index 735b4e2c74..73251382c8 100644 --- a/src/renderer/initializers/workload-events.tsx +++ b/src/renderer/initializers/workload-events.tsx @@ -34,7 +34,7 @@ export const WorkloadEvents = withInjectables getProps: (di, props) => ({ workloadEventsAreAllowed: di.inject(shouldShowResourceInjectionToken, { apiName: "events", - group: "v1", + group: "", }), ...props, }),