network.go 22 KB

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