package server import ( "net/http" "github.com/go-chi/chi/v5" "git.unkin.net/unkin/tomswallapi/internal/model" ) // mountTraffic wires the traffic-control tier: mangle, accounting, tc_*. func (s *Server) mountTraffic(r chi.Router) { idCRUD(r, "/mangle", s.listMangle, s.createMangle, s.getMangle, s.deleteMangle) idCRUD(r, "/accounting", s.listAccounting, s.createAccounting, s.getAccounting, s.deleteAccounting) idCRUD(r, "/tc-devices", s.listTCDevices, s.createTCDevice, s.getTCDevice, s.deleteTCDevice) idCRUD(r, "/tc-classes", s.listTCClasses, s.createTCClass, s.getTCClass, s.deleteTCClass) idCRUD(r, "/tc-filters", s.listTCFilters, s.createTCFilter, s.getTCFilter, s.deleteTCFilter) idCRUD(r, "/tc-interfaces", s.listTCInterfaces, s.createTCInterface, s.getTCInterface, s.deleteTCInterface) idCRUD(r, "/tc-priorities", s.listTCPriorities, s.createTCPriority, s.getTCPriority, s.deleteTCPriority) } func (s *Server) listMangle(w http.ResponseWriter, r *http.Request) { list, err := s.store.ListMangle(r.Context()) respondList(w, list, err) } func (s *Server) createMangle(w http.ResponseWriter, r *http.Request) { var v model.MangleRule if !decode(w, r, &v) { return } if v.Device == "" || v.Action == "" { writeError(w, http.StatusBadRequest, "device and action are required") return } id, err := s.store.CreateMangle(r.Context(), v) if err == nil { v.ID = id } respondCreated(w, v, err) } func (s *Server) getMangle(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } v, err := s.store.GetMangle(r.Context(), id) respondOne(w, v, err) } func (s *Server) deleteMangle(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } respondDelete(w, s.store.DeleteMangle(r.Context(), id)) } func (s *Server) listAccounting(w http.ResponseWriter, r *http.Request) { list, err := s.store.ListAccounting(r.Context()) respondList(w, list, err) } func (s *Server) createAccounting(w http.ResponseWriter, r *http.Request) { var v model.AccountingRule if !decode(w, r, &v) { return } if v.Device == "" || v.Action == "" { writeError(w, http.StatusBadRequest, "device and action are required") return } id, err := s.store.CreateAccounting(r.Context(), v) if err == nil { v.ID = id } respondCreated(w, v, err) } func (s *Server) getAccounting(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } v, err := s.store.GetAccounting(r.Context(), id) respondOne(w, v, err) } func (s *Server) deleteAccounting(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } respondDelete(w, s.store.DeleteAccounting(r.Context(), id)) } func (s *Server) listTCDevices(w http.ResponseWriter, r *http.Request) { list, err := s.store.ListTCDevices(r.Context()) respondList(w, list, err) } func (s *Server) createTCDevice(w http.ResponseWriter, r *http.Request) { var v model.TCDevice if !decode(w, r, &v) { return } if v.Device == "" || v.Interface == "" { writeError(w, http.StatusBadRequest, "device and interface are required") return } id, err := s.store.CreateTCDevice(r.Context(), v) if err == nil { v.ID = id } respondCreated(w, v, err) } func (s *Server) getTCDevice(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } v, err := s.store.GetTCDevice(r.Context(), id) respondOne(w, v, err) } func (s *Server) deleteTCDevice(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } respondDelete(w, s.store.DeleteTCDevice(r.Context(), id)) } func (s *Server) listTCClasses(w http.ResponseWriter, r *http.Request) { list, err := s.store.ListTCClasses(r.Context()) respondList(w, list, err) } func (s *Server) createTCClass(w http.ResponseWriter, r *http.Request) { var v model.TCClass if !decode(w, r, &v) { return } if v.Device == "" || v.Interface == "" { writeError(w, http.StatusBadRequest, "device and interface are required") return } id, err := s.store.CreateTCClass(r.Context(), v) if err == nil { v.ID = id } respondCreated(w, v, err) } func (s *Server) getTCClass(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } v, err := s.store.GetTCClass(r.Context(), id) respondOne(w, v, err) } func (s *Server) deleteTCClass(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } respondDelete(w, s.store.DeleteTCClass(r.Context(), id)) } func (s *Server) listTCFilters(w http.ResponseWriter, r *http.Request) { list, err := s.store.ListTCFilters(r.Context()) respondList(w, list, err) } func (s *Server) createTCFilter(w http.ResponseWriter, r *http.Request) { var v model.TCFilter if !decode(w, r, &v) { return } if v.Device == "" || v.Class == "" { writeError(w, http.StatusBadRequest, "device and class are required") return } id, err := s.store.CreateTCFilter(r.Context(), v) if err == nil { v.ID = id } respondCreated(w, v, err) } func (s *Server) getTCFilter(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } v, err := s.store.GetTCFilter(r.Context(), id) respondOne(w, v, err) } func (s *Server) deleteTCFilter(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } respondDelete(w, s.store.DeleteTCFilter(r.Context(), id)) } func (s *Server) listTCInterfaces(w http.ResponseWriter, r *http.Request) { list, err := s.store.ListTCInterfaces(r.Context()) respondList(w, list, err) } func (s *Server) createTCInterface(w http.ResponseWriter, r *http.Request) { var v model.TCInterface if !decode(w, r, &v) { return } if v.Device == "" || v.Interface == "" { writeError(w, http.StatusBadRequest, "device and interface are required") return } id, err := s.store.CreateTCInterface(r.Context(), v) if err == nil { v.ID = id } respondCreated(w, v, err) } func (s *Server) getTCInterface(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } v, err := s.store.GetTCInterface(r.Context(), id) respondOne(w, v, err) } func (s *Server) deleteTCInterface(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } respondDelete(w, s.store.DeleteTCInterface(r.Context(), id)) } func (s *Server) listTCPriorities(w http.ResponseWriter, r *http.Request) { list, err := s.store.ListTCPriorities(r.Context()) respondList(w, list, err) } func (s *Server) createTCPriority(w http.ResponseWriter, r *http.Request) { var v model.TCPriority if !decode(w, r, &v) { return } if v.Device == "" || v.Band == 0 { writeError(w, http.StatusBadRequest, "device and band are required") return } id, err := s.store.CreateTCPriority(r.Context(), v) if err == nil { v.ID = id } respondCreated(w, v, err) } func (s *Server) getTCPriority(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } v, err := s.store.GetTCPriority(r.Context(), id) respondOne(w, v, err) } func (s *Server) deleteTCPriority(w http.ResponseWriter, r *http.Request) { id, ok := idParam(w, r) if !ok { return } respondDelete(w, s.store.DeleteTCPriority(r.Context(), id)) }