network.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. package controller
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "net/http"
  8. "strings"
  9. "github.com/google/uuid"
  10. "github.com/gorilla/mux"
  11. "golang.org/x/exp/slog"
  12. "github.com/gravitl/netmaker/database"
  13. "github.com/gravitl/netmaker/logger"
  14. "github.com/gravitl/netmaker/logic"
  15. "github.com/gravitl/netmaker/logic/acls"
  16. "github.com/gravitl/netmaker/models"
  17. "github.com/gravitl/netmaker/mq"
  18. "github.com/gravitl/netmaker/servercfg"
  19. )
  20. func networkHandlers(r *mux.Router) {
  21. r.HandleFunc("/api/networks", logic.SecurityCheck(true, http.HandlerFunc(getNetworks))).
  22. Methods(http.MethodGet)
  23. r.HandleFunc("/api/v1/networks/stats", logic.SecurityCheck(true, http.HandlerFunc(getNetworksStats))).
  24. Methods(http.MethodGet)
  25. r.HandleFunc("/api/networks", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceNetworks, http.HandlerFunc(createNetwork)))).
  26. Methods(http.MethodPost)
  27. r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(getNetwork))).
  28. Methods(http.MethodGet)
  29. r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(deleteNetwork))).
  30. Methods(http.MethodDelete)
  31. r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(updateNetwork))).
  32. Methods(http.MethodPut)
  33. // ACLs
  34. r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(updateNetworkACL))).
  35. Methods(http.MethodPut)
  36. r.HandleFunc("/api/networks/{networkname}/acls/v2", logic.SecurityCheck(true, http.HandlerFunc(updateNetworkACLv2))).
  37. Methods(http.MethodPut)
  38. r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(getNetworkACL))).
  39. Methods(http.MethodGet)
  40. r.HandleFunc("/api/networks/{networkname}/egress_routes", logic.SecurityCheck(true, http.HandlerFunc(getNetworkEgressRoutes)))
  41. }
  42. // @Summary Lists all networks
  43. // @Router /api/networks [get]
  44. // @Tags Networks
  45. // @Security oauth
  46. // @Produce json
  47. // @Success 200 {object} models.Network
  48. // @Failure 500 {object} models.ErrorResponse
  49. func getNetworks(w http.ResponseWriter, r *http.Request) {
  50. var err error
  51. allnetworks, err := logic.GetNetworks()
  52. if err != nil && !database.IsEmptyRecord(err) {
  53. slog.Error("failed to fetch networks", "error", err.Error())
  54. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  55. return
  56. }
  57. if r.Header.Get("ismaster") != "yes" {
  58. username := r.Header.Get("user")
  59. user, err := logic.GetUser(username)
  60. if err != nil {
  61. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  62. return
  63. }
  64. allnetworks = logic.FilterNetworksByRole(allnetworks, *user)
  65. }
  66. logger.Log(2, r.Header.Get("user"), "fetched networks.")
  67. logic.SortNetworks(allnetworks[:])
  68. w.WriteHeader(http.StatusOK)
  69. json.NewEncoder(w).Encode(allnetworks)
  70. }
  71. // @Summary Lists all networks with stats
  72. // @Router /api/v1/networks/stats [get]
  73. // @Tags Networks
  74. // @Security oauth
  75. // @Produce json
  76. // @Success 200 {object} models.SuccessResponse
  77. // @Failure 500 {object} models.ErrorResponse
  78. func getNetworksStats(w http.ResponseWriter, r *http.Request) {
  79. var err error
  80. allnetworks, err := logic.GetNetworks()
  81. if err != nil && !database.IsEmptyRecord(err) {
  82. slog.Error("failed to fetch networks", "error", err.Error())
  83. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  84. return
  85. }
  86. if r.Header.Get("ismaster") != "yes" {
  87. username := r.Header.Get("user")
  88. user, err := logic.GetUser(username)
  89. if err != nil {
  90. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  91. return
  92. }
  93. allnetworks = logic.FilterNetworksByRole(allnetworks, *user)
  94. }
  95. allNodes, err := logic.GetAllNodes()
  96. if err != nil {
  97. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  98. return
  99. }
  100. netstats := []models.NetworkStatResp{}
  101. logic.SortNetworks(allnetworks[:])
  102. for _, network := range allnetworks {
  103. netstats = append(netstats, models.NetworkStatResp{
  104. Network: network,
  105. Hosts: len(logic.GetNetworkNodesMemory(allNodes, network.NetID)),
  106. })
  107. }
  108. logger.Log(2, r.Header.Get("user"), "fetched networks.")
  109. logic.ReturnSuccessResponseWithJson(w, r, netstats, "fetched networks with stats")
  110. }
  111. // @Summary Get a network
  112. // @Router /api/networks/{networkname} [get]
  113. // @Tags Networks
  114. // @Security oauth
  115. // @Param networkname path string true "Network name"
  116. // @Produce json
  117. // @Success 200 {object} models.Network
  118. // @Failure 500 {object} models.ErrorResponse
  119. func getNetwork(w http.ResponseWriter, r *http.Request) {
  120. // set header.
  121. w.Header().Set("Content-Type", "application/json")
  122. var params = mux.Vars(r)
  123. netname := params["networkname"]
  124. network, err := logic.GetNetwork(netname)
  125. if err != nil {
  126. logger.Log(0, r.Header.Get("user"), fmt.Sprintf("failed to fetch network [%s] info: %v",
  127. netname, err))
  128. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  129. return
  130. }
  131. logger.Log(2, r.Header.Get("user"), "fetched network", netname)
  132. w.WriteHeader(http.StatusOK)
  133. json.NewEncoder(w).Encode(network)
  134. }
  135. // @Summary Update a network ACL (Access Control List)
  136. // @Router /api/networks/{networkname}/acls [put]
  137. // @Tags Networks
  138. // @Security oauth
  139. // @Param networkname path string true "Network name"
  140. // @Param body body acls.ACLContainer true "ACL container"
  141. // @Produce json
  142. // @Success 200 {object} acls.ACLContainer
  143. // @Failure 400 {object} models.ErrorResponse
  144. // @Failure 500 {object} models.ErrorResponse
  145. func updateNetworkACL(w http.ResponseWriter, r *http.Request) {
  146. w.Header().Set("Content-Type", "application/json")
  147. var params = mux.Vars(r)
  148. netname := params["networkname"]
  149. var networkACLChange acls.ACLContainer
  150. networkACLChange, err := networkACLChange.Get(acls.ContainerID(netname))
  151. if err != nil {
  152. logger.Log(0, r.Header.Get("user"),
  153. fmt.Sprintf("failed to fetch ACLs for network [%s]: %v", netname, err))
  154. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  155. return
  156. }
  157. err = json.NewDecoder(r.Body).Decode(&networkACLChange)
  158. if err != nil {
  159. logger.Log(0, r.Header.Get("user"), "error decoding request body: ",
  160. err.Error())
  161. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  162. return
  163. }
  164. newNetACL, err := networkACLChange.Save(acls.ContainerID(netname))
  165. if err != nil {
  166. logger.Log(0, r.Header.Get("user"),
  167. fmt.Sprintf("failed to update ACLs for network [%s]: %v", netname, err))
  168. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  169. return
  170. }
  171. logger.Log(1, r.Header.Get("user"), "updated ACLs for network", netname)
  172. // send peer updates
  173. go func() {
  174. if err = mq.PublishPeerUpdate(false); err != nil {
  175. logger.Log(0, "failed to publish peer update after ACL update on network:", netname)
  176. }
  177. }()
  178. w.WriteHeader(http.StatusOK)
  179. json.NewEncoder(w).Encode(newNetACL)
  180. }
  181. // @Summary Update a network ACL (Access Control List)
  182. // @Router /api/networks/{networkname}/acls/v2 [put]
  183. // @Tags Networks
  184. // @Security oauth
  185. // @Param networkname path string true "Network name"
  186. // @Param body body acls.ACLContainer true "ACL container"
  187. // @Produce json
  188. // @Success 200 {object} acls.ACLContainer
  189. // @Failure 400 {object} models.ErrorResponse
  190. // @Failure 500 {object} models.ErrorResponse
  191. func updateNetworkACLv2(w http.ResponseWriter, r *http.Request) {
  192. w.Header().Set("Content-Type", "application/json")
  193. var params = mux.Vars(r)
  194. netname := params["networkname"]
  195. var networkACLChange acls.ACLContainer
  196. networkACLChange, err := networkACLChange.Get(acls.ContainerID(netname))
  197. if err != nil {
  198. logger.Log(0, r.Header.Get("user"),
  199. fmt.Sprintf("failed to fetch ACLs for network [%s]: %v", netname, err))
  200. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  201. return
  202. }
  203. err = json.NewDecoder(r.Body).Decode(&networkACLChange)
  204. if err != nil {
  205. logger.Log(0, r.Header.Get("user"), "error decoding request body: ",
  206. err.Error())
  207. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  208. return
  209. }
  210. // clone req body to use as return data successful update
  211. retData := make(acls.ACLContainer)
  212. data, err := json.Marshal(networkACLChange)
  213. if err != nil {
  214. slog.Error("failed to marshal networkACLChange whiles cloning", "error", err.Error())
  215. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  216. return
  217. }
  218. err = json.Unmarshal(data, &retData)
  219. if err != nil {
  220. slog.Error("failed to unmarshal networkACLChange whiles cloning", "error", err.Error())
  221. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  222. return
  223. }
  224. allNodes, err := logic.GetAllNodes()
  225. if err != nil {
  226. slog.Error("failed to fetch all nodes", "error", err.Error())
  227. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  228. return
  229. }
  230. networkNodes := make([]models.Node, 0)
  231. for _, node := range allNodes {
  232. if node.Network == netname {
  233. networkNodes = append(networkNodes, node)
  234. }
  235. }
  236. networkNodesIdMap := make(map[string]models.Node)
  237. for _, node := range networkNodes {
  238. networkNodesIdMap[node.ID.String()] = node
  239. }
  240. networkClients, err := logic.GetNetworkExtClients(netname)
  241. if err != nil {
  242. slog.Error("failed to fetch network clients", "error", err.Error())
  243. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  244. return
  245. }
  246. networkClientsMap := make(map[string]models.ExtClient)
  247. for _, client := range networkClients {
  248. networkClientsMap[client.ClientID] = client
  249. }
  250. // keep track of ingress gateways to disconnect from their clients
  251. // this is required because PublishPeerUpdate only somehow does not stop communication
  252. // between blocked clients and their ingress
  253. assocClientsToDisconnectPerHost := make(map[uuid.UUID][]models.ExtClient)
  254. // update client acls and then, remove client acls from req data to pass to existing functions
  255. for id, acl := range networkACLChange {
  256. // for node acls
  257. if _, ok := networkNodesIdMap[string(id)]; ok {
  258. nodeId := string(id)
  259. // check acl update, then remove client entries
  260. for id2 := range acl {
  261. if _, ok := networkNodesIdMap[string(id2)]; !ok {
  262. // update client acl
  263. clientId := string(id2)
  264. if client, ok := networkClientsMap[clientId]; ok {
  265. if client.DeniedACLs == nil {
  266. client.DeniedACLs = make(map[string]struct{})
  267. }
  268. if acl[acls.AclID(clientId)] == acls.NotAllowed {
  269. client.DeniedACLs[nodeId] = struct{}{}
  270. } else {
  271. delete(client.DeniedACLs, string(nodeId))
  272. }
  273. networkClientsMap[clientId] = client
  274. }
  275. }
  276. }
  277. } else {
  278. // for client acls
  279. clientId := string(id)
  280. for id2 := range acl {
  281. if _, ok := networkNodesIdMap[string(id2)]; !ok {
  282. // update client acl
  283. clientId2 := string(id2)
  284. if client, ok := networkClientsMap[clientId]; ok {
  285. if client.DeniedACLs == nil {
  286. client.DeniedACLs = make(map[string]struct{})
  287. }
  288. {
  289. // TODO: review this when client-to-client acls are supported
  290. // if acl[acls.AclID(clientId2)] == acls.NotAllowed {
  291. // client.DeniedACLs[clientId2] = struct{}{}
  292. // } else {
  293. // delete(client.DeniedACLs, clientId2)
  294. // }
  295. delete(client.DeniedACLs, clientId2)
  296. }
  297. networkClientsMap[clientId] = client
  298. }
  299. } else {
  300. nodeId2 := string(id2)
  301. if networkClientsMap[clientId].IngressGatewayID == nodeId2 && acl[acls.AclID(nodeId2)] == acls.NotAllowed {
  302. assocClientsToDisconnectPerHost[networkNodesIdMap[nodeId2].HostID] = append(assocClientsToDisconnectPerHost[networkNodesIdMap[nodeId2].HostID], networkClientsMap[clientId])
  303. }
  304. }
  305. }
  306. }
  307. }
  308. // update each client in db for pro servers
  309. if servercfg.IsPro {
  310. for _, client := range networkClientsMap {
  311. client := client
  312. err := logic.DeleteExtClient(client.Network, client.ClientID)
  313. if err != nil {
  314. slog.Error(
  315. "failed to delete client during update",
  316. "client",
  317. client.ClientID,
  318. "error",
  319. err.Error(),
  320. )
  321. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  322. return
  323. }
  324. err = logic.SaveExtClient(&client)
  325. if err != nil {
  326. slog.Error(
  327. "failed to save client during update",
  328. "client",
  329. client.ClientID,
  330. "error",
  331. err.Error(),
  332. )
  333. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  334. return
  335. }
  336. }
  337. }
  338. _, err = networkACLChange.Save(acls.ContainerID(netname))
  339. if err != nil {
  340. logger.Log(0, r.Header.Get("user"),
  341. fmt.Sprintf("failed to update ACLs for network [%s]: %v", netname, err))
  342. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  343. return
  344. }
  345. logger.Log(1, r.Header.Get("user"), "updated ACLs for network", netname)
  346. // send peer updates
  347. go func() {
  348. if err = mq.PublishPeerUpdate(false); err != nil {
  349. logger.Log(0, "failed to publish peer update after ACL update on network:", netname)
  350. }
  351. // update ingress gateways of associated clients
  352. hosts, err := logic.GetAllHosts()
  353. if err != nil {
  354. slog.Error(
  355. "failed to fetch hosts after network ACL update. skipping publish extclients ACL",
  356. "network",
  357. netname,
  358. )
  359. return
  360. }
  361. hostsMap := make(map[uuid.UUID]models.Host)
  362. for _, host := range hosts {
  363. hostsMap[host.ID] = host
  364. }
  365. for hostId, clients := range assocClientsToDisconnectPerHost {
  366. if host, ok := hostsMap[hostId]; ok {
  367. if err = mq.PublishSingleHostPeerUpdate(&host, allNodes, nil, clients, false, nil); err != nil {
  368. slog.Error("failed to publish peer update to ingress after ACL update on network", "network", netname, "host", hostId)
  369. }
  370. }
  371. }
  372. }()
  373. w.WriteHeader(http.StatusOK)
  374. json.NewEncoder(w).Encode(networkACLChange)
  375. }
  376. // @Summary Get a network ACL (Access Control List)
  377. // @Router /api/networks/{networkname}/acls [get]
  378. // @Tags Networks
  379. // @Security oauth
  380. // @Param networkname path string true "Network name"
  381. // @Produce json
  382. // @Success 200 {object} acls.ACLContainer
  383. // @Failure 500 {object} models.ErrorResponse
  384. func getNetworkACL(w http.ResponseWriter, r *http.Request) {
  385. w.Header().Set("Content-Type", "application/json")
  386. var params = mux.Vars(r)
  387. netname := params["networkname"]
  388. var networkACL acls.ACLContainer
  389. networkACL, err := networkACL.Get(acls.ContainerID(netname))
  390. if err != nil {
  391. if database.IsEmptyRecord(err) {
  392. networkACL = acls.ACLContainer{}
  393. w.WriteHeader(http.StatusOK)
  394. json.NewEncoder(w).Encode(networkACL)
  395. return
  396. }
  397. logger.Log(0, r.Header.Get("user"),
  398. fmt.Sprintf("failed to fetch ACLs for network [%s]: %v", netname, err))
  399. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  400. return
  401. }
  402. logger.Log(2, r.Header.Get("user"), "fetched acl for network", netname)
  403. w.WriteHeader(http.StatusOK)
  404. json.NewEncoder(w).Encode(networkACL)
  405. }
  406. // @Summary Get a network Egress routes
  407. // @Router /api/networks/{networkname}/egress_routes [get]
  408. // @Tags Networks
  409. // @Security oauth
  410. // @Param networkname path string true "Network name"
  411. // @Produce json
  412. // @Success 200 {object} models.SuccessResponse
  413. // @Failure 500 {object} models.ErrorResponse
  414. func getNetworkEgressRoutes(w http.ResponseWriter, r *http.Request) {
  415. var params = mux.Vars(r)
  416. netname := params["networkname"]
  417. // check if network exists
  418. _, err := logic.GetNetwork(netname)
  419. if err != nil {
  420. logger.Log(0, r.Header.Get("user"),
  421. fmt.Sprintf("failed to fetch ACLs for network [%s]: %v", netname, err))
  422. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  423. return
  424. }
  425. nodeEgressRoutes, _, err := logic.GetEgressRanges(models.NetworkID(netname))
  426. if err != nil {
  427. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  428. return
  429. }
  430. logic.ReturnSuccessResponseWithJson(w, r, nodeEgressRoutes, "fetched network egress routes")
  431. }
  432. // @Summary Delete a network
  433. // @Router /api/networks/{networkname} [delete]
  434. // @Tags Networks
  435. // @Security oauth
  436. // @Param networkname path string true "Network name"
  437. // @Param force query bool false "Force Delete"
  438. // @Produce json
  439. // @Success 200 {object} models.SuccessResponse
  440. // @Failure 400 {object} models.ErrorResponse
  441. // @Failure 403 {object} models.ErrorResponse
  442. func deleteNetwork(w http.ResponseWriter, r *http.Request) {
  443. // Set header
  444. w.Header().Set("Content-Type", "application/json")
  445. force := r.URL.Query().Get("force") == "true"
  446. var params = mux.Vars(r)
  447. network := params["networkname"]
  448. doneCh := make(chan struct{}, 1)
  449. networkNodes, err := logic.GetNetworkNodes(network)
  450. if err != nil {
  451. logger.Log(0, r.Header.Get("user"),
  452. fmt.Sprintf("failed to get network nodes [%s]: %v", network, err))
  453. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  454. return
  455. }
  456. err = logic.DeleteNetwork(network, force, doneCh)
  457. if err != nil {
  458. errtype := logic.BadReq
  459. if strings.Contains(err.Error(), "Node check failed") {
  460. errtype = logic.Forbidden
  461. }
  462. logger.Log(0, r.Header.Get("user"),
  463. fmt.Sprintf("failed to delete network [%s]: %v", network, err))
  464. logic.ReturnErrorResponse(w, r, logic.FormatError(err, errtype))
  465. return
  466. }
  467. go logic.UnlinkNetworkAndTagsFromEnrollmentKeys(network, true)
  468. go logic.DeleteNetworkRoles(network)
  469. go logic.DeleteAllNetworkTags(models.NetworkID(network))
  470. go logic.DeleteNetworkPolicies(models.NetworkID(network))
  471. //delete network from allocated ip map
  472. go logic.RemoveNetworkFromAllocatedIpMap(network)
  473. go func() {
  474. <-doneCh
  475. mq.PublishPeerUpdate(true)
  476. // send node update to clean up locally
  477. for _, node := range networkNodes {
  478. node := node
  479. node.PendingDelete = true
  480. node.Action = models.NODE_DELETE
  481. if err := mq.NodeUpdate(&node); err != nil {
  482. slog.Error("error publishing node update to node", "node", node.ID, "error", err)
  483. }
  484. }
  485. if servercfg.IsDNSMode() {
  486. logic.SetDNS()
  487. }
  488. }()
  489. logic.LogEvent(&models.Event{
  490. Action: models.Delete,
  491. Source: models.Subject{
  492. ID: r.Header.Get("user"),
  493. Name: r.Header.Get("user"),
  494. Type: models.UserSub,
  495. },
  496. TriggeredBy: r.Header.Get("user"),
  497. Target: models.Subject{
  498. ID: network,
  499. Name: network,
  500. Type: models.NetworkSub,
  501. },
  502. Origin: models.Dashboard,
  503. })
  504. logger.Log(1, r.Header.Get("user"), "deleted network", network)
  505. w.WriteHeader(http.StatusOK)
  506. json.NewEncoder(w).Encode("success")
  507. }
  508. // @Summary Create a network
  509. // @Router /api/networks [post]
  510. // @Tags Networks
  511. // @Security oauth
  512. // @Param body body models.Network true "Network details"
  513. // @Produce json
  514. // @Success 200 {object} models.Network
  515. // @Failure 400 {object} models.ErrorResponse
  516. func createNetwork(w http.ResponseWriter, r *http.Request) {
  517. w.Header().Set("Content-Type", "application/json")
  518. var network models.Network
  519. // we decode our body request params
  520. err := json.NewDecoder(r.Body).Decode(&network)
  521. if err != nil {
  522. logger.Log(0, r.Header.Get("user"), "error decoding request body: ",
  523. err.Error())
  524. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  525. return
  526. }
  527. if len(network.NetID) > 32 {
  528. err := errors.New("network name shouldn't exceed 32 characters")
  529. logger.Log(0, r.Header.Get("user"), "failed to create network: ",
  530. err.Error())
  531. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  532. return
  533. }
  534. if network.AddressRange == "" && network.AddressRange6 == "" {
  535. err := errors.New("IPv4 or IPv6 CIDR required")
  536. logger.Log(0, r.Header.Get("user"), "failed to create network: ",
  537. err.Error())
  538. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  539. return
  540. }
  541. // validate address ranges: must be private
  542. if network.AddressRange != "" {
  543. _, _, err := net.ParseCIDR(network.AddressRange)
  544. if err != nil {
  545. logger.Log(0, r.Header.Get("user"), "failed to create network: ",
  546. err.Error())
  547. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  548. return
  549. }
  550. }
  551. if network.AddressRange6 != "" {
  552. _, _, err := net.ParseCIDR(network.AddressRange6)
  553. if err != nil {
  554. logger.Log(0, r.Header.Get("user"), "failed to create network: ",
  555. err.Error())
  556. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  557. return
  558. }
  559. }
  560. network, err = logic.CreateNetwork(network)
  561. if err != nil {
  562. logger.Log(0, r.Header.Get("user"), "failed to create network: ",
  563. err.Error())
  564. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  565. return
  566. }
  567. logic.CreateDefaultNetworkRolesAndGroups(models.NetworkID(network.NetID))
  568. logic.CreateDefaultAclNetworkPolicies(models.NetworkID(network.NetID))
  569. logic.CreateDefaultTags(models.NetworkID(network.NetID))
  570. logic.AddNetworkToAllocatedIpMap(network.NetID)
  571. go func() {
  572. defaultHosts := logic.GetDefaultHosts()
  573. for i := range defaultHosts {
  574. currHost := &defaultHosts[i]
  575. newNode, err := logic.UpdateHostNetwork(currHost, network.NetID, true)
  576. if err != nil {
  577. logger.Log(
  578. 0,
  579. r.Header.Get("user"),
  580. "failed to add host to network:",
  581. currHost.ID.String(),
  582. network.NetID,
  583. err.Error(),
  584. )
  585. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  586. return
  587. }
  588. logger.Log(1, "added new node", newNode.ID.String(), "to host", currHost.Name)
  589. if err = mq.HostUpdate(&models.HostUpdate{
  590. Action: models.JoinHostToNetwork,
  591. Host: *currHost,
  592. Node: *newNode,
  593. }); err != nil {
  594. logger.Log(
  595. 0,
  596. r.Header.Get("user"),
  597. "failed to add host to network:",
  598. currHost.ID.String(),
  599. network.NetID,
  600. err.Error(),
  601. )
  602. }
  603. // make host failover
  604. logic.CreateFailOver(*newNode)
  605. // make host remote access gateway
  606. logic.CreateIngressGateway(network.NetID, newNode.ID.String(), models.IngressRequest{})
  607. logic.CreateRelay(models.RelayRequest{
  608. NodeID: newNode.ID.String(),
  609. NetID: network.NetID,
  610. })
  611. }
  612. // send peer updates
  613. if err = mq.PublishPeerUpdate(false); err != nil {
  614. logger.Log(1, "failed to publish peer update for default hosts after network is added")
  615. }
  616. }()
  617. logic.LogEvent(&models.Event{
  618. Action: models.Create,
  619. Source: models.Subject{
  620. ID: r.Header.Get("user"),
  621. Name: r.Header.Get("user"),
  622. Type: models.UserSub,
  623. },
  624. TriggeredBy: r.Header.Get("user"),
  625. Target: models.Subject{
  626. ID: network.NetID,
  627. Name: network.NetID,
  628. Type: models.NetworkSub,
  629. Info: network,
  630. },
  631. Origin: models.Dashboard,
  632. })
  633. logger.Log(1, r.Header.Get("user"), "created network", network.NetID)
  634. w.WriteHeader(http.StatusOK)
  635. json.NewEncoder(w).Encode(network)
  636. }
  637. // @Summary Update network settings
  638. // @Router /api/networks/{networkname} [put]
  639. // @Tags Networks
  640. // @Security oauth
  641. // @Param networkname path string true "Network name"
  642. // @Param body body models.Network true "Network details"
  643. // @Produce json
  644. // @Success 200 {object} models.Network
  645. // @Failure 400 {object} models.ErrorResponse
  646. func updateNetwork(w http.ResponseWriter, r *http.Request) {
  647. w.Header().Set("Content-Type", "application/json")
  648. var payload models.Network
  649. // we decode our body request params
  650. err := json.NewDecoder(r.Body).Decode(&payload)
  651. if err != nil {
  652. slog.Info("error decoding request body", "user", r.Header.Get("user"), "err", err)
  653. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  654. return
  655. }
  656. netOld, err := logic.GetNetwork(payload.NetID)
  657. if err != nil {
  658. slog.Info("error fetching network", "user", r.Header.Get("user"), "err", err)
  659. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  660. return
  661. }
  662. netNew := netOld
  663. netNew.NameServers = payload.NameServers
  664. netNew.DefaultACL = payload.DefaultACL
  665. _, _, _, err = logic.UpdateNetwork(&netOld, &netNew)
  666. if err != nil {
  667. slog.Info("failed to update network", "user", r.Header.Get("user"), "err", err)
  668. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  669. return
  670. }
  671. go mq.PublishPeerUpdate(false)
  672. slog.Info("updated network", "network", payload.NetID, "user", r.Header.Get("user"))
  673. w.WriteHeader(http.StatusOK)
  674. json.NewEncoder(w).Encode(payload)
  675. }