add authentik connection crd

This commit is contained in:
Morten Olsen
2025-08-11 23:16:12 +02:00
parent 130bfec468
commit d4b56007f1
9 changed files with 289 additions and 6 deletions

View File

@@ -0,0 +1,50 @@
import type { KubernetesObject } from '@kubernetes/client-node';
import { ResourceReference } from './resources.ref.ts';
abstract class ResourceInstance<T extends KubernetesObject> extends ResourceReference<T> {
public get resource() {
if (!this.current) {
throw new Error('Instance needs a resource');
}
return this.current;
}
public get manifest() {
return this.resource.metadata;
}
public get apiVersion() {
return this.resource.apiVersion;
}
public get kind() {
return this.resource.kind;
}
public get name() {
return this.resource.name;
}
public get namespace() {
return this.resource.namespace;
}
public get metadata() {
return this.resource.metadata;
}
public get spec() {
return this.resource.spec;
}
public get data() {
return this.resource.data;
}
public patch = this.resource.patch;
public reload = this.resource.load;
public delete = this.resource.delete;
}
export { ResourceInstance };

View File

@@ -0,0 +1,83 @@
import { z } from 'zod';
import { V1Secret } from '@kubernetes/client-node';
import { EventEmitter } from 'eventemitter3';
import deepEqual from 'deep-equal';
import { ResourceReference, ResourceService } from '../resources/resources.ts';
import type { Services } from '../../utils/service.ts';
import { getWithNamespace } from '../../utils/naming.ts';
import { decodeSecret } from '../../utils/secrets.ts';
const valueReferenceInfoSchema = z.object({
value: z.string().optional(),
secretRef: z.string().optional(),
key: z.string().optional(),
});
type ValueReferenceInfo = z.infer<typeof valueReferenceInfoSchema>;
type ValueRefOptions = {
services: Services;
namespace: string;
};
type ValueReferenceEvents = {
changed: () => void;
};
class ValueReference extends EventEmitter<ValueReferenceEvents> {
#options: ValueRefOptions;
#ref?: ValueReferenceInfo;
#resource: ResourceReference;
constructor(options: ValueRefOptions) {
super();
this.#options = options;
this.#resource = new ResourceReference<V1Secret>();
this.#resource.on('changed', this.#handleChange);
}
public get ref() {
return this.#ref;
}
public set ref(ref: ValueReferenceInfo | undefined) {
if (deepEqual(this.#ref, ref)) {
return;
}
if (ref?.secretRef && ref.key) {
const { services, namespace } = this.#options;
const resourceService = services.get(ResourceService);
const refNames = getWithNamespace(ref.secretRef, namespace);
this.#resource.current = resourceService.get({
apiVersion: 'v1',
kind: 'Secret',
name: refNames.name,
namespace: refNames.namespace,
});
} else {
this.#resource.current = undefined;
}
this.#ref = ref;
}
public get value() {
console.log('get', this.#ref);
if (!this.#ref) {
return undefined;
}
if (this.#ref.value) {
return this.#ref.value;
}
if (this.#resource.current && this.#ref.key) {
const decoded = decodeSecret(this.#resource.current.data);
return decoded?.[this.#ref.key];
}
return undefined;
}
#handleChange = () => {
this.emit('changed');
};
}
export { ValueReference, valueReferenceInfoSchema, type ValueReferenceInfo };

View File

@@ -0,0 +1,21 @@
import type { Services } from '../../utils/service.ts';
import { ValueReference } from './value-reference.instance.ts';
class ValueReferenceService {
#services: Services;
constructor(services: Services) {
this.#services = services;
}
public get = (namespace: string) => {
return new ValueReference({
namespace,
services: this.#services,
});
};
}
export * from './value-reference.instance.ts';
export { ValueReferenceService };