Блог ·
Біллінг і провізіювання CloudPanel
Оплачене замовлення, прострочений рахунок, скасування. У CloudPanel є команда для двох із трьох. Третя вимагає редагування vhost, і цей вибір має наслідки.
Автор: Provibr
Автоматизований хостинговий продукт має рівно три моменти, коли гроші й машини стикаються одне з одним:
- Замовлення оплачено: сайт має існувати, правильно налаштований, протягом кількох секунд.
- Рахунок прострочено: сайт має згаснути й повернутися щойно його оплачено.
- Підписка завершується: сайт треба видалити, по-справжньому, разом з даними.
У CloudPanel є чиста команда для першого моменту й чиста команда для третього. Для другого в нього немає взагалі нічого. Це не дрібна виноска до звичайнісінької інтеграції; це визначальний факт автоматизації білінгу на цій панелі, і він заслуговує на середину цієї сторінки, а не на рядок унизу.
Три моменти та що пропонує CloudPanel
| Момент | CloudPanel | Існує? |
|---|---|---|
| Оплачене замовлення | clpctl site:add:php (плюс clpctl db:add для бази даних) | Так |
| Прострочено | Немає команди; важелем є vhost | Немає в панелі |
| Все ж оплачено | Немає команди; той самий важіль, у зворотний бік | Немає в панелі |
| Підвищення / зниження | Немає команди; немає й поняття пакета | Ні |
| Скасування | clpctl site:delete --domainName=… --force | Так |
Все проходить через clpctl, інструмент командного рядка панелі. REST API немає: CloudPanel є панеллю із серверним рендерингом плюс CLI, і автоматизація йде через CLI, або не йде взагалі.
Дві команди, які таки існують, добре зроблені. site:add:php бере домен, версію PHP, шаблон vhost та Linux-користувача сайту з його паролем і повертається, записавши vhost, пул і домашній каталог. site:delete --force виконує справжнє видалення, а не мʼяке. Між ними лежить прогалина.
Відсутня середина, і як її заповнюють
Призупинення є дією, яку система білінгу виконує частіше за будь-яку іншу, бо саме вона запускається без нагляду, за розкладом, проти облікових записів, на які ніхто не дивиться. Це також єдиний зворотний важіль, який ви маєте між «хостити їх безкоштовно» та «видалити їхній бізнес».
У CloudPanel немає для цього слова. Немає ні site:suspend, ні site:disable, ні прапорця обслуговування в панелі, ні статусу на рівні сайту, який можна перемкнути. Тож якщо ви продаєте хостинг на CloudPanel, призупинення ви будуєте самі. Реалістичні варіанти, з їхньою чесною ціною:
Зупинити PHP-FPM-пул сайту. Швидко, зворотно, і це справді припиняє обслуговування сайту. Це також дає 502 замість пояснення, тож ваш клієнт бачить зламаний вебсайт, а не призупинений обліковий запис. І це операція systemd на хості, а не clpctl, тож підтримувати її працездатною через оновлення панелі маєте ви самі.
Відредагувати vhost. Конфігурація NGINX сайту є файлом на хості, і один рядок у ньому вирішує, чи відповідає сайт. Зворотно, миттєво, і коштує клієнту лише доступу. Заковика в тому, що ви пишете у файл, яким володіє CloudPanel, тож дуже важливо, як саме ви в нього пишете.
Видалити, спершу зробивши резервну копію. Однозначно й остаточно, і це зрештою коштуватиме вам клієнта, який оплатив тридцять першого дня. Відновлення не є перемикачем, з усім, що це означає щодо DNS, сертифікатів і листа, який доведеться надіслати після.
Четвертого чистого варіанта немає. Важливо те, що ви обираєте один свідомо й переконуєтеся, що людина, яка відповідає на дзвінок, знає, який саме. Збій тут не технічний: це співробітник підтримки, який обіцяє клієнту, що його сайт одразу повернеться, у системі, де «повернутися» означає відновити резервну копію.
Який вигляд має обережне редагування vhost
Другий варіант варто зробити як слід, а «як слід» зводиться до короткого переліку. Ось як це робить Provibr, і міркування переносяться незалежно від того, користуєтеся ви Provibr чи пишете це самі.
Позначайте те, що вставили. Призупинення є рядком return 403;, обгорнутим у коментар початку й коментар кінця. Прибрати його означає видалити рівно рядки між цими позначками, тож відновлення лишає файл байт у байт таким, яким він був, а return 403;, який клієнт поставив там з власних міркувань, лишається недоторканим. Пошук із заміною за return 403 не мав би цієї властивості.
Кожен публічний блок server, а не перший-ліпший. У vhost зазвичай є блок для порту 80 і блок для 443. Вставте в один, і ви отримаєте призупинений сайт по HTTP та цілком здоровий по HTTPS, що гірше, ніж не призупиняти взагалі, бо має вигляд, ніби спрацювало.
Перевіряйте конфігурацію перед перезавантаженням. Спершу виконується nginx -t. Призупинення, яке кладе кожен інший сайт на машині, не є призупиненням: це спільний вебсервер за задумом.
Робіть стан читабельним із хоста. Оскільки позначка є коментарем у файлі, призупинені сайти на відстані одного grep, і агент читає це назад, замість довіряти власній базі даних. Якщо хтось редагує файл вручну, наступне опитування це помічає.
Чого все це не змінює: у самого CloudPanel досі немає поняття призупиненого сайту. Панель показуватиме його як звичайний сайт, бо з погляду панелі він таким і є. Будь-хто з доступом до CloudPanel (зокрема клієнт, якого ви щойно призупинили) може відкрити цей файл і прибрати рядок. Стан читабельний і застосований на вебсервері, але ним не володіє панель, і жодне рішення на цій панелі не може цього змінити.
Шляху підвищення теж немає, бо немає пакетів
У CloudPanel немає ні планів, ні квот, ні лімітів на рівні сайту. Це прибирає з переліку вище цілий момент: виклику «змінити пакет» немає, бо немає пакета.
Це також означає, що різниця між вашими планами має бути реальною десь інде. Якщо ваш план за €5 і ваш план за €15 опиняються на тому самому CloudPanel з однаковісіньким усім, то клієнт купив ціну, і перший, хто це второпає, розповість решті. Застосування живе над панеллю: окремі хости на кожен рівень, квоти на рівні файлової системи або ліміти, які застосовує й рахує ваша власна платформа.
Для звіряння потрібен список, а його немає
clpctl уміє перелічити користувачів панелі. Він не вміє перелічити сайти: ті живуть у власній базі даних SQLite панелі на хості.
Для білінгу це справжня прогалина, бо система білінгу має вміти будь-коли поставити два питання: чи все, за що я беру плату, ще існує? і чи є тут щось, за що я плату не беру? На обидва відповідає порівняння ваших записів зі списком того, що справді є на машині. Без списку ви дізнаєтеся про видалений вручну сайт, коли клієнт напише листа, а про створений вручну не дізнаєтеся ніколи.
Хоч би що ви збудували над CloudPanel, воно має брати цей список звідкись інде, ніж clpctl, і для цього йому потрібен доступ до хоста. На практиці є рівно одне місце: власна база даних панелі, /home/clp/htdocs/app/data/db.sq3, де простий select за таблицею site дає вам домен, Linux-користувача, тип, шаблон vhost і версію PHP за один раз. Provibr читає її там.
Це працює, і варто чітко розуміти, на що ви погоджуєтеся, коли це робите. Ця схема є внутрішньою справою CloudPanel, а не опублікованим інтерфейсом, тож вона може змінитися в релізі без того, щоб хтось порушив обіцянку. Читати її варто (система білінгу без звіряння гірша), але вона належить до короткого переліку речей, які треба перевірити наново після оновлення панелі, поряд із форматами виводу clpctl.
Обліковий доступ не є API-токеном
Варто сказати прямо, бо це найбільша практична відмінність між автоматизацією CloudPanel і автоматизацією панелі з REST API.
clpctl працює від root. Він записує конфігурацію NGINX, створює Linux-користувачів і керує службами, тож root не є недоглядом: це сама суть роботи. Тому все, що ним керує, має адміністративний доступ до робочого вебсервера, на якому є чужі сайти, а не обмежений токен, зведений до однієї поверхні API.
Два наслідки для кожного, хто підключає білінг сюди. Радіус ураження інший: витік API-токена панелі дозволяє комусь створювати й видаляти облікові записи, тоді як витік облікового доступу до оболонки вебсервера відкриває іншу розмову з іншим набором обовʼязків. І найменші привілеї є вашою власною роботою: тут немає галочки дозволів, на яку можна спертися, тож розмежування ви проєктуєте, а не налаштовуєте.
Де насправді живе рахунок
Варто сказати прямо, бо це найпоширеніше непорозуміння: Provibr не виставляє рахунки вашим клієнтам. Він не надсилає їм рахунок, не переслідує їх і не знає, скільки ви з них берете. Ці стосунки належать вам.
Provibr виставляє рахунок за потужність, яку резервуєте ви: скільки хостингових облікових записів вам дозволено запускати одночасно, за місяць, за ціною за одиницю з рівнями. Те, що ви берете з власних клієнтів, і як, лишається цілком усередині вашої власної системи білінгу.
Зʼєднати ці дві половини можна двома способами:
Модуль WHMCS. Якщо ви вже користуєтеся WHMCS, встановіть модуль провізіювання Provibr і вкажіть одному продукту WHMCS один вебплан Provibr. Ваш клієнт має один обліковий запис, один рахунок і один вхід. Модуль є звичайним zip-архівом, який ви встановлюєте самі, і він працює всередині вашого WHMCS. З нашого боку нічого вмикати не треба.
REST API. Якщо ви користуєтеся FOSSBilling, Blesta, чимось власним чи таблицею й cron-завданням, керуйте ним напряму. Один ключ, одна базова URL і рівно ті дозволи, які вже має учасник за цим ключем.
Єдине правило для керування ним із власного коду
Все, що торкається машини, є асинхронним, і так має бути. Ваша інфраструктура доступна лише через агента всередині вашої власної мережі, а той агент дзвонить назовні. Тож кінцева точка, яка змінює обліковий запис, не може відповісти результатом. Вона відповідає, що замовлення прийнято, і віддає вам команду, за якою треба стежити: ви читаєте її, доки її статус не стане остаточним (виконано, не вдалося, вичерпано час або скасовано).
Читання так не працює ніколи. Інвентар, адреса чи рахунок відповідають одразу, бо ця відповідь надходить із бази даних, а не з вашого хоста.
Практичний наслідок для гачка білінгу: не позначайте замовлення завершеним за відповіддю про прийняття. Перша відповідь, яку ви отримуєте, означає «ми надіслали», а не «спрацювало».
Призупинення є також вашим власним контролем витрат
Один звʼязок, який легко пропустити, і саме через нього відсутня середина вище коштує грошей, а не лише доброї волі. У Provibr призупинений сервер перестає враховуватися в потужність, за яку ви платите. Для хостингового облікового запису немає «зупинено»: є активний і є призупинений.
Тож крок нагадування, якого ви вже хотіли з комерційних причин, також звільняє слот, за який ви платите, за умови, що призупинення є реальною дією, а не приміткою у вашій власній базі даних. Це й є практичний аргумент на користь того, щоб його збудувати, а не лишати середину порожньою: неоплачений обліковий запис, який ви ще не вирішили видалити, і далі займає потужність, за яку ви платите.
Все вище про панель є властивістю CloudPanel, а не описом інтеграції, і це навмисно: прогалини реальні, і не нам їх бажати геть. Інтеграція може лише ретельно обрати, який із трьох варіантів вона бере, і сказати вголос, чого цей вибір усе одно не виправляє.
Якщо ви також продаєте VPS, ігрові сервери чи облікові записи cPanel, ті самі три моменти стосуються всіх їх, і вони можуть жити в одному інвентарі. Provibr сьогодні тримає свої панелі керування, гіпервізори та ігрові панелі пліч-о-пліч, з одним набором прав і одним журналом активності на всіх.