Fix behaviour of auto generated CRD KubeApis and KubeObjectStores (#7384)

* Simplify CRD KubeApi registrations

- Switch to auto injectable registrations

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Make sure that stores can still be retrieved

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Cleanup get extension fake to simplify impl

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Simplify logic for extensionInjectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix test in differencing registrator

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Cleanup code style

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix some tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix HPA details tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

---------

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton authored and GitHub committed 2023-03-22 17:51:26 +02:00
1 parent 8a80607d85
commit 4b1d740d61
17 files changed
+315 -189

No files matched your search

@@ -0,0 +1,53 @@
/**
* 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 { reaction } from "mobx";
import { customResourceDefinitionApiInjectionToken } from "../../../common/k8s-api/api-manager/crd-api-token";
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 maybeKubeApiInjectable from "../../../common/k8s-api/maybe-kube-api.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import { injectableDifferencingRegistratorWith } from "../../../common/utils/registrator-helper";
import customResourceDefinitionStoreInjectable from "../../components/+custom-resources/definition.store.injectable";
import { beforeClusterFrameStartsSecondInjectionToken } from "../tokens";
const setupAutoCrdApiCreationsInjectable = getInjectable({
id: "setup-auto-crd-api-creations",
instantiate: (di) => ({
run: () => {
const customResourceDefinitionStore = di.inject(customResourceDefinitionStoreInjectable);
const injectableDifferencingRegistrator = injectableDifferencingRegistratorWith(di);
reaction(
() => customResourceDefinitionStore.getItems().map(toCrdApiInjectable),
injectableDifferencingRegistrator,
{
fireImmediately: true,
},
);
},
}),
injectionToken: beforeClusterFrameStartsSecondInjectionToken,
});
export default setupAutoCrdApiCreationsInjectable;
const toCrdApiInjectable = (crd: CustomResourceDefinition) => getInjectable({
id: `default-kube-api-for-custom-resource-definition-${crd.getResourceApiBase()}`,
instantiate: (di) => {
const objectConstructor = class extends KubeObject {
static readonly kind = crd.getResourceKind();
static readonly namespaced = crd.isNamespaced();
static readonly apiBase = crd.getResourceApiBase();
};
return new KubeApi({
logger: di.inject(loggerInjectable),
maybeKubeApi: di.inject(maybeKubeApiInjectable),
}, { objectConstructor });
},
injectionToken: customResourceDefinitionApiInjectionToken,
});
@@ -5,71 +5,22 @@
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);
};
autoRegistrationEmitter
.on("customResourceDefinition", (crd) => {
if (initialized) {
autoInitCustomResourceStore(crd);
} else {
beforeApiManagerInitializationCrds.push(crd);
}
})
.on("kubeApi", (api) => {
if (initialized) {
autoInitKubeApi(api);
@@ -81,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;
},