721f4c1af3
Storage + CRUD (migration 0006, model, id-keyed store, REST handlers) plus compiler rendering: each section is owned by a device and projected into that device's rendered config (hosts/providers/routes/routing_rules).
191 lines
4.5 KiB
Go
191 lines
4.5 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"git.unkin.net/unkin/tomswallapi/internal/model"
|
|
)
|
|
|
|
// mountPerDevice wires the per-device long-tail sections: hosts, providers,
|
|
// routes, and routing-rules.
|
|
func (s *Server) mountPerDevice(r chi.Router) {
|
|
r.Route("/hosts", func(r chi.Router) {
|
|
r.Get("/", s.listHosts)
|
|
r.Post("/", s.createHost)
|
|
r.Get("/{id}", s.getHost)
|
|
r.Delete("/{id}", s.deleteHost)
|
|
})
|
|
r.Route("/providers", func(r chi.Router) {
|
|
r.Get("/", s.listProviders)
|
|
r.Post("/", s.createProvider)
|
|
r.Get("/{id}", s.getProvider)
|
|
r.Delete("/{id}", s.deleteProvider)
|
|
})
|
|
r.Route("/routes", func(r chi.Router) {
|
|
r.Get("/", s.listRoutes)
|
|
r.Post("/", s.createRoute)
|
|
r.Get("/{id}", s.getRoute)
|
|
r.Delete("/{id}", s.deleteRoute)
|
|
})
|
|
r.Route("/routing-rules", func(r chi.Router) {
|
|
r.Get("/", s.listRoutingRules)
|
|
r.Post("/", s.createRoutingRule)
|
|
r.Get("/{id}", s.getRoutingRule)
|
|
r.Delete("/{id}", s.deleteRoutingRule)
|
|
})
|
|
}
|
|
|
|
func (s *Server) listHosts(w http.ResponseWriter, r *http.Request) {
|
|
list, err := s.store.ListHosts(r.Context())
|
|
respondList(w, list, err)
|
|
}
|
|
|
|
func (s *Server) createHost(w http.ResponseWriter, r *http.Request) {
|
|
var v model.Host
|
|
if !decode(w, r, &v) {
|
|
return
|
|
}
|
|
if v.Device == "" || v.Zone == "" || v.Interface == "" {
|
|
writeError(w, http.StatusBadRequest, "device, zone, and interface are required")
|
|
return
|
|
}
|
|
id, err := s.store.CreateHost(r.Context(), v)
|
|
if err == nil {
|
|
v.ID = id
|
|
}
|
|
respondCreated(w, v, err)
|
|
}
|
|
|
|
func (s *Server) getHost(w http.ResponseWriter, r *http.Request) {
|
|
id, ok := idParam(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
v, err := s.store.GetHost(r.Context(), id)
|
|
respondOne(w, v, err)
|
|
}
|
|
|
|
func (s *Server) deleteHost(w http.ResponseWriter, r *http.Request) {
|
|
id, ok := idParam(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
respondDelete(w, s.store.DeleteHost(r.Context(), id))
|
|
}
|
|
|
|
func (s *Server) listProviders(w http.ResponseWriter, r *http.Request) {
|
|
list, err := s.store.ListProviders(r.Context())
|
|
respondList(w, list, err)
|
|
}
|
|
|
|
func (s *Server) createProvider(w http.ResponseWriter, r *http.Request) {
|
|
var v model.Provider
|
|
if !decode(w, r, &v) {
|
|
return
|
|
}
|
|
if v.Device == "" || v.Name == "" || v.Interface == "" {
|
|
writeError(w, http.StatusBadRequest, "device, name, and interface are required")
|
|
return
|
|
}
|
|
id, err := s.store.CreateProvider(r.Context(), v)
|
|
if err == nil {
|
|
v.ID = id
|
|
}
|
|
respondCreated(w, v, err)
|
|
}
|
|
|
|
func (s *Server) getProvider(w http.ResponseWriter, r *http.Request) {
|
|
id, ok := idParam(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
v, err := s.store.GetProvider(r.Context(), id)
|
|
respondOne(w, v, err)
|
|
}
|
|
|
|
func (s *Server) deleteProvider(w http.ResponseWriter, r *http.Request) {
|
|
id, ok := idParam(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
respondDelete(w, s.store.DeleteProvider(r.Context(), id))
|
|
}
|
|
|
|
func (s *Server) listRoutes(w http.ResponseWriter, r *http.Request) {
|
|
list, err := s.store.ListRoutes(r.Context())
|
|
respondList(w, list, err)
|
|
}
|
|
|
|
func (s *Server) createRoute(w http.ResponseWriter, r *http.Request) {
|
|
var v model.Route
|
|
if !decode(w, r, &v) {
|
|
return
|
|
}
|
|
if v.Device == "" || v.Dest == "" {
|
|
writeError(w, http.StatusBadRequest, "device and dest are required")
|
|
return
|
|
}
|
|
id, err := s.store.CreateRoute(r.Context(), v)
|
|
if err == nil {
|
|
v.ID = id
|
|
}
|
|
respondCreated(w, v, err)
|
|
}
|
|
|
|
func (s *Server) getRoute(w http.ResponseWriter, r *http.Request) {
|
|
id, ok := idParam(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
v, err := s.store.GetRoute(r.Context(), id)
|
|
respondOne(w, v, err)
|
|
}
|
|
|
|
func (s *Server) deleteRoute(w http.ResponseWriter, r *http.Request) {
|
|
id, ok := idParam(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
respondDelete(w, s.store.DeleteRoute(r.Context(), id))
|
|
}
|
|
|
|
func (s *Server) listRoutingRules(w http.ResponseWriter, r *http.Request) {
|
|
list, err := s.store.ListRoutingRules(r.Context())
|
|
respondList(w, list, err)
|
|
}
|
|
|
|
func (s *Server) createRoutingRule(w http.ResponseWriter, r *http.Request) {
|
|
var v model.RoutingRule
|
|
if !decode(w, r, &v) {
|
|
return
|
|
}
|
|
if v.Device == "" || v.Provider == "" {
|
|
writeError(w, http.StatusBadRequest, "device and provider are required")
|
|
return
|
|
}
|
|
id, err := s.store.CreateRoutingRule(r.Context(), v)
|
|
if err == nil {
|
|
v.ID = id
|
|
}
|
|
respondCreated(w, v, err)
|
|
}
|
|
|
|
func (s *Server) getRoutingRule(w http.ResponseWriter, r *http.Request) {
|
|
id, ok := idParam(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
v, err := s.store.GetRoutingRule(r.Context(), id)
|
|
respondOne(w, v, err)
|
|
}
|
|
|
|
func (s *Server) deleteRoutingRule(w http.ResponseWriter, r *http.Request) {
|
|
id, ok := idParam(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
respondDelete(w, s.store.DeleteRoutingRule(r.Context(), id))
|
|
}
|