diff --git a/packages/vitec/Classes/Command/SsrHealthSampleCommand.php b/packages/vitec/Classes/Command/SsrHealthSampleCommand.php index 2b8a59b..ebe37d8 100644 --- a/packages/vitec/Classes/Command/SsrHealthSampleCommand.php +++ b/packages/vitec/Classes/Command/SsrHealthSampleCommand.php @@ -9,6 +9,7 @@ use Evomedien\Vitec\Service\SsrPurgeService; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Http\RequestFactory; @@ -33,8 +34,24 @@ final class SsrHealthSampleCommand extends Command parent::__construct(); } + protected function configure(): void + { + $this->addOption( + 'test-mail', + null, + InputOption::VALUE_OPTIONAL, + 'Send a sample alert mail through the real alert path and exit (no health sample). Optional address; default: the configured alert recipients', + false + ); + } + protected function execute(InputInterface $input, OutputInterface $output): int { + $testMail = $input->getOption('test-mail'); + if ($testMail !== false) { + return $this->sendTestMail((string)$testMail, $output); + } + $endpoint = $this->purgeService->getHealthEndpoint(); if ($endpoint === '') { $output->writeln('SSR_HEALTH_ENDPOINT missing in var/vitec-ssr-purge.env'); @@ -204,6 +221,38 @@ final class SsrHealthSampleCommand extends Command return Command::SUCCESS; } + /** + * Deliverability check (e.g. mail-tester.com): same sender, mailer and + * plain-text format as a real alert, clearly marked as a test. + */ + private function sendTestMail(string $address, OutputInterface $output): int + { + $override = []; + if ($address !== '') { + if (!GeneralUtility::validEmail($address)) { + $output->writeln('invalid address: ' . $address . ''); + return Command::INVALID; + } + $override = [$address]; + } + $this->sendAlert( + '[VITEC SSR] TEST: alert mail check', + "This is a test of the VITEC SSR alert mail - nothing is wrong.\n\n" + . "Real alerts look like this one and are sent when the 5-minute health\n" + . "check sees the SSR server go down or come back, and when the\n" + . "auto-failover switches the site to SPA delivery.\n\n" + . 'Time: ' . date('d.m.Y H:i:s') . "\n" + . 'Current state: switch vitec.ssr.enabled = ' + . ($this->flagService->isEnabledInSettings() ? 'ON' : 'OFF') + . ', flag file ' . ($this->flagService->isFlagSet() ? 'present (SSR active)' : 'missing (SPA delivery)') . ".\n\n" + . "Recipients are maintained in the TYPO3 backend:\n" + . "Site Management > Settings > VITEC > SSR alert mail recipients.\n", + $output, + $override + ); + return Command::SUCCESS; + } + /** * Mails are best effort: a mail problem must never break the sampler * (the cron would stop logging history). Recipients come from the site @@ -211,13 +260,13 @@ final class SsrHealthSampleCommand extends Command * fallback SSR_ALERT_EMAIL in var/vitec-ssr-purge.env - none at all * means "alerts off", which the output states so the cron log shows why. */ - private function sendAlert(string $subject, string $body, OutputInterface $output): void + private function sendAlert(string $subject, string $body, OutputInterface $output, array $override = []): void { $alert = $this->purgeService->getAlertRecipients(); - if ($alert['invalid'] !== []) { + if ($alert['invalid'] !== [] && $override === []) { $output->writeln('skipped invalid alert addresses: ' . implode(', ', $alert['invalid']) . ''); } - $recipients = $alert['recipients']; + $recipients = $override !== [] ? $override : $alert['recipients']; if ($recipients === []) { $output->writeln('transition detected but no alert recipients are configured (Site settings › VITEC or SSR_ALERT_EMAIL) - no mail sent'); return;