Naar de inhoud

Blog ·

CloudPanel-facturatie automatiseren

Een betaalde bestelling, een te late factuur, een opzegging. CloudPanel heeft voor twee van die drie een commando. Het derde is een vhost-bewerking.

Door Provibr

Een geautomatiseerd hostingproduct heeft precies drie momenten waarop geld en machines elkaar raken:

  1. De bestelling is betaald: de site moet binnen enkele seconden bestaan, juist geconfigureerd.
  2. De factuur is te laat: de site moet uit, en terug zodra er betaald wordt.
  3. Het abonnement eindigt: de site moet weg, echt weg, inclusief de data.

CloudPanel heeft een net commando voor moment één en een net commando voor moment drie. Voor moment twee heeft het helemaal niets. Dat is geen kleine voetnoot bij een verder gewone integratie; het is het bepalende feit van facturatie automatiseren op dit paneel, en het verdient het midden van deze pagina in plaats van een regel onderaan.

De drie momenten, en wat CloudPanel biedt

MomentCloudPanelBestaat?
Betaalde bestellingclpctl site:add:php (plus clpctl db:add voor een database)Ja
Te laatGeen commando; de vhost is de hendelNiet in het paneel
Toch betaaldGeen commando; dezelfde hendel, omgekeerdNiet in het paneel
Upgrade / downgradeGeen commando; er is geen pakketbegripNee
Opzeggingclpctl site:delete --domainName=… --forceJa

Alles loopt via clpctl, de commandoregeltool van het paneel. Er is geen REST-API: CloudPanel is een server-gerenderd paneel plus een CLI, en automatisering gaat via die CLI of ze gaat niet.

De twee commando's die er wél zijn, zijn goede commando's. site:add:php neemt het domein, de PHP-versie, een vhost-template en de Linux-sitegebruiker met wachtwoord, en komt terug nadat het de vhost, de pool en de homedirectory heeft geschreven. site:delete --force is een echte verwijdering, geen zachte. Daartussen zit het gat.

Het ontbrekende midden, en hoe het gevuld wordt

Opschorting is de actie die een facturatiesysteem vaker uitvoert dan welke andere ook, want het is degene die onbewaakt draait, volgens een schema, tegen accounts waar niemand naar kijkt. Het is ook de enige omkeerbare hendel die je hebt tussen "gratis blijven hosten" en "hun bedrijf verwijderen".

CloudPanel heeft er geen woord voor. Er is geen site:suspend, geen site:disable, geen onderhoudsvlag in het paneel, en geen status per site die je kunt omzetten. Verkoop je CloudPanel-hosting, dan is opschorting dus iets dat je bouwt. De realistische opties, met hun eerlijke prijs:

De PHP-FPM-pool van de site stoppen. Snel, omkeerbaar, en het stopt de site echt met serveren. Het levert ook een 502 op in plaats van een uitleg, dus je klant ziet een kapotte website in plaats van een opgeschort account. En het is een systemd-handeling op de host, geen clpctl-handeling, dus jij houdt het werkend over panelupgrades heen.

De vhost bewerken. De NGINX-configuratie van de site is een bestand op de host, en één regel daarin bepaalt of de site antwoordt. Omkeerbaar, direct, en het kost de klant niets behalve toegang. De valstrik is dat je schrijft in een bestand dat CloudPanel bezit, dus het maakt veel uit hoe je erin schrijft.

Verwijderen met eerst een back-up. Ondubbelzinnig, en permanent op een manier die je ooit een klant gaat kosten die op dag eenendertig betaalt. Terugzetten is geen schakelaar, met alles wat dat betekent voor DNS, certificaten en de mail die je erna moet sturen.

Er is geen vierde optie die schoon is. Wat telt is dat je er bewust één kiest en zorgt dat degene die de telefoon opneemt weet welke het is. De faalstand is hier niet technisch. Het is een supportmedewerker die een klant belooft dat zijn site zo weer terug is, op een systeem waar terugkomen een back-up terugzetten betekent.

Hoe een zorgvuldige vhost-bewerking eruitziet

De tweede optie is degene die het waard is om goed te doen, en "goed" is een korte lijst. Zo doet Provibr het, en de redenering geldt of je nu Provibr gebruikt of het zelf schrijft.

Markeer wat je invoegt. De opschorting is een return 403; tussen een begin- en een eindcommentaar. Verwijderen betekent precies de regels daartussen weghalen, dus hervatten laat het bestand byte voor byte achter zoals het was, en een return 403; die de klant er om eigen redenen in zette blijft onaangeroerd. Een zoek-en-vervang op return 403 heeft die eigenschap niet.

Elk publiek server-blok, niet het eerste. Een vhost heeft meestal een blok voor poort 80 en één voor 443. Injecteer je in één, dan krijg je een opgeschorte site over HTTP en een kerngezonde over HTTPS, wat erger is dan niet opschorten, want het ziet eruit alsof het werkte.

Test de configuratie vóór je herlaadt. nginx -t gaat eerst. Een opschorting die elke andere site op de doos platlegt is geen opschorting, en dit is per ontwerp een gedeelde webserver.

Maak de toestand afleesbaar vanaf de host. Omdat de markering een commentaar in een bestand is, zijn de opgeschorte sites één grep ver, en de agent leest dat terug in plaats van zijn eigen database te geloven. Bewerkt iemand het bestand met de hand, dan valt dat bij de volgende ronde op.

Wat dit allemaal niet verandert: CloudPanel zelf kent nog steeds geen opgeschorte site. Het paneel toont hem als een gewone site, want vanuit het paneel gezien ís het er een. Iedereen met CloudPanel-toegang, inclusief de klant die je net opschortte, kan dat bestand openen en de regel eruit halen. De toestand is afleesbaar en hij wordt bij de webserver afgedwongen, maar hij is geen eigendom van het paneel, en geen enkele opzet op dit paneel kan dat veranderen.

Er is ook geen upgradepad, want er zijn geen pakketten

CloudPanel heeft geen plannen, geen quota en geen limieten per site. Dat haalt een heel moment uit de lijst hierboven: er is geen change package-aanroep, want er is geen pakket.

Het betekent ook dat het verschil tussen je plannen ergens anders echt moet zijn. Landen je plan van € 5 en je plan van € 15 op dezelfde CloudPanel met overal hetzelfde, dan kocht je klant een prijs, en de eerste die dat doorheeft vertelt het de anderen. Handhaving leeft boven het paneel: aparte hosts per niveau, quota op bestandssysteemniveau, of limieten die je eigen platform toepast en telt.

Afstemming vraagt een lijst, en die is er niet

clpctl kan panelgebruikers opsommen. Het kan geen sites opsommen: die leven in de eigen SQLite-database van het paneel op de host.

Voor facturatie is dat een echt gat, want een facturatiesysteem hoort op elk moment twee vragen te kunnen stellen: bestaat alles waarvoor ik factureer nog? en staat hier iets waarvoor ik niet factureer? Beide worden beantwoord door je administratie te vergelijken met een lijst van wat er werkelijk op de machine staat. Zonder lijst hoor je van een met de hand verwijderde site als de klant mailt, en van een met de hand aangemaakte nooit.

Wat je ook boven CloudPanel bouwt, moet die lijst ergens anders vandaan halen dan uit clpctl, en daar is hosttoegang voor nodig. In de praktijk is er precies één plek: de eigen database van het paneel, /home/clp/htdocs/app/data/db.sq3, waar een gewone select over de tabel site je in één keer het domein, de Linux-gebruiker, het type, het vhost-sjabloon en de PHP-versie geeft. Provibr leest hem daar.

Dat werkt, en het is goed om helder te zijn over waar je dan mee akkoord gaat. Dat schema is de interne zaak van CloudPanel, geen gepubliceerde interface, dus het kan in een release veranderen zonder dat iemand een belofte heeft gebroken. Hem lezen is de juiste keuze (een facturatiesysteem zonder afstemming is erger), maar het hoort op het korte lijstje van dingen om na een panelupgrade opnieuw te controleren, naast de uitvoervormen van clpctl.

Het credential is geen API-token

De moeite waard om onomwonden te zijn, want het is het grootste praktische verschil tussen CloudPanel automatiseren en een paneel met een REST-API automatiseren.

clpctl draait als root. Het schrijft NGINX-configuratie, maakt Linux-gebruikers aan en beheert diensten, dus root is geen vergissing: het is de opdracht. Alles wat het aanstuurt heeft daarmee administratieve toegang tot een productiewebserver die de sites van andere mensen draagt, geen afgebakend token dat maar één API-oppervlak kan raken.

Twee gevolgen voor wie hier facturatie aan knoopt. De schade bij een lek is anders: een gelekt paneel-API-token laat iemand accounts aanmaken en verwijderen, terwijl een gelekt shell-credential op de webserver een ander gesprek is met een andere set verplichtingen. En minimale rechten zijn je eigen werk: er is geen rechtenvinkje om op te leunen, dus afbakening is iets dat je ontwerpt in plaats van instelt.

Waar de factuur eigenlijk staat

De moeite waard om expliciet te zijn, want het is het meest voorkomende misverstand: Provibr factureert jouw klanten niet. Het stuurt ze geen rekening, maant ze niet aan, en weet niet wat je ze in rekening brengt. Die relatie is van jou.

Wat Provibr factureert is de capaciteit die jij reserveert: hoeveel hostingaccounts je tegelijk mag draaien, per maand, tegen een staffelprijs. Wat je je eigen klanten rekent, en hoe, blijft volledig binnen je eigen facturatiesysteem.

Er zijn twee manieren om de twee helften te verbinden:

Een WHMCS-module. Draai je al WHMCS, installeer dan de Provibr-provisioningmodule en laat één WHMCS-product naar één Provibr-webhostingplan wijzen. Je klant houdt één account, één factuur en één login. De module is een gewone zip die je zelf installeert en die in jouw WHMCS draait. Aan onze kant hoeft er niets aangezet te worden.

De REST-API. Draai je FOSSBilling, Blesta, iets eigens, of een spreadsheet met een cronjob, stuur het dan rechtstreeks aan. Eén sleutel, één basis-URL, en precies de rechten die het lid achter die sleutel al heeft.

De ene regel voor aansturing uit eigen code

Alles wat een machine raakt is asynchroon, en dat moet ook. Je infrastructuur is alleen bereikbaar via de agent in je eigen netwerk, en die verbindt uitgaand. Een endpoint dat een account wijzigt kan dus niet met het resultaat antwoorden. Het antwoordt dat de opdracht is aangenomen en geeft je een commando om te volgen, dat je leest tot de status definitief is: klaar, mislukt, verlopen of geannuleerd.

Lezen werkt nooit zo. Een inventaris, een adres of een factuur antwoordt meteen, want dat antwoord komt uit een database en niet van jouw host.

Het praktische gevolg voor een facturatiehook: markeer de bestelling niet als afgerond op het aangenomen-antwoord. Het antwoord dat je eerst krijgt is "we hebben het verstuurd", niet "het is gelukt".

Opschorten is ook je eigen kostenbeheersing

Eén verband dat makkelijk te missen is, en het is de reden dat het ontbrekende midden hierboven niet alleen goodwill maar ook geld kost. In Provibr telt een opgeschorte server niet mee voor de capaciteit waarvoor je betaalt. Voor een hostingaccount bestaat er geen "gestopt": er is actief en opgeschort.

Op een paneel waar opschorten een echte, ondersteunde actie is, maakt de aanmaanstap die je om commerciële redenen toch al wilde dus ook de plek vrij waarvoor je betaalt. Op een paneel zonder die actie is elk onbetaald account dat je nog niet hebt willen verwijderen capaciteit die je blijft dragen. Dat is een argument om je opschortingsbeleid vroeg te bepalen, en om het op te schrijven.

Alles hierboven over het paneel is een eigenschap van CloudPanel en geen beschrijving van een integratie, en dat is bewust: de gaten zijn echt en ze zijn niet aan ons om weg te wensen. Wat een integratie wél kan doen is zorgvuldig kiezen welke van de drie opties hij neemt, en hardop zeggen wat die keuze nog steeds niet oplost.

Verkoop je ook VPS'en, gameservers of cPanel-accounts, dan gelden dezelfde drie momenten daar net zo goed, en ze kunnen in één inventaris leven. Provibr draait vandaag zijn controlepanelen, hypervisors en gamepanelen naast elkaar, met één rechtenmodel en één activiteitenlog over het geheel.

Begin met één host en één agent

Maak een account aan, installeer de agent met één commando en koppel je eerste Proxmox-host. De proefperiode loopt 14 dagen en vraagt geen betaalgegevens.