CluPilotCloud/app/Services/Dns/LegacyRecordIds.php

64 lines
2.4 KiB
PHP

<?php
namespace App\Services\Dns;
use App\Models\DnsRecord;
use Illuminate\Support\Facades\Log;
use Throwable;
/**
* Record ids from the OLD Hetzner DNS API, brought across where that is
* possible — and left alone where it is not.
*
* The cloud API addresses an RRSet by `{name}/{type}`; the old one issued an
* opaque id like `rec-abc123`. Every id this installation stored before the
* move is of the old shape, and nothing in the new client can address one.
*
* I got this wrong in the first pass. I counted the rows on the DEVELOPMENT
* database — hosts, dns_records and run_resources, all empty — and wrote that
* into RrsetId as though it settled the question. It settles nothing: the live
* server is a different installation with its own rows, and a format change
* across a schema is not made safe by one machine happening to be empty.
* (Codex review 2026-07-31, P1.)
*
* What can be converted: `dns_records` carries `fqdn` and `type` beside the id,
* so the RRSet name follows exactly. What cannot: `hosts.dns_record_id` (only a
* short name is stored, never the fqdn that was published) and the
* `dns_record_id` run resources (an id and nothing else). Those are handled at
* the other end — HttpHetznerDnsClient::deleteRecord() lets a legacy id pass
* with a loud log instead of throwing, so a purge completes rather than dying
* on the same row for ever.
*
* Guessing is deliberately not done. A record whose fqdn is not inside the
* configured zone is left untouched: it was never something this client could
* have written, and inventing a name for it would publish a deletion against
* whatever happens to carry that name today.
*/
class LegacyRecordIds
{
/** @return int how many rows were rewritten */
public function migrate(): int
{
$rewritten = 0;
foreach (DnsRecord::query()->get() as $record) {
if (str_contains((string) $record->record_id, '/')) {
continue;
}
try {
$id = RrsetId::for((string) $record->fqdn, (string) $record->type);
} catch (Throwable) {
// Outside the configured zone, or no zone configured at all.
// Left exactly as it is — see the class comment.
continue;
}
$record->update(['record_id' => $id]);
$rewritten++;
}
return $rewritten;
}
}