feat: discover external gateway domains

This commit is contained in:
2026-04-29 15:34:48 +00:00
parent 452aaa3862
commit 4eba247472
2 changed files with 72 additions and 1 deletions
+1
View File
@@ -137,6 +137,7 @@ export class Cloudly {
await this.deploymentManager.start();
await this.taskManager.init();
await this.registryManager.start();
await this.domainManager.init();
await this.cloudflareConnector.init();
await this.letsencryptConnector.init();
@@ -2,6 +2,17 @@ import type { Cloudly } from '../classes.cloudly.js';
import * as plugins from '../plugins.js';
import { Domain } from './classes.domain.js';
interface IWorkHosterDomain {
name: string;
nameservers?: string[];
capabilities?: {
canCreateSubdomains: boolean;
canManageDnsRecords: boolean;
canIssueCertificates: boolean;
canHostEmail: boolean;
};
}
export class DomainManager {
public typedrouter = new plugins.typedrequest.TypedRouter();
public cloudlyRef: Cloudly;
@@ -150,9 +161,68 @@ export class DomainManager {
* Initialize the domain manager
*/
public async init() {
await this.syncExternalGatewayDomains().catch((error) => {
console.log(`External gateway domain sync failed: ${(error as Error).message}`);
});
console.log('Domain Manager initialized');
}
public async syncExternalGatewayDomains(): Promise<number> {
const settings = await this.cloudlyRef.settingsManager.getSettings();
if (!settings.dcrouterGatewayUrl || !settings.dcrouterGatewayApiToken) {
return 0;
}
const typedRequest = new plugins.typedrequest.TypedRequest<any>(
`${settings.dcrouterGatewayUrl.replace(/\/+$/, '')}/typedrequest`,
'getWorkHosterDomains',
);
const response = await typedRequest.fire({
apiToken: settings.dcrouterGatewayApiToken,
}) as { domains: IWorkHosterDomain[] };
const activeDomainNames = new Set<string>();
for (const gatewayDomain of response.domains) {
const domainName = gatewayDomain.name.trim().toLowerCase();
if (!domainName) continue;
activeDomainNames.add(domainName);
const existingDomain = await this.CDomain.getDomainByName(domainName);
const tags = Array.from(new Set([...(existingDomain?.data.tags || []), 'dcrouter']));
const domainData: Partial<plugins.servezoneInterfaces.data.IDomain['data']> = {
name: domainName,
status: 'active',
verificationStatus: 'not_required',
nameservers: gatewayDomain.nameservers || existingDomain?.data.nameservers || [],
autoRenew: gatewayDomain.capabilities?.canIssueCertificates !== false,
activationState: 'available',
syncSource: 'manual',
lastSyncAt: Date.now(),
isExternal: true,
tags,
};
if (existingDomain) {
await this.CDomain.updateDomain(existingDomain.id, domainData);
} else {
await this.CDomain.createDomain(domainData as plugins.servezoneInterfaces.data.IDomain['data']);
}
}
const knownDomains = await this.CDomain.getDomains();
for (const domain of knownDomains) {
if (domain.data.tags?.includes('dcrouter') && !activeDomainNames.has(domain.data.name)) {
await this.CDomain.updateDomain(domain.id, {
activationState: 'ignored',
lastSyncAt: Date.now(),
});
}
}
console.log(`Synced ${activeDomainNames.size} domain(s) from external dcrouter gateway`);
return activeDomainNames.size;
}
/**
* Stop the domain manager
*/