package configapi import ( "encoding/json" "net/http" "strings" "github.com/azukaar/cosmos-server/src/utils" ) type UpdateRouteRequest struct { RouteName string `json:"routeName"` Operation string `json:"operation"` NewRoute *utils.ProxyRouteConfig `json:"newRoute,omitempty"` } func ConfigApiPatch(w http.ResponseWriter, req *http.Request) { if utils.AdminOnly(w, req) != nil { return } utils.Log("RouteSettingsUpdate: Patching config") utils.ConfigLock.Lock() defer utils.ConfigLock.Unlock() var updateReq UpdateRouteRequest err := json.NewDecoder(req.Body).Decode(&updateReq) if err != nil { utils.Error("RouteSettingsUpdate: Invalid Update Request", err) utils.HTTPError(w, "Invalid Update Request", http.StatusBadRequest, "UR001") return } config := utils.ReadConfigFromFile() routes := config.HTTPConfig.ProxyConfig.Routes routeIndex := -1 if updateReq.Operation != "add" { if updateReq.RouteName == "" { utils.Error("RouteSettingsUpdate: RouteName must be provided", nil) utils.HTTPError(w, "RouteName must be provided", http.StatusBadRequest, "UR002") return } for i, route := range routes { if route.Name == updateReq.RouteName { routeIndex = i break } } if routeIndex == -1 { utils.Error("RouteSettingsUpdate: Route not found: "+updateReq.RouteName, nil) utils.HTTPError(w, "Route not found", http.StatusNotFound, "UR002") return } } switch updateReq.Operation { case "replace": utils.Log("RouteSettingsUpdate: Replacing route: "+updateReq.RouteName) if updateReq.NewRoute == nil { utils.Error("RouteSettingsUpdate: NewRoute must be provided for replace operation", nil) utils.HTTPError(w, "NewRoute must be provided for replace operation", http.StatusBadRequest, "UR003") return } routes[routeIndex] = *updateReq.NewRoute case "move_up": utils.Log("RouteSettingsUpdate: Moving up route: "+updateReq.RouteName) if routeIndex > 0 { routes[routeIndex-1], routes[routeIndex] = routes[routeIndex], routes[routeIndex-1] } case "move_down": utils.Log("RouteSettingsUpdate: Moving down route: "+updateReq.RouteName) if routeIndex < len(routes)-1 { routes[routeIndex+1], routes[routeIndex] = routes[routeIndex], routes[routeIndex+1] } case "delete": utils.Log("RouteSettingsUpdate: Deleting route: "+updateReq.RouteName) routes = append(routes[:routeIndex], routes[routeIndex+1:]...) case "add": utils.Log("RouteSettingsUpdate: Adding route") if updateReq.NewRoute == nil { utils.Error("RouteSettingsUpdate: NewRoute must be provided for add operation", nil) utils.HTTPError(w, "NewRoute must be provided for add operation", http.StatusBadRequest, "UR003") return } routes = append([]utils.ProxyRouteConfig{*updateReq.NewRoute}, routes...) default: utils.Error("RouteSettingsUpdate: Unsupported operation: "+updateReq.Operation, nil) utils.HTTPError(w, "Unsupported operation", http.StatusBadRequest, "UR004") return } config.HTTPConfig.ProxyConfig.Routes = routes utils.SetBaseMainConfig(config) utils.RestartHTTPServer() if updateReq.NewRoute.Mode == "SERVAPP" { utils.Log("RouteSettingsUpdate: Service needs update: "+updateReq.NewRoute.Target) target := updateReq.NewRoute.Target tokens := strings.Split(target, ":") name := tokens[1][2:] utils.Log("RouteSettingsUpdate: Service needs update: "+name) utils.ReBootstrapContainer(name) } json.NewEncoder(w).Encode(map[string]interface{}{ "status": "OK", }) }