Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72045afcde |
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
Публичные URL (без API-ключа, вне `WEBUI_IP_WHITELIST` Traefik): `GET /v1/firewall/install.sh`, `GET /v1/firewall/sync-script`, `POST /v1/firewall/enroll`. Всегда **HTTPS**.
|
Публичные URL (без API-ключа, вне `WEBUI_IP_WHITELIST` Traefik): `GET /v1/firewall/install.sh`, `GET /v1/firewall/sync-script`, `POST /v1/firewall/enroll`. Всегда **HTTPS**.
|
||||||
|
|
||||||
|
Требуется миграция **`000027_firewall`** в PostgreSQL (применяется при старте API с актуальным бинарём). Если enroll отвечает `503` / `database schema outdated` — перезапустите `evobgp-api` / `evobgp-all` после деплоя новой версии.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://<api>/v1/firewall/install.sh | \
|
curl -fsSL https://<api>/v1/firewall/install.sh | \
|
||||||
EVOBGP_CP_URL=https://<api> \
|
EVOBGP_CP_URL=https://<api> \
|
||||||
|
|||||||
@@ -38,10 +38,18 @@ CP_URL="${EVOBGP_CP_URL%/}"
|
|||||||
ENROLL_BODY=$(printf '{"name":"%s","hostname":"%s","client_token":"%s","client_version":"install.sh/1"}' \
|
ENROLL_BODY=$(printf '{"name":"%s","hostname":"%s","client_token":"%s","client_version":"install.sh/1"}' \
|
||||||
"$EVOBGP_CLIENT_NAME" "$HOSTNAME" "$CLIENT_TOKEN")
|
"$EVOBGP_CLIENT_NAME" "$HOSTNAME" "$CLIENT_TOKEN")
|
||||||
|
|
||||||
RESP=$(curl -fsS -X POST "${CP_URL}/v1/firewall/enroll" \
|
ENROLL_TMP=$(mktemp)
|
||||||
|
trap 'rm -f "$ENROLL_TMP"' EXIT
|
||||||
|
ENROLL_CODE=$(curl -sS -o "$ENROLL_TMP" -w "%{http_code}" -X POST "${CP_URL}/v1/firewall/enroll" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-H "X-EvoBGP-Seed: ${EVOBGP_SEED}" \
|
-H "X-EvoBGP-Seed: ${EVOBGP_SEED}" \
|
||||||
-d "$ENROLL_BODY")
|
-d "$ENROLL_BODY")
|
||||||
|
if [[ "$ENROLL_CODE" != "201" ]]; then
|
||||||
|
echo "evobgp-firewall enroll failed: HTTP ${ENROLL_CODE} from ${CP_URL}/v1/firewall/enroll" >&2
|
||||||
|
cat "$ENROLL_TMP" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
RESP=$(cat "$ENROLL_TMP")
|
||||||
|
|
||||||
CLIENT_ID=""
|
CLIENT_ID=""
|
||||||
if command -v jq >/dev/null 2>&1; then
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import (
|
|||||||
"evobgp/internal/pipeline"
|
"evobgp/internal/pipeline"
|
||||||
"evobgp/internal/runtimelogs"
|
"evobgp/internal/runtimelogs"
|
||||||
"evobgp/internal/store"
|
"evobgp/internal/store"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgconn"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) registerCRUDRoutes(m *http.ServeMux) {
|
func (s *Server) registerCRUDRoutes(m *http.ServeMux) {
|
||||||
@@ -188,9 +190,29 @@ func writeStoreErr(w http.ResponseWriter, err error) {
|
|||||||
writeProblem(w, http.StatusUnprocessableEntity, "Unprocessable Entity", invalidInputDetail)
|
writeProblem(w, http.StatusUnprocessableEntity, "Unprocessable Entity", invalidInputDetail)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if writePostgresStoreErr(w, err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
writeInternalError(w, "store", err)
|
writeInternalError(w, "store", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writePostgresStoreErr(w http.ResponseWriter, err error) bool {
|
||||||
|
var pgErr *pgconn.PgError
|
||||||
|
if !errors.As(err, &pgErr) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch pgErr.Code {
|
||||||
|
case "42P01":
|
||||||
|
writeProblem(w, http.StatusServiceUnavailable, "Service Unavailable",
|
||||||
|
"database schema outdated; restart API after deploy or apply migration 000027_firewall")
|
||||||
|
return true
|
||||||
|
case "23505":
|
||||||
|
writeProblem(w, http.StatusConflict, "Conflict", "resource already exists")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) handleListCDNSources(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) handleListCDNSources(w http.ResponseWriter, r *http.Request) {
|
||||||
a, ok := authFromContext(r.Context())
|
a, ok := authFromContext(r.Context())
|
||||||
if !ok || !s.requireAtLeast(w, a, "viewer") {
|
if !ok || !s.requireAtLeast(w, a, "viewer") {
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ func (s *Server) handleFirewallEnrollPublic(w http.ResponseWriter, r *http.Reque
|
|||||||
writeProblem(w, http.StatusConflict, "Conflict", "client token already enrolled")
|
writeProblem(w, http.StatusConflict, "Conflict", "client token already enrolled")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
writeInternalError(w, "internal", err)
|
writeStoreErr(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
writeJSON(w, http.StatusCreated, map[string]any{
|
writeJSON(w, http.StatusCreated, map[string]any{
|
||||||
|
|||||||
@@ -38,10 +38,18 @@ CP_URL="${EVOBGP_CP_URL%/}"
|
|||||||
ENROLL_BODY=$(printf '{"name":"%s","hostname":"%s","client_token":"%s","client_version":"install.sh/1"}' \
|
ENROLL_BODY=$(printf '{"name":"%s","hostname":"%s","client_token":"%s","client_version":"install.sh/1"}' \
|
||||||
"$EVOBGP_CLIENT_NAME" "$HOSTNAME" "$CLIENT_TOKEN")
|
"$EVOBGP_CLIENT_NAME" "$HOSTNAME" "$CLIENT_TOKEN")
|
||||||
|
|
||||||
RESP=$(curl -fsS -X POST "${CP_URL}/v1/firewall/enroll" \
|
ENROLL_TMP=$(mktemp)
|
||||||
|
trap 'rm -f "$ENROLL_TMP"' EXIT
|
||||||
|
ENROLL_CODE=$(curl -sS -o "$ENROLL_TMP" -w "%{http_code}" -X POST "${CP_URL}/v1/firewall/enroll" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-H "X-EvoBGP-Seed: ${EVOBGP_SEED}" \
|
-H "X-EvoBGP-Seed: ${EVOBGP_SEED}" \
|
||||||
-d "$ENROLL_BODY")
|
-d "$ENROLL_BODY")
|
||||||
|
if [[ "$ENROLL_CODE" != "201" ]]; then
|
||||||
|
echo "evobgp-firewall enroll failed: HTTP ${ENROLL_CODE} from ${CP_URL}/v1/firewall/enroll" >&2
|
||||||
|
cat "$ENROLL_TMP" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
RESP=$(cat "$ENROLL_TMP")
|
||||||
|
|
||||||
CLIENT_ID=""
|
CLIENT_ID=""
|
||||||
if command -v jq >/dev/null 2>&1; then
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
|||||||
Reference in New Issue
Block a user