58 lines
1.8 KiB
PHP
58 lines
1.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Traefik;
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
/**
|
|
* Writes Traefik file-provider YAML into the configured dynamic directory (where
|
|
* Traefik runs) and checks HTTP-01 cert issuance by probing the fqdn over HTTPS.
|
|
* The concrete write path (host SSH / mounted volume) is a deployment watch-item.
|
|
* Not unit-tested (live I/O).
|
|
*/
|
|
class SshTraefikWriter implements TraefikWriter
|
|
{
|
|
public function write(string $subdomain, string $targetHost): void
|
|
{
|
|
$zone = (string) config('provisioning.dns.zone');
|
|
$fqdn = "{$subdomain}.{$zone}";
|
|
$yaml = $this->render($subdomain, $fqdn, $targetHost);
|
|
|
|
$path = rtrim((string) config('provisioning.traefik.dynamic_path'), '/')."/{$subdomain}.yml";
|
|
file_put_contents($path, $yaml);
|
|
}
|
|
|
|
public function remove(string $subdomain): void
|
|
{
|
|
$path = rtrim((string) config('provisioning.traefik.dynamic_path'), '/')."/{$subdomain}.yml";
|
|
if (is_file($path)) {
|
|
unlink($path);
|
|
}
|
|
}
|
|
|
|
public function certReachable(string $fqdn): bool
|
|
{
|
|
return Http::timeout(5)->connectTimeout(5)->get("https://{$fqdn}/status.php")->successful();
|
|
}
|
|
|
|
private function render(string $subdomain, string $fqdn, string $targetHost): string
|
|
{
|
|
return implode("\n", [
|
|
'http:',
|
|
' routers:',
|
|
" {$subdomain}:",
|
|
" rule: \"Host(`{$fqdn}`)\"",
|
|
" service: \"{$subdomain}\"",
|
|
' entryPoints: ["websecure"]',
|
|
' tls:',
|
|
' certResolver: "letsencrypt"',
|
|
' services:',
|
|
" {$subdomain}:",
|
|
' loadBalancer:',
|
|
' servers:',
|
|
" - url: \"http://{$targetHost}:80\"",
|
|
'',
|
|
]);
|
|
}
|
|
}
|