package api import ( "encoding/json" "net/http" "debtik/internal/vpn" ) // ======================== VXLAN Handlers ======================== func (s *Server) handleListVXLAN(w http.ResponseWriter, r *http.Request) { if s.vpnMgr == nil || s.vpnMgr.VXLAN == nil { writeJSON(w, http.StatusOK, []*vpn.VXLANInstance{}) return } list := s.vpnMgr.VXLAN.List() writeJSON(w, http.StatusOK, list) } func (s *Server) handleSaveVXLAN(w http.ResponseWriter, r *http.Request) { if s.vpnMgr == nil || s.vpnMgr.VXLAN == nil { writeError(w, http.StatusServiceUnavailable, "vxlan subsystem unavailable") return } var inst vpn.VXLANInstance if err := json.NewDecoder(r.Body).Decode(&inst); err != nil { writeError(w, http.StatusBadRequest, "invalid request body") return } if err := s.vpnMgr.VXLAN.Save(&inst); err != nil { writeError(w, http.StatusBadRequest, err.Error()) return } writeJSON(w, http.StatusOK, map[string]any{ "success": true, "id": inst.ID, "name": inst.Name, "vni": inst.VNI, "port": inst.Port, }) } func (s *Server) handleDeleteVXLAN(w http.ResponseWriter, r *http.Request) { if s.vpnMgr == nil || s.vpnMgr.VXLAN == nil { writeError(w, http.StatusServiceUnavailable, "vxlan subsystem unavailable") return } id := r.PathValue("id") if id == "" { writeError(w, http.StatusBadRequest, "interface id required") return } if err := s.vpnMgr.VXLAN.Delete(id); err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } writeJSON(w, http.StatusOK, map[string]any{"success": true, "id": id}) } func (s *Server) handleSetVXLANState(w http.ResponseWriter, r *http.Request) { if s.vpnMgr == nil || s.vpnMgr.VXLAN == nil { writeError(w, http.StatusServiceUnavailable, "vxlan subsystem unavailable") return } id := r.PathValue("id") var req struct { Disabled bool `json:"disabled"` } _ = json.NewDecoder(r.Body).Decode(&req) if err := s.vpnMgr.VXLAN.SetState(id, req.Disabled); err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } writeJSON(w, http.StatusOK, map[string]any{"success": true, "id": id, "disabled": req.Disabled}) } // ======================== VXLAN VTEP Handlers ======================== func (s *Server) handleListVXLANVteps(w http.ResponseWriter, r *http.Request) { if s.vpnMgr == nil || s.vpnMgr.VXLAN == nil { writeJSON(w, http.StatusOK, []*vpn.VXLANVtep{}) return } filterIface := r.URL.Query().Get("interface") list := s.vpnMgr.VXLAN.ListVteps(filterIface) writeJSON(w, http.StatusOK, list) } func (s *Server) handleSaveVXLANVtep(w http.ResponseWriter, r *http.Request) { if s.vpnMgr == nil || s.vpnMgr.VXLAN == nil { writeError(w, http.StatusServiceUnavailable, "vxlan subsystem unavailable") return } var vtep vpn.VXLANVtep if err := json.NewDecoder(r.Body).Decode(&vtep); err != nil { writeError(w, http.StatusBadRequest, "invalid request body") return } if vtep.Interface == "" { writeError(w, http.StatusBadRequest, "interface is required") return } if vtep.RemoteIP == "" { writeError(w, http.StatusBadRequest, "remote_ip is required") return } if err := s.vpnMgr.VXLAN.AddVtep(vtep.Interface, &vtep); err != nil { writeError(w, http.StatusBadRequest, err.Error()) return } writeJSON(w, http.StatusOK, map[string]any{ "success": true, "id": vtep.ID, "interface": vtep.Interface, "remote_ip": vtep.RemoteIP, "port": vtep.Port, }) } func (s *Server) handleDeleteVXLANVtep(w http.ResponseWriter, r *http.Request) { if s.vpnMgr == nil || s.vpnMgr.VXLAN == nil { writeError(w, http.StatusServiceUnavailable, "vxlan subsystem unavailable") return } id := r.PathValue("id") vtepid := r.PathValue("vtepid") if id == "" || vtepid == "" { writeError(w, http.StatusBadRequest, "interface id and vtepid required") return } if err := s.vpnMgr.VXLAN.DeleteVtep(id, vtepid); err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } writeJSON(w, http.StatusOK, map[string]any{"success": true, "id": id, "vtepid": vtepid}) }