node.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. package controller
  2. import (
  3. "crypto/ed25519"
  4. "encoding/json"
  5. "fmt"
  6. "log"
  7. "net/http"
  8. "strings"
  9. "github.com/gorilla/mux"
  10. "github.com/gravitl/netmaker/database"
  11. "github.com/gravitl/netmaker/functions"
  12. "github.com/gravitl/netmaker/logger"
  13. "github.com/gravitl/netmaker/logic"
  14. "github.com/gravitl/netmaker/models"
  15. "github.com/gravitl/netmaker/mq"
  16. "github.com/gravitl/netmaker/netclient/config"
  17. "github.com/gravitl/netmaker/netclient/server"
  18. "github.com/gravitl/netmaker/servercfg"
  19. "github.com/gravitl/netmaker/tls"
  20. "github.com/kr/pretty"
  21. "golang.org/x/crypto/bcrypt"
  22. )
  23. func nodeHandlers(r *mux.Router) {
  24. r.HandleFunc("/api/nodes", authorize(false, "user", http.HandlerFunc(getAllNodes))).Methods("GET")
  25. r.HandleFunc("/api/nodes/{network}", authorize(true, "network", http.HandlerFunc(getNetworkNodes))).Methods("GET")
  26. r.HandleFunc("/api/nodes/{network}/{nodeid}", authorize(true, "node", http.HandlerFunc(getNode))).Methods("GET")
  27. r.HandleFunc("/api/nodes/{network}/{nodeid}", authorize(true, "node", http.HandlerFunc(updateNode))).Methods("PUT")
  28. r.HandleFunc("/api/nodes/{network}/{nodeid}", authorize(true, "node", http.HandlerFunc(deleteNode))).Methods("DELETE")
  29. r.HandleFunc("/api/nodes/{network}/{nodeid}/createrelay", authorize(true, "user", http.HandlerFunc(createRelay))).Methods("POST")
  30. r.HandleFunc("/api/nodes/{network}/{nodeid}/deleterelay", authorize(true, "user", http.HandlerFunc(deleteRelay))).Methods("DELETE")
  31. r.HandleFunc("/api/nodes/{network}/{nodeid}/creategateway", authorize(true, "user", http.HandlerFunc(createEgressGateway))).Methods("POST")
  32. r.HandleFunc("/api/nodes/{network}/{nodeid}/deletegateway", authorize(true, "user", http.HandlerFunc(deleteEgressGateway))).Methods("DELETE")
  33. r.HandleFunc("/api/nodes/{network}/{nodeid}/createingress", securityCheck(false, http.HandlerFunc(createIngressGateway))).Methods("POST")
  34. r.HandleFunc("/api/nodes/{network}/{nodeid}/deleteingress", securityCheck(false, http.HandlerFunc(deleteIngressGateway))).Methods("DELETE")
  35. r.HandleFunc("/api/nodes/{network}/{nodeid}/approve", authorize(true, "user", http.HandlerFunc(uncordonNode))).Methods("POST")
  36. r.HandleFunc("/api/nodes/join", createNode).Methods("POST")
  37. r.HandleFunc("/api/nodes/adm/{network}/lastmodified", authorize(true, "network", http.HandlerFunc(getLastModified))).Methods("GET")
  38. r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods("POST")
  39. }
  40. func authenticate(response http.ResponseWriter, request *http.Request) {
  41. var params = mux.Vars(request)
  42. networkname := params["network"]
  43. var authRequest models.AuthParams
  44. var result models.Node
  45. var errorResponse = models.ErrorResponse{
  46. Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
  47. }
  48. decoder := json.NewDecoder(request.Body)
  49. decoderErr := decoder.Decode(&authRequest)
  50. defer request.Body.Close()
  51. if decoderErr != nil {
  52. errorResponse.Code = http.StatusBadRequest
  53. errorResponse.Message = decoderErr.Error()
  54. returnErrorResponse(response, request, errorResponse)
  55. return
  56. } else {
  57. errorResponse.Code = http.StatusBadRequest
  58. if authRequest.MacAddress == "" {
  59. errorResponse.Message = "W1R3: MacAddress can't be empty"
  60. returnErrorResponse(response, request, errorResponse)
  61. return
  62. } else if authRequest.Password == "" {
  63. errorResponse.Message = "W1R3: Password can't be empty"
  64. returnErrorResponse(response, request, errorResponse)
  65. return
  66. } else {
  67. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  68. if err != nil {
  69. errorResponse.Code = http.StatusBadRequest
  70. errorResponse.Message = err.Error()
  71. returnErrorResponse(response, request, errorResponse)
  72. return
  73. }
  74. for _, value := range collection {
  75. if err := json.Unmarshal([]byte(value), &result); err != nil {
  76. continue
  77. }
  78. if (result.ID == authRequest.ID || result.MacAddress == authRequest.MacAddress) && result.IsPending != "yes" && result.Network == networkname {
  79. break
  80. }
  81. }
  82. if err != nil {
  83. errorResponse.Code = http.StatusBadRequest
  84. errorResponse.Message = err.Error()
  85. returnErrorResponse(response, request, errorResponse)
  86. return
  87. }
  88. err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password))
  89. if err != nil {
  90. errorResponse.Code = http.StatusBadRequest
  91. errorResponse.Message = err.Error()
  92. returnErrorResponse(response, request, errorResponse)
  93. return
  94. } else {
  95. tokenString, _ := logic.CreateJWT(authRequest.ID, authRequest.MacAddress, result.Network)
  96. if tokenString == "" {
  97. errorResponse.Code = http.StatusBadRequest
  98. errorResponse.Message = "Could not create Token"
  99. returnErrorResponse(response, request, errorResponse)
  100. return
  101. }
  102. var successResponse = models.SuccessResponse{
  103. Code: http.StatusOK,
  104. Message: "W1R3: Device " + authRequest.MacAddress + " Authorized",
  105. Response: models.SuccessfulLoginResponse{
  106. AuthToken: tokenString,
  107. MacAddress: authRequest.MacAddress,
  108. },
  109. }
  110. successJSONResponse, jsonError := json.Marshal(successResponse)
  111. if jsonError != nil {
  112. errorResponse.Code = http.StatusBadRequest
  113. errorResponse.Message = err.Error()
  114. returnErrorResponse(response, request, errorResponse)
  115. return
  116. }
  117. response.WriteHeader(http.StatusOK)
  118. response.Header().Set("Content-Type", "application/json")
  119. response.Write(successJSONResponse)
  120. }
  121. }
  122. }
  123. }
  124. //The middleware for most requests to the API
  125. //They all pass through here first
  126. //This will validate the JWT (or check for master token)
  127. //This will also check against the authNetwork and make sure the node should be accessing that endpoint,
  128. //even if it's technically ok
  129. //This is kind of a poor man's RBAC. There's probably a better/smarter way.
  130. //TODO: Consider better RBAC implementations
  131. func authorize(networkCheck bool, authNetwork string, next http.Handler) http.HandlerFunc {
  132. return func(w http.ResponseWriter, r *http.Request) {
  133. var errorResponse = models.ErrorResponse{
  134. Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
  135. }
  136. var params = mux.Vars(r)
  137. networkexists, _ := functions.NetworkExists(params["network"])
  138. //check that the request is for a valid network
  139. //if (networkCheck && !networkexists) || err != nil {
  140. if networkCheck && !networkexists {
  141. errorResponse = models.ErrorResponse{
  142. Code: http.StatusNotFound, Message: "W1R3: This network does not exist. ",
  143. }
  144. returnErrorResponse(w, r, errorResponse)
  145. return
  146. } else {
  147. w.Header().Set("Content-Type", "application/json")
  148. //get the auth token
  149. bearerToken := r.Header.Get("Authorization")
  150. var tokenSplit = strings.Split(bearerToken, " ")
  151. //I put this in in case the user doesn't put in a token at all (in which case it's empty)
  152. //There's probably a smarter way of handling this.
  153. var authToken = "928rt238tghgwe@TY@$Y@#WQAEGB2FC#@HG#@$Hddd"
  154. if len(tokenSplit) > 1 {
  155. authToken = tokenSplit[1]
  156. } else {
  157. errorResponse = models.ErrorResponse{
  158. Code: http.StatusUnauthorized, Message: "W1R3: Missing Auth Token.",
  159. }
  160. returnErrorResponse(w, r, errorResponse)
  161. return
  162. }
  163. var isAuthorized = false
  164. var nodeID = ""
  165. username, networks, isadmin, errN := logic.VerifyUserToken(authToken)
  166. if errN != nil {
  167. errorResponse = models.ErrorResponse{
  168. Code: http.StatusUnauthorized, Message: "W1R3: Unauthorized, Invalid Token Processed.",
  169. }
  170. returnErrorResponse(w, r, errorResponse)
  171. return
  172. }
  173. isnetadmin := isadmin
  174. if errN == nil && isadmin {
  175. nodeID = "mastermac"
  176. isAuthorized = true
  177. r.Header.Set("ismasterkey", "yes")
  178. }
  179. if !isadmin && params["network"] != "" {
  180. if logic.StringSliceContains(networks, params["network"]) {
  181. isnetadmin = true
  182. }
  183. }
  184. //The mastermac (login with masterkey from config) can do everything!! May be dangerous.
  185. if nodeID == "mastermac" {
  186. isAuthorized = true
  187. r.Header.Set("ismasterkey", "yes")
  188. //for everyone else, there's poor man's RBAC. The "cases" are defined in the routes in the handlers
  189. //So each route defines which access network should be allowed to access it
  190. } else {
  191. switch authNetwork {
  192. case "all":
  193. isAuthorized = true
  194. case "nodes":
  195. isAuthorized = (nodeID != "") || isnetadmin
  196. case "network":
  197. if isnetadmin {
  198. isAuthorized = true
  199. } else {
  200. node, err := logic.GetNodeByID(nodeID)
  201. if err != nil {
  202. errorResponse = models.ErrorResponse{
  203. Code: http.StatusUnauthorized, Message: "W1R3: Missing Auth Token.",
  204. }
  205. returnErrorResponse(w, r, errorResponse)
  206. return
  207. }
  208. isAuthorized = (node.Network == params["network"])
  209. }
  210. case "node":
  211. if isnetadmin {
  212. isAuthorized = true
  213. } else {
  214. isAuthorized = (nodeID == params["netid"])
  215. }
  216. case "user":
  217. isAuthorized = true
  218. default:
  219. isAuthorized = false
  220. }
  221. }
  222. if !isAuthorized {
  223. errorResponse = models.ErrorResponse{
  224. Code: http.StatusUnauthorized, Message: "W1R3: You are unauthorized to access this endpoint.",
  225. }
  226. returnErrorResponse(w, r, errorResponse)
  227. return
  228. } else {
  229. //If authorized, this function passes along it's request and output to the appropriate route function.
  230. if username == "" {
  231. username = "(user not found)"
  232. }
  233. r.Header.Set("user", username)
  234. next.ServeHTTP(w, r)
  235. }
  236. }
  237. }
  238. }
  239. //Gets all nodes associated with network, including pending nodes
  240. func getNetworkNodes(w http.ResponseWriter, r *http.Request) {
  241. w.Header().Set("Content-Type", "application/json")
  242. var nodes []models.Node
  243. var params = mux.Vars(r)
  244. networkName := params["network"]
  245. nodes, err := logic.GetNetworkNodes(networkName)
  246. if err != nil {
  247. returnErrorResponse(w, r, formatError(err, "internal"))
  248. return
  249. }
  250. //Returns all the nodes in JSON format
  251. logger.Log(2, r.Header.Get("user"), "fetched nodes on network", networkName)
  252. w.WriteHeader(http.StatusOK)
  253. json.NewEncoder(w).Encode(nodes)
  254. }
  255. //A separate function to get all nodes, not just nodes for a particular network.
  256. //Not quite sure if this is necessary. Probably necessary based on front end but may want to review after iteration 1 if it's being used or not
  257. func getAllNodes(w http.ResponseWriter, r *http.Request) {
  258. w.Header().Set("Content-Type", "application/json")
  259. user, err := logic.GetUser(r.Header.Get("user"))
  260. if err != nil && r.Header.Get("ismasterkey") != "yes" {
  261. returnErrorResponse(w, r, formatError(err, "internal"))
  262. return
  263. }
  264. var nodes []models.Node
  265. if user.IsAdmin || r.Header.Get("ismasterkey") == "yes" {
  266. nodes, err = logic.GetAllNodes()
  267. if err != nil {
  268. returnErrorResponse(w, r, formatError(err, "internal"))
  269. return
  270. }
  271. } else {
  272. nodes, err = getUsersNodes(user)
  273. if err != nil {
  274. returnErrorResponse(w, r, formatError(err, "internal"))
  275. return
  276. }
  277. }
  278. //Return all the nodes in JSON format
  279. logger.Log(3, r.Header.Get("user"), "fetched all nodes they have access to")
  280. w.WriteHeader(http.StatusOK)
  281. json.NewEncoder(w).Encode(nodes)
  282. }
  283. func getUsersNodes(user models.User) ([]models.Node, error) {
  284. var nodes []models.Node
  285. var err error
  286. for _, networkName := range user.Networks {
  287. tmpNodes, err := logic.GetNetworkNodes(networkName)
  288. if err != nil {
  289. continue
  290. }
  291. nodes = append(nodes, tmpNodes...)
  292. }
  293. return nodes, err
  294. }
  295. //Get an individual node. Nothin fancy here folks.
  296. func getNode(w http.ResponseWriter, r *http.Request) {
  297. // set header.
  298. w.Header().Set("Content-Type", "application/json")
  299. var params = mux.Vars(r)
  300. node, err := logic.GetNodeByID(params["nodeid"])
  301. if err != nil {
  302. returnErrorResponse(w, r, formatError(err, "internal"))
  303. return
  304. }
  305. logger.Log(2, r.Header.Get("user"), "fetched node", params["nodeid"])
  306. w.WriteHeader(http.StatusOK)
  307. json.NewEncoder(w).Encode(node)
  308. }
  309. //Get the time that a network of nodes was last modified.
  310. //TODO: This needs to be refactored
  311. //Potential way to do this: On UpdateNode, set a new field for "LastModified"
  312. //If we go with the existing way, we need to at least set network.NodesLastModified on UpdateNode
  313. func getLastModified(w http.ResponseWriter, r *http.Request) {
  314. // set header.
  315. w.Header().Set("Content-Type", "application/json")
  316. var params = mux.Vars(r)
  317. network, err := logic.GetNetwork(params["network"])
  318. if err != nil {
  319. returnErrorResponse(w, r, formatError(err, "internal"))
  320. return
  321. }
  322. logger.Log(2, r.Header.Get("user"), "called last modified")
  323. w.WriteHeader(http.StatusOK)
  324. json.NewEncoder(w).Encode(network.NodesLastModified)
  325. }
  326. func createNode(w http.ResponseWriter, r *http.Request) {
  327. log.Println("create node request")
  328. w.Header().Set("Content-Type", "application/json")
  329. var errorResponse = models.ErrorResponse{
  330. Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
  331. }
  332. //get node from body of request
  333. //var request = config.JoinRequest{}
  334. var node = models.Node{}
  335. err := json.NewDecoder(r.Body).Decode(&node)
  336. if err != nil {
  337. log.Println("json decoder error")
  338. returnErrorResponse(w, r, formatError(err, "badrequest"))
  339. return
  340. }
  341. //Generate certificate for client
  342. //client key
  343. _, private, err := ed25519.GenerateKey()
  344. if err != nil {
  345. log.Println("failed to gen client key", err)
  346. returnErrorResponse(w, r, formatError(err, "internal"))
  347. return
  348. }
  349. name := tls.NewCName(node.Name)
  350. csr, err := tls.NewCSR(private, name)
  351. if err != nil {
  352. log.Println("failed to gen client csr", err)
  353. returnErrorResponse(w, r, formatError(err, "internal"))
  354. return
  355. }
  356. key, err := tls.ReadKey("/etc/netmaker/root.key")
  357. if err != nil {
  358. log.Println("error reading root private key ", err)
  359. returnErrorResponse(w, r, formatError(err, "internal"))
  360. return
  361. }
  362. pretty.Println(key)
  363. ca, err := tls.ReadCert("/etc/netmaker/root.pem")
  364. if err != nil {
  365. log.Println("error reading root certificate ", err)
  366. returnErrorResponse(w, r, formatError(err, "internal"))
  367. return
  368. }
  369. cert, err := tls.NewEndEntityCert(*key, csr, ca, 30)
  370. if err != nil {
  371. log.Println("error creating client certificate ", err)
  372. returnErrorResponse(w, r, formatError(err, "internal"))
  373. return
  374. }
  375. //node := request.Node
  376. //pretty.Println(node)
  377. log.Println("check if network exists ", node.Network)
  378. networkexists, err := functions.NetworkExists(node.Network)
  379. if err != nil {
  380. log.Println("network does not exist error")
  381. returnErrorResponse(w, r, formatError(err, "internal"))
  382. return
  383. } else if !networkexists {
  384. log.Println("network does not exist ")
  385. errorResponse = models.ErrorResponse{
  386. Code: http.StatusNotFound, Message: "W1R3: Network does not exist! ",
  387. }
  388. returnErrorResponse(w, r, errorResponse)
  389. return
  390. }
  391. network, err := logic.GetNetworkByNode(&node)
  392. if err != nil {
  393. log.Println("failed to get Network")
  394. returnErrorResponse(w, r, formatError(err, "internal"))
  395. return
  396. }
  397. validKey := logic.IsKeyValid(network.NetID, node.AccessKey)
  398. if !validKey {
  399. // Check to see if network will allow manual sign up
  400. // may want to switch this up with the valid key check and avoid a DB call that way.
  401. if network.AllowManualSignUp == "yes" {
  402. node.IsPending = "yes"
  403. } else {
  404. errorResponse = models.ErrorResponse{
  405. Code: http.StatusUnauthorized, Message: "W1R3: Key invalid, or none provided.",
  406. }
  407. returnErrorResponse(w, r, errorResponse)
  408. return
  409. }
  410. }
  411. newNode, err := logic.CreateNode(&node)
  412. if err != nil {
  413. log.Println("error creating node")
  414. returnErrorResponse(w, r, formatError(err, "internal"))
  415. return
  416. }
  417. // get peers
  418. isIngress := false
  419. if newNode.IsIngressGateway == "yes" {
  420. isIngress = true
  421. }
  422. isDualStack := false
  423. if newNode.IsDualStack == "yes" {
  424. isDualStack = true
  425. }
  426. peers, _, _, err := server.GetPeers(newNode.MacAddress, newNode.Network, "", isDualStack, isIngress, false)
  427. response := config.JoinResponse{
  428. Node: *newNode,
  429. Peers: peers,
  430. Certificate: *cert,
  431. CA: *ca,
  432. Key: private,
  433. }
  434. logger.Log(1, r.Header.Get("user"), "created new node", node.Name, "on network", node.Network)
  435. w.WriteHeader(http.StatusOK)
  436. json.NewEncoder(w).Encode(response)
  437. runForceServerUpdate(&node)
  438. }
  439. // Takes node out of pending state
  440. // TODO: May want to use cordon/uncordon terminology instead of "ispending".
  441. func uncordonNode(w http.ResponseWriter, r *http.Request) {
  442. var params = mux.Vars(r)
  443. w.Header().Set("Content-Type", "application/json")
  444. var nodeid = params["nodeid"]
  445. node, err := logic.UncordonNode(nodeid)
  446. if err != nil {
  447. returnErrorResponse(w, r, formatError(err, "internal"))
  448. return
  449. }
  450. logger.Log(1, r.Header.Get("user"), "uncordoned node", node.Name)
  451. w.WriteHeader(http.StatusOK)
  452. json.NewEncoder(w).Encode("SUCCESS")
  453. runUpdates(&node, false)
  454. }
  455. // == EGRESS ==
  456. func createEgressGateway(w http.ResponseWriter, r *http.Request) {
  457. var gateway models.EgressGatewayRequest
  458. var params = mux.Vars(r)
  459. w.Header().Set("Content-Type", "application/json")
  460. err := json.NewDecoder(r.Body).Decode(&gateway)
  461. if err != nil {
  462. returnErrorResponse(w, r, formatError(err, "internal"))
  463. return
  464. }
  465. gateway.NetID = params["network"]
  466. gateway.NodeID = params["nodeid"]
  467. node, err := logic.CreateEgressGateway(gateway)
  468. if err != nil {
  469. returnErrorResponse(w, r, formatError(err, "internal"))
  470. return
  471. }
  472. logger.Log(1, r.Header.Get("user"), "created egress gateway on node", gateway.NodeID, "on network", gateway.NetID)
  473. w.WriteHeader(http.StatusOK)
  474. json.NewEncoder(w).Encode(node)
  475. runUpdates(&node, true)
  476. }
  477. func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
  478. w.Header().Set("Content-Type", "application/json")
  479. var params = mux.Vars(r)
  480. nodeid := params["nodeid"]
  481. netid := params["network"]
  482. node, err := logic.DeleteEgressGateway(netid, nodeid)
  483. if err != nil {
  484. returnErrorResponse(w, r, formatError(err, "internal"))
  485. return
  486. }
  487. logger.Log(1, r.Header.Get("user"), "deleted egress gateway", nodeid, "on network", netid)
  488. w.WriteHeader(http.StatusOK)
  489. json.NewEncoder(w).Encode(node)
  490. runUpdates(&node, true)
  491. }
  492. // == INGRESS ==
  493. func createIngressGateway(w http.ResponseWriter, r *http.Request) {
  494. var params = mux.Vars(r)
  495. w.Header().Set("Content-Type", "application/json")
  496. nodeid := params["nodeid"]
  497. netid := params["network"]
  498. node, err := logic.CreateIngressGateway(netid, nodeid)
  499. if err != nil {
  500. returnErrorResponse(w, r, formatError(err, "internal"))
  501. return
  502. }
  503. logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid)
  504. w.WriteHeader(http.StatusOK)
  505. json.NewEncoder(w).Encode(node)
  506. runUpdates(&node, true)
  507. }
  508. func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
  509. w.Header().Set("Content-Type", "application/json")
  510. var params = mux.Vars(r)
  511. nodeid := params["nodeid"]
  512. node, err := logic.DeleteIngressGateway(params["network"], nodeid)
  513. if err != nil {
  514. returnErrorResponse(w, r, formatError(err, "internal"))
  515. return
  516. }
  517. logger.Log(1, r.Header.Get("user"), "deleted ingress gateway", nodeid)
  518. w.WriteHeader(http.StatusOK)
  519. json.NewEncoder(w).Encode(node)
  520. runUpdates(&node, true)
  521. }
  522. func updateNode(w http.ResponseWriter, r *http.Request) {
  523. w.Header().Set("Content-Type", "application/json")
  524. var params = mux.Vars(r)
  525. var node models.Node
  526. //start here
  527. node, err := logic.GetNodeByID(params["nodeid"])
  528. if err != nil {
  529. returnErrorResponse(w, r, formatError(err, "internal"))
  530. return
  531. }
  532. var newNode models.Node
  533. // we decode our body request params
  534. err = json.NewDecoder(r.Body).Decode(&newNode)
  535. if err != nil {
  536. returnErrorResponse(w, r, formatError(err, "badrequest"))
  537. return
  538. }
  539. relayupdate := false
  540. if node.IsRelay == "yes" && len(newNode.RelayAddrs) > 0 {
  541. if len(newNode.RelayAddrs) != len(node.RelayAddrs) {
  542. relayupdate = true
  543. } else {
  544. for i, addr := range newNode.RelayAddrs {
  545. if addr != node.RelayAddrs[i] {
  546. relayupdate = true
  547. }
  548. }
  549. }
  550. }
  551. if !servercfg.GetRce() {
  552. newNode.PostDown = node.PostDown
  553. newNode.PostUp = node.PostUp
  554. }
  555. ifaceDelta := logic.IfaceDelta(&node, &newNode)
  556. err = logic.UpdateNode(&node, &newNode)
  557. if err != nil {
  558. returnErrorResponse(w, r, formatError(err, "internal"))
  559. return
  560. }
  561. if relayupdate {
  562. updatenodes := logic.UpdateRelay(node.Network, node.RelayAddrs, newNode.RelayAddrs)
  563. if err = logic.NetworkNodesUpdatePullChanges(node.Network); err != nil {
  564. logger.Log(1, "error setting relay updates:", err.Error())
  565. }
  566. if len(updatenodes) > 0 {
  567. for _, relayedNode := range updatenodes {
  568. runUpdates(&relayedNode, false)
  569. }
  570. }
  571. }
  572. if servercfg.IsDNSMode() {
  573. logic.SetDNS()
  574. }
  575. logger.Log(1, r.Header.Get("user"), "updated node", node.ID, "on network", node.Network)
  576. w.WriteHeader(http.StatusOK)
  577. json.NewEncoder(w).Encode(newNode)
  578. runUpdates(&newNode, ifaceDelta)
  579. }
  580. func deleteNode(w http.ResponseWriter, r *http.Request) {
  581. // Set header
  582. w.Header().Set("Content-Type", "application/json")
  583. // get params
  584. var params = mux.Vars(r)
  585. var nodeid = params["nodeid"]
  586. var node, err = logic.GetNodeByID(nodeid)
  587. if err != nil {
  588. returnErrorResponse(w, r, formatError(err, "badrequest"))
  589. return
  590. }
  591. if isServer(&node) {
  592. returnErrorResponse(w, r, formatError(fmt.Errorf("cannot delete server node"), "badrequest"))
  593. return
  594. }
  595. //send update to node to be deleted before deleting on server otherwise message cannot be sent
  596. node.Action = models.NODE_DELETE
  597. err = logic.DeleteNodeByID(&node, false)
  598. if err != nil {
  599. returnErrorResponse(w, r, formatError(err, "internal"))
  600. return
  601. }
  602. returnSuccessResponse(w, r, nodeid+" deleted.")
  603. logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
  604. runUpdates(&node, false)
  605. runForceServerUpdate(&node)
  606. }
  607. func runUpdates(node *models.Node, ifaceDelta bool) {
  608. go func() { // don't block http response
  609. // publish node update if not server
  610. if err := mq.NodeUpdate(node); err != nil {
  611. logger.Log(1, "error publishing node update to node", node.Name, node.ID, err.Error())
  612. }
  613. if err := runServerUpdate(node, ifaceDelta); err != nil {
  614. logger.Log(1, "error running server update", err.Error())
  615. }
  616. }()
  617. }
  618. // updates local peers for a server on a given node's network
  619. func runServerUpdate(node *models.Node, ifaceDelta bool) error {
  620. if servercfg.IsClientMode() != "on" || !isServer(node) {
  621. return nil
  622. }
  623. currentServerNode, err := logic.GetNetworkServerLocal(node.Network)
  624. if err != nil {
  625. return err
  626. }
  627. if ifaceDelta && logic.IsLeader(&currentServerNode) {
  628. if err := mq.PublishPeerUpdate(&currentServerNode); err != nil {
  629. logger.Log(1, "failed to publish peer update "+err.Error())
  630. }
  631. }
  632. if err := logic.ServerUpdate(&currentServerNode, ifaceDelta); err != nil {
  633. logger.Log(1, "server node:", currentServerNode.ID, "failed update")
  634. return err
  635. }
  636. return nil
  637. }