mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Make sure that stores can still be retrieved
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
886c812679
commit
5856210aa9
@ -24,6 +24,7 @@ import { KubeApi as ExternalKubeApi } from "../../../extensions/common-api/k8s-a
|
||||
import { Cluster } from "../../cluster/cluster";
|
||||
import { runInAction } from "mobx";
|
||||
import { customResourceDefinitionApiInjectionToken } from "../api-manager/crd-api-token";
|
||||
import assert from "assert";
|
||||
|
||||
class TestApi extends KubeApi<KubeObject> {
|
||||
protected async checkPreferredVersion() {
|
||||
@ -156,6 +157,10 @@ describe("ApiManager", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("can have a default KubeObjectStore instance retrieved for it", () => {
|
||||
expect(apiManager.getStore(apiBase)).toBeInstanceOf(KubeObjectStore);
|
||||
});
|
||||
|
||||
describe("given that an extension registers an api with the same apibase", () => {
|
||||
beforeEach(() => {
|
||||
void Object.assign(new ExternalKubeApi({
|
||||
@ -172,6 +177,34 @@ describe("ApiManager", () => {
|
||||
myField: 2,
|
||||
});
|
||||
});
|
||||
|
||||
it("can have a default KubeObjectStore instance retrieved for it", () => {
|
||||
expect(apiManager.getStore(apiBase)).toBeInstanceOf(KubeObjectStore);
|
||||
});
|
||||
|
||||
describe("given that an extension registers a store for the same apibase", () => {
|
||||
beforeEach(() => {
|
||||
const api = apiManager.getApi(apiBase);
|
||||
|
||||
assert(api);
|
||||
|
||||
apiManager.registerStore(Object.assign(
|
||||
new KubeObjectStore({
|
||||
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
}, api),
|
||||
{
|
||||
someField: 2,
|
||||
},
|
||||
));
|
||||
});
|
||||
|
||||
it("can gets the custom KubeObjectStore instance instead", () => {
|
||||
expect(apiManager.getStore(apiBase)).toMatchObject({
|
||||
someField: 2,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -10,7 +10,8 @@ import { autorun, action, observable } from "mobx";
|
||||
import type { KubeApi } from "../kube-api";
|
||||
import type { KubeObject, ObjectReference } from "../kube-object";
|
||||
import { parseKubeApi, createKubeApiURL } from "../kube-api-parse";
|
||||
import { iter } from "@k8slens/utilities";
|
||||
import { getOrInsertWith, iter } from "@k8slens/utilities";
|
||||
import type { CreateCustomResourceStore } from "./create-custom-resource-store.injectable";
|
||||
|
||||
export type RegisterableStore<Store> = Store extends KubeObjectStore<any, any, any>
|
||||
? Store
|
||||
@ -28,12 +29,13 @@ interface Dependencies {
|
||||
readonly apis: IComputedValue<KubeApi[]>;
|
||||
readonly crdApis: IComputedValue<KubeApi[]>;
|
||||
readonly stores: IComputedValue<KubeObjectStore[]>;
|
||||
createCustomResourceStore: CreateCustomResourceStore;
|
||||
}
|
||||
|
||||
export class ApiManager {
|
||||
private readonly externalApis = observable.array<KubeApi>();
|
||||
private readonly externalStores = observable.array<KubeObjectStore>();
|
||||
|
||||
private readonly defaultCrdStores = observable.map<string, KubeObjectStore>();
|
||||
private readonly apis = observable.map<string, KubeApi>();
|
||||
|
||||
constructor(private readonly dependencies: Dependencies) {
|
||||
@ -117,6 +119,16 @@ export class ApiManager {
|
||||
this.externalStores.push(store);
|
||||
}
|
||||
|
||||
private apiIsDefaultCrdApi(api: KubeApi): boolean {
|
||||
for (const crdApi of this.dependencies.crdApis.get()) {
|
||||
if (crdApi.apiBase === api.apiBase) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getStore(api: string | undefined): KubeObjectStore | undefined;
|
||||
getStore<Api>(api: RegisterableApi<Api>): KubeObjectStoreFrom<Api> | undefined;
|
||||
/**
|
||||
@ -137,9 +149,19 @@ export class ApiManager {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return iter.chain(this.dependencies.stores.get().values())
|
||||
const defaultResult = iter.chain(this.dependencies.stores.get().values())
|
||||
.concat(this.externalStores.values())
|
||||
.find(store => store.api.apiBase === api.apiBase);
|
||||
|
||||
if (defaultResult) {
|
||||
return defaultResult;
|
||||
}
|
||||
|
||||
if (this.apiIsDefaultCrdApi(api)) {
|
||||
return getOrInsertWith(this.defaultCrdStores, api.apiBase, () => this.dependencies.createCustomResourceStore(api));
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
lookupApiLink(ref: ObjectReference, parentObject?: KubeObject): string {
|
||||
|
||||
@ -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 clusterFrameContextForNamespacedResourcesInjectable from "../../../renderer/cluster-frame-context/for-namespaced-resources.injectable";
|
||||
import loggerInjectable from "../../logger.injectable";
|
||||
import type { KubeApi } from "../kube-api";
|
||||
import type { KubeObject } from "../kube-object";
|
||||
import type { KubeObjectStoreDependencies } from "../kube-object.store";
|
||||
import { CustomResourceStore } from "./resource.store";
|
||||
|
||||
export type CreateCustomResourceStore = <K extends KubeObject>(api: KubeApi<K>) => CustomResourceStore<K>;
|
||||
|
||||
const createCustomResourceStoreInjectable = getInjectable({
|
||||
id: "create-custom-resource-store",
|
||||
instantiate: (di): CreateCustomResourceStore => {
|
||||
const deps: KubeObjectStoreDependencies = {
|
||||
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
};
|
||||
|
||||
return (api) => new CustomResourceStore(deps, api);
|
||||
},
|
||||
});
|
||||
|
||||
export default createCustomResourceStoreInjectable;
|
||||
@ -10,6 +10,7 @@ import { kubeObjectStoreInjectionToken } from "./kube-object-store-token";
|
||||
import { kubeApiInjectionToken } from "../kube-api/kube-api-injection-token";
|
||||
import { computed } from "mobx";
|
||||
import { customResourceDefinitionApiInjectionToken } from "./crd-api-token";
|
||||
import createCustomResourceStoreInjectable from "./create-custom-resource-store.injectable";
|
||||
|
||||
const apiManagerInjectable = getInjectable({
|
||||
id: "api-manager",
|
||||
@ -27,6 +28,7 @@ const apiManagerInjectable = getInjectable({
|
||||
crdApis: storesAndApisCanBeCreated
|
||||
? computedInjectMany(customResourceDefinitionApiInjectionToken)
|
||||
: computed(() => []),
|
||||
createCustomResourceStore: di.inject(createCustomResourceStoreInjectable),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@ -88,7 +88,7 @@ export interface KubeObjectStoreDependencies {
|
||||
readonly logger: Logger;
|
||||
}
|
||||
|
||||
export abstract class KubeObjectStore<
|
||||
export class KubeObjectStore<
|
||||
K extends KubeObject = KubeObject,
|
||||
A extends KubeApi<K, D> = KubeApi<K, KubeJsonApiDataFor<K>>,
|
||||
D extends KubeJsonApiDataFor<K> = KubeApiDataFrom<K, A>,
|
||||
|
||||
@ -5,59 +5,17 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import autoRegistrationEmitterInjectable from "../../../common/k8s-api/api-manager/auto-registration-emitter.injectable";
|
||||
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
||||
import { CustomResourceStore } from "../../../common/k8s-api/api-manager/resource.store";
|
||||
import type { CustomResourceDefinition } from "../../../common/k8s-api/endpoints";
|
||||
import type { KubeApiDependencies } from "../../../common/k8s-api/kube-api";
|
||||
import { KubeApi } from "../../../common/k8s-api/kube-api";
|
||||
import { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||
import type { KubeApi } from "../../../common/k8s-api/kube-api";
|
||||
import { beforeClusterFrameStartsSecondInjectionToken } from "../tokens";
|
||||
import type { KubeObjectStoreDependencies } from "../../../common/k8s-api/kube-object.store";
|
||||
import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import maybeKubeApiInjectable from "../../../common/k8s-api/maybe-kube-api.injectable";
|
||||
|
||||
const setupAutoRegistrationInjectable = getInjectable({
|
||||
id: "setup-auto-registration",
|
||||
instantiate: (di) => ({
|
||||
run: () => {
|
||||
const autoRegistrationEmitter = di.inject(autoRegistrationEmitterInjectable);
|
||||
const beforeApiManagerInitializationCrds: CustomResourceDefinition[] = [];
|
||||
const beforeApiManagerInitializationApis: KubeApi[] = [];
|
||||
const kubeApiDependencies: KubeApiDependencies = {
|
||||
logger: di.inject(loggerInjectable),
|
||||
maybeKubeApi: di.inject(maybeKubeApiInjectable),
|
||||
};
|
||||
const kubeObjectStoreDependencies: KubeObjectStoreDependencies = {
|
||||
context: di.inject(clusterFrameContextForNamespacedResourcesInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
};
|
||||
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(kubeApiDependencies, { objectConstructor });
|
||||
|
||||
apiManager.registerApi(api);
|
||||
|
||||
return api;
|
||||
})();
|
||||
|
||||
if (!apiManager.getStore(api)) {
|
||||
apiManager.registerStore(new CustomResourceStore(kubeObjectStoreDependencies, api));
|
||||
}
|
||||
};
|
||||
const autoInitKubeApi = (api: KubeApi) => {
|
||||
apiManager.registerApi(api);
|
||||
};
|
||||
@ -74,7 +32,6 @@ const setupAutoRegistrationInjectable = getInjectable({
|
||||
// NOTE: this MUST happen after the event emitter listeners are registered
|
||||
const apiManager = di.inject(apiManagerInjectable);
|
||||
|
||||
beforeApiManagerInitializationCrds.forEach(autoInitCustomResourceStore);
|
||||
beforeApiManagerInitializationApis.forEach(autoInitKubeApi);
|
||||
initialized = true;
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user