mirror of
https://github.com/morten-olsen/homelab-operator.git
synced 2026-02-08 01:36:28 +01:00
lot more stuff
This commit is contained in:
91
src/services/custom-resources/custom-resources.conditions.ts
Normal file
91
src/services/custom-resources/custom-resources.conditions.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import equal from 'deep-equal';
|
||||
|
||||
import type { CustomResource } from './custom-resources.custom-resource.ts';
|
||||
import type { CustomResourceStatus } from './custom-resources.types.ts';
|
||||
|
||||
type CustomResourceStatusOptions = {
|
||||
resource: CustomResource<ExpectedAny>;
|
||||
};
|
||||
|
||||
type CustomResourceConditionsEvents = {
|
||||
changed: (type: string, condition: Condition) => void;
|
||||
};
|
||||
|
||||
type Condition = {
|
||||
lastTransitionTime: Date;
|
||||
status: 'True' | 'False' | 'Unknown';
|
||||
syncing?: boolean;
|
||||
failed?: boolean;
|
||||
resource?: boolean;
|
||||
reason?: string;
|
||||
message?: string;
|
||||
observedGeneration?: number;
|
||||
};
|
||||
|
||||
class CustomResourceConditions extends EventEmitter<CustomResourceConditionsEvents> {
|
||||
#options: CustomResourceStatusOptions;
|
||||
#conditions: Record<string, Condition>;
|
||||
|
||||
constructor(options: CustomResourceStatusOptions) {
|
||||
super();
|
||||
this.#options = options;
|
||||
this.#conditions = Object.fromEntries(
|
||||
(options.resource.status?.conditions || []).map(({ type, lastTransitionTime, ...condition }) => [
|
||||
type,
|
||||
{
|
||||
...condition,
|
||||
lastTransitionTime: new Date(lastTransitionTime),
|
||||
},
|
||||
]),
|
||||
);
|
||||
options.resource.on('changed', this.#handleChange);
|
||||
}
|
||||
|
||||
#handleChange = () => {
|
||||
const { resource } = this.#options;
|
||||
for (const { type, ...condition } of resource.status?.conditions || []) {
|
||||
const next = {
|
||||
...condition,
|
||||
lastTransitionTime: new Date(condition.lastTransitionTime),
|
||||
};
|
||||
const current = this.#conditions[type];
|
||||
const isEqual = equal(current, next);
|
||||
const isNewer = !current || next.lastTransitionTime > current.lastTransitionTime;
|
||||
if (isEqual || !isNewer) {
|
||||
return;
|
||||
}
|
||||
this.#conditions[type] = next;
|
||||
this.emit('changed', type, next);
|
||||
}
|
||||
};
|
||||
|
||||
public get = (type: string): Condition | undefined => {
|
||||
return this.#conditions[type];
|
||||
};
|
||||
|
||||
public set = async (type: string, condition: Omit<Condition, 'lastTransitionTime'>) => {
|
||||
const current = this.#conditions[type];
|
||||
this.#conditions[type] = {
|
||||
...condition,
|
||||
|
||||
lastTransitionTime: current && current.status === condition.status ? current.lastTransitionTime : new Date(),
|
||||
observedGeneration: this.#options.resource.metadata?.generation,
|
||||
};
|
||||
await this.save();
|
||||
};
|
||||
|
||||
public save = async () => {
|
||||
const { resource } = this.#options;
|
||||
const status: CustomResourceStatus = {
|
||||
conditions: Object.entries(this.#conditions).map(([type, condition]) => ({
|
||||
...condition,
|
||||
type,
|
||||
lastTransitionTime: condition.lastTransitionTime.toISOString(),
|
||||
})),
|
||||
};
|
||||
await resource.patchStatus(status);
|
||||
};
|
||||
}
|
||||
|
||||
export { CustomResourceConditions };
|
||||
Reference in New Issue
Block a user