1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

fix KubeApi's not being registered

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-04-25 12:08:54 -04:00
parent 8499f26707
commit 25796b736d
7 changed files with 78 additions and 43 deletions

View File

@ -10,7 +10,7 @@ import type { KubeApi } from "../kube-api";
export interface LegacyAutoRegistration { export interface LegacyAutoRegistration {
customResourceDefinition: (crd: CustomResourceDefinition) => void; customResourceDefinition: (crd: CustomResourceDefinition) => void;
kubeApi: (api: KubeApi) => void; kubeApi: (api: KubeApi<any, any>) => void;
} }
/** /**

View File

@ -3,6 +3,7 @@
* 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 { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import type { CustomResourceDefinition } from "../endpoints";
import { KubeApi } from "../kube-api"; import { KubeApi } from "../kube-api";
import { KubeObject } from "../kube-object"; import { KubeObject } from "../kube-object";
import autoRegistrationEmitterInjectable from "./auto-registration-emitter.injectable"; import autoRegistrationEmitterInjectable from "./auto-registration-emitter.injectable";
@ -12,36 +13,61 @@ import { CustomResourceStore } from "./resource.store";
const autoRegistrationInjectable = getInjectable({ const autoRegistrationInjectable = getInjectable({
id: "api-manager-auto-registration", id: "api-manager-auto-registration",
instantiate: (di) => { instantiate: (di) => {
const apiManager = di.inject(apiManagerInjectable);
const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable); const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable);
const beforeApiManagerInitializationCrds: CustomResourceDefinition[] = [];
const beforeApiManagerInitializationApis: KubeApi[] = [];
let initialized = false;
const autoInitCustomResourceStore = (crd: CustomResourceDefinition) => {
const objectConstructor = class extends KubeObject {
static readonly kind = crd.getResourceKind();
static readonly namespaced = crd.isNamespaced();
static readonly apiBase = crd.getResourceApiBase();
};
const api = (() => {
const rawApi = apiManager.getApi(objectConstructor.apiBase);
if (rawApi) {
return rawApi;
}
const api = new KubeApi({ objectConstructor });
apiManager.registerApi(api);
return api;
})();
if (!apiManager.getStore(api)) {
apiManager.registerStore(new CustomResourceStore(api));
}
};
const autoInitKubeApi = (api: KubeApi) => {
apiManager.registerApi(api);
};
autoRegistrationEmitter autoRegistrationEmitter
.on("customResourceDefinition", (crd) => { .on("customResourceDefinition", (crd) => {
const objectConstructor = class extends KubeObject { if (initialized) {
static readonly kind = crd.getResourceKind(); autoInitCustomResourceStore(crd);
static readonly namespaced = crd.isNamespaced(); } else {
static readonly apiBase = crd.getResourceApiBase(); beforeApiManagerInitializationCrds.push(crd);
};
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)); .on("kubeApi", (api) => {
if (initialized) {
autoInitKubeApi(api);
} else {
beforeApiManagerInitializationApis.push(api);
}
});
const apiManager = di.inject(apiManagerInjectable);
beforeApiManagerInitializationCrds.forEach(autoInitCustomResourceStore);
beforeApiManagerInitializationApis.forEach(autoInitKubeApi);
initialized = true;
}, },
}); });

View File

@ -3,6 +3,7 @@
* 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 { getInjectable, getInjectionToken } from "@ogre-tools/injectable"; import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
import { createStoresAndApisInjectionToken } from "../create-stores-apis.token";
import type { KubeObjectStore } from "../kube-object.store"; import type { KubeObjectStore } from "../kube-object.store";
import { ApiManager } from "./api-manager"; import { ApiManager } from "./api-manager";
@ -14,10 +15,13 @@ const apiManagerInjectable = getInjectable({
id: "api-manager", id: "api-manager",
instantiate: (di) => { instantiate: (di) => {
const apiManager = new ApiManager(); const apiManager = new ApiManager();
const stores = di.injectMany(kubeObjectStoreInjectionToken);
for (const store of stores) { if (di.inject(createStoresAndApisInjectionToken)) {
apiManager.registerStore(store); const stores = di.injectMany(kubeObjectStoreInjectionToken);
for (const store of stores) {
apiManager.registerStore(store);
}
} }
return apiManager; return apiManager;

View File

@ -311,7 +311,7 @@ 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(api: KubeApi): void { function legacyRegisterApi(api: KubeApi<any, any>): 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);
@ -377,7 +377,7 @@ export class KubeApi<
this.apiResource = resource; this.apiResource = resource;
this.request = request; this.request = request;
this.objectConstructor = objectConstructor; this.objectConstructor = objectConstructor;
legacyRegisterApi(this as unknown as KubeApi); legacyRegisterApi(this);
} }
get apiVersionWithGroup() { get apiVersionWithGroup() {
@ -458,7 +458,7 @@ export class KubeApi<
if (this.apiVersionPreferred) { if (this.apiVersionPreferred) {
this.apiBase = this.computeApiBase(); this.apiBase = this.computeApiBase();
legacyRegisterApi(this as unknown as KubeApi); legacyRegisterApi(this);
} }
} }
} }

View File

@ -46,6 +46,7 @@ import assert from "assert";
import openDeleteClusterDialogInjectable from "./components/delete-cluster-dialog/open.injectable"; import openDeleteClusterDialogInjectable from "./components/delete-cluster-dialog/open.injectable";
import { init } from "@sentry/electron/renderer"; import { init } from "@sentry/electron/renderer";
import kubernetesClusterCategoryInjectable from "../common/catalog/categories/kubernetes-cluster.injectable"; import kubernetesClusterCategoryInjectable from "../common/catalog/categories/kubernetes-cluster.injectable";
import autoRegistrationInjectable from "../common/k8s-api/api-manager/auto-registration.injectable";
configurePackages(); // global packages configurePackages(); // global packages
registerCustomThemes(); // monaco editor themes registerCustomThemes(); // monaco editor themes
@ -78,6 +79,17 @@ export async function bootstrap(di: DiContainer) {
const rootNode = createRoot(rootElem); const rootNode = createRoot(rootElem);
const logPrefix = `[BOOTSTRAP-${process.isMainFrame ? "ROOT" : "CLUSTER"}-FRAME]:`; const logPrefix = `[BOOTSTRAP-${process.isMainFrame ? "ROOT" : "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.
*
* This also MUST be done before anything else so that it can start listening for the events for
* auto initialization.
*/
di.inject(autoRegistrationInjectable);
// TODO: Remove temporal dependencies to make timing of initialization not important // TODO: Remove temporal dependencies to make timing of initialization not important
di.inject(userStoreInjectable); di.inject(userStoreInjectable);

View File

@ -103,14 +103,16 @@ class NonInjectedKubeObjectMenu<TKubeObject extends KubeObject, Props extends Ku
} }
render() { render() {
const { remove, update, renderRemoveMessage, isEditable, isRemovable } = this; const { remove, update, renderRemoveMessage, isEditable, isRemovable, store } = this;
const { className, editable, removable, object, ...menuProps } = this.props; const { className, editable, removable, object, ...menuProps } = this.props;
console.log(object, store);
return ( return (
<MenuActions <MenuActions
className={cssNames("KubeObjectMenu", className)} className={cssNames("KubeObjectMenu", className)}
updateAction={object && isEditable ? (() => update(object)) : undefined} updateAction={(object && isEditable) ? (() => update(object)) : undefined}
removeAction={object && isRemovable ? (() => remove(object)) : undefined} removeAction={(object && isRemovable) ? (() => remove(object)) : undefined}
removeConfirmationMessage={renderRemoveMessage} removeConfirmationMessage={renderRemoveMessage}
{...menuProps} {...menuProps}
> >

View File

@ -11,7 +11,6 @@ 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",
@ -21,14 +20,6 @@ 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,