From 55058573d62439930161f5cce4b60811b79f68c0 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Thu, 25 Apr 2024 21:31:26 +0800 Subject: [PATCH] add sd and observer web APIs --- api/api.go | 8 ++ api/config_observer.go | 169 +++++++++++++++++++++++++++++++++++++++++ api/config_sd.go | 169 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+) create mode 100644 api/config_observer.go create mode 100644 api/config_sd.go diff --git a/api/api.go b/api/api.go index b132272..c92ef40 100644 --- a/api/api.go +++ b/api/api.go @@ -165,6 +165,14 @@ func registerConfig(config *gin.RouterGroup) { config.PUT("/routers/:router", updateRouter) config.DELETE("/routers/:router", deleteRouter) + config.POST("/observers", createObserver) + config.PUT("/observers/:observer", updateObserver) + config.DELETE("/observers/:observer", deleteObserver) + + config.POST("/sds", createSD) + config.PUT("/sds/:sd", updateSD) + config.DELETE("/sds/:sd", deleteSD) + config.POST("/limiters", createLimiter) config.PUT("/limiters/:limiter", updateLimiter) config.DELETE("/limiters/:limiter", deleteLimiter) diff --git a/api/config_observer.go b/api/config_observer.go new file mode 100644 index 0000000..42ddece --- /dev/null +++ b/api/config_observer.go @@ -0,0 +1,169 @@ +package api + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-gost/x/config" + parser "github.com/go-gost/x/config/parsing/observer" + "github.com/go-gost/x/registry" +) + +// swagger:parameters createObserverRequest +type createObserverRequest struct { + // in: body + Data config.ObserverConfig `json:"data"` +} + +// successful operation. +// swagger:response createObserverResponse +type createObserverResponse struct { + Data Response +} + +func createObserver(ctx *gin.Context) { + // swagger:route POST /config/observers Observer createObserverRequest + // + // Create a new observer, the name of the observer must be unique in observer list. + // + // Security: + // basicAuth: [] + // + // Responses: + // 200: createObserverResponse + + var req createObserverRequest + ctx.ShouldBindJSON(&req.Data) + + if req.Data.Name == "" { + writeError(ctx, ErrInvalid) + return + } + + v := parser.ParseObserver(&req.Data) + + if err := registry.ObserverRegistry().Register(req.Data.Name, v); err != nil { + writeError(ctx, ErrDup) + return + } + + config.OnUpdate(func(c *config.Config) error { + c.Observers = append(c.Observers, &req.Data) + return nil + }) + + ctx.JSON(http.StatusOK, Response{ + Msg: "OK", + }) +} + +// swagger:parameters updateObserverRequest +type updateObserverRequest struct { + // in: path + // required: true + Observer string `uri:"observer" json:"observer"` + // in: body + Data config.ObserverConfig `json:"data"` +} + +// successful operation. +// swagger:response updateObserverResponse +type updateObserverResponse struct { + Data Response +} + +func updateObserver(ctx *gin.Context) { + // swagger:route PUT /config/observers/{observer} Observer updateObserverRequest + // + // Update observer by name, the observer must already exist. + // + // Security: + // basicAuth: [] + // + // Responses: + // 200: updateObserverResponse + + var req updateObserverRequest + ctx.ShouldBindUri(&req) + ctx.ShouldBindJSON(&req.Data) + + if !registry.ObserverRegistry().IsRegistered(req.Observer) { + writeError(ctx, ErrNotFound) + return + } + + req.Data.Name = req.Observer + + v := parser.ParseObserver(&req.Data) + + registry.ObserverRegistry().Unregister(req.Observer) + + if err := registry.ObserverRegistry().Register(req.Observer, v); err != nil { + writeError(ctx, ErrDup) + return + } + + config.OnUpdate(func(c *config.Config) error { + for i := range c.Observers { + if c.Observers[i].Name == req.Observer { + c.Observers[i] = &req.Data + break + } + } + return nil + }) + + ctx.JSON(http.StatusOK, Response{ + Msg: "OK", + }) +} + +// swagger:parameters deleteObserverRequest +type deleteObserverRequest struct { + // in: path + // required: true + Observer string `uri:"observer" json:"observer"` +} + +// successful operation. +// swagger:response deleteObserverResponse +type deleteObserverResponse struct { + Data Response +} + +func deleteObserver(ctx *gin.Context) { + // swagger:route DELETE /config/observers/{observer} Observer deleteObserverRequest + // + // Delete observer by name. + // + // Security: + // basicAuth: [] + // + // Responses: + // 200: deleteObserverResponse + + var req deleteObserverRequest + ctx.ShouldBindUri(&req) + + if !registry.ObserverRegistry().IsRegistered(req.Observer) { + writeError(ctx, ErrNotFound) + return + } + registry.ObserverRegistry().Unregister(req.Observer) + + config.OnUpdate(func(c *config.Config) error { + observers := c.Observers + c.Observers = nil + for _, s := range observers { + if s.Name == req.Observer { + continue + } + c.Observers = append(c.Observers, s) + } + return nil + }) + + ctx.JSON(http.StatusOK, Response{ + Msg: "OK", + }) +} diff --git a/api/config_sd.go b/api/config_sd.go new file mode 100644 index 0000000..5036668 --- /dev/null +++ b/api/config_sd.go @@ -0,0 +1,169 @@ +package api + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-gost/x/config" + parser "github.com/go-gost/x/config/parsing/sd" + "github.com/go-gost/x/registry" +) + +// swagger:parameters createSDRequest +type createSDRequest struct { + // in: body + Data config.SDConfig `json:"data"` +} + +// successful operation. +// swagger:response createSDResponse +type createSDResponse struct { + Data Response +} + +func createSD(ctx *gin.Context) { + // swagger:route POST /config/sds SD createSDRequest + // + // Create a new SD, the name of the SD must be unique in SD list. + // + // Security: + // basicAuth: [] + // + // Responses: + // 200: createSDResponse + + var req createSDRequest + ctx.ShouldBindJSON(&req.Data) + + if req.Data.Name == "" { + writeError(ctx, ErrInvalid) + return + } + + v := parser.ParseSD(&req.Data) + + if err := registry.SDRegistry().Register(req.Data.Name, v); err != nil { + writeError(ctx, ErrDup) + return + } + + config.OnUpdate(func(c *config.Config) error { + c.SDs = append(c.SDs, &req.Data) + return nil + }) + + ctx.JSON(http.StatusOK, Response{ + Msg: "OK", + }) +} + +// swagger:parameters updateSDRequest +type updateSDRequest struct { + // in: path + // required: true + SD string `uri:"sd" json:"sd"` + // in: body + Data config.SDConfig `json:"data"` +} + +// successful operation. +// swagger:response updateSDResponse +type updateSDResponse struct { + Data Response +} + +func updateSD(ctx *gin.Context) { + // swagger:route PUT /config/sds/{sd} SD updateSDRequest + // + // Update SD by name, the SD must already exist. + // + // Security: + // basicAuth: [] + // + // Responses: + // 200: updateSDResponse + + var req updateSDRequest + ctx.ShouldBindUri(&req) + ctx.ShouldBindJSON(&req.Data) + + if !registry.SDRegistry().IsRegistered(req.SD) { + writeError(ctx, ErrNotFound) + return + } + + req.Data.Name = req.SD + + v := parser.ParseSD(&req.Data) + + registry.SDRegistry().Unregister(req.SD) + + if err := registry.SDRegistry().Register(req.SD, v); err != nil { + writeError(ctx, ErrDup) + return + } + + config.OnUpdate(func(c *config.Config) error { + for i := range c.SDs { + if c.SDs[i].Name == req.SD { + c.SDs[i] = &req.Data + break + } + } + return nil + }) + + ctx.JSON(http.StatusOK, Response{ + Msg: "OK", + }) +} + +// swagger:parameters deleteSDRequest +type deleteSDRequest struct { + // in: path + // required: true + SD string `uri:"sd" json:"sd"` +} + +// successful operation. +// swagger:response deleteSDResponse +type deleteSDResponse struct { + Data Response +} + +func deleteSD(ctx *gin.Context) { + // swagger:route DELETE /config/sds/{sd} SD deleteSDRequest + // + // Delete SD by name. + // + // Security: + // basicAuth: [] + // + // Responses: + // 200: deleteSDResponse + + var req deleteSDRequest + ctx.ShouldBindUri(&req) + + if !registry.SDRegistry().IsRegistered(req.SD) { + writeError(ctx, ErrNotFound) + return + } + registry.SDRegistry().Unregister(req.SD) + + config.OnUpdate(func(c *config.Config) error { + sds := c.SDs + c.SDs = nil + for _, s := range sds { + if s.Name == req.SD { + continue + } + c.SDs = append(c.SDs, s) + } + return nil + }) + + ctx.JSON(http.StatusOK, Response{ + Msg: "OK", + }) +}