cf094f6e6f
Проход по операциям, которые делают не то, что обещает их имя. P0. Удаление bootstrap-admin-peer не было отзывом доступа. Признаком «создавать пир или нет» служило наличие строки в таблице, а HY2XS_ADMIN_CON_PASS продолжает жить в /etc/hy2xs/hy2xs.env — его читает systemd-юнит. Оператор удалял пира, доступ исчезал, и ближайший restart возвращал того же пира с тем же секретом. Молча. Признаком стала отметка BOOTSTRAP_PEER_SEEDED в таблице config: «создавался когда-либо», а не «существует сейчас». Отметка и пир пишутся одной транзакцией. P1. Резервная копия с includeSecrets=true проглатывала и ошибку расшифровки, и отсутствие шифртекста, отдавая пира с пустым secret и успешный ответ. Теперь недоступный секрет любого пира отклоняет весь запрос с указанием имени. P1. DecryptPeerSecret возвращала содержимое колонки как расшифрованный секрет, если оно не начиналось с v1: — остаток поколения с открытыми секретами. P1. doctor перезапускал hysteria-server и hy2xs-admin: диагностика подозрения на проблему обрывала все живые соединения. P1. Админка сама генерировала HYSTERIA2_TRAFFIC_STATS_SECRET, записать который в /etc/hysteria/config.yaml она не может. Сервис объявлял себя здоровым, а machine auth переставал совпадать. P1. Обходы проверки зависимостей (accepted-risk/skipped) не могли произвести артефакт: приёмка требует dependency_security_gate=true. Удалены из сборки и документации, отсутствие проверяется приёмкой. P2. UPDATE по отсутствующей строке config считался успехом, и cron перепланировался при несохранённом значении. Решение по RowsAffected. P2. Слой данных не отличал «записи нет» от «база не ответила»: sentinel-значения ErrPeerNotFound / ErrAdminUserNotFound / ErrConfigNotFound / ErrStorage. P2. Удалены алиасы /:id/client-url и /:id/qr. Контракт разработки: apps/go.mod объявляет toolchain go1.26.7 (директива go — языковой baseline, а не выбор компилятора), tools/dev/doctor.sh|.ps1 сверяют среду с versions.env.
37 lines
1.5 KiB
Go
37 lines
1.5 KiB
Go
package router
|
|
|
|
import (
|
|
"github.com/gin-gonic/gin"
|
|
"hy2xs-admin/controller"
|
|
)
|
|
|
|
func initPeerRouter(peerApi *gin.RouterGroup) {
|
|
peers := peerApi.Group("/peers")
|
|
{
|
|
peers.GET("", controller.PagePeer)
|
|
peers.POST("", controller.SavePeer)
|
|
peers.GET("/:id", controller.GetPeer)
|
|
peers.PATCH("/:id", controller.UpdatePeer)
|
|
peers.DELETE("/:id", controller.DeletePeer)
|
|
|
|
peers.PATCH("/:id/reset-traffic", controller.ResetTraffic)
|
|
peers.PATCH("/:id/release-kick", controller.ReleaseKickPeer)
|
|
peers.PATCH("/:id/kick", controller.KickPeer)
|
|
peers.GET("/:id/client-config", controller.PeerClientConfig)
|
|
|
|
// Алиасов /:id/client-url и /:id/qr здесь больше нет.
|
|
//
|
|
// Они были оставлены «на один миграционный релиз», но миграционного
|
|
// релиза у продукта не существует: HY2XS v1 ставится только на чистый
|
|
// хост, база предыдущего поколения не переносится, а клиентов у этих
|
|
// путей нет — панель ходит в /:id/client-config. Дожив до 1.0.0, они
|
|
// стали бы частью публичного API v1, и убирать их пришлось бы уже со
|
|
// сломом совместимости.
|
|
//
|
|
// Отсутствие закреплено TestRouterHasNoRemovedRoutes.
|
|
}
|
|
|
|
peerApi.POST("/peer-import", controller.ImportPeer)
|
|
peerApi.POST("/peer-export", controller.ExportPeer)
|
|
}
|