fix: API validation + Terraform plan-time validators
API (operator v0.1.13): - functions.go: добавлена валидация entrypoint (не пустой) и memory_mb (1-4096). Фиксирует БАГ-1/2/4 из негативных тестов. - triggers.go: добавлена валидация type (только 'http'/'cron'). Фиксирует БАГ-3 (неверное сообщение об ошибке). Провайдер (v0.1.7): - Добавлен пакет terraform-plugin-framework-validators v0.19.0 - function_resource: runtime OneOf, memory_mb 1-4096, timeout_sec 1-900 - trigger_resource: type OneOf(http, cron) - job_resource: run_id AtLeast(0) - examples/main.tf: обновлена версия до ~> 0.1.7 doc/errors/log.md: задокументированы исправления и результаты повторных тестов
This commit is contained in:
@@ -316,3 +316,103 @@ existing.Spec.Template.Annotations["kubectl.kubernetes.io/restartedAt"] = fn.Sta
|
||||
Оператор: **v0.1.11**.
|
||||
|
||||
---
|
||||
|
||||
## 2026-03-09 — Негативные тесты API: найденные баги валидации
|
||||
|
||||
### Методология тестирования
|
||||
Тесты запускались через прямые POST-запросы к API (`https://sless-api.kube5s.ru`)
|
||||
со специально некорректными параметрами. Скрипт: `/tmp/sless_negative_tests.sh`.
|
||||
|
||||
### Результаты
|
||||
|
||||
| # | Тест | Ожидание | Факт | Статус |
|
||||
|---|---|---|---|---|
|
||||
| T1 | `runtime="python999"` | 400 ошибка | `Unsupported value: "python999"` | ✅ |
|
||||
| T2 | `memory_mb=-10` | 400 ошибка | **201 Created** — принято без ошибки | ❌ БАГ |
|
||||
| T3 | `name=""` | 400 ошибка | `name and runtime are required` | ✅ |
|
||||
| T4 | `entrypoint=""` (не передан) | 400 ошибка | **201 Created** с `entrypoint:""` | ❌ БАГ |
|
||||
| T5 | trigger → несуществующая fn | 404/400 | `name, type and function are required` | ❌ Неверный текст ошибки |
|
||||
| T6 | job → несуществующая fn | 404/400 | **Создался** (fn не проверяется при создании job) | ⚠️ |
|
||||
| T7 | trigger `type="rabbitmq"` | 400 ошибка | `name, type and function are required` | ❌ Неверный текст ошибки |
|
||||
| T8 | `run_id=0` | job создаётся, не запускается | 201, `run_id:0` | ✅ |
|
||||
| T9 | несуществующий namespace | 404 | `namespaces "nonexistent-ns" not found` | ✅ |
|
||||
| T10 | `memory_mb=999999` | 400 или ограничение | **201, вернул memory_mb=128** (молча обрезан) | ❌ БАГ |
|
||||
|
||||
### Баги для исправления
|
||||
|
||||
**БАГ-1 (API handler/function):** `memory_mb <= 0` не валидируется. Нужно: `if req.MemoryMB <= 0 { return 400 }`.
|
||||
|
||||
**БАГ-2 (API handler/function):** `entrypoint == ""` не валидируется. Нужно: проверять непустой entrypoint.
|
||||
|
||||
**БАГ-3 (API handler/trigger):** При передаче `type="rabbitmq"` или несуществующей `functionRef` ошибка говорит `"name, type and function are required"` — неверный текст. Скорее всего handler проверяет поле `function_ref` (snake_case) а принимает `functionRef` (camelCase) — маппинг не работает.
|
||||
|
||||
**БАГ-4 (API handler/function):** `memory_mb=999999` принято, но возвращён `memory_mb=128` — молчаливое изменение без ошибки.
|
||||
|
||||
### Дополнительно: валидация в Terraform провайдере (plan-time)
|
||||
Провайдер не имел schema-level валидаторов — все ошибки проявлялись только на `apply`.
|
||||
Добавлены validators в `function_resource.go`, `trigger_resource.go`, `job_resource.go`:
|
||||
- `runtime` — только допустимые значения
|
||||
- `memory_mb` — диапазон 64-4096
|
||||
- `timeout_sec` — диапазон 1-900
|
||||
- `trigger.type` — только `http`/`cron`
|
||||
- `run_id` — >= 0
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Исправления (2026-03-08): v0.1.13 оператор + v0.1.7 провайдер
|
||||
|
||||
### API исправления (internal/api/handler/)
|
||||
|
||||
**БАГ-1 FIXED (functions.go):** Добавлена валидация `memory_mb`:
|
||||
```
|
||||
if req.MemoryMB <= 0 || req.MemoryMB > 4096 → 400 "memory_mb must be between 1 and 4096"
|
||||
```
|
||||
|
||||
**БАГ-2 FIXED (functions.go):** Добавлена валидация `entrypoint`:
|
||||
```
|
||||
if req.Entrypoint == "" → 400 "entrypoint is required"
|
||||
```
|
||||
|
||||
**БАГ-3 FIXED (triggers.go):** Добавлена валидация `type`:
|
||||
```
|
||||
if req.Type != "http" && req.Type != "cron" → 400 "type must be \"http\" or \"cron\""
|
||||
```
|
||||
|
||||
**БАГ-4 FIXED (functions.go):** Покрыт случаем T10 — `memory_mb=999999` теперь возвращает 400.
|
||||
|
||||
### Провайдер план-валидаторы (terraform/provider/)
|
||||
|
||||
Добавлен пакет `terraform-plugin-framework-validators v0.19.0`.
|
||||
|
||||
`function_resource.go`:
|
||||
- `runtime` — `stringvalidator.OneOf("nodejs20", "python3.11", "go1.21")`
|
||||
- `memory_mb` — `int64validator.Between(1, 4096)`
|
||||
- `timeout_sec` — `int64validator.Between(1, 900)`
|
||||
|
||||
`trigger_resource.go`:
|
||||
- `type` — `stringvalidator.OneOf("http", "cron")`
|
||||
|
||||
`job_resource.go`:
|
||||
- `run_id` — `int64validator.AtLeast(0)`
|
||||
|
||||
### Подтверждение повторными тестами (API)
|
||||
|
||||
| Тест | Ожидание | Результат |
|
||||
|------|----------|----------|
|
||||
| T2: `memory_mb=-10` | 400 | ✅ `{"error":"memory_mb must be between 1 and 4096"}` |
|
||||
| T4: `entrypoint=""` | 400 | ✅ `{"error":"entrypoint is required"}` |
|
||||
| T7: `type="rabbitmq"` | 400 + правильное сообщение | ✅ `{"error":"type must be \"http\" or \"cron\""}` |
|
||||
| T10: `memory_mb=999999` | 400 | ✅ `{"error":"memory_mb must be between 1 and 4096"}` |
|
||||
|
||||
### Подтверждение план-валидаторов (Terraform)
|
||||
|
||||
Тест: `runtime = "python2.7"` в http.tf →
|
||||
```
|
||||
Error: Invalid Attribute Value Match
|
||||
Attribute runtime value must be one of: ["nodejs20" "python3.11" "go1.21"], got: "python2.7"
|
||||
```
|
||||
|
||||
### Версии
|
||||
- Оператор: `naeel/sless-operator:v0.1.13`
|
||||
- Провайдер: `terra.k8c.ru/naeel/sless v0.1.7`
|
||||
|
||||
Reference in New Issue
Block a user