119 lines
5.1 KiB
PHP
119 lines
5.1 KiB
PHP
<?php
|
|
|
|
use App\Services\Dns\FileHostDnsDirectory;
|
|
use App\Services\Dns\HostDnsDirectory;
|
|
|
|
/**
|
|
* Die eigenen Namen im Tunnel-Resolver.
|
|
*
|
|
* Über eine hosts-Datei im schon vorhandenen dns-hosts-Volume, das dnsmasq mit
|
|
* --hostsdir überwacht — dieselbe Stelle, an der die Host-Namen landen. Kein
|
|
* zweites `--address` im Compose-Befehl: das fängt zusätzlich jede Unterdomain
|
|
* mit ab, und über eine variable Namensliste kann eine command-Zeile nicht
|
|
* schleifen.
|
|
*/
|
|
beforeEach(function () {
|
|
$this->dir = sys_get_temp_dir().'/clupilot-hosts-'.bin2hex(random_bytes(6));
|
|
config()->set('provisioning.dns.hosts_dir', $this->dir);
|
|
config()->set('provisioning.wireguard.hub_address', '10.66.0.1');
|
|
config()->set('admin_access.vpn_internal_host', 'admin.clupilot.test');
|
|
});
|
|
|
|
afterEach(function () {
|
|
foreach (glob($this->dir.'/*') ?: [] as $file) {
|
|
@unlink($file);
|
|
}
|
|
@rmdir($this->dir);
|
|
});
|
|
|
|
it('veröffentlicht Portal, Website und Statusseite auf der Hub-Adresse', function () {
|
|
config()->set('admin_access.app_host', 'app.clupilot.test');
|
|
config()->set('admin_access.site_hosts', ['www.clupilot.test', 'clupilot.test']);
|
|
config()->set('admin_access.status_host', 'status.clupilot.test');
|
|
|
|
$this->artisan('clupilot:publish-tunnel-names')->assertSuccessful();
|
|
|
|
$written = file_get_contents($this->dir.'/platform.hosts');
|
|
|
|
expect($written)->toContain('10.66.0.1 app.clupilot.test')
|
|
->and($written)->toContain('10.66.0.1 www.clupilot.test')
|
|
->and($written)->toContain('10.66.0.1 clupilot.test')
|
|
->and($written)->toContain('10.66.0.1 status.clupilot.test');
|
|
});
|
|
|
|
it('lässt den Dateihost draußen', function () {
|
|
// Ein Server im Rettungssystem holt dort sein Archiv — der ist per
|
|
// Definition nicht im Tunnel. Bögen wir den Namen um, holte er es nie.
|
|
config()->set('admin_access.app_host', 'app.clupilot.test');
|
|
config()->set('admin_access.files_host', 'files.clupilot.test');
|
|
|
|
$this->artisan('clupilot:publish-tunnel-names')->assertSuccessful();
|
|
|
|
expect(file_get_contents($this->dir.'/platform.hosts'))
|
|
->not->toContain('files.clupilot.test');
|
|
});
|
|
|
|
it('räumt die Datei weg, wenn kein Name mehr konfiguriert ist', function () {
|
|
config()->set('admin_access.app_host', 'app.clupilot.test');
|
|
$this->artisan('clupilot:publish-tunnel-names')->assertSuccessful();
|
|
expect(file_exists($this->dir.'/platform.hosts'))->toBeTrue();
|
|
|
|
// Eine Datei, nicht eine je Name: sonst bliebe beim Wechsel von zwei
|
|
// Website-Namen auf einen die verwaiste Zeile im Resolver stehen, und der
|
|
// alte Name zeigte weiter in den Tunnel.
|
|
config()->set('admin_access.app_host', '');
|
|
$this->artisan('clupilot:publish-tunnel-names')->assertSuccessful();
|
|
|
|
expect(file_exists($this->dir.'/platform.hosts'))->toBeFalse();
|
|
});
|
|
|
|
it('tut nichts, solange kein Tunnel konfiguriert ist', function () {
|
|
// Ohne VPN_INTERNAL_HOST gibt es den Gateway nicht, und eine hosts-Datei
|
|
// für einen Resolver, den niemand startet, ist nur eine Datei, die beim
|
|
// nächsten Einschalten falsch sein kann.
|
|
config()->set('admin_access.vpn_internal_host', '');
|
|
config()->set('admin_access.app_host', 'app.clupilot.test');
|
|
|
|
$this->artisan('clupilot:publish-tunnel-names')->assertSuccessful();
|
|
|
|
expect(file_exists($this->dir.'/platform.hosts'))->toBeFalse();
|
|
});
|
|
|
|
it('schreibt genau eine Zeile je Name, im hosts-Format', function () {
|
|
config()->set('admin_access.app_host', 'app.clupilot.test');
|
|
config()->set('admin_access.site_hosts', ['www.clupilot.test']);
|
|
|
|
app(HostDnsDirectory::class)->writeMany('probe', ['a.test', 'b.test'], '10.66.0.1');
|
|
|
|
expect(file_get_contents($this->dir.'/probe.hosts'))
|
|
->toBe("10.66.0.1 a.test\n10.66.0.1 b.test\n");
|
|
});
|
|
|
|
it('überspringt einen Wert, der schon vor der bind-hosts-Prüfung in der .env stand', function () {
|
|
// `bind-hosts` weist einen NEUEN Wert dieser Form inzwischen zurück — aber
|
|
// auf einer Produktivmaschine stand genau das schon in der .env, von VOR
|
|
// dieser Prüfung. Ungeprüft ginge der Unsinn hier in platform.hosts, und
|
|
// der Resolver böge einen Namen um, den keine Anfrage je trifft.
|
|
config()->set('admin_access.app_host', 'app.clupilot.test');
|
|
config()->set('admin_access.site_hosts', ['[www.clupilot.test](https://www.clupilot.test)']);
|
|
|
|
$this->artisan('clupilot:publish-tunnel-names')
|
|
->expectsOutputToContain('www.clupilot.test')
|
|
->assertSuccessful();
|
|
|
|
$written = file_get_contents($this->dir.'/platform.hosts');
|
|
|
|
expect($written)->toContain('10.66.0.1 app.clupilot.test')
|
|
->and($written)->not->toContain('[www.clupilot.test]');
|
|
});
|
|
|
|
it('ist dieselbe Datei-Umsetzung wie für die Host-Namen', function () {
|
|
// Nicht Fake gegen Fake geprüft: die Rechte und das Anlegen des
|
|
// Verzeichnisses sind der Teil, der in Produktion schiefgeht.
|
|
//
|
|
// Kein ->skip() hier: die Bedingung `! app()->environment('testing')` kann
|
|
// in einem Testlauf nie zutreffen — der Test lief seit seiner Einführung
|
|
// also immer, und ein Skip, der nie greift, ist bloss eine Behauptung.
|
|
expect(app(HostDnsDirectory::class))->toBeInstanceOf(FileHostDnsDirectory::class);
|
|
});
|