113 lines
4.5 KiB
PHP
113 lines
4.5 KiB
PHP
<?php
|
|
|
|
use App\Models\Datacenter;
|
|
use App\Models\Operator;
|
|
use App\Services\Secrets\SecretVault;
|
|
use App\Support\OperatingMode;
|
|
use App\Support\Readiness;
|
|
use App\Support\Readiness\Check;
|
|
use App\Support\Settings;
|
|
|
|
/**
|
|
* Die Bereitschaftsprüfung berichtet, was fehlt — und sagt dazu, was
|
|
* kaputtgeht. Siehe BillingChecksTest für dieselbe Begründung.
|
|
*/
|
|
function onboardingCheck(string $key): ?Check
|
|
{
|
|
return collect(Readiness::all())->firstWhere('key', $key);
|
|
}
|
|
|
|
it('needs at least one datacenter', function () {
|
|
// create_datacenters_table selbst legt 'fsn'/'hel' als Vorgabe an — auch
|
|
// in dieser Suite, da es sich um eine Migration und keinen Seeder
|
|
// handelt. Erst geleert, damit dieser Test den echten leeren Zustand
|
|
// prüft statt der Werkseinstellung dieser Installation.
|
|
Datacenter::query()->delete();
|
|
|
|
// ValidateHostInput ist der erste Schritt der Host-Kette und bricht ohne
|
|
// Rechenzentrum ab — bevor überhaupt eine SSH-Verbindung versucht wird.
|
|
expect(onboardingCheck('onboarding.datacenter')->satisfied)->toBeFalse();
|
|
|
|
Datacenter::factory()->create();
|
|
|
|
expect(onboardingCheck('onboarding.datacenter')->satisfied)->toBeTrue();
|
|
});
|
|
|
|
it('needs an ssh private key', function () {
|
|
// Mode selbst gesetzt (Testisolation: CACHE_STORE=array wird zwischen
|
|
// Testdateien nicht geleert), damit dieser Test nicht vom Rest der Zeile
|
|
// abhängt, in der die Suite läuft.
|
|
OperatingMode::set(OperatingMode::Live);
|
|
|
|
// Diese Installation hat in .env tatsächlich einen SSH-Schlüssel
|
|
// konfiguriert (CLUPILOT_SSH_PRIVATE_KEY_PATH), auf den SecretVault::get()
|
|
// zurückfällt, solange kein Tresor-Eintrag existiert — direkt
|
|
// zurückgesetzt, damit der Test nicht vom Entwicklerrechner abhängt.
|
|
config()->set('provisioning.ssh.private_key', '');
|
|
|
|
expect(onboardingCheck('onboarding.ssh_private_key')->satisfied)->toBeFalse();
|
|
|
|
app(SecretVault::class)->put(
|
|
'ssh.private_key',
|
|
'-----BEGIN OPENSSH PRIVATE KEY-----',
|
|
Operator::factory()->create(),
|
|
OperatingMode::Live,
|
|
);
|
|
|
|
expect(onboardingCheck('onboarding.ssh_private_key')->satisfied)->toBeTrue();
|
|
});
|
|
|
|
it('needs a usable vault key', function () {
|
|
// isUsable() statt eines bloßen filled()-Checks: SecretCipher warnt in
|
|
// seinem eigenen Kommentar genau davor, eine zweite, schwächere Regel zu
|
|
// bauen, die einen falsch geformten Schlüssel als gültig durchwinkt.
|
|
config()->set('admin_access.secrets_key', '');
|
|
expect(onboardingCheck('onboarding.secrets_key')->satisfied)->toBeFalse();
|
|
|
|
config()->set('admin_access.secrets_key', base64_encode(str_repeat('a', 32)));
|
|
expect(onboardingCheck('onboarding.secrets_key')->satisfied)->toBeTrue();
|
|
});
|
|
|
|
it('needs a usable vpn config key', function () {
|
|
config()->set('admin_access.vpn_config_key', '');
|
|
expect(onboardingCheck('onboarding.vpn_config_key')->satisfied)->toBeFalse();
|
|
|
|
config()->set('admin_access.vpn_config_key', base64_encode(str_repeat('b', 32)));
|
|
expect(onboardingCheck('onboarding.vpn_config_key')->satisfied)->toBeTrue();
|
|
});
|
|
|
|
it('needs all three wireguard values, not just some', function () {
|
|
// Zwei von drei ist kein halber Tunnel, sondern gar keiner. Subnet wird
|
|
// bewusst direkt über config() geprüft statt über Settings/
|
|
// ProvisioningSettings (siehe deren eigener Kopfkommentar: der Compose-
|
|
// Stack liest denselben Schlüssel beim Containerstart) — und hier im Test
|
|
// ebenso direkt zurückgesetzt, damit das Ergebnis nicht von den echten
|
|
// WireGuard-Werten dieser Installation abhängt.
|
|
config()->set('provisioning.wireguard.hub_public_key', '');
|
|
config()->set('provisioning.wireguard.endpoint', '');
|
|
config()->set('provisioning.wireguard.subnet', '');
|
|
|
|
expect(onboardingCheck('onboarding.wg_hub')->satisfied)->toBeFalse();
|
|
|
|
Settings::set('provisioning.wg_hub_pubkey', 'abc=');
|
|
Settings::set('provisioning.wg_endpoint', '198.51.45.9:51820');
|
|
|
|
expect(onboardingCheck('onboarding.wg_hub')->satisfied)->toBeFalse();
|
|
|
|
config()->set('provisioning.wireguard.subnet', '10.66.0.0/24');
|
|
|
|
expect(onboardingCheck('onboarding.wg_hub')->satisfied)->toBeTrue();
|
|
});
|
|
|
|
it('names what breaks for every onboarding check, not just what is missing', function () {
|
|
foreach ([
|
|
'onboarding.ssh_private_key',
|
|
'onboarding.secrets_key',
|
|
'onboarding.vpn_config_key',
|
|
'onboarding.wg_hub',
|
|
'onboarding.datacenter',
|
|
] as $key) {
|
|
expect(onboardingCheck($key)->breaks)->not->toBe('');
|
|
}
|
|
});
|