diff --git a/subdomains/src/Models/Subdomain.php b/subdomains/src/Models/Subdomain.php index 105b427f..e501bc00 100644 --- a/subdomains/src/Models/Subdomain.php +++ b/subdomains/src/Models/Subdomain.php @@ -62,27 +62,6 @@ public function upsertOnCloudflare(): void throw new Exception('Server has no allocation'); } - // @phpstan-ignore staticMethod.notFound - $response = Http::cloudflare()->get("zones/{$this->domain->cloudflare_id}/dns_records/$this->cloudflare_id", ['search' => $this->name])->json(); - - if ($response['success']) { - if (!empty($response['result'])) { - throw new Exception('A subdomain with that name already exists'); - } - } else { - if ($response['errors'] && count($response['errors']) > 0) { - throw new Exception($response['errors'][0]['message']); - } - } - - $payload = [ - 'name' => $this->name, - 'type' => $this->record_type, - 'comment' => 'Created by Pelican Subdomains plugin', - 'content' => $this->server->allocation->ip, - 'proxied' => false, - ]; - if ($this->record_type === 'SRV') { $srvTarget = $this->server->node->srv_target; // @phpstan-ignore property.notFound @@ -96,8 +75,10 @@ public function upsertOnCloudflare(): void throw new Exception('Server has no SRV type'); } + $searchName = "$srvServiceType->value.$this->name"; + $payload = [ - 'name' => "$srvServiceType->value.$this->name", + 'name' => $searchName, 'type' => $this->record_type, 'comment' => 'Created by Pelican Subdomains plugin', 'data' => [ @@ -112,6 +93,36 @@ public function upsertOnCloudflare(): void if ($this->server->allocation->ip === '0.0.0.0' || $this->server->allocation->ip === '::') { throw new Exception('Server has invalid allocation ip (0.0.0.0 or ::)'); } + + $searchName = $this->name; + + $payload = [ + 'name' => $searchName, + 'type' => $this->record_type, + 'comment' => 'Created by Pelican Subdomains plugin', + 'content' => $this->server->allocation->ip, + 'proxied' => false, + ]; + } + + // @phpstan-ignore staticMethod.notFound + $searchResponse = Http::cloudflare()->get("zones/{$this->domain->cloudflare_id}/dns_records", [ + 'name' => $searchName, + 'type' => $this->record_type, + ])->json(); + + if ($searchResponse['success']) { + $results = $searchResponse['result'] ?? []; + + foreach ($results as $record) { + if ($record['id'] !== $this->cloudflare_id) { + throw new Exception('A subdomain with that name already exists'); + } + } + } else { + if ($searchResponse['errors'] && count($searchResponse['errors']) > 0) { + throw new Exception($searchResponse['errors'][0]['message']); + } } if ($this->cloudflare_id) { diff --git a/subdomains/src/Services/SubdomainService.php b/subdomains/src/Services/SubdomainService.php index b2490784..3592993b 100644 --- a/subdomains/src/Services/SubdomainService.php +++ b/subdomains/src/Services/SubdomainService.php @@ -14,13 +14,23 @@ class SubdomainService */ public function handle(array $data, ?Subdomain $subdomain = null): Subdomain { - $subdomain ??= Subdomain::create($data); - $subdomain->update($data); + $newSubdomain = true; + + if (is_null($subdomain)) { + $subdomain = Subdomain::create($data); + } else { + $subdomain->update($data); + $newSubdomain = false; + } + + $subdomain->refresh(); try { $subdomain->upsertOnCloudflare(); } catch (Exception $exception) { - $subdomain->delete(); + if ($newSubdomain) { + $subdomain->delete(); + } throw $exception; }