package api import ( "encoding/json" "net/http" "proxmox-router/internal/dynamicrouting" ) // Summary func (s *Server) handleDynamicRoutingSummary(w http.ResponseWriter, r *http.Request) { summary := s.dynRoutingMgr.GetSummary() writeJSON(w, http.StatusOK, summary) } // ------------------------------------------------------------- // BGP Handlers // ------------------------------------------------------------- func (s *Server) handleGetBGPInstance(w http.ResponseWriter, r *http.Request) { inst := s.dynRoutingMgr.GetBGPInstance() writeJSON(w, http.StatusOK, inst) } func (s *Server) handleUpdateBGPInstance(w http.ResponseWriter, r *http.Request) { var inst dynamicrouting.BGPInstance if err := json.NewDecoder(r.Body).Decode(&inst); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()}) return } if err := s.dynRoutingMgr.UpdateBGPInstance(inst); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, s.dynRoutingMgr.GetBGPInstance()) } func (s *Server) handleListBGPPeers(w http.ResponseWriter, r *http.Request) { peers := s.dynRoutingMgr.ListBGPPeers() if peers == nil { peers = []dynamicrouting.BGPPeer{} } writeJSON(w, http.StatusOK, peers) } func (s *Server) handleSaveBGPPeer(w http.ResponseWriter, r *http.Request) { var peer dynamicrouting.BGPPeer if err := json.NewDecoder(r.Body).Decode(&peer); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()}) return } if peer.RemoteAddress == "" || peer.RemoteAS == 0 { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "remote_address and remote_as are required"}) return } if err := s.dynRoutingMgr.SaveBGPPeer(peer); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "peer": peer}) } func (s *Server) handleDeleteBGPPeer(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") if id == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing peer id"}) return } if err := s.dynRoutingMgr.DeleteBGPPeer(id); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"}) } func (s *Server) handleSetBGPPeerState(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") var req struct { Disabled bool `json:"disabled"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"}) return } if err := s.dynRoutingMgr.SetBGPPeerState(id, req.Disabled); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled}) } func (s *Server) handleListBGPNetworks(w http.ResponseWriter, r *http.Request) { nets := s.dynRoutingMgr.ListBGPNetworks() if nets == nil { nets = []dynamicrouting.BGPNetwork{} } writeJSON(w, http.StatusOK, nets) } func (s *Server) handleSaveBGPNetwork(w http.ResponseWriter, r *http.Request) { var net dynamicrouting.BGPNetwork if err := json.NewDecoder(r.Body).Decode(&net); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()}) return } if net.Network == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "network (CIDR) is required"}) return } if err := s.dynRoutingMgr.SaveBGPNetwork(net); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "network": net}) } func (s *Server) handleDeleteBGPNetwork(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") if id == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing network id"}) return } if err := s.dynRoutingMgr.DeleteBGPNetwork(id); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"}) } func (s *Server) handleGetBGPRoutes(w http.ResponseWriter, r *http.Request) { routes := s.dynRoutingMgr.GetBGPRoutes() if routes == nil { routes = []dynamicrouting.BGPRoute{} } writeJSON(w, http.StatusOK, routes) } // ------------------------------------------------------------- // OSPF Handlers // ------------------------------------------------------------- func (s *Server) handleGetOSPFInstance(w http.ResponseWriter, r *http.Request) { inst := s.dynRoutingMgr.GetOSPFInstance() writeJSON(w, http.StatusOK, inst) } func (s *Server) handleUpdateOSPFInstance(w http.ResponseWriter, r *http.Request) { var inst dynamicrouting.OSPFInstance if err := json.NewDecoder(r.Body).Decode(&inst); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()}) return } if err := s.dynRoutingMgr.UpdateOSPFInstance(inst); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, s.dynRoutingMgr.GetOSPFInstance()) } func (s *Server) handleListOSPFAreas(w http.ResponseWriter, r *http.Request) { areas := s.dynRoutingMgr.ListOSPFAreas() if areas == nil { areas = []dynamicrouting.OSPFArea{} } writeJSON(w, http.StatusOK, areas) } func (s *Server) handleSaveOSPFArea(w http.ResponseWriter, r *http.Request) { var area dynamicrouting.OSPFArea if err := json.NewDecoder(r.Body).Decode(&area); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()}) return } if area.AreaID == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "area_id is required"}) return } if err := s.dynRoutingMgr.SaveOSPFArea(area); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "area": area}) } func (s *Server) handleDeleteOSPFArea(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") if id == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing area id"}) return } if err := s.dynRoutingMgr.DeleteOSPFArea(id); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"}) } func (s *Server) handleListOSPFInterfaces(w http.ResponseWriter, r *http.Request) { ifaces := s.dynRoutingMgr.ListOSPFInterfaces() if ifaces == nil { ifaces = []dynamicrouting.OSPFInterface{} } writeJSON(w, http.StatusOK, ifaces) } func (s *Server) handleSaveOSPFInterface(w http.ResponseWriter, r *http.Request) { var iface dynamicrouting.OSPFInterface if err := json.NewDecoder(r.Body).Decode(&iface); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()}) return } if iface.Network == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "network is required"}) return } if err := s.dynRoutingMgr.SaveOSPFInterface(iface); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "interface": iface}) } func (s *Server) handleDeleteOSPFInterface(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") if id == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing interface id"}) return } if err := s.dynRoutingMgr.DeleteOSPFInterface(id); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"}) } func (s *Server) handleSetOSPFInterfaceState(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") var req struct { Disabled bool `json:"disabled"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"}) return } if err := s.dynRoutingMgr.SetOSPFInterfaceState(id, req.Disabled); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled}) } func (s *Server) handleGetOSPFNeighbors(w http.ResponseWriter, r *http.Request) { nbrs := s.dynRoutingMgr.GetOSPFNeighbors() if nbrs == nil { nbrs = []dynamicrouting.OSPFNeighbor{} } writeJSON(w, http.StatusOK, nbrs) } func (s *Server) handleGetOSPFRoutes(w http.ResponseWriter, r *http.Request) { routes := s.dynRoutingMgr.GetOSPFRoutes() if routes == nil { routes = []dynamicrouting.OSPFRoute{} } writeJSON(w, http.StatusOK, routes) } // ------------------------------------------------------------- // Routing Filters Handlers (/routing filter) // ------------------------------------------------------------- func (s *Server) handleListRoutingFilters(w http.ResponseWriter, r *http.Request) { filters := s.dynRoutingMgr.ListRoutingFilters() if filters == nil { filters = []dynamicrouting.RoutingFilterRule{} } writeJSON(w, http.StatusOK, filters) } func (s *Server) handleSaveRoutingFilter(w http.ResponseWriter, r *http.Request) { var rule dynamicrouting.RoutingFilterRule if err := json.NewDecoder(r.Body).Decode(&rule); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()}) return } if rule.Chain == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Chain name is required"}) return } if rule.Action == "" { rule.Action = "accept" } if err := s.dynRoutingMgr.SaveRoutingFilter(&rule); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]string{"status": "success", "id": rule.ID}) } func (s *Server) handleDeleteRoutingFilter(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") if id == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing filter rule ID"}) return } if err := s.dynRoutingMgr.DeleteRoutingFilter(id); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"}) } func (s *Server) handleSetRoutingFilterState(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") if id == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing filter rule ID"}) return } var req struct { Disabled bool `json:"disabled"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"}) return } if err := s.dynRoutingMgr.SetRoutingFilterState(id, req.Disabled); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled}) }