mirror of
https://github.com/morten-olsen/homelab-operator.git
synced 2026-02-08 01:36:28 +01:00
fixes
This commit is contained in:
@@ -13,9 +13,11 @@ import { PROVISIONER } from '#resources/core/pvc/pvc.ts';
|
||||
import { Gateway } from '#resources/istio/gateway/gateway.ts';
|
||||
import { NotReadyError } from '#utils/errors.ts';
|
||||
import { NamespaceService } from '#bootstrap/namespaces/namespaces.ts';
|
||||
import { CloudflareService } from '#services/cloudflare/cloudflare.ts';
|
||||
|
||||
const specSchema = z.object({
|
||||
domain: z.string(),
|
||||
networkIp: z.string().optional(),
|
||||
tls: z.object({
|
||||
issuer: z.string(),
|
||||
}),
|
||||
@@ -34,31 +36,36 @@ class Environment extends CustomResource<typeof specSchema> {
|
||||
#postgresCluster: PostgresCluster;
|
||||
#redisServer: RedisServer;
|
||||
#authentikServer: AuthentikServer;
|
||||
#cloudflareService: CloudflareService;
|
||||
|
||||
constructor(options: CustomResourceOptions<typeof specSchema>) {
|
||||
super(options);
|
||||
const resourceService = this.services.get(ResourceService);
|
||||
const namespaceService = this.services.get(NamespaceService);
|
||||
const homelabNamespace = namespaceService.homelab.name;
|
||||
|
||||
this.#cloudflareService = this.services.get(CloudflareService);
|
||||
this.#cloudflareService.on('changed', this.queueReconcile);
|
||||
|
||||
this.#namespace = resourceService.get(Namespace, this.name);
|
||||
this.#namespace.on('changed', this.queueReconcile);
|
||||
|
||||
this.#certificate = resourceService.get(Certificate, this.name, namespaceService.homelab.name);
|
||||
this.#certificate = resourceService.get(Certificate, this.name, homelabNamespace);
|
||||
this.#certificate.on('changed', this.queueReconcile);
|
||||
|
||||
this.#storageClass = resourceService.get(StorageClass, this.name);
|
||||
this.#storageClass.on('changed', this.queueReconcile);
|
||||
|
||||
this.#postgresCluster = resourceService.get(PostgresCluster, `${this.name}-postgres-cluster`, this.name);
|
||||
this.#postgresCluster = resourceService.get(PostgresCluster, `${this.name}-postgres-cluster`, homelabNamespace);
|
||||
this.#postgresCluster.on('changed', this.queueReconcile);
|
||||
|
||||
this.#redisServer = resourceService.get(RedisServer, `${this.name}-redis-server`, this.name);
|
||||
this.#redisServer = resourceService.get(RedisServer, `${this.name}-redis-server`, homelabNamespace);
|
||||
this.#redisServer.on('changed', this.queueReconcile);
|
||||
|
||||
this.#gateway = resourceService.get(Gateway, this.name, this.name);
|
||||
this.#gateway = resourceService.get(Gateway, this.name, homelabNamespace);
|
||||
this.#gateway.on('changed', this.queueReconcile);
|
||||
|
||||
this.#authentikServer = resourceService.get(AuthentikServer, `${this.name}-authentik`, this.name);
|
||||
this.#authentikServer = resourceService.get(AuthentikServer, `${this.name}-authentik`, homelabNamespace);
|
||||
this.#authentikServer.on('changed', this.queueReconcile);
|
||||
}
|
||||
|
||||
@@ -91,6 +98,28 @@ class Environment extends CustomResource<typeof specSchema> {
|
||||
if (!success || !spec) {
|
||||
throw new NotReadyError('InvalidSpec');
|
||||
}
|
||||
|
||||
if (this.#cloudflareService.ready && spec.networkIp) {
|
||||
const client = this.#cloudflareService.client;
|
||||
const zones = await client.zones.list({
|
||||
name: spec.domain,
|
||||
});
|
||||
const [zone] = zones.result;
|
||||
if (!zone) {
|
||||
throw new NotReadyError('NoZoneFound');
|
||||
}
|
||||
|
||||
const existingRecords = await client.dns.records.list({
|
||||
zone_id: zone.id,
|
||||
name: {
|
||||
exact: `*.${spec.domain}`,
|
||||
},
|
||||
});
|
||||
|
||||
console.log('Cloudflare records', existingRecords);
|
||||
|
||||
// zones.result[0].
|
||||
}
|
||||
await this.#namespace.ensure({
|
||||
metadata: {
|
||||
labels: {
|
||||
|
||||
57
src/services/cloudflare/cloudflare.ts
Normal file
57
src/services/cloudflare/cloudflare.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { Cloudflare } from 'cloudflare';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
|
||||
import { NamespaceService } from '#bootstrap/namespaces/namespaces.ts';
|
||||
import { Secret } from '#resources/core/secret/secret.ts';
|
||||
import { ResourceService } from '#services/resources/resources.ts';
|
||||
import type { Services } from '#utils/service.ts';
|
||||
|
||||
type SecretData = {
|
||||
account: string;
|
||||
tunnelName: string;
|
||||
tunnelId: string;
|
||||
secret: string;
|
||||
token: string;
|
||||
};
|
||||
|
||||
type CloudflareServiceEvents = {
|
||||
changed: () => void;
|
||||
};
|
||||
|
||||
class CloudflareService extends EventEmitter<CloudflareServiceEvents> {
|
||||
#services: Services;
|
||||
#secret: Secret<SecretData>;
|
||||
|
||||
constructor(services: Services) {
|
||||
super();
|
||||
this.#services = services;
|
||||
const resourceService = this.#services.get(ResourceService);
|
||||
const namespaceService = this.#services.get(NamespaceService);
|
||||
this.#secret = resourceService.get(Secret<SecretData>, 'cloudflare', namespaceService.homelab.name);
|
||||
|
||||
this.#secret.on('changed', this.emit.bind(this, 'changed'));
|
||||
}
|
||||
|
||||
public get secret() {
|
||||
return this.#secret.value;
|
||||
}
|
||||
|
||||
public get ready() {
|
||||
return !!this.secret;
|
||||
}
|
||||
|
||||
public get client() {
|
||||
const token = this.#secret.value?.token;
|
||||
if (!token) {
|
||||
throw new Error('Cloudflare API token is not set');
|
||||
}
|
||||
|
||||
const client = new Cloudflare({
|
||||
apiToken: token,
|
||||
});
|
||||
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
export { CloudflareService };
|
||||
Reference in New Issue
Block a user