
## Переключить режим

`PATCH /v1/infra/servers/:id/mode`

Переключает сервер между режимами `BLACKHOLE` (всё закрыто фаерволом, доступ только через HTTPS-субдомен) и `OPEN` (прямой доступ по IP, SSH на порту 22 открыт). При переходе в `OPEN` фаервол полностью снимается и генерируется SSH-пароль. При обратном переходе фаервол восстанавливается и пароль удаляется. Переход в `OPEN` запрещён, если платформа (флаг `openModeEnabled`) или портал (политика `allowOpenMode`) не разрешают его.

> **OPEN отключает защиту Black Hole.** Сервер становится доступен из интернета по IP. Все Deploy API эндпоинты (`/exec`, `/upload`, `/logs`, `/deploy`) работают только в BLACKHOLE-режиме — в OPEN они вернут ошибку.

## Параметры

| Параметр | В | Тип | Обяз. | Описание |
|----------|---|-----|:-----:|----------|
| `id` | path | string (UUID) | да | ID сервера |

## Поля запроса (body)

| Поле | Тип | Обяз. | Описание |
|------|-----|:-----:|----------|
| `mode` | string | **да** | Целевой режим: `OPEN` или `BLACKHOLE` |

## Примеры

### curl — личный ключ

```bash
# BLACKHOLE → OPEN
curl -X PATCH https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/mode \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode": "OPEN"}'

# OPEN → BLACKHOLE (вернуть защиту)
curl -X PATCH https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/mode \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode": "BLACKHOLE"}'
```

### curl — OAuth-приложение

```bash
curl -X PATCH https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/mode \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode": "OPEN"}'
```

### JavaScript — личный ключ

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/mode`,
  {
    method: 'PATCH',
    headers: {
      'X-Api-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ mode: 'OPEN' }),
  }
)
const { data } = await res.json()
if (data.sshPassword) console.log(`Новый SSH-пароль: ${data.sshPassword}`)
```

### JavaScript — OAuth-приложение

```javascript
await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/mode`,
  {
    method: 'PATCH',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ mode: 'BLACKHOLE' }),
  }
)
```

## Поля ответа

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | Всегда `true` при успехе |
| `data.mode` | string | Новый режим (`OPEN` или `BLACKHOLE`) |
| `data.ip` | string \| null | IP сервера (не меняется при переключении) |
| `data.sshPassword` | string \| null | Сгенерированный SSH-пароль. Отдаётся только при переходе в `OPEN`. При переходе в `BLACKHOLE` — `null` |

## Пример ответа

Переход BLACKHOLE → OPEN:

```json
{
  "success": true,
  "data": {
    "mode": "OPEN",
    "ip": "178.154.230.106",
    "sshPassword": "rT9xQ2mKaPzFHyB3"
  }
}
```

Переход OPEN → BLACKHOLE:

```json
{
  "success": true,
  "data": {
    "mode": "BLACKHOLE",
    "ip": "178.154.230.106",
    "sshPassword": null
  }
}
```

## Пример ответа при ошибке

403 — переход в `OPEN` запрещён политикой портала:

```json
{
  "success": false,
  "error": {
    "code": "OPEN_MODE_NOT_ALLOWED",
    "message": "OPEN mode is not allowed by portal policy",
    "userMessage": "Режим OPEN не разрешён политикой портала. Администратор включает его в Настройки → Создание. Пока используйте Deploy API (exec/upload/logs)."
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 400 | `INVALID_MODE` | `mode` не равен `OPEN` или `BLACKHOLE` |
| 400 | `SAME_MODE` | Сервер уже в запрошенном режиме |
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 401 | `INVALID_API_KEY` | Неверный или просроченный API-ключ |
| 403 | `OPEN_MODE_DISABLED` | Режим OPEN отключён на платформе (флаг `openModeEnabled`). Обратитесь к администратору платформы. Ответ несёт `error.userMessage` — готовый текст на языке пользователя |
| 403 | `OPEN_MODE_NOT_ALLOWED` | Режим OPEN запрещён политикой портала (флаг `allowOpenMode`). Обратитесь к администратору портала. Ответ несёт `error.userMessage`. Исключение — вторая ветка этого же кода с сообщением `Portal context required`: она приходит без `userMessage` |
| 403 | `INFRA_FORBIDDEN_FOR_COWORK_KEY` | Вызов сделан ключом Cowork/Code — такой ключ работает только с данными, изменяющие операции ему закрыты. Что делать — [Проектный ключ для деплоя](/docs/cowork/deploy-key) |
| 403 | `SERVER_ROLE_FORBIDDEN` | Вы состоите в команде разработки этого сервера с ролью «Разработчик», а операция открыта роли «Администратор». В `error.hint` придут ваша роль, требуемый порог и перечень открытых вам вызовов. Разбор ролей — [Список серверов](/docs/infra/servers/list) |
| 404 | `NOT_FOUND` | Сервер не существует, удалён или привязан к другому API-ключу, и вы не состоите в его команде разработки |
| 429 | `RATE_LIMITED` | Превышен общий лимит запросов платформы |
| 502 | `PROVIDER_ERROR` | Облачный провайдер вернул ошибку при смене конфигурации сети |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Известные особенности

- **Порядок разрешения OPEN** (оба уровня должны пропустить): сначала платформенный флаг `openModeEnabled` — **платформенный админ тоже не обходит эту проверку**. Затем портальная политика `allowOpenMode` — **платформенный админ обходит её**. Только если оба разрешают, переход в OPEN возможен.
- **IP не меняется при переключении.** Облачная виртуальная машина остаётся той же — меняются только правила iptables и SSH-конфигурация.
- **Туннель (`blackholeStatus`) сохраняется в OPEN-режиме.** Агент Black Hole продолжает работать, HTTPS-субдомен остаётся рабочим — просто фаервол больше не блокирует внешний трафик. Однако Deploy API всё равно откажет: он требует именно BLACKHOLE.
- **`accessPolicy` не применяется в OPEN.** В OPEN защита строится на SSH-ключах и iptables (который снят). Политика HTTPS-субдомена фактически не работает. При переключении значение `accessPolicy` сохраняется в базе — и снова начнёт действовать после возврата в BLACKHOLE.

## Смотрите также

- [SSH-данные](./ssh.md)
- [Политика доступа](./access-policy.md)
- [Deploy API](/docs/infra/deploy)
- [Получить сервер](/docs/infra/servers/get)
