dynamic_routing_handlers.go 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326
  1. package api
  2. import (
  3. "encoding/json"
  4. "io"
  5. "net/http"
  6. "strings"
  7. "debtik/internal/dynamicrouting"
  8. )
  9. // Summary
  10. func (s *Server) handleDynamicRoutingSummary(w http.ResponseWriter, r *http.Request) {
  11. summary := s.dynRoutingMgr.GetSummary()
  12. writeJSON(w, http.StatusOK, summary)
  13. }
  14. // -------------------------------------------------------------
  15. // BGP Handlers
  16. // -------------------------------------------------------------
  17. func (s *Server) handleGetBGPInstance(w http.ResponseWriter, r *http.Request) {
  18. inst := s.dynRoutingMgr.GetBGPInstance()
  19. writeJSON(w, http.StatusOK, inst)
  20. }
  21. func (s *Server) handleUpdateBGPInstance(w http.ResponseWriter, r *http.Request) {
  22. var inst dynamicrouting.BGPInstance
  23. if err := json.NewDecoder(r.Body).Decode(&inst); err != nil {
  24. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  25. return
  26. }
  27. if err := s.dynRoutingMgr.UpdateBGPInstance(inst); err != nil {
  28. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  29. return
  30. }
  31. writeJSON(w, http.StatusOK, s.dynRoutingMgr.GetBGPInstance())
  32. }
  33. func (s *Server) handleListBGPPeers(w http.ResponseWriter, r *http.Request) {
  34. peers := s.dynRoutingMgr.ListBGPPeers()
  35. if peers == nil {
  36. peers = []dynamicrouting.BGPPeer{}
  37. }
  38. writeJSON(w, http.StatusOK, peers)
  39. }
  40. func (s *Server) handleSaveBGPPeer(w http.ResponseWriter, r *http.Request) {
  41. var peer dynamicrouting.BGPPeer
  42. if err := json.NewDecoder(r.Body).Decode(&peer); err != nil {
  43. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  44. return
  45. }
  46. if peer.RemoteAddress == "" || peer.RemoteAS == 0 {
  47. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "remote_address and remote_as are required"})
  48. return
  49. }
  50. if err := s.dynRoutingMgr.SaveBGPPeer(&peer); err != nil {
  51. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  52. return
  53. }
  54. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "peer": peer})
  55. }
  56. func (s *Server) handleDeleteBGPPeer(w http.ResponseWriter, r *http.Request) {
  57. id := r.PathValue("id")
  58. if id == "" {
  59. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing peer id"})
  60. return
  61. }
  62. if err := s.dynRoutingMgr.DeleteBGPPeer(id); err != nil {
  63. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  64. return
  65. }
  66. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  67. }
  68. func (s *Server) handleSetBGPPeerState(w http.ResponseWriter, r *http.Request) {
  69. id := r.PathValue("id")
  70. var req struct {
  71. Disabled bool `json:"disabled"`
  72. }
  73. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  74. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  75. return
  76. }
  77. if err := s.dynRoutingMgr.SetBGPPeerState(id, req.Disabled); err != nil {
  78. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  79. return
  80. }
  81. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  82. }
  83. func (s *Server) handleListBGPNetworks(w http.ResponseWriter, r *http.Request) {
  84. nets := s.dynRoutingMgr.ListBGPNetworks()
  85. if nets == nil {
  86. nets = []dynamicrouting.BGPNetwork{}
  87. }
  88. writeJSON(w, http.StatusOK, nets)
  89. }
  90. func (s *Server) handleSaveBGPNetwork(w http.ResponseWriter, r *http.Request) {
  91. var net dynamicrouting.BGPNetwork
  92. if err := json.NewDecoder(r.Body).Decode(&net); err != nil {
  93. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  94. return
  95. }
  96. if net.Network == "" {
  97. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "network (CIDR) is required"})
  98. return
  99. }
  100. if err := s.dynRoutingMgr.SaveBGPNetwork(net); err != nil {
  101. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  102. return
  103. }
  104. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "network": net})
  105. }
  106. func (s *Server) handleDeleteBGPNetwork(w http.ResponseWriter, r *http.Request) {
  107. id := r.PathValue("id")
  108. if id == "" {
  109. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing network id"})
  110. return
  111. }
  112. if err := s.dynRoutingMgr.DeleteBGPNetwork(id); err != nil {
  113. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  114. return
  115. }
  116. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  117. }
  118. func (s *Server) handleGetBGPRoutes(w http.ResponseWriter, r *http.Request) {
  119. routes := s.dynRoutingMgr.GetBGPRoutes()
  120. if routes == nil {
  121. routes = []dynamicrouting.BGPRoute{}
  122. }
  123. writeJSON(w, http.StatusOK, routes)
  124. }
  125. // -------------------------------------------------------------
  126. // OSPF Handlers (RouterOS v7 Style OSPF)
  127. // -------------------------------------------------------------
  128. func (s *Server) handleListOSPFInstances(w http.ResponseWriter, r *http.Request) {
  129. insts := s.dynRoutingMgr.ListOSPFInstances()
  130. if insts == nil {
  131. insts = []dynamicrouting.OSPFInstance{}
  132. }
  133. writeJSON(w, http.StatusOK, insts)
  134. }
  135. func (s *Server) handleSaveOSPFInstance(w http.ResponseWriter, r *http.Request) {
  136. var inst dynamicrouting.OSPFInstance
  137. if err := json.NewDecoder(r.Body).Decode(&inst); err != nil {
  138. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  139. return
  140. }
  141. if err := s.dynRoutingMgr.SaveOSPFInstance(&inst); err != nil {
  142. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  143. return
  144. }
  145. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "instance": inst})
  146. }
  147. func (s *Server) handleDeleteOSPFInstance(w http.ResponseWriter, r *http.Request) {
  148. id := r.PathValue("id")
  149. if id == "" {
  150. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing instance id"})
  151. return
  152. }
  153. if err := s.dynRoutingMgr.DeleteOSPFInstance(id); err != nil {
  154. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  155. return
  156. }
  157. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  158. }
  159. func (s *Server) handleSetOSPFInstanceState(w http.ResponseWriter, r *http.Request) {
  160. id := r.PathValue("id")
  161. var req struct {
  162. Disabled bool `json:"disabled"`
  163. }
  164. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  165. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  166. return
  167. }
  168. if err := s.dynRoutingMgr.SetOSPFInstanceState(id, req.Disabled); err != nil {
  169. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  170. return
  171. }
  172. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  173. }
  174. func (s *Server) handleGetOSPFInstance(w http.ResponseWriter, r *http.Request) {
  175. inst := s.dynRoutingMgr.GetOSPFInstance()
  176. writeJSON(w, http.StatusOK, inst)
  177. }
  178. func (s *Server) handleUpdateOSPFInstance(w http.ResponseWriter, r *http.Request) {
  179. var inst dynamicrouting.OSPFInstance
  180. if err := json.NewDecoder(r.Body).Decode(&inst); err != nil {
  181. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  182. return
  183. }
  184. if err := s.dynRoutingMgr.UpdateOSPFInstance(inst); err != nil {
  185. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  186. return
  187. }
  188. writeJSON(w, http.StatusOK, s.dynRoutingMgr.GetOSPFInstance())
  189. }
  190. func (s *Server) handleListOSPFAreas(w http.ResponseWriter, r *http.Request) {
  191. areas := s.dynRoutingMgr.ListOSPFAreas()
  192. if areas == nil {
  193. areas = []dynamicrouting.OSPFArea{}
  194. }
  195. writeJSON(w, http.StatusOK, areas)
  196. }
  197. func (s *Server) handleSaveOSPFArea(w http.ResponseWriter, r *http.Request) {
  198. var area dynamicrouting.OSPFArea
  199. if err := json.NewDecoder(r.Body).Decode(&area); err != nil {
  200. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  201. return
  202. }
  203. if area.AreaID == "" {
  204. area.AreaID = "0.0.0.0"
  205. }
  206. if err := s.dynRoutingMgr.SaveOSPFArea(area); err != nil {
  207. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  208. return
  209. }
  210. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "area": area})
  211. }
  212. func (s *Server) handleDeleteOSPFArea(w http.ResponseWriter, r *http.Request) {
  213. id := r.PathValue("id")
  214. if id == "" {
  215. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing area id"})
  216. return
  217. }
  218. if err := s.dynRoutingMgr.DeleteOSPFArea(id); err != nil {
  219. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  220. return
  221. }
  222. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  223. }
  224. func (s *Server) handleSetOSPFAreaState(w http.ResponseWriter, r *http.Request) {
  225. id := r.PathValue("id")
  226. var req struct {
  227. Disabled bool `json:"disabled"`
  228. }
  229. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  230. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  231. return
  232. }
  233. if err := s.dynRoutingMgr.SetOSPFAreaState(id, req.Disabled); err != nil {
  234. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  235. return
  236. }
  237. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  238. }
  239. // Area Ranges
  240. func (s *Server) handleListOSPFAreaRanges(w http.ResponseWriter, r *http.Request) {
  241. ranges := s.dynRoutingMgr.ListOSPFAreaRanges()
  242. if ranges == nil {
  243. ranges = []dynamicrouting.OSPFAreaRange{}
  244. }
  245. writeJSON(w, http.StatusOK, ranges)
  246. }
  247. func (s *Server) handleSaveOSPFAreaRange(w http.ResponseWriter, r *http.Request) {
  248. var ar dynamicrouting.OSPFAreaRange
  249. if err := json.NewDecoder(r.Body).Decode(&ar); err != nil {
  250. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  251. return
  252. }
  253. if ar.Prefix == "" {
  254. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Prefix is required"})
  255. return
  256. }
  257. if err := s.dynRoutingMgr.SaveOSPFAreaRange(ar); err != nil {
  258. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  259. return
  260. }
  261. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "area_range": ar})
  262. }
  263. func (s *Server) handleDeleteOSPFAreaRange(w http.ResponseWriter, r *http.Request) {
  264. id := r.PathValue("id")
  265. if id == "" {
  266. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing range id"})
  267. return
  268. }
  269. if err := s.dynRoutingMgr.DeleteOSPFAreaRange(id); err != nil {
  270. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  271. return
  272. }
  273. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  274. }
  275. // Interface Templates
  276. func (s *Server) handleListOSPFInterfaces(w http.ResponseWriter, r *http.Request) {
  277. ifaces := s.dynRoutingMgr.ListOSPFInterfaces()
  278. if ifaces == nil {
  279. ifaces = []dynamicrouting.OSPFInterface{}
  280. }
  281. writeJSON(w, http.StatusOK, ifaces)
  282. }
  283. func (s *Server) handleSaveOSPFInterface(w http.ResponseWriter, r *http.Request) {
  284. var iface dynamicrouting.OSPFInterface
  285. if err := json.NewDecoder(r.Body).Decode(&iface); err != nil {
  286. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  287. return
  288. }
  289. if err := s.dynRoutingMgr.SaveOSPFInterface(iface); err != nil {
  290. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  291. return
  292. }
  293. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "interface": iface})
  294. }
  295. func (s *Server) handleDeleteOSPFInterface(w http.ResponseWriter, r *http.Request) {
  296. id := r.PathValue("id")
  297. if id == "" {
  298. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing interface id"})
  299. return
  300. }
  301. if err := s.dynRoutingMgr.DeleteOSPFInterface(id); err != nil {
  302. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  303. return
  304. }
  305. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  306. }
  307. func (s *Server) handleSetOSPFInterfaceState(w http.ResponseWriter, r *http.Request) {
  308. id := r.PathValue("id")
  309. var req struct {
  310. Disabled bool `json:"disabled"`
  311. }
  312. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  313. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  314. return
  315. }
  316. if err := s.dynRoutingMgr.SetOSPFInterfaceState(id, req.Disabled); err != nil {
  317. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  318. return
  319. }
  320. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  321. }
  322. // Live Dynamic Interfaces
  323. func (s *Server) handleGetOSPFInterfacesLive(w http.ResponseWriter, r *http.Request) {
  324. live := s.dynRoutingMgr.GetOSPFInterfacesLive()
  325. if live == nil {
  326. live = []dynamicrouting.OSPFInterfaceLive{}
  327. }
  328. writeJSON(w, http.StatusOK, live)
  329. }
  330. // Static Neighbors
  331. func (s *Server) handleListOSPFStaticNeighbors(w http.ResponseWriter, r *http.Request) {
  332. nbrs := s.dynRoutingMgr.ListOSPFStaticNeighbors()
  333. if nbrs == nil {
  334. nbrs = []dynamicrouting.OSPFStaticNeighbor{}
  335. }
  336. writeJSON(w, http.StatusOK, nbrs)
  337. }
  338. func (s *Server) handleSaveOSPFStaticNeighbor(w http.ResponseWriter, r *http.Request) {
  339. var nbr dynamicrouting.OSPFStaticNeighbor
  340. if err := json.NewDecoder(r.Body).Decode(&nbr); err != nil {
  341. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  342. return
  343. }
  344. if nbr.Address == "" {
  345. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Address is required"})
  346. return
  347. }
  348. if err := s.dynRoutingMgr.SaveOSPFStaticNeighbor(nbr); err != nil {
  349. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  350. return
  351. }
  352. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "neighbor": nbr})
  353. }
  354. func (s *Server) handleDeleteOSPFStaticNeighbor(w http.ResponseWriter, r *http.Request) {
  355. id := r.PathValue("id")
  356. if id == "" {
  357. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing static neighbor id"})
  358. return
  359. }
  360. if err := s.dynRoutingMgr.DeleteOSPFStaticNeighbor(id); err != nil {
  361. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  362. return
  363. }
  364. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  365. }
  366. func (s *Server) handleSetOSPFStaticNeighborState(w http.ResponseWriter, r *http.Request) {
  367. id := r.PathValue("id")
  368. if id == "" {
  369. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing static neighbor id"})
  370. return
  371. }
  372. var req struct {
  373. Disabled bool `json:"disabled"`
  374. }
  375. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  376. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  377. return
  378. }
  379. if err := s.dynRoutingMgr.SetOSPFStaticNeighborState(id, req.Disabled); err != nil {
  380. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  381. return
  382. }
  383. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  384. }
  385. // Live Neighbors
  386. func (s *Server) handleGetOSPFNeighbors(w http.ResponseWriter, r *http.Request) {
  387. nbrs := s.dynRoutingMgr.GetOSPFNeighbors()
  388. if nbrs == nil {
  389. nbrs = []dynamicrouting.OSPFNeighbor{}
  390. }
  391. writeJSON(w, http.StatusOK, nbrs)
  392. }
  393. // Live LSA Database
  394. func (s *Server) handleGetOSPFLSA(w http.ResponseWriter, r *http.Request) {
  395. lsa := s.dynRoutingMgr.GetOSPFLSA()
  396. if lsa == nil {
  397. lsa = []dynamicrouting.OSPFLSA{}
  398. }
  399. writeJSON(w, http.StatusOK, lsa)
  400. }
  401. func (s *Server) handleGetOSPFRoutes(w http.ResponseWriter, r *http.Request) {
  402. routes := s.dynRoutingMgr.GetOSPFRoutes()
  403. if routes == nil {
  404. routes = []dynamicrouting.OSPFRoute{}
  405. }
  406. writeJSON(w, http.StatusOK, routes)
  407. }
  408. // -------------------------------------------------------------
  409. // Routing Filters Handlers (/routing filter)
  410. // -------------------------------------------------------------
  411. func (s *Server) handleListRoutingFilters(w http.ResponseWriter, r *http.Request) {
  412. filters := s.dynRoutingMgr.ListRoutingFilters()
  413. if filters == nil {
  414. filters = []dynamicrouting.RoutingFilterRule{}
  415. }
  416. writeJSON(w, http.StatusOK, filters)
  417. }
  418. func (s *Server) handleSaveRoutingFilter(w http.ResponseWriter, r *http.Request) {
  419. var rule dynamicrouting.RoutingFilterRule
  420. if err := json.NewDecoder(r.Body).Decode(&rule); err != nil {
  421. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  422. return
  423. }
  424. if rule.Chain == "" {
  425. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Chain name is required"})
  426. return
  427. }
  428. if rule.Action == "" && rule.Rule == "" {
  429. rule.Action = "accept"
  430. }
  431. if err := s.dynRoutingMgr.SaveRoutingFilter(&rule); err != nil {
  432. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  433. return
  434. }
  435. writeJSON(w, http.StatusOK, map[string]string{"status": "success", "id": rule.ID})
  436. }
  437. func (s *Server) handleDeleteRoutingFilter(w http.ResponseWriter, r *http.Request) {
  438. id := r.PathValue("id")
  439. if id == "" {
  440. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing filter rule ID"})
  441. return
  442. }
  443. if err := s.dynRoutingMgr.DeleteRoutingFilter(id); err != nil {
  444. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  445. return
  446. }
  447. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  448. }
  449. func (s *Server) handleSetRoutingFilterState(w http.ResponseWriter, r *http.Request) {
  450. id := r.PathValue("id")
  451. if id == "" {
  452. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing filter rule ID"})
  453. return
  454. }
  455. var req struct {
  456. Disabled bool `json:"disabled"`
  457. }
  458. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  459. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  460. return
  461. }
  462. if err := s.dynRoutingMgr.SetRoutingFilterState(id, req.Disabled); err != nil {
  463. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  464. return
  465. }
  466. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  467. }
  468. func (s *Server) handleMoveRoutingFilter(w http.ResponseWriter, r *http.Request) {
  469. id := r.PathValue("id")
  470. if id == "" {
  471. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing filter rule ID"})
  472. return
  473. }
  474. var req struct {
  475. Direction string `json:"direction"`
  476. }
  477. if err := json.NewDecoder(r.Body).Decode(&req); err != nil && err != io.EOF {
  478. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  479. return
  480. }
  481. dir := strings.ToLower(strings.TrimSpace(req.Direction))
  482. if dir != "up" && dir != "down" {
  483. dir = "up"
  484. }
  485. if err := s.dynRoutingMgr.MoveRoutingFilter(id, dir); err != nil {
  486. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  487. return
  488. }
  489. writeJSON(w, http.StatusOK, map[string]any{"status": "success", "id": id, "direction": dir})
  490. }
  491. // -------------------------------------------------------------
  492. // Community Lists Handlers (/routing filter community-list)
  493. // -------------------------------------------------------------
  494. func (s *Server) handleListCommunityLists(w http.ResponseWriter, r *http.Request) {
  495. lists := s.dynRoutingMgr.ListCommunityLists()
  496. if lists == nil {
  497. lists = []dynamicrouting.RoutingFilterCommunityList{}
  498. }
  499. writeJSON(w, http.StatusOK, lists)
  500. }
  501. func (s *Server) handleSaveCommunityList(w http.ResponseWriter, r *http.Request) {
  502. var cl dynamicrouting.RoutingFilterCommunityList
  503. if err := json.NewDecoder(r.Body).Decode(&cl); err != nil {
  504. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  505. return
  506. }
  507. if strings.TrimSpace(cl.Name) == "" {
  508. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "List name is required"})
  509. return
  510. }
  511. if err := s.dynRoutingMgr.SaveCommunityList(&cl); err != nil {
  512. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  513. return
  514. }
  515. writeJSON(w, http.StatusOK, map[string]string{"status": "success", "id": cl.ID})
  516. }
  517. func (s *Server) handleDeleteCommunityList(w http.ResponseWriter, r *http.Request) {
  518. id := r.PathValue("id")
  519. if id == "" {
  520. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing community list ID"})
  521. return
  522. }
  523. if err := s.dynRoutingMgr.DeleteCommunityList(id); err != nil {
  524. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  525. return
  526. }
  527. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  528. }
  529. func (s *Server) handleSetCommunityListState(w http.ResponseWriter, r *http.Request) {
  530. id := r.PathValue("id")
  531. if id == "" {
  532. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing community list ID"})
  533. return
  534. }
  535. var req struct {
  536. Disabled bool `json:"disabled"`
  537. }
  538. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  539. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  540. return
  541. }
  542. if err := s.dynRoutingMgr.SetCommunityListState(id, req.Disabled); err != nil {
  543. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  544. return
  545. }
  546. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  547. }
  548. // -------------------------------------------------------------
  549. // AS Lists Handlers (/routing filter num-list)
  550. // -------------------------------------------------------------
  551. func (s *Server) handleListASLists(w http.ResponseWriter, r *http.Request) {
  552. lists := s.dynRoutingMgr.ListASLists()
  553. if lists == nil {
  554. lists = []dynamicrouting.RoutingFilterASList{}
  555. }
  556. writeJSON(w, http.StatusOK, lists)
  557. }
  558. func (s *Server) handleSaveASList(w http.ResponseWriter, r *http.Request) {
  559. var al dynamicrouting.RoutingFilterASList
  560. if err := json.NewDecoder(r.Body).Decode(&al); err != nil {
  561. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  562. return
  563. }
  564. if strings.TrimSpace(al.Name) == "" {
  565. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "List name is required"})
  566. return
  567. }
  568. if err := s.dynRoutingMgr.SaveASList(&al); err != nil {
  569. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  570. return
  571. }
  572. writeJSON(w, http.StatusOK, map[string]string{"status": "success", "id": al.ID})
  573. }
  574. func (s *Server) handleDeleteASList(w http.ResponseWriter, r *http.Request) {
  575. id := r.PathValue("id")
  576. if id == "" {
  577. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing AS list ID"})
  578. return
  579. }
  580. if err := s.dynRoutingMgr.DeleteASList(id); err != nil {
  581. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  582. return
  583. }
  584. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  585. }
  586. func (s *Server) handleSetASListState(w http.ResponseWriter, r *http.Request) {
  587. id := r.PathValue("id")
  588. if id == "" {
  589. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing AS list ID"})
  590. return
  591. }
  592. var req struct {
  593. Disabled bool `json:"disabled"`
  594. }
  595. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  596. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  597. return
  598. }
  599. if err := s.dynRoutingMgr.SetASListState(id, req.Disabled); err != nil {
  600. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  601. return
  602. }
  603. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  604. }
  605. // -------------------------------------------------------------
  606. // RIP Handlers (/api/routing/rip/*)
  607. // -------------------------------------------------------------
  608. func (s *Server) handleListRIPInstances(w http.ResponseWriter, r *http.Request) {
  609. insts := s.dynRoutingMgr.ListRIPInstances()
  610. if insts == nil {
  611. insts = []dynamicrouting.RIPInstance{}
  612. }
  613. writeJSON(w, http.StatusOK, insts)
  614. }
  615. func (s *Server) handleSaveRIPInstance(w http.ResponseWriter, r *http.Request) {
  616. var inst dynamicrouting.RIPInstance
  617. if err := json.NewDecoder(r.Body).Decode(&inst); err != nil {
  618. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  619. return
  620. }
  621. res, err := s.dynRoutingMgr.SaveRIPInstance(inst)
  622. if err != nil {
  623. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  624. return
  625. }
  626. writeJSON(w, http.StatusOK, res)
  627. }
  628. func (s *Server) handleDeleteRIPInstance(w http.ResponseWriter, r *http.Request) {
  629. id := r.PathValue("id")
  630. if id == "" {
  631. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing instance ID"})
  632. return
  633. }
  634. if err := s.dynRoutingMgr.DeleteRIPInstance(id); err != nil {
  635. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  636. return
  637. }
  638. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  639. }
  640. func (s *Server) handleSetRIPInstanceState(w http.ResponseWriter, r *http.Request) {
  641. id := r.PathValue("id")
  642. var req struct {
  643. Disabled bool `json:"disabled"`
  644. }
  645. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  646. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  647. return
  648. }
  649. if err := s.dynRoutingMgr.SetRIPInstanceState(id, req.Disabled); err != nil {
  650. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  651. return
  652. }
  653. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  654. }
  655. func (s *Server) handleListRIPInterfaces(w http.ResponseWriter, r *http.Request) {
  656. ifaces := s.dynRoutingMgr.ListRIPInterfaces()
  657. if ifaces == nil {
  658. ifaces = []dynamicrouting.RIPInterface{}
  659. }
  660. writeJSON(w, http.StatusOK, ifaces)
  661. }
  662. func (s *Server) handleSaveRIPInterface(w http.ResponseWriter, r *http.Request) {
  663. var iface dynamicrouting.RIPInterface
  664. if err := json.NewDecoder(r.Body).Decode(&iface); err != nil {
  665. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  666. return
  667. }
  668. res, err := s.dynRoutingMgr.SaveRIPInterface(iface)
  669. if err != nil {
  670. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  671. return
  672. }
  673. writeJSON(w, http.StatusOK, res)
  674. }
  675. func (s *Server) handleDeleteRIPInterface(w http.ResponseWriter, r *http.Request) {
  676. id := r.PathValue("id")
  677. if id == "" {
  678. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing interface ID"})
  679. return
  680. }
  681. if err := s.dynRoutingMgr.DeleteRIPInterface(id); err != nil {
  682. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  683. return
  684. }
  685. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  686. }
  687. func (s *Server) handleSetRIPInterfaceState(w http.ResponseWriter, r *http.Request) {
  688. id := r.PathValue("id")
  689. var req struct {
  690. Disabled bool `json:"disabled"`
  691. }
  692. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  693. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  694. return
  695. }
  696. if err := s.dynRoutingMgr.SetRIPInterfaceState(id, req.Disabled); err != nil {
  697. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  698. return
  699. }
  700. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  701. }
  702. func (s *Server) handleListRIPNeighbors(w http.ResponseWriter, r *http.Request) {
  703. nbrs := s.dynRoutingMgr.ListRIPNeighbors()
  704. if nbrs == nil {
  705. nbrs = []dynamicrouting.RIPNeighbor{}
  706. }
  707. writeJSON(w, http.StatusOK, nbrs)
  708. }
  709. func (s *Server) handleSaveRIPNeighbor(w http.ResponseWriter, r *http.Request) {
  710. var nbr dynamicrouting.RIPNeighbor
  711. if err := json.NewDecoder(r.Body).Decode(&nbr); err != nil {
  712. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  713. return
  714. }
  715. res, err := s.dynRoutingMgr.SaveRIPNeighbor(nbr)
  716. if err != nil {
  717. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  718. return
  719. }
  720. writeJSON(w, http.StatusOK, res)
  721. }
  722. func (s *Server) handleDeleteRIPNeighbor(w http.ResponseWriter, r *http.Request) {
  723. id := r.PathValue("id")
  724. if id == "" {
  725. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing neighbor ID"})
  726. return
  727. }
  728. if err := s.dynRoutingMgr.DeleteRIPNeighbor(id); err != nil {
  729. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  730. return
  731. }
  732. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  733. }
  734. func (s *Server) handleGetRIPNeighborsLive(w http.ResponseWriter, r *http.Request) {
  735. nbrs := s.dynRoutingMgr.GetRIPNeighbors()
  736. if nbrs == nil {
  737. nbrs = []dynamicrouting.RIPNeighborLive{}
  738. }
  739. writeJSON(w, http.StatusOK, nbrs)
  740. }
  741. func (s *Server) handleGetRIPRoutes(w http.ResponseWriter, r *http.Request) {
  742. rts := s.dynRoutingMgr.GetRIPRoutes()
  743. if rts == nil {
  744. rts = []dynamicrouting.RIPRoute{}
  745. }
  746. writeJSON(w, http.StatusOK, rts)
  747. }
  748. // -------------------------------------------------------------
  749. // BFD Handlers (/api/routing/bfd/*)
  750. // -------------------------------------------------------------
  751. func (s *Server) handleGetBFDInstance(w http.ResponseWriter, r *http.Request) {
  752. inst := s.dynRoutingMgr.GetBFDInstance()
  753. writeJSON(w, http.StatusOK, inst)
  754. }
  755. func (s *Server) handleSaveBFDInstance(w http.ResponseWriter, r *http.Request) {
  756. var inst dynamicrouting.BFDInstance
  757. if err := json.NewDecoder(r.Body).Decode(&inst); err != nil {
  758. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  759. return
  760. }
  761. if err := s.dynRoutingMgr.SaveBFDInstance(inst); err != nil {
  762. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  763. return
  764. }
  765. writeJSON(w, http.StatusOK, s.dynRoutingMgr.GetBFDInstance())
  766. }
  767. func (s *Server) handleListBFDInterfaces(w http.ResponseWriter, r *http.Request) {
  768. ifaces := s.dynRoutingMgr.ListBFDInterfaces()
  769. if ifaces == nil {
  770. ifaces = []dynamicrouting.BFDInterface{}
  771. }
  772. writeJSON(w, http.StatusOK, ifaces)
  773. }
  774. func (s *Server) handleSaveBFDInterface(w http.ResponseWriter, r *http.Request) {
  775. var iface dynamicrouting.BFDInterface
  776. if err := json.NewDecoder(r.Body).Decode(&iface); err != nil {
  777. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  778. return
  779. }
  780. res, err := s.dynRoutingMgr.SaveBFDInterface(iface)
  781. if err != nil {
  782. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  783. return
  784. }
  785. writeJSON(w, http.StatusOK, res)
  786. }
  787. func (s *Server) handleDeleteBFDInterface(w http.ResponseWriter, r *http.Request) {
  788. id := r.PathValue("id")
  789. if id == "" {
  790. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing interface ID"})
  791. return
  792. }
  793. if err := s.dynRoutingMgr.DeleteBFDInterface(id); err != nil {
  794. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  795. return
  796. }
  797. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  798. }
  799. func (s *Server) handleSetBFDInterfaceState(w http.ResponseWriter, r *http.Request) {
  800. id := r.PathValue("id")
  801. var req struct {
  802. Disabled bool `json:"disabled"`
  803. }
  804. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  805. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  806. return
  807. }
  808. if err := s.dynRoutingMgr.SetBFDInterfaceState(id, req.Disabled); err != nil {
  809. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  810. return
  811. }
  812. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  813. }
  814. func (s *Server) handleListBFDNeighbors(w http.ResponseWriter, r *http.Request) {
  815. nbrs := s.dynRoutingMgr.ListBFDNeighbors()
  816. if nbrs == nil {
  817. nbrs = []dynamicrouting.BFDNeighbor{}
  818. }
  819. writeJSON(w, http.StatusOK, nbrs)
  820. }
  821. func (s *Server) handleSaveBFDNeighbor(w http.ResponseWriter, r *http.Request) {
  822. var nbr dynamicrouting.BFDNeighbor
  823. if err := json.NewDecoder(r.Body).Decode(&nbr); err != nil {
  824. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  825. return
  826. }
  827. res, err := s.dynRoutingMgr.SaveBFDNeighbor(nbr)
  828. if err != nil {
  829. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  830. return
  831. }
  832. writeJSON(w, http.StatusOK, res)
  833. }
  834. func (s *Server) handleDeleteBFDNeighbor(w http.ResponseWriter, r *http.Request) {
  835. id := r.PathValue("id")
  836. if id == "" {
  837. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing neighbor ID"})
  838. return
  839. }
  840. if err := s.dynRoutingMgr.DeleteBFDNeighbor(id); err != nil {
  841. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  842. return
  843. }
  844. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  845. }
  846. func (s *Server) handleGetBFDSessions(w http.ResponseWriter, r *http.Request) {
  847. sessions := s.dynRoutingMgr.GetBFDSessions()
  848. if sessions == nil {
  849. sessions = []dynamicrouting.BFDSession{}
  850. }
  851. writeJSON(w, http.StatusOK, sessions)
  852. }
  853. // -------------------------------------------------------------
  854. // Babel Handlers (/api/routing/babel/*)
  855. // -------------------------------------------------------------
  856. func (s *Server) handleListBabelInstances(w http.ResponseWriter, r *http.Request) {
  857. insts := s.dynRoutingMgr.ListBabelInstances()
  858. if insts == nil {
  859. insts = []dynamicrouting.BabelInstance{}
  860. }
  861. writeJSON(w, http.StatusOK, insts)
  862. }
  863. func (s *Server) handleSaveBabelInstance(w http.ResponseWriter, r *http.Request) {
  864. var inst dynamicrouting.BabelInstance
  865. if err := json.NewDecoder(r.Body).Decode(&inst); err != nil {
  866. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  867. return
  868. }
  869. res, err := s.dynRoutingMgr.SaveBabelInstance(inst)
  870. if err != nil {
  871. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  872. return
  873. }
  874. writeJSON(w, http.StatusOK, res)
  875. }
  876. func (s *Server) handleDeleteBabelInstance(w http.ResponseWriter, r *http.Request) {
  877. id := r.PathValue("id")
  878. if id == "" {
  879. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing instance ID"})
  880. return
  881. }
  882. if err := s.dynRoutingMgr.DeleteBabelInstance(id); err != nil {
  883. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  884. return
  885. }
  886. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  887. }
  888. func (s *Server) handleSetBabelInstanceState(w http.ResponseWriter, r *http.Request) {
  889. id := r.PathValue("id")
  890. var req struct {
  891. Disabled bool `json:"disabled"`
  892. }
  893. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  894. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  895. return
  896. }
  897. if err := s.dynRoutingMgr.SetBabelInstanceState(id, req.Disabled); err != nil {
  898. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  899. return
  900. }
  901. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  902. }
  903. func (s *Server) handleListBabelInterfaces(w http.ResponseWriter, r *http.Request) {
  904. ifaces := s.dynRoutingMgr.ListBabelInterfaces()
  905. if ifaces == nil {
  906. ifaces = []dynamicrouting.BabelInterface{}
  907. }
  908. writeJSON(w, http.StatusOK, ifaces)
  909. }
  910. func (s *Server) handleGetBabelInterfacesLive(w http.ResponseWriter, r *http.Request) {
  911. ifaces := s.dynRoutingMgr.GetBabelInterfacesLive()
  912. if ifaces == nil {
  913. ifaces = []dynamicrouting.BabelInterfaceLive{}
  914. }
  915. writeJSON(w, http.StatusOK, ifaces)
  916. }
  917. func (s *Server) handleSaveBabelInterface(w http.ResponseWriter, r *http.Request) {
  918. var iface dynamicrouting.BabelInterface
  919. if err := json.NewDecoder(r.Body).Decode(&iface); err != nil {
  920. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  921. return
  922. }
  923. res, err := s.dynRoutingMgr.SaveBabelInterface(iface)
  924. if err != nil {
  925. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  926. return
  927. }
  928. writeJSON(w, http.StatusOK, res)
  929. }
  930. func (s *Server) handleDeleteBabelInterface(w http.ResponseWriter, r *http.Request) {
  931. id := r.PathValue("id")
  932. if id == "" {
  933. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing interface ID"})
  934. return
  935. }
  936. if err := s.dynRoutingMgr.DeleteBabelInterface(id); err != nil {
  937. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  938. return
  939. }
  940. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  941. }
  942. func (s *Server) handleSetBabelInterfaceState(w http.ResponseWriter, r *http.Request) {
  943. id := r.PathValue("id")
  944. var req struct {
  945. Disabled bool `json:"disabled"`
  946. }
  947. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  948. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  949. return
  950. }
  951. if err := s.dynRoutingMgr.SetBabelInterfaceState(id, req.Disabled); err != nil {
  952. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  953. return
  954. }
  955. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  956. }
  957. func (s *Server) handleGetBabelNeighbors(w http.ResponseWriter, r *http.Request) {
  958. nbrs := s.dynRoutingMgr.GetBabelNeighbors()
  959. if nbrs == nil {
  960. nbrs = []dynamicrouting.BabelNeighbor{}
  961. }
  962. writeJSON(w, http.StatusOK, nbrs)
  963. }
  964. func (s *Server) handleGetBabelRoutes(w http.ResponseWriter, r *http.Request) {
  965. rts := s.dynRoutingMgr.GetBabelRoutes()
  966. if rts == nil {
  967. rts = []dynamicrouting.BabelRoute{}
  968. }
  969. writeJSON(w, http.StatusOK, rts)
  970. }
  971. // -------------------------------------------------------------
  972. // RAdv Handlers (/api/routing/radv/*)
  973. // -------------------------------------------------------------
  974. func (s *Server) handleListRAdvInstances(w http.ResponseWriter, r *http.Request) {
  975. insts := s.dynRoutingMgr.ListRAdvInstances()
  976. if insts == nil {
  977. insts = []dynamicrouting.RAdvInstance{}
  978. }
  979. writeJSON(w, http.StatusOK, insts)
  980. }
  981. func (s *Server) handleSaveRAdvInstance(w http.ResponseWriter, r *http.Request) {
  982. var inst dynamicrouting.RAdvInstance
  983. if err := json.NewDecoder(r.Body).Decode(&inst); err != nil {
  984. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  985. return
  986. }
  987. res, err := s.dynRoutingMgr.SaveRAdvInstance(inst)
  988. if err != nil {
  989. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  990. return
  991. }
  992. writeJSON(w, http.StatusOK, res)
  993. }
  994. func (s *Server) handleDeleteRAdvInstance(w http.ResponseWriter, r *http.Request) {
  995. id := r.PathValue("id")
  996. if id == "" {
  997. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing instance ID"})
  998. return
  999. }
  1000. if err := s.dynRoutingMgr.DeleteRAdvInstance(id); err != nil {
  1001. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1002. return
  1003. }
  1004. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  1005. }
  1006. func (s *Server) handleSetRAdvInstanceState(w http.ResponseWriter, r *http.Request) {
  1007. id := r.PathValue("id")
  1008. var req struct {
  1009. Disabled bool `json:"disabled"`
  1010. }
  1011. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  1012. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  1013. return
  1014. }
  1015. if err := s.dynRoutingMgr.SetRAdvInstanceState(id, req.Disabled); err != nil {
  1016. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1017. return
  1018. }
  1019. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  1020. }
  1021. func (s *Server) handleListRAdvInterfaces(w http.ResponseWriter, r *http.Request) {
  1022. ifaces := s.dynRoutingMgr.ListRAdvInterfaces()
  1023. if ifaces == nil {
  1024. ifaces = []dynamicrouting.RAdvInterface{}
  1025. }
  1026. writeJSON(w, http.StatusOK, ifaces)
  1027. }
  1028. func (s *Server) handleSaveRAdvInterface(w http.ResponseWriter, r *http.Request) {
  1029. var iface dynamicrouting.RAdvInterface
  1030. if err := json.NewDecoder(r.Body).Decode(&iface); err != nil {
  1031. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  1032. return
  1033. }
  1034. res, err := s.dynRoutingMgr.SaveRAdvInterface(iface)
  1035. if err != nil {
  1036. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1037. return
  1038. }
  1039. writeJSON(w, http.StatusOK, res)
  1040. }
  1041. func (s *Server) handleDeleteRAdvInterface(w http.ResponseWriter, r *http.Request) {
  1042. id := r.PathValue("id")
  1043. if id == "" {
  1044. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing interface ID"})
  1045. return
  1046. }
  1047. if err := s.dynRoutingMgr.DeleteRAdvInterface(id); err != nil {
  1048. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1049. return
  1050. }
  1051. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  1052. }
  1053. func (s *Server) handleSetRAdvInterfaceState(w http.ResponseWriter, r *http.Request) {
  1054. id := r.PathValue("id")
  1055. var req struct {
  1056. Disabled bool `json:"disabled"`
  1057. }
  1058. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  1059. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  1060. return
  1061. }
  1062. if err := s.dynRoutingMgr.SetRAdvInterfaceState(id, req.Disabled); err != nil {
  1063. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1064. return
  1065. }
  1066. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  1067. }
  1068. // ==========================================
  1069. // EIGRP Handlers (/api/routing/eigrp/...)
  1070. // ==========================================
  1071. func (s *Server) handleListEIGRPInstances(w http.ResponseWriter, r *http.Request) {
  1072. insts := s.dynRoutingMgr.ListEIGRPInstances()
  1073. if insts == nil {
  1074. insts = []dynamicrouting.EIGRPInstance{}
  1075. }
  1076. writeJSON(w, http.StatusOK, insts)
  1077. }
  1078. func (s *Server) handleSaveEIGRPInstance(w http.ResponseWriter, r *http.Request) {
  1079. var inst dynamicrouting.EIGRPInstance
  1080. if err := json.NewDecoder(r.Body).Decode(&inst); err != nil {
  1081. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  1082. return
  1083. }
  1084. res, err := s.dynRoutingMgr.SaveEIGRPInstance(inst)
  1085. if err != nil {
  1086. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1087. return
  1088. }
  1089. writeJSON(w, http.StatusOK, res)
  1090. }
  1091. func (s *Server) handleDeleteEIGRPInstance(w http.ResponseWriter, r *http.Request) {
  1092. id := r.PathValue("id")
  1093. if id == "" {
  1094. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing instance ID"})
  1095. return
  1096. }
  1097. if err := s.dynRoutingMgr.DeleteEIGRPInstance(id); err != nil {
  1098. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1099. return
  1100. }
  1101. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  1102. }
  1103. func (s *Server) handleSetEIGRPInstanceState(w http.ResponseWriter, r *http.Request) {
  1104. id := r.PathValue("id")
  1105. var req struct {
  1106. Disabled bool `json:"disabled"`
  1107. }
  1108. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  1109. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  1110. return
  1111. }
  1112. if err := s.dynRoutingMgr.SetEIGRPInstanceState(id, req.Disabled); err != nil {
  1113. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1114. return
  1115. }
  1116. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  1117. }
  1118. func (s *Server) handleListEIGRPInterfaces(w http.ResponseWriter, r *http.Request) {
  1119. ifaces := s.dynRoutingMgr.ListEIGRPInterfaces()
  1120. if ifaces == nil {
  1121. ifaces = []dynamicrouting.EIGRPInterface{}
  1122. }
  1123. writeJSON(w, http.StatusOK, ifaces)
  1124. }
  1125. func (s *Server) handleSaveEIGRPInterface(w http.ResponseWriter, r *http.Request) {
  1126. var iface dynamicrouting.EIGRPInterface
  1127. if err := json.NewDecoder(r.Body).Decode(&iface); err != nil {
  1128. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  1129. return
  1130. }
  1131. res, err := s.dynRoutingMgr.SaveEIGRPInterface(iface)
  1132. if err != nil {
  1133. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1134. return
  1135. }
  1136. writeJSON(w, http.StatusOK, res)
  1137. }
  1138. func (s *Server) handleDeleteEIGRPInterface(w http.ResponseWriter, r *http.Request) {
  1139. id := r.PathValue("id")
  1140. if id == "" {
  1141. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing interface ID"})
  1142. return
  1143. }
  1144. if err := s.dynRoutingMgr.DeleteEIGRPInterface(id); err != nil {
  1145. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1146. return
  1147. }
  1148. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  1149. }
  1150. func (s *Server) handleSetEIGRPInterfaceState(w http.ResponseWriter, r *http.Request) {
  1151. id := r.PathValue("id")
  1152. var req struct {
  1153. Disabled bool `json:"disabled"`
  1154. }
  1155. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  1156. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON"})
  1157. return
  1158. }
  1159. if err := s.dynRoutingMgr.SetEIGRPInterfaceState(id, req.Disabled); err != nil {
  1160. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1161. return
  1162. }
  1163. writeJSON(w, http.StatusOK, map[string]interface{}{"status": "success", "disabled": req.Disabled})
  1164. }
  1165. func (s *Server) handleListEIGRPNetworks(w http.ResponseWriter, r *http.Request) {
  1166. nets := s.dynRoutingMgr.ListEIGRPNetworks()
  1167. if nets == nil {
  1168. nets = []dynamicrouting.EIGRPNetwork{}
  1169. }
  1170. writeJSON(w, http.StatusOK, nets)
  1171. }
  1172. func (s *Server) handleSaveEIGRPNetwork(w http.ResponseWriter, r *http.Request) {
  1173. var net dynamicrouting.EIGRPNetwork
  1174. if err := json.NewDecoder(r.Body).Decode(&net); err != nil {
  1175. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  1176. return
  1177. }
  1178. res, err := s.dynRoutingMgr.SaveEIGRPNetwork(net)
  1179. if err != nil {
  1180. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1181. return
  1182. }
  1183. writeJSON(w, http.StatusOK, res)
  1184. }
  1185. func (s *Server) handleDeleteEIGRPNetwork(w http.ResponseWriter, r *http.Request) {
  1186. id := r.PathValue("id")
  1187. if id == "" {
  1188. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Missing network ID"})
  1189. return
  1190. }
  1191. if err := s.dynRoutingMgr.DeleteEIGRPNetwork(id); err != nil {
  1192. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  1193. return
  1194. }
  1195. writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  1196. }
  1197. func (s *Server) handleListEIGRPNeighbors(w http.ResponseWriter, r *http.Request) {
  1198. nbrs := s.dynRoutingMgr.ListEIGRPNeighborsLive()
  1199. if nbrs == nil {
  1200. nbrs = []dynamicrouting.EIGRPNeighborLive{}
  1201. }
  1202. writeJSON(w, http.StatusOK, nbrs)
  1203. }
  1204. func (s *Server) handleListEIGRPTopology(w http.ResponseWriter, r *http.Request) {
  1205. routes := s.dynRoutingMgr.ListEIGRPTopologyLive()
  1206. if routes == nil {
  1207. routes = []dynamicrouting.EIGRPRouteLive{}
  1208. }
  1209. writeJSON(w, http.StatusOK, routes)
  1210. }