mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-04 04:04:17 +08:00
NET-1956: Async Node Status API (#3341)
* add node status api * upsate node status api to return map data * resolve merge conflicts
This commit is contained in:
parent
a805901a73
commit
48535f7ef1
5 changed files with 90 additions and 8 deletions
|
@ -31,6 +31,7 @@ func nodeHandlers(r *mux.Router) {
|
|||
r.HandleFunc("/api/nodes/{network}/{nodeid}/createingress", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceIngress, http.HandlerFunc(createGateway)))).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/deleteingress", logic.SecurityCheck(true, http.HandlerFunc(deleteGateway))).Methods(http.MethodDelete)
|
||||
r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/v1/nodes/{network}/status", logic.SecurityCheck(true, http.HandlerFunc(getNetworkNodeStatus))).Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/v1/nodes/migrate", migrate).Methods(http.MethodPost)
|
||||
}
|
||||
|
||||
|
@ -328,7 +329,7 @@ func getNetworkNodes(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
nodes = logic.AddStaticNodestoList(nodes)
|
||||
nodes = logic.AddStatusToNodes(nodes)
|
||||
nodes = logic.AddStatusToNodes(nodes, false)
|
||||
// returns all the nodes in JSON/API format
|
||||
apiNodes := logic.GetAllNodesAPI(nodes[:])
|
||||
logger.Log(2, r.Header.Get("user"), "fetched nodes on network", networkName)
|
||||
|
@ -368,7 +369,7 @@ func getAllNodes(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
}
|
||||
nodes = logic.AddStaticNodestoList(nodes)
|
||||
nodes = logic.AddStatusToNodes(nodes)
|
||||
nodes = logic.AddStatusToNodes(nodes, false)
|
||||
// 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")
|
||||
|
@ -377,6 +378,52 @@ func getAllNodes(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(apiNodes)
|
||||
}
|
||||
|
||||
// @Summary Get all nodes status on the network
|
||||
// @Router /api/v1/nodes/{network}/status [get]
|
||||
// @Tags Nodes
|
||||
// @Securitydefinitions.oauth2.application OAuth2Application
|
||||
// @Success 200 {array} models.ApiNode
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// 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
|
||||
func getNetworkNodeStatus(w http.ResponseWriter, r *http.Request) {
|
||||
var params = mux.Vars(r)
|
||||
netID := params["network"]
|
||||
// validate network
|
||||
_, err := logic.GetNetwork(netID)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to get network %v", err), "badrequest"))
|
||||
return
|
||||
}
|
||||
var nodes []models.Node
|
||||
nodes, err = logic.GetNetworkNodes(netID)
|
||||
if err != nil {
|
||||
logger.Log(0, "error fetching all nodes info: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
username := r.Header.Get("user")
|
||||
if r.Header.Get("ismaster") == "no" {
|
||||
user, err := logic.GetUser(username)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
userPlatformRole, err := logic.GetRole(user.PlatformRoleID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !userPlatformRole.FullAccess {
|
||||
nodes = logic.GetFilteredNodesByUserAccess(*user, nodes)
|
||||
}
|
||||
|
||||
}
|
||||
nodes = logic.AddStaticNodestoList(nodes)
|
||||
nodes = logic.AddStatusToNodes(nodes, false)
|
||||
// return all the nodes in JSON/API format
|
||||
apiNodesStatusMap := logic.GetNodesStatusAPI(nodes[:])
|
||||
logger.Log(3, r.Header.Get("user"), "fetched all nodes they have access to")
|
||||
logic.ReturnSuccessResponseWithJson(w, r, apiNodesStatusMap, "fetched nodes with metric status")
|
||||
}
|
||||
|
||||
// @Summary Get an individual node
|
||||
// @Router /api/nodes/{network}/{nodeid} [get]
|
||||
// @Tags Nodes
|
||||
|
|
|
@ -443,7 +443,7 @@ func AddStaticNodestoList(nodes []models.Node) []models.Node {
|
|||
return nodes
|
||||
}
|
||||
|
||||
func AddStatusToNodes(nodes []models.Node) (nodesWithStatus []models.Node) {
|
||||
func AddStatusToNodes(nodes []models.Node, statusCall bool) (nodesWithStatus []models.Node) {
|
||||
aclDefaultPolicyStatusMap := make(map[string]bool)
|
||||
for _, node := range nodes {
|
||||
if _, ok := aclDefaultPolicyStatusMap[node.Network]; !ok {
|
||||
|
@ -451,7 +451,12 @@ func AddStatusToNodes(nodes []models.Node) (nodesWithStatus []models.Node) {
|
|||
defaultPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
||||
aclDefaultPolicyStatusMap[node.Network] = defaultPolicy.Enabled
|
||||
}
|
||||
GetNodeStatus(&node, aclDefaultPolicyStatusMap[node.Network])
|
||||
if statusCall {
|
||||
GetNodeStatus(&node, aclDefaultPolicyStatusMap[node.Network])
|
||||
} else {
|
||||
GetNodeCheckInStatus(&node, true)
|
||||
}
|
||||
|
||||
nodesWithStatus = append(nodesWithStatus, node)
|
||||
}
|
||||
return
|
||||
|
@ -572,6 +577,16 @@ func GetAllNodesAPI(nodes []models.Node) []models.ApiNode {
|
|||
return apiNodes[:]
|
||||
}
|
||||
|
||||
// GetNodesStatusAPI - gets nodes status
|
||||
func GetNodesStatusAPI(nodes []models.Node) map[string]models.ApiNodeStatus {
|
||||
apiStatusNodesMap := make(map[string]models.ApiNodeStatus)
|
||||
for i := range nodes {
|
||||
newApiNode := nodes[i].ConvertToStatusNode()
|
||||
apiStatusNodesMap[newApiNode.ID] = *newApiNode
|
||||
}
|
||||
return apiStatusNodesMap
|
||||
}
|
||||
|
||||
// DeleteExpiredNodes - goroutine which deletes nodes which are expired
|
||||
func DeleteExpiredNodes(ctx context.Context, peerUpdate chan *models.Node) {
|
||||
// Delete Expired Nodes Every Hour
|
||||
|
|
|
@ -6,9 +6,9 @@ import (
|
|||
"github.com/gravitl/netmaker/models"
|
||||
)
|
||||
|
||||
var GetNodeStatus = getNodeStatus
|
||||
var GetNodeStatus = GetNodeCheckInStatus
|
||||
|
||||
func getNodeStatus(node *models.Node, t bool) {
|
||||
func GetNodeCheckInStatus(node *models.Node, t bool) {
|
||||
// On CE check only last check-in time
|
||||
if node.IsStatic {
|
||||
if !node.StaticNode.Enabled {
|
||||
|
|
|
@ -8,6 +8,13 @@ import (
|
|||
"golang.org/x/exp/slog"
|
||||
)
|
||||
|
||||
type ApiNodeStatus struct {
|
||||
ID string `json:"id"`
|
||||
IsStatic bool `json:"is_static"`
|
||||
IsUserNode bool `json:"is_user_node"`
|
||||
Status NodeStatus `json:"status"`
|
||||
}
|
||||
|
||||
// ApiNode is a stripped down Node DTO that exposes only required fields to external systems
|
||||
type ApiNode struct {
|
||||
ID string `json:"id,omitempty" validate:"required,min=5,id_unique"`
|
||||
|
@ -132,6 +139,19 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
|
|||
return &convertedNode
|
||||
}
|
||||
|
||||
func (nm *Node) ConvertToStatusNode() *ApiNodeStatus {
|
||||
apiNode := ApiNodeStatus{}
|
||||
if nm.IsStatic {
|
||||
apiNode.ID = nm.StaticNode.ClientID
|
||||
} else {
|
||||
apiNode.ID = nm.ID.String()
|
||||
}
|
||||
apiNode.IsStatic = nm.IsStatic
|
||||
apiNode.IsUserNode = nm.IsUserNode
|
||||
apiNode.Status = nm.Status
|
||||
return &apiNode
|
||||
}
|
||||
|
||||
// Node.ConvertToAPINode - converts a node to an API node
|
||||
func (nm *Node) ConvertToAPINode() *ApiNode {
|
||||
apiNode := ApiNode{}
|
||||
|
|
|
@ -1102,7 +1102,7 @@ func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) {
|
|||
slog.Error("failed to get node network", "error", err)
|
||||
continue
|
||||
}
|
||||
nodesWithStatus := logic.AddStatusToNodes([]models.Node{node})
|
||||
nodesWithStatus := logic.AddStatusToNodes([]models.Node{node}, false)
|
||||
if len(nodesWithStatus) > 0 {
|
||||
node = nodesWithStatus[0]
|
||||
}
|
||||
|
@ -1143,7 +1143,7 @@ func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
continue
|
||||
}
|
||||
nodesWithStatus := logic.AddStatusToNodes([]models.Node{node})
|
||||
nodesWithStatus := logic.AddStatusToNodes([]models.Node{node}, false)
|
||||
if len(nodesWithStatus) > 0 {
|
||||
node = nodesWithStatus[0]
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue