122 lines
5.9 KiB
PHP
122 lines
5.9 KiB
PHP
<?php
|
|
|
|
use App\Provisioning\Steps\Customer;
|
|
use App\Provisioning\Steps\Host;
|
|
|
|
$wgSubnet = env('CLUPILOT_WG_SUBNET', '10.66.0.0/24');
|
|
[$wgNetwork, $wgBits] = array_pad(explode('/', $wgSubnet), 2, '24');
|
|
$wgBase = ip2long($wgNetwork) & (0xFFFFFFFF << (32 - (int) $wgBits)) & 0xFFFFFFFF;
|
|
$wgHubDefault = long2ip($wgBase + 1); // first usable address in the CIDR
|
|
|
|
return [
|
|
/*
|
|
| Ordered step classes per pipeline. ::class is textual — listing steps that
|
|
| are built incrementally does not autoload them until the pipeline runs.
|
|
*/
|
|
'pipelines' => [
|
|
'host' => [
|
|
Host\ValidateHostInput::class,
|
|
Host\EstablishSshTrust::class,
|
|
Host\PrepareBaseSystem::class,
|
|
Host\ConfigureWireguard::class,
|
|
Host\InstallProxmoxVe::class,
|
|
Host\RebootIntoPveKernel::class,
|
|
Host\ConfigureProxmox::class,
|
|
Host\CreateAutomationToken::class,
|
|
Host\VerifyProxmoxApi::class,
|
|
Host\RegisterCapacity::class,
|
|
Host\CompleteHostOnboarding::class,
|
|
],
|
|
'customer' => [
|
|
Customer\ValidateOrder::class,
|
|
Customer\ReserveResources::class,
|
|
Customer\CloneVirtualMachine::class,
|
|
Customer\ConfigureCloudInit::class,
|
|
Customer\StartVirtualMachine::class,
|
|
Customer\WaitForGuestAgent::class,
|
|
Customer\ConfigureNetwork::class,
|
|
Customer\DeployApplicationStack::class,
|
|
Customer\ConfigureNextcloud::class,
|
|
Customer\CreateCustomerAdmin::class,
|
|
Customer\ConfigureDnsAndTls::class,
|
|
Customer\RegisterBackup::class,
|
|
Customer\RegisterMonitoring::class,
|
|
Customer\RunAcceptanceChecks::class,
|
|
Customer\CompleteProvisioning::class,
|
|
],
|
|
],
|
|
|
|
// Plan → resource sizing + monthly price + Nextcloud blueprint template VMID.
|
|
// quota_gb/disk_gb/ram_mb/cores drive infrastructure placement and are
|
|
// ADMIN-ONLY. Customers compare seats, storage, performance class and
|
|
// features — never raw vCPU/RAM (see docs/specs/2026-07-25-portal-d-*).
|
|
'plans' => [
|
|
'start' => ['quota_gb' => 100, 'disk_gb' => 120, 'ram_mb' => 4096, 'cores' => 2, 'seats' => 5, 'performance' => 'standard', 'price_cents' => 4900, 'template_vmid' => 9000],
|
|
'team' => ['quota_gb' => 500, 'disk_gb' => 540, 'ram_mb' => 8192, 'cores' => 4, 'seats' => 25, 'performance' => 'enhanced', 'price_cents' => 17900, 'template_vmid' => 9000],
|
|
'business' => ['quota_gb' => 1000, 'disk_gb' => 1050, 'ram_mb' => 16384, 'cores' => 8, 'seats' => 100, 'performance' => 'high', 'price_cents' => 39900, 'template_vmid' => 9000],
|
|
'enterprise' => ['quota_gb' => 2000, 'disk_gb' => 2100, 'ram_mb' => 32768, 'cores' => 16, 'seats' => 500, 'performance' => 'dedicated', 'price_cents' => 79900, 'template_vmid' => 9000],
|
|
],
|
|
|
|
// Default branding applied when a customer has not set their own (resolved by
|
|
// Customer::brandingResolved(); NULL customer fields fall back to these).
|
|
'branding_defaults' => [
|
|
'display_name' => 'CluPilot Cloud',
|
|
'logo_path' => null, // null → CluPilot logo used by the provisioner
|
|
'primary_color' => '#f97316',
|
|
'accent_color' => '#c2560a',
|
|
],
|
|
|
|
// Extra storage add-on (per unit) and the add-on catalogue (labels in lang/*/billing.php).
|
|
'storage_addon' => ['gb' => 100, 'price_cents' => 1000],
|
|
'addons' => [
|
|
'extra_backups' => ['price_cents' => 500],
|
|
'priority_support' => ['price_cents' => 2900],
|
|
'collabora_pro' => ['price_cents' => 1900],
|
|
],
|
|
|
|
// Customer-facing feature bullets per plan (labels in lang/*/billing.php →
|
|
// billing.feature.<key>). Cumulative tiers: each plan lists its own bullets.
|
|
'plan_features' => [
|
|
'start' => ['managed_updates', 'daily_backups', 'monitoring', 'subdomain'],
|
|
'team' => ['managed_updates', 'daily_backups', 'monitoring', 'subdomain', 'office', 'branding', 'priority_support'],
|
|
'business' => ['managed_updates', 'daily_backups', 'monitoring', 'custom_domain', 'office', 'branding', 'priority_support', 'extended_retention', 'audit_log'],
|
|
'enterprise' => ['managed_updates', 'daily_backups', 'monitoring', 'custom_domain', 'office', 'branding', 'premium_sla', 'extended_retention', 'audit_log', 'onboarding'],
|
|
],
|
|
|
|
'dns' => [
|
|
'provider' => 'hetzner',
|
|
'token' => env('HETZNER_DNS_TOKEN', ''),
|
|
'zone' => env('CLUPILOT_DNS_ZONE', 'clupilot.com'),
|
|
],
|
|
|
|
'traefik' => [
|
|
'dynamic_path' => env('TRAEFIK_DYNAMIC_PATH', '/etc/traefik/dynamic'),
|
|
],
|
|
|
|
// CluPilot VM acts as the WireGuard hub; hosts join it during onboarding.
|
|
'wireguard' => [
|
|
'subnet' => $wgSubnet,
|
|
'hub_ip' => env('CLUPILOT_WG_HUB_IP', $wgHubDefault), // handshake target
|
|
'endpoint' => env('CLUPILOT_WG_ENDPOINT', ''), // host:port reachable by peers
|
|
'hub_public_key' => env('CLUPILOT_WG_HUB_PUBKEY', ''),
|
|
'config_path' => env('CLUPILOT_WG_CONFIG_PATH', '/etc/wireguard/wg0.conf'),
|
|
],
|
|
|
|
// SSH identity CluPilot deploys to each host after first password login.
|
|
'ssh' => [
|
|
'public_key' => env('CLUPILOT_SSH_PUBLIC_KEY', ''),
|
|
'private_key' => env('CLUPILOT_SSH_PRIVATE_KEY', ''),
|
|
// Per-command SSH timeout; below the job timeout (2100s) but far above
|
|
// the phpseclib ~10s default so apt full-upgrade etc. can finish.
|
|
'command_timeout' => (int) env('CLUPILOT_SSH_COMMAND_TIMEOUT', 2000),
|
|
],
|
|
|
|
// Proxmox automation role/user created on each host.
|
|
'proxmox' => [
|
|
'role_id' => 'CluPilotAutomation',
|
|
'role_privs' => 'VM.Allocate,VM.Clone,VM.Config.Disk,VM.Config.CPU,VM.Config.Memory,VM.Config.Network,VM.Config.Options,VM.Config.Cloudinit,VM.PowerMgmt,VM.Monitor,VM.Audit,VM.Backup,VM.GuestAgent.Audit,VM.GuestAgent.Unrestricted,Datastore.AllocateSpace,Datastore.Audit,Sys.Audit',
|
|
'user' => 'automation@pve',
|
|
'token_name' => 'clupilot',
|
|
],
|
|
];
|