Phase9
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { prisma } from '@hexahost/database';
|
||||
import type { GameNode, GameServer } from '@hexahost/database';
|
||||
|
||||
import { createDnsProvider, resolveDnsProviderName } from './providers';
|
||||
import type { DnsRecordSpec } from './providers';
|
||||
import { buildJoinSlug } from './slug';
|
||||
|
||||
export function getPlayDomain(): string {
|
||||
@@ -21,6 +23,10 @@ function joinHostname(slug: string, playDomain = getPlayDomain()): string {
|
||||
return `${slug}.${playDomain}`;
|
||||
}
|
||||
|
||||
function initialDnsStatus(): 'PENDING' | 'ACTIVE' {
|
||||
return resolveDnsProviderName() === 'rfc2136' ? 'PENDING' : 'ACTIVE';
|
||||
}
|
||||
|
||||
async function upsertDnsRecord(input: {
|
||||
serverId: string;
|
||||
fqdn: string;
|
||||
@@ -30,6 +36,8 @@ async function upsertDnsRecord(input: {
|
||||
srvPriority?: number;
|
||||
srvWeight?: number;
|
||||
}): Promise<void> {
|
||||
const status = initialDnsStatus();
|
||||
|
||||
await prisma.serverDnsRecord.upsert({
|
||||
where: {
|
||||
serverId_recordType_fqdn: {
|
||||
@@ -46,21 +54,77 @@ async function upsertDnsRecord(input: {
|
||||
port: input.port,
|
||||
srvPriority: input.srvPriority,
|
||||
srvWeight: input.srvWeight,
|
||||
status: 'ACTIVE',
|
||||
lastSyncedAt: new Date(),
|
||||
status,
|
||||
lastSyncedAt: status === 'ACTIVE' ? new Date() : null,
|
||||
},
|
||||
update: {
|
||||
target: input.target,
|
||||
port: input.port,
|
||||
srvPriority: input.srvPriority,
|
||||
srvWeight: input.srvWeight,
|
||||
status: 'ACTIVE',
|
||||
lastSyncedAt: new Date(),
|
||||
status,
|
||||
lastSyncedAt: status === 'ACTIVE' ? new Date() : null,
|
||||
lastError: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function toDnsRecordSpec(record: {
|
||||
serverId: string;
|
||||
fqdn: string;
|
||||
recordType: string;
|
||||
target: string;
|
||||
port: number | null;
|
||||
srvPriority: number | null;
|
||||
srvWeight: number | null;
|
||||
}): DnsRecordSpec {
|
||||
return {
|
||||
serverId: record.serverId,
|
||||
fqdn: record.fqdn,
|
||||
recordType: record.recordType as 'A' | 'SRV',
|
||||
target: record.target,
|
||||
port: record.port ?? undefined,
|
||||
srvPriority: record.srvPriority ?? undefined,
|
||||
srvWeight: record.srvWeight ?? undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export async function pushPendingDnsRecords(limit = 50): Promise<number> {
|
||||
const provider = createDnsProvider();
|
||||
const pending = await prisma.serverDnsRecord.findMany({
|
||||
where: { status: 'PENDING' },
|
||||
take: limit,
|
||||
orderBy: { updatedAt: 'asc' },
|
||||
});
|
||||
|
||||
let synced = 0;
|
||||
|
||||
for (const record of pending) {
|
||||
try {
|
||||
await provider.syncRecord(toDnsRecordSpec(record));
|
||||
await prisma.serverDnsRecord.update({
|
||||
where: { id: record.id },
|
||||
data: {
|
||||
status: 'ACTIVE',
|
||||
lastSyncedAt: new Date(),
|
||||
lastError: null,
|
||||
},
|
||||
});
|
||||
synced += 1;
|
||||
} catch (error) {
|
||||
await prisma.serverDnsRecord.update({
|
||||
where: { id: record.id },
|
||||
data: {
|
||||
status: 'FAILED',
|
||||
lastError: error instanceof Error ? error.message : 'DNS sync failed',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return synced;
|
||||
}
|
||||
|
||||
export async function syncServerDnsRecords(
|
||||
server: GameServer & { node: GameNode | null },
|
||||
playDomain = getPlayDomain(),
|
||||
@@ -91,6 +155,12 @@ export async function syncServerDnsRecords(
|
||||
srvWeight: 5,
|
||||
});
|
||||
}
|
||||
|
||||
if (resolveDnsProviderName() === 'local') {
|
||||
return;
|
||||
}
|
||||
|
||||
await pushPendingDnsRecords(10);
|
||||
}
|
||||
|
||||
async function ensureUniqueSlug(serverId: string, serverName: string): Promise<string> {
|
||||
|
||||
Reference in New Issue
Block a user