97 lines
4.0 KiB
PHP
97 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Support\Readiness;
|
|
|
|
use App\Models\Host;
|
|
use App\Models\PlanVersion;
|
|
use App\Services\Secrets\SecretVault;
|
|
use App\Support\ProvisioningSettings;
|
|
|
|
/**
|
|
* What has to be in place for a PAID order to actually turn into a running,
|
|
* reachable machine: somewhere to put it, a name for it, and a router that
|
|
* knows about it.
|
|
*/
|
|
final class ProvisioningChecks
|
|
{
|
|
public const GROUP = 'provisioning';
|
|
|
|
/** @return array<int, Check> */
|
|
public static function all(): array
|
|
{
|
|
return [
|
|
new Check(
|
|
key: 'provisioning.dns_token',
|
|
group: self::GROUP,
|
|
severity: Check::SEVERITY_BLOCKING,
|
|
label: __('readiness.provisioning.dns_token'),
|
|
breaks: __('readiness.provisioning.dns_token_breaks'),
|
|
tab: 'integrations',
|
|
satisfied: filled(app(SecretVault::class)->get('dns.token')),
|
|
),
|
|
new Check(
|
|
key: 'provisioning.dns_zone',
|
|
group: self::GROUP,
|
|
severity: Check::SEVERITY_BLOCKING,
|
|
label: __('readiness.provisioning.dns_zone'),
|
|
breaks: __('readiness.provisioning.dns_zone_breaks'),
|
|
tab: 'integrations',
|
|
satisfied: filled(ProvisioningSettings::dnsZone()),
|
|
),
|
|
new Check(
|
|
key: 'provisioning.traefik_path',
|
|
group: self::GROUP,
|
|
severity: Check::SEVERITY_WARNING,
|
|
label: __('readiness.provisioning.traefik_path'),
|
|
breaks: __('readiness.provisioning.traefik_path_breaks'),
|
|
tab: 'integrations',
|
|
satisfied: filled(ProvisioningSettings::traefikDynamicPath()),
|
|
),
|
|
new Check(
|
|
key: 'provisioning.usable_host',
|
|
group: self::GROUP,
|
|
severity: Check::SEVERITY_BLOCKING,
|
|
label: __('readiness.provisioning.usable_host'),
|
|
breaks: __('readiness.provisioning.usable_host_breaks'),
|
|
tab: 'hosts',
|
|
// `active` ALONE is not enough. A host without a readable
|
|
// token is still selectable to ReserveResources, and the
|
|
// order then dies in CloneVirtualMachine — after payment.
|
|
satisfied: Host::query()
|
|
->where('status', 'active')
|
|
->whereNotNull('api_token_ref')
|
|
->exists(),
|
|
),
|
|
new Check(
|
|
key: 'provisioning.vm_template',
|
|
group: self::GROUP,
|
|
severity: Check::SEVERITY_BLOCKING,
|
|
label: __('readiness.provisioning.vm_template'),
|
|
breaks: __('readiness.provisioning.vm_template_breaks'),
|
|
tab: 'plans',
|
|
// A field check only. Whether the template actually EXISTS on
|
|
// a node is answered by the button in Task 9 — that has to
|
|
// ask Proxmox, and a live API call does not belong on every
|
|
// page load of this readiness page.
|
|
satisfied: PlanVersion::query()
|
|
->whereNotNull('published_at')
|
|
->whereNull('template_vmid')
|
|
->doesntExist(),
|
|
),
|
|
new Check(
|
|
key: 'provisioning.monitoring_token',
|
|
group: self::GROUP,
|
|
severity: Check::SEVERITY_WARNING,
|
|
label: __('readiness.provisioning.monitoring_token'),
|
|
breaks: __('readiness.provisioning.monitoring_token_breaks'),
|
|
tab: 'integrations',
|
|
// Warning, never blocking: RegisterMonitoring itself already
|
|
// degrades (retries, then continues) rather than fail the run
|
|
// — this page must not claim a stricter rule than the pipeline
|
|
// actually enforces.
|
|
satisfied: filled(app(SecretVault::class)->get('monitoring.token')),
|
|
),
|
|
];
|
|
}
|
|
}
|