mirror of
https://github.com/MizuchiLabs/mantrae.git
synced 2026-05-08 00:49:49 -05:00
fix: handle deletion better, optimized bulk delete
This commit is contained in:
@@ -21,6 +21,20 @@ type UpsertMiddlewareParams struct {
|
||||
TCPMiddleware *runtime.TCPMiddlewareInfo `json:"tcpMiddleware"`
|
||||
}
|
||||
|
||||
type DeleteMiddlewareParams struct {
|
||||
ProfileID int64 `json:"profileId"`
|
||||
Name string `json:"name"`
|
||||
Protocol string `json:"protocol"`
|
||||
}
|
||||
|
||||
type BulkDeleteMiddlewareParams struct {
|
||||
ProfileID int64 `json:"profileId"`
|
||||
Items []struct {
|
||||
Name string `json:"name"`
|
||||
Protocol string `json:"protocol"`
|
||||
} `json:"items"`
|
||||
}
|
||||
|
||||
type Plugin struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
@@ -132,22 +146,19 @@ func UpsertMiddleware(a *config.App) http.HandlerFunc {
|
||||
// DeleteMiddleware deletes a middleware
|
||||
func DeleteMiddleware(a *config.App) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
q := a.Conn.GetQuery()
|
||||
profileID, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid profile ID", http.StatusBadRequest)
|
||||
var params DeleteMiddlewareParams
|
||||
if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil {
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
mwName := r.PathValue("name")
|
||||
mwProto := r.PathValue("protocol")
|
||||
|
||||
if mwName == "" || mwProto == "" {
|
||||
if params.ProfileID == 0 || params.Name == "" || params.Protocol == "" {
|
||||
http.Error(w, "Missing middleware name or protocol", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
existingConfig, err := q.GetLocalTraefikConfig(r.Context(), profileID)
|
||||
q := a.Conn.GetQuery()
|
||||
existingConfig, err := q.GetLocalTraefikConfig(r.Context(), params.ProfileID)
|
||||
if err != nil {
|
||||
http.Error(
|
||||
w,
|
||||
@@ -157,11 +168,11 @@ func DeleteMiddleware(a *config.App) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
switch mwProto {
|
||||
switch params.Protocol {
|
||||
case "http":
|
||||
delete(existingConfig.Config.Middlewares, mwName)
|
||||
delete(existingConfig.Config.Middlewares, params.Name)
|
||||
case "tcp":
|
||||
delete(existingConfig.Config.TCPMiddlewares, mwName)
|
||||
delete(existingConfig.Config.TCPMiddlewares, params.Name)
|
||||
default:
|
||||
http.Error(w, "invalid router type: must be http, tcp, or udp", http.StatusBadRequest)
|
||||
return
|
||||
@@ -185,6 +196,63 @@ func DeleteMiddleware(a *config.App) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func BulkDeleteMiddleware(a *config.App) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var params BulkDeleteMiddlewareParams
|
||||
if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil {
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if params.ProfileID == 0 {
|
||||
http.Error(w, "Missing profile ID", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
q := a.Conn.GetQuery()
|
||||
existingConfig, err := q.GetLocalTraefikConfig(r.Context(), params.ProfileID)
|
||||
if err != nil {
|
||||
http.Error(
|
||||
w,
|
||||
"Failed to get existing config: "+err.Error(),
|
||||
http.StatusInternalServerError,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range params.Items {
|
||||
if item.Name == "" || item.Protocol == "" {
|
||||
continue // Skip invalid entries
|
||||
}
|
||||
|
||||
switch item.Protocol {
|
||||
case "http":
|
||||
delete(existingConfig.Config.Middlewares, item.Name)
|
||||
case "tcp":
|
||||
delete(existingConfig.Config.TCPMiddlewares, item.Name)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
err = q.UpsertTraefikConfig(r.Context(), db.UpsertTraefikConfigParams{
|
||||
ProfileID: existingConfig.ProfileID,
|
||||
Source: source.Local,
|
||||
Config: existingConfig.Config,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to update config: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
util.Broadcast <- util.EventMessage{
|
||||
Type: util.EventTypeDelete,
|
||||
Category: util.EventCategoryTraefik,
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
// GetMiddlewarePlugins retrieves middleware plugins available for Traefik.
|
||||
func GetMiddlewarePlugins(w http.ResponseWriter, r *http.Request) {
|
||||
resp, err := http.Get("https://plugins.traefik.io/api/services/plugins")
|
||||
|
||||
@@ -27,6 +27,20 @@ type UpsertRouterParams struct {
|
||||
UDPService *runtime.UDPServiceInfo `json:"udpService"`
|
||||
}
|
||||
|
||||
type DeleteRouterParams struct {
|
||||
ProfileID int64 `json:"profileId"`
|
||||
Name string `json:"name"`
|
||||
Protocol string `json:"protocol"`
|
||||
}
|
||||
|
||||
type BulkDeleteRouterParams struct {
|
||||
ProfileID int64 `json:"profileId"`
|
||||
Items []struct {
|
||||
Name string `json:"name"`
|
||||
Protocol string `json:"protocol"`
|
||||
} `json:"items"`
|
||||
}
|
||||
|
||||
// UpsertRouter handles both creation and updates of router/service pairs
|
||||
func UpsertRouter(a *config.App) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -160,22 +174,19 @@ func UpsertRouter(a *config.App) http.HandlerFunc {
|
||||
// DeleteRouter handles the removal of router/service pairs
|
||||
func DeleteRouter(a *config.App) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
q := a.Conn.GetQuery()
|
||||
profileID, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid profile ID", http.StatusBadRequest)
|
||||
var params DeleteRouterParams
|
||||
if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil {
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
routerName := r.PathValue("name")
|
||||
routerProto := r.PathValue("protocol")
|
||||
|
||||
if routerName == "" || routerProto == "" {
|
||||
if params.ProfileID == 0 || params.Name == "" || params.Protocol == "" {
|
||||
http.Error(w, "Missing router name or protocol", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
existingConfig, err := q.GetLocalTraefikConfig(r.Context(), profileID)
|
||||
q := a.Conn.GetQuery()
|
||||
existingConfig, err := q.GetLocalTraefikConfig(r.Context(), params.ProfileID)
|
||||
if err != nil {
|
||||
http.Error(
|
||||
w,
|
||||
@@ -186,16 +197,16 @@ func DeleteRouter(a *config.App) http.HandlerFunc {
|
||||
}
|
||||
|
||||
// Remove router and service based on type
|
||||
switch routerProto {
|
||||
switch params.Protocol {
|
||||
case "http":
|
||||
delete(existingConfig.Config.Routers, routerName)
|
||||
delete(existingConfig.Config.Services, routerName)
|
||||
delete(existingConfig.Config.Routers, params.Name)
|
||||
delete(existingConfig.Config.Services, params.Name)
|
||||
case "tcp":
|
||||
delete(existingConfig.Config.TCPRouters, routerName)
|
||||
delete(existingConfig.Config.TCPServices, routerName)
|
||||
delete(existingConfig.Config.TCPRouters, params.Name)
|
||||
delete(existingConfig.Config.TCPServices, params.Name)
|
||||
case "udp":
|
||||
delete(existingConfig.Config.UDPRouters, routerName)
|
||||
delete(existingConfig.Config.UDPServices, routerName)
|
||||
delete(existingConfig.Config.UDPRouters, params.Name)
|
||||
delete(existingConfig.Config.UDPServices, params.Name)
|
||||
default:
|
||||
http.Error(w, "invalid router type: must be http, tcp, or udp", http.StatusBadRequest)
|
||||
return
|
||||
@@ -219,6 +230,74 @@ func DeleteRouter(a *config.App) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func BulkDeleteRouter(a *config.App) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var params BulkDeleteRouterParams
|
||||
if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil {
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if params.ProfileID == 0 {
|
||||
http.Error(w, "Missing router name or protocol", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
q := a.Conn.GetQuery()
|
||||
existingConfig, err := q.GetLocalTraefikConfig(r.Context(), params.ProfileID)
|
||||
if err != nil {
|
||||
http.Error(
|
||||
w,
|
||||
"Failed to get existing config: "+err.Error(),
|
||||
http.StatusInternalServerError,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Remove router and service based on type
|
||||
for _, item := range params.Items {
|
||||
if item.Name == "" || item.Protocol == "" {
|
||||
continue // Skip invalid entries
|
||||
}
|
||||
|
||||
switch item.Protocol {
|
||||
case "http":
|
||||
delete(existingConfig.Config.Routers, item.Name)
|
||||
delete(existingConfig.Config.Services, item.Name)
|
||||
case "tcp":
|
||||
delete(existingConfig.Config.TCPRouters, item.Name)
|
||||
delete(existingConfig.Config.TCPServices, item.Name)
|
||||
case "udp":
|
||||
delete(existingConfig.Config.UDPRouters, item.Name)
|
||||
delete(existingConfig.Config.UDPServices, item.Name)
|
||||
default:
|
||||
http.Error(
|
||||
w,
|
||||
"invalid router type: must be http, tcp, or udp",
|
||||
http.StatusBadRequest,
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = q.UpsertTraefikConfig(r.Context(), db.UpsertTraefikConfigParams{
|
||||
ProfileID: existingConfig.ProfileID,
|
||||
Source: source.Local,
|
||||
Config: existingConfig.Config,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to update config: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
util.Broadcast <- util.EventMessage{
|
||||
Type: util.EventTypeDelete,
|
||||
Category: util.EventCategoryTraefik,
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
func validateRouterParams(params *UpsertRouterParams) error {
|
||||
var (
|
||||
ErrInvalidRouterType = errors.New("invalid router type: must be http, tcp, or udp")
|
||||
|
||||
Reference in New Issue
Block a user