Browse Source

Merge pull request #1857 from gravitl/story/GRA-832

updated controllers to use conversion routines
Matthew R Kasun 2 years ago
parent
commit
a173e5a1c2
5 changed files with 171 additions and 38 deletions
  1. 17 9
      controllers/hosts.go
  2. 130 27
      controllers/node.go
  3. 4 2
      controllers/relay.go
  4. 10 0
      logic/hosts.go
  5. 10 0
      logic/nodes.go

+ 17 - 9
controllers/hosts.go

@@ -39,9 +39,11 @@ func getHosts(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 		return
 	}
+	// return JSON/API formatted hosts
+	apiHosts := logic.GetAllHostsAPI(currentHosts[:])
 	logger.Log(2, r.Header.Get("user"), "fetched all hosts")
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(currentHosts)
+	json.NewEncoder(w).Encode(apiHosts)
 }
 
 // swagger:route PUT /api/hosts/{hostid} hosts updateHost
@@ -56,7 +58,7 @@ func getHosts(w http.ResponseWriter, r *http.Request) {
 //			Responses:
 //				200: updateHostResponse
 func updateHost(w http.ResponseWriter, r *http.Request) {
-	var newHostData models.Host
+	var newHostData models.ApiHost
 	err := json.NewDecoder(r.Body).Decode(&newHostData)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"), "failed to update a host:", err.Error())
@@ -65,23 +67,26 @@ func updateHost(w http.ResponseWriter, r *http.Request) {
 	}
 
 	// confirm host exists
-	currHost, err := logic.GetHost(newHostData.ID.String())
+	currHost, err := logic.GetHost(newHostData.ID)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"), "failed to update a host:", err.Error())
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 		return
 	}
 
-	logic.UpdateHost(&newHostData, currHost) // update the in memory struct values
-	if err = logic.UpsertHost(&newHostData); err != nil {
+	newHost := newHostData.ConvertAPIHostToNMHost(currHost)
+
+	logic.UpdateHost(newHost, currHost) // update the in memory struct values
+	if err = logic.UpsertHost(newHost); err != nil {
 		logger.Log(0, r.Header.Get("user"), "failed to update a host:", err.Error())
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 		return
 	}
 
-	logger.Log(2, r.Header.Get("user"), "updated host", newHostData.ID.String())
+	apiHostData := newHost.ConvertNMHostToAPI()
+	logger.Log(2, r.Header.Get("user"), "updated host", newHost.ID.String())
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(newHostData)
+	json.NewEncoder(w).Encode(apiHostData)
 }
 
 // swagger:route DELETE /api/hosts/{hostid} hosts deleteHost
@@ -112,9 +117,10 @@ func deleteHost(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
+	apiHostData := currHost.ConvertNMHostToAPI()
 	logger.Log(2, r.Header.Get("user"), "removed host", currHost.Name)
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(currHost)
+	json.NewEncoder(w).Encode(apiHostData)
 }
 
 // swagger:route PUT /api/hosts hosts updateHostNetworks
@@ -147,7 +153,9 @@ func updateHostNetworks(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	logger.Log(2, r.Header.Get("user"), "updated host", currHost.Name)
+	// TODO: add and remove hosts to networks (nodes)
+
+	logger.Log(2, r.Header.Get("user"), "updated host networks", currHost.Name)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(payload)
 }

+ 130 - 27
controllers/node.go

@@ -26,6 +26,7 @@ func nodeHandlers(r *mux.Router) {
 	r.HandleFunc("/api/nodes/{network}", authorize(false, true, "network", http.HandlerFunc(getNetworkNodes))).Methods("GET")
 	r.HandleFunc("/api/nodes/{network}/{nodeid}", authorize(true, true, "node", http.HandlerFunc(getNode))).Methods("GET")
 	r.HandleFunc("/api/nodes/{network}/{nodeid}", authorize(false, true, "node", http.HandlerFunc(updateNode))).Methods("PUT")
+	r.HandleFunc("/api/nodes/{network}/{nodeid}/migrate", authorize(true, true, "node", http.HandlerFunc(nodeNodeUpdate))).Methods("PUT")
 	r.HandleFunc("/api/nodes/{network}/{nodeid}", authorize(true, true, "node", http.HandlerFunc(deleteNode))).Methods("DELETE")
 	r.HandleFunc("/api/nodes/{network}/{nodeid}/createrelay", authorize(false, true, "user", http.HandlerFunc(createRelay))).Methods("POST")
 	r.HandleFunc("/api/nodes/{network}/{nodeid}/deleterelay", authorize(false, true, "user", http.HandlerFunc(deleteRelay))).Methods("DELETE")
@@ -373,10 +374,11 @@ func getNetworkNodes(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	//Returns all the nodes in JSON format
+	// returns all the nodes in JSON/API format
+	apiNodes := logic.GetAllNodesAPI(nodes[:])
 	logger.Log(2, r.Header.Get("user"), "fetched nodes on network", networkName)
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(nodes)
+	json.NewEncoder(w).Encode(apiNodes)
 }
 
 // swagger:route GET /api/nodes nodes getAllNodes
@@ -418,10 +420,11 @@ func getAllNodes(w http.ResponseWriter, r *http.Request) {
 			return
 		}
 	}
-	//Return all the nodes in JSON format
+	// return all the nodes in JSON/API format
+	apiNodes := logic.GetAllNodesAPI(nodes[:])
 	logger.Log(3, r.Header.Get("user"), "fetched all nodes they have access to")
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(nodes)
+	json.NewEncoder(w).Encode(apiNodes)
 }
 
 func getUsersNodes(user models.User) ([]models.Node, error) {
@@ -755,9 +758,10 @@ func createEgressGateway(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
+	apiNode := node.ConvertToAPINode()
 	logger.Log(1, r.Header.Get("user"), "created egress gateway on node", gateway.NodeID, "on network", gateway.NetID)
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(node)
+	json.NewEncoder(w).Encode(apiNode)
 
 	runUpdates(&node, true)
 }
@@ -787,9 +791,10 @@ func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
+	apiNode := node.ConvertToAPINode()
 	logger.Log(1, r.Header.Get("user"), "deleted egress gateway on node", nodeid, "on network", netid)
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(node)
+	json.NewEncoder(w).Encode(apiNode)
 
 	runUpdates(&node, true)
 }
@@ -833,9 +838,10 @@ func createIngressGateway(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
+	apiNode := node.ConvertToAPINode()
 	logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid)
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(node)
+	json.NewEncoder(w).Encode(apiNode)
 
 	runUpdates(&node, true)
 }
@@ -871,13 +877,108 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
+	apiNode := node.ConvertToAPINode()
 	logger.Log(1, r.Header.Get("user"), "deleted ingress gateway", nodeid)
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(node)
+	json.NewEncoder(w).Encode(apiNode)
 
 	runUpdates(&node, true)
 }
 
+// swagger:route PUT /api/nodes/{network}/{nodeid}/migrate nodes migrateNode
+//
+// Used to migrate a legacy node.
+//
+//			Schemes: https
+//
+//			Security:
+//	  		oauth
+//
+//			Responses:
+//				200: nodeResponse
+func nodeNodeUpdate(w http.ResponseWriter, r *http.Request) {
+	// should only be used by nodes
+	w.Header().Set("Content-Type", "application/json")
+
+	var params = mux.Vars(r)
+
+	//start here
+	nodeid := params["nodeid"]
+	currentNode, err := logic.GetNodeByID(nodeid)
+	if err != nil {
+		logger.Log(0,
+			fmt.Sprintf("error fetching node [ %s ] info: %v during migrate", nodeid, err))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+
+	var newNode models.Node
+	// we decode our body request params
+	err = json.NewDecoder(r.Body).Decode(&newNode)
+	if err != nil {
+		logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	relayupdate := false
+	if currentNode.IsRelay && len(newNode.RelayAddrs) > 0 {
+		if len(newNode.RelayAddrs) != len(currentNode.RelayAddrs) {
+			relayupdate = true
+		} else {
+			for i, addr := range newNode.RelayAddrs {
+				if addr != currentNode.RelayAddrs[i] {
+					relayupdate = true
+				}
+			}
+		}
+	}
+	relayedUpdate := false
+	if currentNode.IsRelayed && (currentNode.Address.String() != newNode.Address.String() || currentNode.Address6.String() != newNode.Address6.String()) {
+		relayedUpdate = true
+	}
+
+	if !servercfg.GetRce() {
+		newNode.PostDown = currentNode.PostDown
+		newNode.PostUp = currentNode.PostUp
+	}
+
+	ifaceDelta := logic.IfaceDelta(&currentNode, &newNode)
+
+	if ifaceDelta && servercfg.Is_EE {
+		if err = logic.EnterpriseResetAllPeersFailovers(currentNode.ID.String(), currentNode.Network); err != nil {
+			logger.Log(0, "failed to reset failover lists during node update for node", currentNode.ID.String(), currentNode.Network)
+		}
+	}
+
+	err = logic.UpdateNode(&currentNode, &newNode)
+	if err != nil {
+		logger.Log(0, r.Header.Get("user"),
+			fmt.Sprintf("failed to update node info [ %s ] info: %v", nodeid, err))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+	if relayupdate {
+		updatenodes := logic.UpdateRelay(currentNode.Network, currentNode.RelayAddrs, newNode.RelayAddrs)
+		if len(updatenodes) > 0 {
+			for _, relayedNode := range updatenodes {
+				runUpdates(&relayedNode, false)
+			}
+		}
+	}
+	if relayedUpdate {
+		updateRelay(&currentNode, &newNode)
+	}
+	if servercfg.IsDNSMode() {
+		logic.SetDNS()
+	}
+
+	logger.Log(1, r.Header.Get("user"), "updated node", currentNode.ID.String(), "on network", currentNode.Network)
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(newNode)
+
+	runUpdates(&newNode, ifaceDelta)
+}
+
 // swagger:route PUT /api/nodes/{network}/{nodeid} nodes updateNode
 //
 // Update an individual node.
@@ -894,10 +995,9 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 
 	var params = mux.Vars(r)
 
-	var node models.Node
 	//start here
 	nodeid := params["nodeid"]
-	node, err := logic.GetNodeByID(nodeid)
+	currentNode, err := logic.GetNodeByID(nodeid)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"),
 			fmt.Sprintf("error fetching node [ %s ] info: %v", nodeid, err))
@@ -905,44 +1005,45 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	var newNode models.Node
+	var newData models.ApiNode
 	// we decode our body request params
-	err = json.NewDecoder(r.Body).Decode(&newNode)
+	err = json.NewDecoder(r.Body).Decode(&newData)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
+	newNode := newData.ConvertToServerNode(&currentNode)
 	relayupdate := false
-	if node.IsRelay && len(newNode.RelayAddrs) > 0 {
-		if len(newNode.RelayAddrs) != len(node.RelayAddrs) {
+	if currentNode.IsRelay && len(newNode.RelayAddrs) > 0 {
+		if len(newNode.RelayAddrs) != len(currentNode.RelayAddrs) {
 			relayupdate = true
 		} else {
 			for i, addr := range newNode.RelayAddrs {
-				if addr != node.RelayAddrs[i] {
+				if addr != currentNode.RelayAddrs[i] {
 					relayupdate = true
 				}
 			}
 		}
 	}
 	relayedUpdate := false
-	if node.IsRelayed && (node.Address.String() != newNode.Address.String() || node.Address6.String() != newNode.Address6.String()) {
+	if currentNode.IsRelayed && (currentNode.Address.String() != newNode.Address.String() || currentNode.Address6.String() != newNode.Address6.String()) {
 		relayedUpdate = true
 	}
 
 	if !servercfg.GetRce() {
-		newNode.PostDown = node.PostDown
-		newNode.PostUp = node.PostUp
+		newNode.PostDown = currentNode.PostDown
+		newNode.PostUp = currentNode.PostUp
 	}
-	ifaceDelta := logic.IfaceDelta(&node, &newNode)
+	ifaceDelta := logic.IfaceDelta(&currentNode, newNode)
 
 	if ifaceDelta && servercfg.Is_EE {
-		if err = logic.EnterpriseResetAllPeersFailovers(node.ID.String(), node.Network); err != nil {
-			logger.Log(0, "failed to reset failover lists during node update for node", node.ID.String(), node.Network)
+		if err = logic.EnterpriseResetAllPeersFailovers(currentNode.ID.String(), currentNode.Network); err != nil {
+			logger.Log(0, "failed to reset failover lists during node update for node", currentNode.ID.String(), currentNode.Network)
 		}
 	}
 
-	err = logic.UpdateNode(&node, &newNode)
+	err = logic.UpdateNode(&currentNode, newNode)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"),
 			fmt.Sprintf("failed to update node info [ %s ] info: %v", nodeid, err))
@@ -950,7 +1051,7 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	if relayupdate {
-		updatenodes := logic.UpdateRelay(node.Network, node.RelayAddrs, newNode.RelayAddrs)
+		updatenodes := logic.UpdateRelay(currentNode.Network, currentNode.RelayAddrs, newNode.RelayAddrs)
 		if len(updatenodes) > 0 {
 			for _, relayedNode := range updatenodes {
 				runUpdates(&relayedNode, false)
@@ -958,16 +1059,18 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 	if relayedUpdate {
-		updateRelay(&node, &newNode)
+		updateRelay(&currentNode, newNode)
 	}
 	if servercfg.IsDNSMode() {
 		logic.SetDNS()
 	}
-	logger.Log(1, r.Header.Get("user"), "updated node", node.ID.String(), "on network", node.Network)
+
+	apiNode := newNode.ConvertToAPINode()
+	logger.Log(1, r.Header.Get("user"), "updated node", currentNode.ID.String(), "on network", currentNode.Network)
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(newNode)
+	json.NewEncoder(w).Encode(apiNode)
 
-	runUpdates(&newNode, ifaceDelta)
+	runUpdates(newNode, ifaceDelta)
 }
 
 // swagger:route DELETE /api/nodes/{network}/{nodeid} nodes deleteNode

+ 4 - 2
controllers/relay.go

@@ -52,8 +52,9 @@ func createRelay(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
+	apiNode := node.ConvertToAPINode()
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(node)
+	json.NewEncoder(w).Encode(apiNode)
 	runUpdates(&node, true)
 }
 
@@ -86,7 +87,8 @@ func deleteRelay(w http.ResponseWriter, r *http.Request) {
 			logger.Log(1, "error sending update to relayed node ", relayedNode.ID.String(), "on network", netid, ": ", err.Error())
 		}
 	}
+	apiNode := node.ConvertToAPINode()
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(node)
+	json.NewEncoder(w).Encode(apiNode)
 	runUpdates(&node, true)
 }

+ 10 - 0
logic/hosts.go

@@ -28,6 +28,16 @@ func GetAllHosts() ([]models.Host, error) {
 	return currentHosts, nil
 }
 
+// GetAllHostsAPI - get's all the hosts in an API usable format
+func GetAllHostsAPI(hosts []models.Host) []models.ApiHost {
+	apiHosts := []models.ApiHost{}
+	for i := range hosts {
+		newApiHost := hosts[i].ConvertNMHostToAPI()
+		apiHosts = append(apiHosts, *newApiHost)
+	}
+	return apiHosts[:]
+}
+
 // GetHostsMap - gets all the current hosts on machine in a map
 func GetHostsMap() (map[string]*models.Host, error) {
 	records, err := database.FetchRecords(database.HOSTS_TABLE_NAME)

+ 10 - 0
logic/nodes.go

@@ -574,6 +574,16 @@ func GetNetworkIngresses(network string) ([]models.Node, error) {
 	return ingresses, nil
 }
 
+// GetAllNodesAPI - get all nodes for api usage
+func GetAllNodesAPI(nodes []models.Node) []models.ApiNode {
+	apiNodes := []models.ApiNode{}
+	for i := range nodes {
+		newApiNode := nodes[i].ConvertToAPINode()
+		apiNodes = append(apiNodes, *newApiNode)
+	}
+	return apiNodes[:]
+}
+
 // == PRO ==
 
 func updateProNodeACLS(node *models.Node) error {