Files
ospab.host/Manuals/FOR_MAIN_SITE_DEVELOPER.md
Georgiy Syralev d45baf2260 sitemap и тд
2025-11-01 12:29:46 +03:00

13 KiB
Raw Blame History

Инструкция для разработчика главного сайта

📌 Контекст

Главный сайт (ospab.host):

  • Каталог тарифов VPS
  • Система оплаты
  • Создание/удаление VPS на хостинге (Proxmox, VMware и т.д.)

Панель управления (ospab-panel):

  • Клиентская зона для управления своими VPS
  • Получает данные о VPS с главного сайта через API
  • Пользователи видят актуальный статус своих серверов

🔗 Как они соединяются?

Главный сайт                    Панель управления
    │                                    │
    ├─ Пользователь платит           ←──┤
    ├─ Создается VPS на Proxmox     
    │                                    │
    └─ POST /api/vps/sync ──────────────→ Сохраняет в БД
       (отправляет данные)               │
                                    Клиент видит VPS

🚀 Что нужно сделать на главном сайте

Шаг 1: Установить переменные окружения

Добавить в .env:

# URL Панели управления OSPAB
OSPAB_PANEL_URL=https://panel.ospab.host
# При локальной разработке:
# OSPAB_PANEL_URL=http://localhost:5050

# API ключ для синхронизации VPS
# ⚠️ ДОЛЖЕН СОВПАДАТЬ с VPS_SYNC_API_KEY на Панели!
VPS_SYNC_API_KEY=your_secret_api_key_here_min_32_chars_change_this

Шаг 2: Получить значение VPS_SYNC_API_KEY

Вариант 1: Сгенерировать свой ключ

# Linux/Mac
openssl rand -hex 16
# Результат: 6c8a4f2e9b1d3c5a7f9e2b4c6a8d0f1e
# Добавить prefix и получится: 6c8a4f2e9b1d3c5a7f9e2b4c6a8d0f1e6c8a4f2e

Вариант 2: Использовать готовый ключ

  • Свяжитесь с администратором панели
  • Он установит ключ на своей стороне в .env

Шаг 3: Создать сервис для синхронизации VPS

Создайте файл services/ospab-vps-sync.ts:

/**
 * VPS Sync Service - синхронизация с Панелью управления OSPAB
 * Отправляет информацию о VPS через REST API
 */

interface VPSSyncData {
  user_id: number;      // ID пользователя в системе OSPAB
  name: string;         // Имя VPS (например: web-server-01)
  cpu: number;          // Количество ядер (1, 2, 4, 8, etc)
  ram: number;          // ОЗУ в GB (1, 2, 4, 8, 16, 32, etc)
  disk: number;         // Диск в GB (10, 50, 100, 500, 1000, etc)
  os: string;           // Операционная система (Ubuntu 22.04 LTS, CentOS 7, Debian 11, etc)
  hypervisor?: string;  // Тип гипервизора (proxmox по умолчанию, может быть vmware, hyperv, kvm, xen)
}

class VPSSyncService {
  private panelUrl: string;
  private apiKey: string;

  constructor() {
    this.panelUrl = process.env.OSPAB_PANEL_URL || '';
    this.apiKey = process.env.VPS_SYNC_API_KEY || '';

    if (!this.panelUrl || !this.apiKey) {
      throw new Error('Missing OSPAB_PANEL_URL or VPS_SYNC_API_KEY environment variables');
    }
  }

  /**
   * Создать новый VPS на Панели управления
   * Вызывается сразу после создания VPS на хостинге
   */
  async createVPS(data: VPSSyncData) {
    console.log(`[VPS Sync] Creating VPS: ${data.name} for user ${data.user_id}`);

    const response = await fetch(`${this.panelUrl}/api/vps/sync`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': this.apiKey,
      },
      body: JSON.stringify({
        action: 'create',
        vps: {
          user_id: data.user_id,
          name: data.name,
          status: 'creating',
          cpu: data.cpu,
          ram: data.ram * 1024, // 🔴 ВАЖНО: конвертируем GB в MB!
          disk: data.disk,
          os: data.os,
          hypervisor: data.hypervisor || 'proxmox',
        },
      }),
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`[VPS Sync] Create failed: ${error.message}`);
    }

    const result = await response.json();
    console.log(`[VPS Sync] VPS created successfully, ID: ${result.vps.id}`);
    return result.vps;
  }

  /**
   * Обновить статус VPS
   * Вызывается после изменения статуса (например, VPS запущен, остановлен, и т.д.)
   */
  async updateVPSStatus(vpsId: number, status: string) {
    console.log(`[VPS Sync] Updating VPS ${vpsId} status to: ${status}`);

    const response = await fetch(`${this.panelUrl}/api/vps/sync`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': this.apiKey,
      },
      body: JSON.stringify({
        action: 'update',
        vps: {
          id: vpsId,
          status: status,
        },
      }),
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`[VPS Sync] Update failed: ${error.message}`);
    }

    const result = await response.json();
    console.log(`[VPS Sync] VPS ${vpsId} status updated to: ${status}`);
    return result.vps;
  }

  /**
   * Удалить VPS
   * Вызывается когда клиент отменил услугу
   */
  async deleteVPS(vpsId: number) {
    console.log(`[VPS Sync] Deleting VPS ${vpsId}`);

    const response = await fetch(`${this.panelUrl}/api/vps/sync`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': this.apiKey,
      },
      body: JSON.stringify({
        action: 'delete',
        vps: {
          id: vpsId,
        },
      }),
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`[VPS Sync] Delete failed: ${error.message}`);
    }

    console.log(`[VPS Sync] VPS ${vpsId} deleted successfully`);
    return true;
  }
}

export default new VPSSyncService();

Шаг 4: Использовать сервис в основном коде

Пример в Express маршруте (создание VPS):

import vpsSync from './services/ospab-vps-sync';

router.post('/api/vps/create', async (req, res) => {
  try {
    const { user_id, name, cpu, ram, disk, os } = req.body;

    // 1⃣ Создать VPS на хостинге (Proxmox, VMware, etc)
    console.log('Creating VPS on Proxmox...');
    const proxmoxVPS = await createVPSOnProxmox({
      name,
      cpu,
      ram: ram * 1024, // GB to MB for Proxmox
      disk,
      os,
    });

    console.log('VPS created on Proxmox:', proxmoxVPS.id);

    // 2⃣ Синхронизировать с Панелью управления
    console.log('Syncing with OSPAB Panel...');
    const panelVPS = await vpsSync.createVPS({
      user_id,
      name,
      cpu,
      ram,
      disk,
      os,
    });

    console.log('VPS synced with panel, ID:', panelVPS.id);

    // 3⃣ Обновить статус когда VPS готов (через несколько минут)
    // Рекомендуется использовать job queue (bull, rsmq, etc)
    setTimeout(async () => {
      try {
        await vpsSync.updateVPSStatus(panelVPS.id, 'running');
        console.log('VPS status updated to running');
      } catch (err) {
        console.error('Failed to update VPS status:', err);
      }
    }, 60000); // 1 минута

    res.json({
      success: true,
      vps_id: panelVPS.id,
      message: 'VPS created successfully',
    });
  } catch (error) {
    console.error('Error creating VPS:', error);
    res.status(500).json({
      success: false,
      message: error.message,
    });
  }
});

Пример для удаления VPS:

router.post('/api/vps/delete', async (req, res) => {
  try {
    const { vps_id, proxmox_id } = req.body;

    // 1⃣ Удалить с хостинга
    await deleteVPSFromProxmox(proxmox_id);
    console.log('VPS deleted from Proxmox');

    // 2⃣ Удалить из Панели
    await vpsSync.deleteVPS(vps_id);
    console.log('VPS deleted from panel');

    res.json({
      success: true,
      message: 'VPS deleted successfully',
    });
  } catch (error) {
    console.error('Error deleting VPS:', error);
    res.status(500).json({
      success: false,
      message: error.message,
    });
  }
});

⚠️ Важные моменты

1. Конвертация единиц

Параметр Главный сайт Панель Конвертация
RAM GB MB ×1024
Disk GB GB ×1
CPU cores cores ×1
// ❌ НЕПРАВИЛЬНО (забыли конвертировать)
vpsSync.createVPS({ ram: 8 }); // Панель получит 8 MB вместо 8 GB

// ✅ ПРАВИЛЬНО
vpsSync.createVPS({ ram: 8 * 1024 }); // Панель получит 8192 MB = 8 GB

2. User ID

user_id должен быть ID из SSO системы Панели управления:

// ❌ НЕПРАВИЛЬНО (локальный ID главного сайта)
const userId = req.user.id; // 123 в БД главного сайта

// ✅ ПРАВИЛЬНО (ID из SSO)
const userId = req.user.sso_id; // 5 в системе OSPAB Panel

3. Обработка ошибок

try {
  await vpsSync.createVPS(vpsData);
} catch (error) {
  // Важно логировать ошибку!
  console.error('Failed to sync VPS:', error.message);
  
  // Но НЕ прерывать создание VPS на хостинге
  // VPS может быть создан, даже если панель недоступна
  
  // Вариант: сохранить попытку синхронизации в БД
  // и повторить попытку позже через job queue
}

4. Статусы VPS

// Возможные статусы
'creating'    // VPS создается
'running'     // VPS запущен и готов
'stopped'     // VPS остановлен
'suspended'   // VPS приостановлен (например, за неоплату)

🧪 Тестирование

Локальное тестирование

  1. Запустить Панель управления локально:
go run ./cmd/server/main.go
# Будет доступна на http://localhost:5050
  1. В .env главного сайта:
OSPAB_PANEL_URL=http://localhost:5050
VPS_SYNC_API_KEY=your_secret_api_key_here_min_32_chars_change_this
  1. Тестировать создание VPS через API главного сайта

Тест через curl

curl -X POST http://localhost:5050/api/vps/sync \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_secret_api_key_here_min_32_chars_change_this" \
  -d '{
    "action": "create",
    "vps": {
      "user_id": 5,
      "name": "test-vps",
      "cpu": 2,
      "ram": 2048,
      "disk": 50,
      "os": "Ubuntu 22.04 LTS",
      "status": "creating",
      "hypervisor": "proxmox"
    }
  }'

Ожидаемый ответ:

{
  "status": "success",
  "message": "VPS synced successfully",
  "vps": {
    "id": 1,
    "name": "test-vps",
    "status": "creating",
    "created_at": "2025-10-27T10:30:00Z"
  }
}

📚 Дополнительно

  • Полная документация: CLIENT_VPS_INTEGRATION.md
  • Примеры кода: VPS_SYNC_EXAMPLES.md
  • Быстрый старт: VPS_SYNC_QUICK_START.md

Часто задаваемые вопросы

Q: Что если панель недоступна?
A: VPS все равно создастся на хостинге. Добавьте retry logic и job queue (bull/rsmq) для повторных попыток синхронизации.

Q: Может ли быть несовпадение данных?
A: Да, если синхронизация сорвалась. Рекомендуется периодически проверять консистентность и добавить маршрут для ручной синхронизации.

Q: Как обновлять IP адрес VPS?
A: Текущий API синхронизирует только основные параметры. IP адрес может быть добавлен позже через расширение API.

Q: Нужна ли двусторонняя синхронизация?
A: Нет, панель только получает данные. Главный сайт - источник истины.


Вопросы? Смотрите документацию выше или свяжитесь с разработчиком панели.