# Fission Console API — Руководство пользователя > Версия: актуальна для модернизированного Fission с мультитенантностью (ngcloud). --- ## Базовый URL ``` https://fission.kube5s.ru/console/api ``` --- ## Аутентификация ### Где взять токен Сервер поддерживает два типа токенов — определяет автоматически по форме: | Форма токена | Тип | Описание | |---|---|---| | JWT (три части через `.`) | **Production** | JWT из личного кабинета NUBES (Профиль → Токены). Валидируется через Deck API облака | | Любая строка ≥ 6 символов | **Demo** | Любой произвольный логин — без внешней проверки. Удобно для разработки и тестирования | | Строка < 6 символов | — | 401 | **Production (NUBES):** JWT-токен берётся в личном кабинете NUBES → Профиль → Токены. **Demo:** любая строка ≥ 6 символов — например `myuser@example.com` или `dev-user-1`. ### Передача токена Два способа — оба равнозначны: ```http X-Auth-Token: <токен> ``` ```http Authorization: Bearer <токен> ``` ### POST /auth Проверка токена и получение информации о своём namespace. ```bash curl -X POST https://fission.kube5s.ru/console/api/auth \ -H "Content-Type: application/json" \ -d '{"token": "myuser@example.com", "env": "test"}' ``` **Параметры:** | Поле | Описание | |---|---| | `token` | Токен (JWT или demo-строка) | | `env` | Стенд: `prod`, `dev`, `test` (только для JWT; по умолчанию `test`) | **Ответ 200:** ```json { "ok": true, "env": "test", "namespace": "fission-a3f9c1b2d4e6f8a1", "email": "user@example.com" } ``` **Ошибки:** | Код | Причина | |-----|---------| | 400 | Тело не JSON или `token` пустой | | 401 | Токен < 6 символов или JWT не прошёл валидацию в Deck API | | 405 | GET вместо POST | > **Namespace детерминирован**: `fission-` + hex(SHA256(sub)[:8]) — одинаковый токен → всегда один namespace. > Namespace и RBAC создаются автоматически при первом обращении. --- ## Мультитенантность ★ КЛЮЧЕВОЕ ОТЛИЧИЕ - Каждый пользователь работает в **изолированном K8s namespace**: `fission-` - Все операции (создание, список, вызов, удаление) **автоматически ограничены своим namespace** - Указать namespace вручную **невозможно** - Функции другого пользователя **не видны и не доступны** — любая операция над чужим объектом возвращает **404** (не 403, чтобы не раскрывать факт существования) - **Routes изолированы**: функции разных пользователей с одинаковым именем получают разные HTTP-маршруты ### Квоты (применяются автоматически, значения по умолчанию) | Ресурс | Лимит | |--------|-------| | Функции (`count/functions.fission.io`) | 20 | | Пакеты (`count/packages.fission.io`) | 40 | | HTTP Triggers (`count/httptriggers.fission.io`) | 20 | | Pods | 30 | | CPU requests (суммарно) | 1 | | CPU limits (суммарно) | 12 | | RAM requests (суммарно) | 2 Gi | | RAM limits (суммарно) | 6 Gi | > Значения настраиваются env vars (`QUOTA_REQ_CPU`, `QUOTA_PODS`, и т.д.) без пересборки. --- ## Функции ### POST /functions — Создать функцию из кода (JSON) ```bash curl -X POST https://fission.kube5s.ru/console/api/functions \ -H "X-Auth-Token: user@domain.com" \ -H "Content-Type: application/json" \ -d '{ "name": "my-fn", "language": "nodejs", "code": "module.exports = async function(ctx) { return { status: 200, body: \"hello\" }; }" }' ``` **Параметры запроса:** | Поле | Тип | Обязательно | Описание | |------|-----|:-----------:|---------| | `name` | string | ✓ | Имя функции (см. правила ниже) | | `language` | string | ✓ | Среда выполнения: `nodejs`, `python`, `go`, `php`, `ruby` | | `code` | string | ✓ | Исходный код (строка). Максимум 1 MB | | `entrypoint` | string | — | Точка входа (по умолчанию — зависит от языка) | | `route` | string | — | HTTP-маршрут (по умолчанию `//`) | | `methods` | []string | — | HTTP-методы (по умолчанию `["GET"]`) | | `timeout` | int64 | — | Таймаут функции в секундах | | `ttl` | string | — | Время жизни функции: `15m`, `1h`, `2d` и т.д. ★ | **Правила именования (`name`):** - Только строчные буквы, цифры, дефис - Не начинается и не заканчивается дефисом - Максимум **57 символов** **Ответ 201:** ```json { "name": "my-fn", "package": "my-fn-pkg", "httptrigger": "my-fn-route", "route": "/a3f9c1b2d4e6/my-fn", "expires_at": null } ``` > `expires_at` — время удаления функции (RFC3339), `null` если TTL не задан. **Ошибки:** | Код | Причина | |-----|---------| | 400 | Нет `name`/`language`/`code`, невалидное имя, неизвестный язык, код > 1 MB, невалидный TTL | | 409 | Функция с таким именем уже существует у этого пользователя | --- ### POST /functions — Создать функцию из zip-архива (multipart) Альтернативный способ: передать архив напрямую при создании функции. ```bash curl -X POST https://fission.kube5s.ru/console/api/functions \ -H "X-Auth-Token: user@domain.com" \ -F "name=my-fn" \ -F "language=python" \ -F "entrypoint=main.handler" \ -F "archive=@my-function.zip" ``` **Параметры формы (multipart/form-data):** | Поле | Тип | Обязательно | Описание | |------|-----|:-----------:|---------| | `name` | string | ✓ | Имя функции | | `language` | string | ✓* | Язык (`python`, `nodejs`, `go`, `php`, `ruby`) — или `environment` | | `environment` | string | ✓* | Явное имя environment (вместо `language`) | | `archive` | file | ✓ | zip-архив с кодом. Максимум 100 KB | | `entrypoint` | string | — | Точка входа | | `route` | string | — | HTTP-маршрут | | `methods` | string | — | HTTP-методы через запятую (`GET,POST`) | | `timeout` | string | — | Таймаут в секундах | | `ttl` | string | — | Время жизни: `15m`, `1h`, `2d` и т.д. | > Архив должен быть валидным zip (magic bytes `PK`). Максимальный суммарный распакованный размер — 100 KB (защита от zip bomb). **Ответ 201:** ```json { "name": "my-fn", "namespace": "fission-a3f9c1b2d4e6f8a1", "environment": "python-env", "route": "/a3f9c1b2d4e6/my-fn", "source_type": "archive" } ``` --- ### GET /functions — Список функций ```bash curl https://fission.kube5s.ru/console/api/functions \ -H "X-Auth-Token: user@domain.com" ``` **Ответ 200** — массив сырых K8s объектов типа `Function`. Новый пользователь → `[]`. Возвращает **только функции текущего пользователя**. --- ### GET /functions/{name} — Описание функции ```bash curl https://fission.kube5s.ru/console/api/functions/my-fn \ -H "X-Auth-Token: user@domain.com" ``` **Ответ 200:** ```json { "name": "my-fn", "namespace": "fission-a3f9c1b2d4e6f8a1", "environment": "nodejs-env", "package": "my-fn-pkg", "entrypoint": "main", "timeout": 60, "created_at": "2026-05-01T10:00:00Z", "updated_at": "2026-05-01T12:00:00Z", "code": "module.exports = async function(ctx) { ... }", "source_type": "code", "archive_filename": "", "route": "/a3f9c1b2d4e6/my-fn", "methods": ["GET", "POST"], "raw": {} } ``` > `code` — исходный код (если хранится как literal). Для функций из архива может быть пустым. > `source_type` — `"code"` или `"archive"`. > `raw` — полный K8s объект Function. **Ошибки:** | Код | Причина | |-----|---------| | 404 | Функция не существует или принадлежит другому пользователю | --- ### POST /functions/{name}/invoke — Вызов функции ```bash curl -X POST https://fission.kube5s.ru/console/api/functions/my-fn/invoke \ -H "X-Auth-Token: user@domain.com" \ -H "Content-Type: application/json" \ -d '{}' ``` **Ответ 200:** ```json { "status": 200, "latency_ms": 42, "response_raw": "hello" } ``` > `response_raw` — тело ответа функции как строка. > `status` — HTTP-статус ответа функции. > `latency_ms` — время выполнения в миллисекундах. > Cold start (первый вызов после создания) может занять **10-60 секунд** — Pod создаётся и прогревается. Последующие вызовы быстрые. **Ошибки:** | Код | Причина | |-----|---------| | 404 | Функция не существует или принадлежит другому пользователю | | 502 | Fission router недоступен или функция завершилась с timeout | --- ### PUT /functions/{name}/code — Обновить код функции ★ Обновляет код существующей функции. Создаётся новый Package, executor подхватывает его при следующем вызове. ```bash curl -X PUT https://fission.kube5s.ru/console/api/functions/my-fn/code \ -H "X-Auth-Token: user@domain.com" \ -H "Content-Type: application/json" \ -d '{ "code": "module.exports = async function(ctx) { return { status: 200, body: \"v2\" }; }" }' ``` **Параметры:** | Поле | Тип | Обязательно | Описание | |------|-----|:-----------:|---------| | `code` | string | ✓ | Новый исходный код | | `timeout` | int64 | — | Новый таймаут в секундах | **Ответ 200:** ```json { "updated": true, "package": "my-fn-pkg-xxxxxx" } ``` **Ошибки:** | Код | Причина | |-----|---------| | 400 | `code` пустой или только пробелы | | 404 | Функция не существует или принадлежит другому пользователю | --- ### PUT /functions/{name}/archive — Обновить архив функции ★ Обновляет функцию новым zip-архивом (multipart/form-data, поле `archive`). ```bash curl -X PUT https://fission.kube5s.ru/console/api/functions/my-fn/archive \ -H "X-Auth-Token: user@domain.com" \ -F "archive=@my-function-v2.zip" ``` **Ответ 200:** ```json { "updated": true, "package": "my-fn-pkg-xxxxxx" } ``` --- ### PUT /functions/{name}/timeout — Обновить таймаут функции ★ Обновляет только таймаут (и опционально entrypoint) без замены кода или архива. ```bash curl -X PUT https://fission.kube5s.ru/console/api/functions/my-fn/timeout \ -H "X-Auth-Token: user@domain.com" \ -H "Content-Type: application/json" \ -d '{"timeout": 120}' ``` **Параметры:** | Поле | Тип | Описание | |------|-----|---------| | `timeout` | int64 | Новый таймаут в секундах | | `entrypoint` | string | Новая точка входа (опционально) | **Ответ 200:** ```json { "updated": true, "timeout": 120 } ``` --- ### DELETE /functions/{name} — Удалить функцию ```bash curl -X DELETE https://fission.kube5s.ru/console/api/functions/my-fn \ -H "X-Auth-Token: user@domain.com" ``` **Ответ 200:** ```json { "deleted": true, "name": "my-fn", "package": "my-fn-pkg" } ``` > Удаляются также связанные HTTPTrigger, TimeTrigger и Package. > Архив в S3 удаляется асинхронно. > Если язык больше не используется ни одной функцией — environment Pod'ы убираются автоматически. **Ошибки:** | Код | Причина | |-----|---------| | 404 | Функция не существует или принадлежит другому пользователю | > Повторное удаление той же функции → **404**. --- ## Прямой вызов по route — GET|POST /fn/{route} Вызов функции напрямую по HTTP-маршруту без обёртки invoke. Ответ проксируется как есть — без JSON-обёртки. ```bash curl https://fission.kube5s.ru/fn/a3f9c1b2d4e6/my-fn \ -H "X-Auth-Token: user@domain.com" ``` > Используйте этот endpoint когда нужно получить чистый HTTP-ответ функции, а не JSON-обёртку с `response_raw`. > Метод запроса (GET/POST/…) проксируется без изменений. --- ## Time Triggers (расписание) ### GET /timetriggers — Список ```bash curl https://fission.kube5s.ru/console/api/timetriggers \ -H "X-Auth-Token: user@domain.com" ``` Возвращает массив сырых K8s объектов TimeTrigger. ### POST /timetriggers — Создать ```bash curl -X POST https://fission.kube5s.ru/console/api/timetriggers \ -H "X-Auth-Token: user@domain.com" \ -H "Content-Type: application/json" \ -d '{ "name": "my-cron", "functionName": "my-fn", "cron": "*/5 * * * *" }' ``` **Параметры:** | Поле | Тип | Обязательно | Описание | |------|-----|:-----------:|---------| | `name` | string | ✓ | Имя trigger'а | | `functionName` | string | ✓ | Имя функции | | `cron` | string | ✓ | Cron-выражение (стандартный формат) | | `method` | string | — | HTTP-метод для вызова (по умолчанию `POST`) | | `subpath` | string | — | Дополнительный путь | **Ответ 201:** ```json { "name": "my-cron", "namespace": "fission-a3f9c1b2d4e6f8a1", "cron": "*/5 * * * *", "method": "POST", "subpath": "", "function": "my-fn", "raw": {} } ``` ### GET /timetriggers/{name} — Описание **Ответ 200** — та же структура что и при создании. ### PUT /timetriggers/{name} — Обновить **Ответ 200:** ```json { "updated": true, "trigger": { ...та же структура... } } ``` ### DELETE /timetriggers/{name} — Удалить **Ответ 200:** ```json { "deleted": true, "name": "my-cron" } ``` --- ## AI-линтер архивов ★ Проверяет zip-архив на синтаксические ошибки до деплоя. Не создаёт функцию. Поддерживаемые файлы: `.py`, `.js`, `.rb`, `.php`. ### POST /ai/lint-archive ```bash curl -X POST https://fission.kube5s.ru/console/api/ai/lint-archive \ -H "X-Auth-Token: user@domain.com" \ -F "archive=@my-function.zip" \ -F "entrypoint=main.handler" \ -F "language=python" ``` **Параметры формы:** | Поле | Описание | |------|---------| | `archive` | zip-архив (обязательно) | | `entrypoint` | Точка входа `module.function` — проверяется что файл и функция существуют в архиве | | `language` | Язык — проверяется что архив содержит файлы нужного расширения | **Ответ 200:** ```json { "ok": true, "results": [ {"file": "main.py", "ok": true}, {"file": "helper.py", "ok": false, "output": "SyntaxError: invalid syntax (helper.py, line 5)"}, {"file": "main.handler", "ok": true, "output": "entrypoint 'main.handler' найден"} ] } ``` > `ok: false` в корне объекта означает что хотя бы один файл не прошёл проверку. > `output` содержит вывод линтера — присутствует только при ошибке (для entrypoint — всегда). **Ошибки:** | Код | Причина | |-----|---------| | 400 | Нет поля `archive`, нет поддерживаемых файлов (.py/.js/.rb/.php) в архиве | | 413 | Архив > 100 KB или суммарный распакованный размер > 100 KB (zip bomb protection) | --- ## TTL — Время жизни функции ★ Функция может быть создана с ограниченным временем жизни. После истечения TTL функция удаляется автоматически. **Формат:** число + суффикс: `m` (минуты), `h` (часы), `d` (дни). **Примеры:** `15m`, `1h`, `2d`, `12h` ```bash curl -X POST .../functions \ -H "X-Auth-Token: user@domain.com" \ -H "Content-Type: application/json" \ -d '{ "name": "temp-fn", "language": "python", "code": "def main(event, context): return \"hi\"", "ttl": "1h" }' ``` В ответе будет поле `expires_at` (формат RFC3339): ```json { "name": "temp-fn", "package": "temp-fn-pkg", "httptrigger": "temp-fn-route", "route": "/...", "expires_at": "2026-05-06T14:00:00Z" } ``` Невалидные значения TTL (`0d`, `-1h`, `99z`, `abc`) → **400**. --- ## HTTP-коды — сводная таблица | Код | Значение | |-----|---------| | 200 | Успех (GET, DELETE, PUT) | | 201 | Объект создан (POST /functions, POST /timetriggers) | | 400 | Ошибка валидации параметров | | 401 | Не авторизован (нет токена или < 6 символов) | | 404 | Объект не найден (или чужой) | | 405 | Неверный HTTP-метод | | 409 | Конфликт (дубликат имени) | | 413 | Тело слишком большое (код > 1 MB, архив > 100 KB) | | 502 | Ошибка взаимодействия с Fission (router/executor недоступен) | **Формат ошибки:** ```json { "error": "описание ошибки" } ``` --- ## Поддерживаемые языки | `language` | Расширение файла | Entrypoint по умолчанию | |------------|-----------------|------------------------| | `python` | `.py` | `main.main` | | `nodejs` | `.js` | зависит от runtime | | `go` | `.go` | зависит от runtime | | `php` | `.php` | зависит от runtime | | `ruby` | `.rb` | зависит от runtime | --- ## Примеры сценариев ### Быстрый старт (inline-код) ```bash BASE="https://fission.kube5s.ru/console/api" TOKEN="myuser@example.com" # Создать функцию curl -X POST "$BASE/functions" \ -H "X-Auth-Token: $TOKEN" -H "Content-Type: application/json" \ -d '{"name":"hello","language":"python","code":"def main(event, context): return \"hello world\""}' # Вызвать curl -X POST "$BASE/functions/hello/invoke" \ -H "X-Auth-Token: $TOKEN" -H "Content-Type: application/json" -d '{}' # Обновить код curl -X PUT "$BASE/functions/hello/code" \ -H "X-Auth-Token: $TOKEN" -H "Content-Type: application/json" \ -d '{"code":"def main(event, context): return \"v2\""}' # Удалить curl -X DELETE "$BASE/functions/hello" -H "X-Auth-Token: $TOKEN" ``` ### Создать из архива напрямую ```bash curl -X POST "$BASE/functions" \ -H "X-Auth-Token: $TOKEN" \ -F "name=my-fn" \ -F "language=python" \ -F "entrypoint=main.handler" \ -F "archive=@my-fn.zip" ``` ### Проверить архив перед деплоем ```bash curl -X POST "$BASE/ai/lint-archive" \ -H "X-Auth-Token: $TOKEN" \ -F "archive=@my-fn.zip" \ -F "entrypoint=main.handler" \ -F "language=python" ``` ### Создать временную функцию (исчезнет через 30 минут) ```bash curl -X POST "$BASE/functions" \ -H "X-Auth-Token: $TOKEN" -H "Content-Type: application/json" \ -d '{"name":"temp-fn","language":"nodejs","code":"module.exports = async () => ({status:200,body:\"tmp\"})","ttl":"30m"}' ``` ### Настроить расписание ```bash # Вызывать my-fn каждые 5 минут curl -X POST "$BASE/timetriggers" \ -H "X-Auth-Token: $TOKEN" -H "Content-Type: application/json" \ -d '{"name":"my-cron","functionName":"my-fn","cron":"*/5 * * * *"}' ```