mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix stack overflow and cycles in DI
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
375018c330
commit
26062aa20b
@ -9,22 +9,27 @@ import { KubeObject } from "../kube-object";
|
|||||||
import AbortController from "abort-controller";
|
import AbortController from "abort-controller";
|
||||||
import { delay } from "../../utils/delay";
|
import { delay } from "../../utils/delay";
|
||||||
import { PassThrough } from "stream";
|
import { PassThrough } from "stream";
|
||||||
import type { ApiManager } from "../api-manager";
|
import { ApiManager } from "../api-manager";
|
||||||
import { apiManager } from "../api-manager";
|
|
||||||
import type { FetchMock } from "jest-fetch-mock/types";
|
import type { FetchMock } from "jest-fetch-mock/types";
|
||||||
import { DeploymentApi, Ingress, IngressApi, Pod, PodApi } from "../endpoints";
|
import { DeploymentApi, Ingress, IngressApi, Pod, PodApi } from "../endpoints";
|
||||||
import { getDiForUnitTesting } from "../../../main/getDiForUnitTesting";
|
import { getDiForUnitTesting } from "../../../main/getDiForUnitTesting";
|
||||||
|
import apiManagerInjectable from "../api-manager/manager.injectable";
|
||||||
|
|
||||||
jest.mock("../api-manager");
|
jest.mock("../api-manager");
|
||||||
|
|
||||||
const mockApiManager = apiManager as jest.Mocked<ApiManager>;
|
|
||||||
const mockFetch = fetch as FetchMock;
|
const mockFetch = fetch as FetchMock;
|
||||||
|
|
||||||
describe("forRemoteCluster", () => {
|
describe("forRemoteCluster", () => {
|
||||||
|
let apiManager: jest.Mocked<ApiManager>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||||
|
|
||||||
await di.runSetups();
|
await di.runSetups();
|
||||||
|
|
||||||
|
apiManager = new ApiManager() as jest.Mocked<ApiManager>;
|
||||||
|
|
||||||
|
di.override(apiManagerInjectable, () => apiManager);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("builds api client for KubeObject", async () => {
|
it("builds api client for KubeObject", async () => {
|
||||||
@ -79,6 +84,7 @@ describe("forRemoteCluster", () => {
|
|||||||
|
|
||||||
describe("KubeApi", () => {
|
describe("KubeApi", () => {
|
||||||
let request: KubeJsonApi;
|
let request: KubeJsonApi;
|
||||||
|
let apiManager: jest.Mocked<ApiManager>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||||
@ -89,6 +95,9 @@ describe("KubeApi", () => {
|
|||||||
serverAddress: `http://127.0.0.1:9999`,
|
serverAddress: `http://127.0.0.1:9999`,
|
||||||
apiBase: "/api-kube",
|
apiBase: "/api-kube",
|
||||||
});
|
});
|
||||||
|
apiManager = new ApiManager() as jest.Mocked<ApiManager>;
|
||||||
|
|
||||||
|
di.override(apiManagerInjectable, () => apiManager);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("uses url from apiBase if apiBase contains the resource", async () => {
|
it("uses url from apiBase if apiBase contains the resource", async () => {
|
||||||
@ -218,7 +227,7 @@ describe("KubeApi", () => {
|
|||||||
await (api as any).checkPreferredVersion();
|
await (api as any).checkPreferredVersion();
|
||||||
|
|
||||||
expect(api.apiVersionPreferred).toBe("v1beta1");
|
expect(api.apiVersionPreferred).toBe("v1beta1");
|
||||||
expect(mockApiManager.registerApi).toBeCalledWith("/apis/extensions/v1beta1/ingresses", expect.anything());
|
expect(apiManager.registerApi).toBeCalledWith("/apis/extensions/v1beta1/ingresses", expect.anything());
|
||||||
});
|
});
|
||||||
|
|
||||||
it("registers with apiManager if checkPreferredVersion changes apiVersionPreferred with non-grouped apis", async () => {
|
it("registers with apiManager if checkPreferredVersion changes apiVersionPreferred with non-grouped apis", async () => {
|
||||||
@ -258,7 +267,7 @@ describe("KubeApi", () => {
|
|||||||
await (api as any).checkPreferredVersion();
|
await (api as any).checkPreferredVersion();
|
||||||
|
|
||||||
expect(api.apiVersionPreferred).toBe("v1beta1");
|
expect(api.apiVersionPreferred).toBe("v1beta1");
|
||||||
expect(mockApiManager.registerApi).toBeCalledWith("/api/v1beta1/pods", expect.anything());
|
expect(apiManager.registerApi).toBeCalledWith("/api/v1beta1/pods", expect.anything());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -42,17 +42,28 @@ export class ApiManager {
|
|||||||
return iter.find(this.apis.values(), api => api.kind === kind && api.apiVersionWithGroup === apiVersion);
|
return iter.find(this.apis.values(), api => api.kind === kind && api.apiVersionWithGroup === apiVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerApi<Api>(apiBase: string, api: RegisterableApi<Api>) {
|
registerApi<Api>(api: RegisterableApi<Api>): void;
|
||||||
if (!api.apiBase) return;
|
/**
|
||||||
|
* @deprecated Just register the `api` by itself
|
||||||
|
*/
|
||||||
|
registerApi<Api>(apiBase: string, api: RegisterableApi<Api>): void;
|
||||||
|
registerApi<Api>(apiBaseRaw: string | RegisterableApi<Api>, apiRaw?: RegisterableApi<Api>) {
|
||||||
|
const api = typeof apiBaseRaw === "string"
|
||||||
|
? apiRaw
|
||||||
|
: apiBaseRaw;
|
||||||
|
|
||||||
if (!this.apis.has(apiBase)) {
|
if (!api?.apiBase) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.apis.has(api.apiBase)) {
|
||||||
this.stores.forEach((store) => {
|
this.stores.forEach((store) => {
|
||||||
if (store.api as never === api) {
|
if (store.api === api) {
|
||||||
this.stores.set(apiBase, store);
|
this.stores.set(api.apiBase, store);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.apis.set(apiBase, api as never);
|
this.apis.set(api.apiBase, api);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import EventEmitter from "events";
|
||||||
|
import type TypedEventEmitter from "typed-emitter";
|
||||||
|
import type { CustomResourceDefinition } from "../endpoints";
|
||||||
|
import type { KubeApi } from "../kube-api";
|
||||||
|
|
||||||
|
export interface LegacyAutoRegistration {
|
||||||
|
customResourceDefinition: (crd: CustomResourceDefinition) => void;
|
||||||
|
kubeApi: (api: KubeApi) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is used to remove dependency cycles from auto registering of instances
|
||||||
|
*
|
||||||
|
* - Custom Resource Definitions get their own registered store (will need in the future)
|
||||||
|
* - All KubeApi's get auto registered (this should be changed in the future)
|
||||||
|
*/
|
||||||
|
const autoRegistrationEmitterInjectable = getInjectable({
|
||||||
|
id: "auto-registration-emitter",
|
||||||
|
instantiate: (): TypedEventEmitter<LegacyAutoRegistration> => new EventEmitter(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default autoRegistrationEmitterInjectable;
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { KubeApi } from "../kube-api";
|
||||||
|
import { KubeObject } from "../kube-object";
|
||||||
|
import autoRegistrationEmitterInjectable from "./auto-registration-emitter.injectable";
|
||||||
|
import apiManagerInjectable from "./manager.injectable";
|
||||||
|
import { CustomResourceStore } from "./resource.store";
|
||||||
|
|
||||||
|
const autoRegistrationInjectable = getInjectable({
|
||||||
|
id: "api-manager-auto-registration",
|
||||||
|
instantiate: (di) => {
|
||||||
|
const apiManager = di.inject(apiManagerInjectable);
|
||||||
|
const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable);
|
||||||
|
|
||||||
|
autoRegistrationEmitter
|
||||||
|
.on("customResourceDefinition", (crd) => {
|
||||||
|
const objectConstructor = class extends KubeObject {
|
||||||
|
static readonly kind = crd.getResourceKind();
|
||||||
|
static readonly namespaced = crd.isNamespaced();
|
||||||
|
static readonly apiBase = crd.getResourceApiBase();
|
||||||
|
};
|
||||||
|
|
||||||
|
const api = (() => {
|
||||||
|
const rawApi = apiManager.getApi(objectConstructor.apiBase);
|
||||||
|
|
||||||
|
if (rawApi) {
|
||||||
|
return rawApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
const api = new KubeApi({ objectConstructor });
|
||||||
|
|
||||||
|
apiManager.registerApi(api);
|
||||||
|
|
||||||
|
return api;
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (!apiManager.getStore(api)) {
|
||||||
|
apiManager.registerStore(new CustomResourceStore(api));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on("kubeApi", (api) => apiManager.registerApi(api));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default autoRegistrationInjectable;
|
||||||
@ -3,9 +3,9 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { KubeApi } from "../../../common/k8s-api/kube-api";
|
import type { KubeApi } from "../kube-api";
|
||||||
import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
|
import { KubeObjectStore } from "../kube-object.store";
|
||||||
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
import type { KubeObject } from "../kube-object";
|
||||||
|
|
||||||
export class CustomResourceStore<K extends KubeObject> extends KubeObjectStore<K, KubeApi<K>> {
|
export class CustomResourceStore<K extends KubeObject> extends KubeObjectStore<K, KubeApi<K>> {
|
||||||
constructor(api: KubeApi<K>) {
|
constructor(api: KubeApi<K>) {
|
||||||
@ -27,7 +27,7 @@ import assert from "assert";
|
|||||||
import type { PartialDeep } from "type-fest";
|
import type { PartialDeep } from "type-fest";
|
||||||
import logger from "../logger";
|
import logger from "../logger";
|
||||||
import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||||
import apiManagerInjectable from "./api-manager/manager.injectable";
|
import autoRegistrationEmitterInjectable from "./api-manager/auto-registration-emitter.injectable";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The options used for creating a `KubeApi`
|
* The options used for creating a `KubeApi`
|
||||||
@ -311,15 +311,15 @@ export interface DeleteResourceDescriptor extends ResourceDescriptor {
|
|||||||
/**
|
/**
|
||||||
* @deprecated In the new extension API, don't expose `KubeApi`'s constructor
|
* @deprecated In the new extension API, don't expose `KubeApi`'s constructor
|
||||||
*/
|
*/
|
||||||
function legacyRegisterApi(apiBase: string, api: KubeApi): void {
|
function legacyRegisterApi(api: KubeApi): void {
|
||||||
// Try both just in case, because we might be in a testing environment
|
// Try both just in case, because we might be in a testing environment
|
||||||
for (const env of [Environments.main, Environments.renderer]) {
|
for (const env of [Environments.main, Environments.renderer]) {
|
||||||
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(env);
|
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(env);
|
||||||
|
|
||||||
if (di) {
|
if (di) {
|
||||||
const apiManager = di.inject(apiManagerInjectable);
|
const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable);
|
||||||
|
|
||||||
apiManager.registerApi(apiBase, api);
|
autoRegistrationEmitter.emit("kubeApi", api);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -346,15 +346,17 @@ export class KubeApi<
|
|||||||
protected readonly fullApiPathname: string;
|
protected readonly fullApiPathname: string;
|
||||||
protected readonly fallbackApiBases: string[] | undefined;
|
protected readonly fallbackApiBases: string[] | undefined;
|
||||||
|
|
||||||
constructor({
|
constructor(opts: KubeApiOptions<Object, Data>) {
|
||||||
objectConstructor,
|
const {
|
||||||
request = apiKube,
|
objectConstructor,
|
||||||
kind = objectConstructor.kind,
|
request = apiKube,
|
||||||
isNamespaced,
|
kind = objectConstructor.kind,
|
||||||
apiBase: fullApiPathname = objectConstructor.apiBase,
|
isNamespaced,
|
||||||
checkPreferredVersion: doCheckPreferredVersion = false,
|
apiBase: fullApiPathname = objectConstructor.apiBase,
|
||||||
fallbackApiBases,
|
checkPreferredVersion: doCheckPreferredVersion = false,
|
||||||
}: KubeApiOptions<Object, Data>) {
|
fallbackApiBases,
|
||||||
|
} = opts;
|
||||||
|
|
||||||
assert(fullApiPathname, "apiBase MUST be provied either via KubeApiOptions.apiBase or KubeApiOptions.objectConstructor.apiBase");
|
assert(fullApiPathname, "apiBase MUST be provied either via KubeApiOptions.apiBase or KubeApiOptions.objectConstructor.apiBase");
|
||||||
assert(request, "request MUST be provided if not in a cluster page frame context");
|
assert(request, "request MUST be provided if not in a cluster page frame context");
|
||||||
|
|
||||||
@ -375,8 +377,7 @@ export class KubeApi<
|
|||||||
this.apiResource = resource;
|
this.apiResource = resource;
|
||||||
this.request = request;
|
this.request = request;
|
||||||
this.objectConstructor = objectConstructor;
|
this.objectConstructor = objectConstructor;
|
||||||
this.parseResponse = this.parseResponse.bind(this);
|
legacyRegisterApi(this as unknown as KubeApi);
|
||||||
legacyRegisterApi(apiBase, this as unknown as KubeApi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersionWithGroup() {
|
get apiVersionWithGroup() {
|
||||||
@ -457,7 +458,7 @@ export class KubeApi<
|
|||||||
|
|
||||||
if (this.apiVersionPreferred) {
|
if (this.apiVersionPreferred) {
|
||||||
this.apiBase = this.computeApiBase();
|
this.apiBase = this.computeApiBase();
|
||||||
legacyRegisterApi(this.apiBase, this as unknown as KubeApi);
|
legacyRegisterApi(this as unknown as KubeApi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -114,4 +114,4 @@ export type { ServiceAccountStore as ServiceAccountsStore } from "../../renderer
|
|||||||
export type { RoleStore as RolesStore } from "../../renderer/components/+user-management/+roles/store";
|
export type { RoleStore as RolesStore } from "../../renderer/components/+user-management/+roles/store";
|
||||||
export type { RoleBindingStore as RoleBindingsStore } from "../../renderer/components/+user-management/+role-bindings/store";
|
export type { RoleBindingStore as RoleBindingsStore } from "../../renderer/components/+user-management/+role-bindings/store";
|
||||||
export type { CustomResourceDefinitionStore as CRDStore } from "../../renderer/components/+custom-resources/definition.store";
|
export type { CustomResourceDefinitionStore as CRDStore } from "../../renderer/components/+custom-resources/definition.store";
|
||||||
export type { CustomResourceStore as CRDResourceStore } from "../../renderer/components/+custom-resources/resource.store";
|
export type { CustomResourceStore as CRDResourceStore } from "../../common/k8s-api/api-manager/resource.store";
|
||||||
|
|||||||
@ -4,11 +4,11 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import assert from "assert";
|
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/manager.injectable";
|
||||||
import customResourceDefinitionApiInjectable from "../../../common/k8s-api/endpoints/custom-resource-definition.api.injectable";
|
import customResourceDefinitionApiInjectable from "../../../common/k8s-api/endpoints/custom-resource-definition.api.injectable";
|
||||||
import createStoresAndApisInjectable from "../../create-stores-apis.injectable";
|
import createStoresAndApisInjectable from "../../create-stores-apis.injectable";
|
||||||
import { CustomResourceDefinitionStore } from "./definition.store";
|
import { CustomResourceDefinitionStore } from "./definition.store";
|
||||||
import initCustomResourceStoreInjectable from "./init-resource-store.injectable";
|
|
||||||
|
|
||||||
const customResourceDefinitionStoreInjectable = getInjectable({
|
const customResourceDefinitionStoreInjectable = getInjectable({
|
||||||
id: "custom-resource-definition-store",
|
id: "custom-resource-definition-store",
|
||||||
@ -18,7 +18,7 @@ const customResourceDefinitionStoreInjectable = getInjectable({
|
|||||||
const api = di.inject(customResourceDefinitionApiInjectable);
|
const api = di.inject(customResourceDefinitionApiInjectable);
|
||||||
|
|
||||||
return new CustomResourceDefinitionStore({
|
return new CustomResourceDefinitionStore({
|
||||||
initCustomResourceStore: di.inject(initCustomResourceStoreInjectable),
|
autoRegistration: di.inject(autoRegistrationEmitterInjectable),
|
||||||
}, api);
|
}, api);
|
||||||
},
|
},
|
||||||
injectionToken: kubeObjectStoreInjectionToken,
|
injectionToken: kubeObjectStoreInjectionToken,
|
||||||
|
|||||||
@ -9,10 +9,11 @@ import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
|
|||||||
import { autoBind } from "../../utils";
|
import { autoBind } from "../../utils";
|
||||||
import type { CustomResourceDefinition, CustomResourceDefinitionApi } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
import type { CustomResourceDefinition, CustomResourceDefinitionApi } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
||||||
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
import type { InitCustomResourceStore } from "./init-resource-store.injectable";
|
import type TypedEventEmitter from "typed-emitter";
|
||||||
|
import type { LegacyAutoRegistration } from "../../../common/k8s-api/api-manager/auto-registration-emitter.injectable";
|
||||||
|
|
||||||
export interface CustomResourceDefinitionStoreDependencies {
|
export interface CustomResourceDefinitionStoreDependencies {
|
||||||
initCustomResourceStore: InitCustomResourceStore;
|
readonly autoRegistration: TypedEventEmitter<LegacyAutoRegistration>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CustomResourceDefinitionStore extends KubeObjectStore<CustomResourceDefinition, CustomResourceDefinitionApi> {
|
export class CustomResourceDefinitionStore extends KubeObjectStore<CustomResourceDefinition, CustomResourceDefinitionApi> {
|
||||||
@ -25,8 +26,14 @@ export class CustomResourceDefinitionStore extends KubeObjectStore<CustomResourc
|
|||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
autoBind(this);
|
autoBind(this);
|
||||||
|
|
||||||
// auto-init stores for crd-s
|
reaction(
|
||||||
reaction(() => this.getItems(), items => items.forEach(this.dependencies.initCustomResourceStore));
|
() => this.getItems(),
|
||||||
|
crds => {
|
||||||
|
for (const crd of crds) {
|
||||||
|
this.dependencies.autoRegistration.emit("customResourceDefinition", crd);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected sortItems(items: CustomResourceDefinition[]) {
|
protected sortItems(items: CustomResourceDefinition[]) {
|
||||||
|
|||||||
@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
|
||||||
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
|
||||||
import type { CustomResourceDefinition } from "../../../common/k8s-api/endpoints";
|
|
||||||
import { KubeApi } from "../../../common/k8s-api/kube-api";
|
|
||||||
import { KubeObject } from "../../../common/k8s-api/kube-object";
|
|
||||||
import { CustomResourceStore } from "./resource.store";
|
|
||||||
|
|
||||||
export type InitCustomResourceStore = (crd: CustomResourceDefinition) => void;
|
|
||||||
|
|
||||||
const initCustomResourceStoreInjectable = getInjectable({
|
|
||||||
id: "init-custom-resource-store",
|
|
||||||
instantiate: (di): InitCustomResourceStore => {
|
|
||||||
const apiManager = di.inject(apiManagerInjectable);
|
|
||||||
|
|
||||||
return (crd) => {
|
|
||||||
const objectConstructor = class extends KubeObject {
|
|
||||||
static readonly kind = crd.getResourceKind();
|
|
||||||
static readonly namespaced = crd.isNamespaced();
|
|
||||||
static readonly apiBase = crd.getResourceApiBase();
|
|
||||||
};
|
|
||||||
|
|
||||||
const api = apiManager.getApi(objectConstructor.apiBase)
|
|
||||||
?? new KubeApi({ objectConstructor });
|
|
||||||
|
|
||||||
if (!apiManager.getStore(api)) {
|
|
||||||
apiManager.registerStore(new CustomResourceStore(api));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default initCustomResourceStoreInjectable;
|
|
||||||
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
import ingressApiInjectable from "../../../common/k8s-api/endpoints/ingress.api.injectable";
|
import ingressApiInjectable from "../../../common/k8s-api/endpoints/ingress.api.injectable";
|
||||||
import createStoresAndApisInjectable from "../../create-stores-apis.injectable";
|
import createStoresAndApisInjectable from "../../create-stores-apis.injectable";
|
||||||
import { IngressStore } from "./store";
|
import { IngressStore } from "./store";
|
||||||
@ -15,13 +15,10 @@ const ingressStoreInjectable = getInjectable({
|
|||||||
assert(di.inject(createStoresAndApisInjectable), "ingressStore is only available in certain environments");
|
assert(di.inject(createStoresAndApisInjectable), "ingressStore is only available in certain environments");
|
||||||
|
|
||||||
const api = di.inject(ingressApiInjectable);
|
const api = di.inject(ingressApiInjectable);
|
||||||
const apiManager = di.inject(apiManagerInjectable);
|
|
||||||
const store = new IngressStore(api);
|
|
||||||
|
|
||||||
apiManager.registerStore(store);
|
return new IngressStore(api);
|
||||||
|
|
||||||
return store;
|
|
||||||
},
|
},
|
||||||
|
injectionToken: kubeObjectStoreInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ingressStoreInjectable;
|
export default ingressStoreInjectable;
|
||||||
|
|||||||
@ -55,7 +55,10 @@ export const NonInjectedClusterFrame = observer(({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<MainLayout sidebar={<Sidebar />} footer={<Dock />}>
|
<MainLayout
|
||||||
|
sidebar={<Sidebar />}
|
||||||
|
footer={<Dock />}
|
||||||
|
>
|
||||||
{
|
{
|
||||||
Component
|
Component
|
||||||
? <Component />
|
? <Component />
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import hostedClusterInjectable from "../../../../common/cluster-store/hosted-clu
|
|||||||
import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable";
|
import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable";
|
||||||
import clusterFrameContextInjectable from "../../../cluster-frame-context/cluster-frame-context.injectable";
|
import clusterFrameContextInjectable from "../../../cluster-frame-context/cluster-frame-context.injectable";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
|
import autoRegistrationInjectable from "../../../../common/k8s-api/api-manager/auto-registration.injectable";
|
||||||
|
|
||||||
const initClusterFrameInjectable = getInjectable({
|
const initClusterFrameInjectable = getInjectable({
|
||||||
id: "init-cluster-frame",
|
id: "init-cluster-frame",
|
||||||
@ -20,6 +21,14 @@ const initClusterFrameInjectable = getInjectable({
|
|||||||
|
|
||||||
assert(hostedCluster, "This can only be injected within a cluster frame");
|
assert(hostedCluster, "This can only be injected within a cluster frame");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is injected here to initialize it for the side effect.
|
||||||
|
*
|
||||||
|
* The side effect CANNOT be within `apiManagerInjectable` itself since that causes circular
|
||||||
|
* dependencies with the current need for legacy di use
|
||||||
|
*/
|
||||||
|
di.inject(autoRegistrationInjectable);
|
||||||
|
|
||||||
return initClusterFrame({
|
return initClusterFrame({
|
||||||
hostedCluster,
|
hostedCluster,
|
||||||
loadExtensions: di.inject(extensionLoaderInjectable).loadOnClusterRenderer,
|
loadExtensions: di.inject(extensionLoaderInjectable).loadOnClusterRenderer,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user