mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-12 10:16:37 +08:00
migrate
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Rain-kl/Wavelet/internal/apps/openflare/compat"
|
||||
"github.com/Rain-kl/Wavelet/internal/apps/openflare/websocket"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// RegisterRoutes mounts agent API routes under /agent.
|
||||
func RegisterRoutes(apiGroup *gin.RouterGroup) {
|
||||
agentRoute := apiGroup.Group("/agent")
|
||||
{
|
||||
discoveryRoute := agentRoute.Group("/")
|
||||
discoveryRoute.Use(AgentRegisterAuth())
|
||||
{
|
||||
discoveryRoute.POST("/nodes/register", RegisterHandler)
|
||||
}
|
||||
|
||||
authorizedRoute := agentRoute.Group("/")
|
||||
authorizedRoute.Use(AgentAuth())
|
||||
{
|
||||
authorizedRoute.GET("/ws", AgentWebSocketHandler)
|
||||
authorizedRoute.POST("/nodes/heartbeat", HeartbeatHandler)
|
||||
authorizedRoute.GET("/config-versions/active", GetActiveConfigHandler)
|
||||
authorizedRoute.GET("/pages/deployments/:deployment_id/package", DownloadPagesPackageHandler)
|
||||
authorizedRoute.POST("/waf/ip-groups/sync", SyncWAFIPGroupsHandler)
|
||||
authorizedRoute.POST("/apply-logs", ReportApplyLogHandler)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterHandler registers or discovers an agent node.
|
||||
func RegisterHandler(c *gin.Context) {
|
||||
var payload NodePayload
|
||||
if !compat.BindJSON(c, &payload) {
|
||||
return
|
||||
}
|
||||
payload.IP = resolveReportedNodeIP(payload.IP, c.Request.RemoteAddr)
|
||||
|
||||
var (
|
||||
result *RegistrationResponse
|
||||
err error
|
||||
)
|
||||
if authNode, ok := AgentNodeFromContext(c); ok {
|
||||
result, err = RegisterWithAccessToken(c.Request.Context(), authNode, payload)
|
||||
} else {
|
||||
result, err = RegisterWithDiscovery(c.Request.Context(), payload)
|
||||
}
|
||||
if err != nil {
|
||||
compat.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
compat.OK(c, result)
|
||||
}
|
||||
|
||||
// HeartbeatHandler records agent heartbeat state.
|
||||
func HeartbeatHandler(c *gin.Context) {
|
||||
var payload NodePayload
|
||||
if !compat.BindJSON(c, &payload) {
|
||||
return
|
||||
}
|
||||
payload.IP = resolveReportedNodeIP(payload.IP, c.Request.RemoteAddr)
|
||||
|
||||
authNode, ok := AgentNodeFromContext(c)
|
||||
if !ok {
|
||||
compat.Unauthorized(c, errInvalidAgentToken)
|
||||
return
|
||||
}
|
||||
|
||||
response, err := HeartbeatNode(c.Request.Context(), authNode, payload)
|
||||
if err != nil {
|
||||
compat.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
okWithExtras(c, response.Node, gin.H{
|
||||
"agent_settings": response.AgentSettings,
|
||||
"active_config": response.ActiveConfig,
|
||||
"waf_ip_groups": response.WAFIPGroups,
|
||||
})
|
||||
}
|
||||
|
||||
// GetActiveConfigHandler returns the active configuration version.
|
||||
func GetActiveConfigHandler(c *gin.Context) {
|
||||
if _, ok := AgentNodeFromContext(c); !ok {
|
||||
compat.Unauthorized(c, errNodeMissingFromContext)
|
||||
return
|
||||
}
|
||||
config, err := GetActiveConfig(c.Request.Context())
|
||||
if err != nil {
|
||||
compat.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
compat.OK(c, config)
|
||||
}
|
||||
|
||||
// SyncWAFIPGroupsHandler syncs WAF IP groups for an agent (stub).
|
||||
func SyncWAFIPGroupsHandler(c *gin.Context) {
|
||||
var input WAFIPGroupSyncInput
|
||||
if !compat.BindJSON(c, &input) {
|
||||
return
|
||||
}
|
||||
result, err := SyncWAFIPGroups(c.Request.Context(), input)
|
||||
if err != nil {
|
||||
compat.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
compat.OK(c, result)
|
||||
}
|
||||
|
||||
// ReportApplyLogHandler records an agent apply log entry.
|
||||
func ReportApplyLogHandler(c *gin.Context) {
|
||||
var payload ApplyLogPayload
|
||||
if !compat.BindJSON(c, &payload) {
|
||||
return
|
||||
}
|
||||
if authNode, ok := AgentNodeFromContext(c); ok {
|
||||
payload.NodeID = authNode.NodeID
|
||||
}
|
||||
log, err := ReportApplyLog(c.Request.Context(), payload)
|
||||
if err != nil {
|
||||
compat.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
compat.OK(c, log)
|
||||
}
|
||||
|
||||
// DownloadPagesPackageHandler is a stub until Pages agent packaging is migrated.
|
||||
func DownloadPagesPackageHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusNotFound, compat.Envelope{
|
||||
Success: false,
|
||||
Message: errPagesPackageNotFound,
|
||||
Data: nil,
|
||||
})
|
||||
}
|
||||
|
||||
// AgentWebSocketHandler upgrades an authenticated agent websocket connection.
|
||||
func AgentWebSocketHandler(c *gin.Context) {
|
||||
authNode, ok := AgentNodeFromContext(c)
|
||||
if !ok {
|
||||
compat.Unauthorized(c, errInvalidAgentToken)
|
||||
return
|
||||
}
|
||||
websocket.ServeAgent(c, authNode.NodeID)
|
||||
}
|
||||
|
||||
func okWithExtras(c *gin.Context, data any, extras gin.H) {
|
||||
payload := gin.H{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": data,
|
||||
}
|
||||
for key, value := range extras {
|
||||
payload[key] = value
|
||||
}
|
||||
c.JSON(http.StatusOK, payload)
|
||||
}
|
||||
Reference in New Issue
Block a user