v0.1.35: лимит очередей JWT-тенантов 50, обновление лимита при логине
This commit is contained in:
@@ -519,3 +519,30 @@ DeleteQueue всегда успешен; NextSequenceNumber пересоздаё
|
||||
**Проверки**: go build OK (v0.1.35), go vet чистый (кроме известной некомпиляции
|
||||
тестов gosqs — пакет fixtures), go test app/models OK.
|
||||
|
||||
**Ход деплоя и эмпирические уточнения**:
|
||||
- Первый вариант фикса resolveProtocol («query-mode → XML») оказался НЕВЕРНЫМ:
|
||||
эмпирика показала, что AWS CLI v2 в query-mode парсит именно JSON-ответы
|
||||
(list-queues на XML вернул None, на JSON — список). Откачено: протокол ответа
|
||||
по Content-Type, как было; дефект «Code=None» закрыт правильным форматом
|
||||
JSON-ошибок {"__type":"com.amazonaws.sqs#Code","message":"..."} в encodeResponse
|
||||
и GeneralError в actionHandler.
|
||||
- Whitelist имён атрибутов для JSON-протокола реализован через
|
||||
QueueAttributes.UnmarshalJSON (единый список models.AttrNameWhitelist);
|
||||
в whitelist включены FifoQueue/ContentBasedDeduplication (иначе CLI v2
|
||||
не мог создать FIFO — регрессия была поймана api_test).
|
||||
- Прод v0.1.35, digest `sha256:7d1c82e9…` (по digest).
|
||||
|
||||
**Проверки против прода (v0.1.35)**:
|
||||
- Пробы ошибок: пустое тело → MissingParameter; max=11 → InvalidParameterValue;
|
||||
VisibilityTimeout=43201 → InvalidParameterValue; FooBar=1 → InvalidParameterValue;
|
||||
повторный purge → PurgeQueueInProgress; delete несуществующей → NonExistentQueue;
|
||||
FIFO без MessageGroupId → MissingParameter. Все с AWS-кодами (Code=None устранён).
|
||||
- api_test.sh (CLI v2): 22/22 PASS. sdk_test.py (boto3): 15/15 PASS.
|
||||
- Целостность 25 циклов: с ВМ 25/25 PASS (lost=0, mismatch=0, errors=0).
|
||||
С локальной машины периодически ReceiptHandleIsInvalid — анализ логов пода
|
||||
показал: это retry-дубли (первый delete успешен, ответ теряется на пути
|
||||
клиент→шлюз; сообщение фактически удалено и подбирается следующими циклами).
|
||||
Инфраструктурная потеря ответов (DDoS-Guard/Nubes gateway), не дефект сервиса.
|
||||
- smoke.sh: 11/11 PASS.
|
||||
- 30-мин нагрузочный тест с ВМ — в процессе.
|
||||
|
||||
|
||||
+1
-1
@@ -245,7 +245,7 @@ func (h *Handler) jwtAuth(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Auto-provisioning: тенант и ключи детерминированы из email.
|
||||
// Токен — только аутентификация; ключи в ответ не возвращаем (GET /ui/api/credentials).
|
||||
t, err := h.store.CreateFromJWT(claims.Sub, claims.Email, 10)
|
||||
t, err := h.store.CreateFromJWT(claims.Sub, claims.Email, tenant.DefaultTenantMaxQueues)
|
||||
if err != nil {
|
||||
log.Errorf("jwt auth: failed to create tenant: %v", err)
|
||||
jsonErr(w, http.StatusInternalServerError, "failed to provision tenant")
|
||||
|
||||
@@ -18,6 +18,11 @@ import (
|
||||
// MaxTenantsGlobal — глобальный лимит тенантов (защита от OOM, Fix #12)
|
||||
const MaxTenantsGlobal = 1000
|
||||
|
||||
// DefaultTenantMaxQueues — лимит очередей для JWT-тенантов (auto-provisioning).
|
||||
// Используется в app/admin при логине; при каждом логине лимит существующего
|
||||
// тенанта обновляется до этого значения (см. CreateFromJWT).
|
||||
const DefaultTenantMaxQueues = 50
|
||||
|
||||
// Tenant — модель тенанта shared-sqs.
|
||||
// AccessKey используется как идентификатор в AWS Authorization header.
|
||||
type Tenant struct {
|
||||
@@ -215,6 +220,16 @@ func (s *TenantStore) CreateFromJWT(sub, email string, maxQueues int) (*Tenant,
|
||||
if sub != "" {
|
||||
existing.NubesSub = sub
|
||||
}
|
||||
// Обновляем лимит очередей на актуальное значение из кода при каждом
|
||||
// логине и персистим в Redis — иначе после рестарта пода из Redis
|
||||
// восстановится старый лимит (было: тенант навсегда оставался с лимитом,
|
||||
// заданным при первом логине).
|
||||
if existing.MaxQueues != maxQueues {
|
||||
existing.MaxQueues = maxQueues
|
||||
if data, err := json.Marshal(existing); err == nil {
|
||||
persistence.SaveTenantRaw(existing.ID, data)
|
||||
}
|
||||
}
|
||||
return existing, nil
|
||||
}
|
||||
// Легаси: убираем старую запись из всех индексов и из Redis, ниже создаём новую
|
||||
|
||||
Reference in New Issue
Block a user