Очередь job получила lease и fencing, телеметрия и прогресс deploy сохраняются, ревизия пишет manifest входов. Обновление префиксов не переписывает неизменённый снимок, большие наборы идут через COPY, а устаревшая ревизия не попадает в deploy. Бандл ноды кэшируется, prune и постановка job больше не держат горячий путь. Co-authored-by: Cursor <cursoragent@cursor.com>
43 lines
1.0 KiB
Go
43 lines
1.0 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"evobgp/internal/lookup"
|
|
"evobgp/internal/store"
|
|
)
|
|
|
|
// handleLookup implements GET /v1/lookup?q= (operationId: lookupMembership).
|
|
func (s *Server) handleLookup(w http.ResponseWriter, r *http.Request) {
|
|
a, ok := authFromContext(r.Context())
|
|
if !ok {
|
|
writeProblem(w, http.StatusUnauthorized, "Unauthorized", "missing auth")
|
|
return
|
|
}
|
|
if !s.requirePerm(w, a, "bgp:lookup:read") {
|
|
return
|
|
}
|
|
q := strings.TrimSpace(r.URL.Query().Get("q"))
|
|
if q == "" {
|
|
writeProblem(w, http.StatusBadRequest, "Bad Request", "query parameter q is required")
|
|
return
|
|
}
|
|
release, ok := s.acquireOperation(w, r, a.TenantID, lookupOperation)
|
|
if !ok {
|
|
return
|
|
}
|
|
defer release()
|
|
res, err := lookup.Lookup(r.Context(), s.store, a.TenantID, q)
|
|
if err != nil {
|
|
if errors.Is(err, store.ErrInvalidInput) {
|
|
writeProblem(w, http.StatusBadRequest, "Bad Request", "query must be an IP address, CIDR, or FQDN")
|
|
return
|
|
}
|
|
writeStoreErr(w, err)
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, res)
|
|
}
|