Блог ·
Автоматизація білінгу для PufferPanel
Від замовлення до сервера й від неоплаченого рахунку до зупиненого, на PufferPanel. Зіставлення циклу, правило асинхронності та прогалина призупинення.
Автор: Provibr
Більшість сторінок про автоматизацію білінгу починаються зі щасливого шляху. Ця починається з прогалини, бо в PufferPanel саме прогалина визначає дизайн.
У PufferPanel немає призупинення. Ні стовпчика, ні кінцевої точки. Статус сервера знає лише running та installing. Усе нижче випливає з цього.
Виміряно на PufferPanel 3.0.9.
Два шари білінгу, і це не одне й те саме
| Шар | Хто кому виставляє рахунок | Що він рахує |
|---|---|---|
| Ваш білінг | Ви → ваш клієнт | Ігровий сервер, за місяць, за скільки б ви не брали |
| Біллінг платформи | Provibr → ви | Потужність: скільки серверів кожного виду вам дозволено запускати одночасно |
Те, що ви берете з власних клієнтів, лишається цілком усередині вашої системи білінгу. Provibr ніколи не бачить рахунку клієнта й ніколи не спілкується з вашими клієнтами. Ваша система білінгу володіє рішенням, шар провізіювання володіє виконанням.
Життєвий цикл, зіставлений
| Подія білінгу | Що має статися | Ефект на боці PufferPanel |
|---|---|---|
| Замовлення оплачено | Створити сервер із тарифу | Повне визначення шаблону надіслано вбудовано, сервер створено, інсталятор запускається |
| Рахунок прострочено | Призупинити | Контейнер зупинено + доступ заблоковано в платформі (див. нижче) |
| Платіж отримано | Відновити | Доступ відновлено; клієнт запускає сервер |
| Скасування | Видалити | Сервер спершу зупинено, потім видалено |
| Підвищення / зниження | Перевстановити | Запускає встановлення шаблону знову |
Чотири з цих пʼяти рядків звичайні. Другий не такий.
Прогалина призупинення та як її обійти в дизайні
Коли платформа призупиняє ігровий сервер PufferPanel (щоб застосувати ліміт ліцензії або тому, що ви наказали їй це через несплату), вона зупиняє контейнер і блокує доступ до цього сервера у власній панелі платформи. Сервер не працює, і ваш клієнт не може запустити його з вашого Огляду.
Але це блокування є концепцією платформи, а не панелі. Будь-хто з прямим доступом до інсталяції PufferPanel може запустити сервер знову. PufferPanel нічого не застосовує, бо йому нема чим застосовувати.
Це варто сказати прямо, а не ховати, бо це змінює те, що вам варто продавати:
| Ваша конфігурація | Чи має прогалина значення? |
|---|---|
| Клієнти користуються лише вашим Оглядом; без облікових записів на панелі | Ні. Вони не можуть дістатися до PufferPanel напряму. |
| У клієнтів є входи в PufferPanel | Так. Призупинений клієнт може скасувати призупинення. |
| Ви перепродаєте реселерам з доступом до хоста | Так, і це погано. |
Якщо ви в другому чи третьому рядку й застосування нагадувань має значення, використовуйте панель зі справжнім прапорцем призупинення. У Pelican він є, і призупинений сервер там лишається призупиненим незалежно від того, хто ввійде.
Проміжний шлях, якщо ви хочете лишитися на PufferPanel: припиняйте раніше. Оскільки призупинення мʼяке, вважайте його стадією попередження, а не стадією застосування, і перенесіть справжнє застосування на видалення (з політикою зберігання й резервною копією, зробленою спершу, оголошеними наперед). Це рішення продукту, а не технічне.
Правило, що формує все: ніщо не миттєве
Ваша панель живе у вашій власній мережі, а розсудлива платформа дістається до неї через агента, що зʼєднується назовні, без вхідного порту, без діри у фаєрволі. Наслідок неминучий: кінцева точка, яка змінює машину, не може відповісти результатом. Вона відповідає, що замовлення прийнято:
POST /v1/servers/{serverId}/actions/suspend
Authorization: Bearer pvk_...
Idempotency-Key: dunning-inv-10482{
"command": {
"id": "cmd_...",
"kind": "game.suspend",
"status": "pending"
}
}202 Accepted, а не 200. Далі ви читаєте цю команду, доки її статус не стане остаточним: done, failed, timed_out чи cancelled. Невдала команда несе власний код помилки агента з його аргументами. Читання інше: інвентар, адреса чи рахунок відповідають одразу, бо це надходить із бази даних, а не з вашого хоста.
Проєктуйте свої гачки нагадувань довкола цього. Гачок, який вважає «API повернув відповідь» тим самим, що «роботу виконано», повідомить про успішне призупинення, яке ніколи не сталося, рівно того дня, коли це мало значення.
Повторюйте безпечно
Усе, що щось створює, приймає заголовок Idempotency-Key вашого власного виготовлення. Повторіть той самий запит із тим самим значенням, і ви отримаєте назад перший результат, а не другий сервер. Привʼязуйте його до чогось стабільного з вашого боку (ID рахунку, ID послуги, стадія нагадування), бо повторені вебхуки та пʼятнадцятихвилинні cron нормальні, і обидва мають бути нешкідливими. Повторне використання того значення для іншого запиту відхиляється навмисно: ключ, що означає дві речі, не означає нічого.
Дієслова та коли вони дозволені
Ігровий сервер приймає шість дій через API: start · stop · restart · kill · suspend · resume, які охороняє поточний стан сервера:
| Дія | Дозволено зі стану |
|---|---|
| start | stopped, error, unknown |
| stop / restart / kill | running, error, unknown |
| suspend | running, stopped, installing, error, unknown |
| resume | suspended |
| reinstall | running, stopped, error |
Ви можете призупинити сервер, який уже зупинено, і це навмисно: застосування, якого можна уникнути натисканням «зупинити», застосуванням не є. suspend зі стану installing підпорядковується тій самій логіці: скасування, яке припадає на середину встановлення, не повинно чекати, доки встановлення завершиться.
Замовлення веде тариф, і так має бути
На деяких панелях замовлення можна зібрати вручну. У PufferPanel ви фактично не можете, і причина структурна: PufferPanel вимагає повного визначення шаблону вбудовано при створенні сервера. Немає «зроби один із шаблону X за посиланням», тож визначення має надходити з каталогу. Ігровий тариф несе назву шаблону та ліміти ресурсів; замовлення вказує на тариф. Якщо ви будуєте власний міст, ви однаково зрештою збудуєте цей каталог.
Дві виміряні деталі, на яких легко спіткнутися:
- Шаблони спільноти за замовчуванням націлені на середовище хоста, якому потрібні бінарники, яких немає на свіжому хості панелі. Перемкніться на docker-варіант шаблону, інакше кожне замовлення зазнає невдачі з помилкою про відсутній бінарник, що читається як помилка платформи.
- Видалення спершу зупиняє сервер. Демон відмовляється видаляти запущений контейнер; видалення проти запущеного сервера повертає 500.
Чого тут навмисно немає
- Немає білінгу за використанням. Кінцева точка статистики PufferPanel повідомляє лише відсоток CPU й памʼять (ні диска, ні мережі, ні часу безперебійної роботи). Два з чотирьох стандартних графіків ігрового сервера були б назавжди порожніми, тож графіки використання для цього провайдера вимкнено. Вимірюваний білінг неможливий на даних, яких не існує.
- Немає консолі в Огляді. Консоль PufferPanel побудована на опитуванні, а не на живому терміналі; рукостискання WebSocket за специфікацією на
/consoleповертає 200 JSON замість 101. Ваші клієнти отримують консоль у самому PufferPanel. - Немає розміщення з урахуванням потужності. PufferPanel виставляє свої вузли, але не їхню памʼять, диск чи CPU, тож панель із багатьма вузлами обирається за порядком назв, а не за вільним місцем. Планувальником потужності є ви.
- Немає зміни плану одним викликом. Заміна тарифу означає перевстановлення, з наслідками для даних клієнта, які це передбачає.
- Немає циклу звіряння інвентаря. Синхронізація
_ListAccountsу WHMCS припиняє будь-яку послугу, якої немає у відповіді, а «немає» має невинні причини: вужча область дії API, учасник, обмежений частиною інвентаря, обмеження частоти, коротка сторінка, за курсором якої не пішли. Кожна з них видалила б машини клієнтів.
Як робити це з WHMCS замість коду
Якщо ви вже користуєтеся WHMCS, Provibr постачає модуль провізіювання у вигляді звичайного zip, який ви встановлюєте самі. Один продукт WHMCS указує на один тариф Provibr; звичайний потік замовлень WHMCS робить створення, призупинення, відновлення й припинення. Два рішення в ньому варто скопіювати навіть у власний міст:
Доставка, яка ще триває, зараховується як успіх. Якщо бюджет очікування вичерпується, поки інсталятор працює, модуль повідомляє про успіх: замовлення таки прийнято, а у WHMCS немає статусу «встановлюється» (Pending там означає ще нічого не сталося, що неправда). З командою, яка по-справжньому зазнає невдачі, все інакше: послуга лишається Pending, і адміністратор бачить чому.
Сервер, якого вже немає, означає успішне припинення. 404 означає кілька речей одночасно (невідомий ID, інший обліковий запис, невидимий цьому учаснику, уже видалено), і для гачка припинення правильна дія однакова в усіх них: прибирати вже нічого.
Підрахунок потужності та як він зустрічається з нагадуваннями
Біллінг платформи рахує потужність, а не використання, з одним правилом, що ловить усіх у перший місяць: кожен сервер рахується, працює він чи ні. Не рахується лише призупинений, а також видалений: зупинка машини не звільняє місця.
Це добре збігається з нагадуваннями: клієнт, якого ви призупиняєте, перестає враховуватися, поки призупинений, і рахується знову, коли він платить, а ви відновлюєте.
Запуск PufferPanel поруч з усім іншим
Вам не обовʼязково обирати одну панель. Provibr охоплює свої панелі керування, гіпервізори та ігрові панелі в одному Огляді, з одним API та одним числом потужності.
POST /v1/servers/{id}/actions/suspend робить те саме, чи то під ним сервер Pelican, сервер PufferPanel, чи хостинговий обліковий запис DirectAdmin. Відмінності живуть у провайдері, а не у вашому інтеграційному коді, а там, де провайдер справді чогось не може, ви отримуєте відмову з назвою відсутньої можливості, а не мовчазну бездію.