|
@@ -67,75 +67,112 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
|
|
decoderErr.Error())
|
|
decoderErr.Error())
|
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
|
return
|
|
return
|
|
- } else {
|
|
|
|
- errorResponse.Code = http.StatusBadRequest
|
|
|
|
- if authRequest.ID == "" {
|
|
|
|
- errorResponse.Message = "W1R3: ID can't be empty"
|
|
|
|
- logger.Log(0, request.Header.Get("user"), errorResponse.Message)
|
|
|
|
- logic.ReturnErrorResponse(response, request, errorResponse)
|
|
|
|
- return
|
|
|
|
- } else if authRequest.Password == "" {
|
|
|
|
- errorResponse.Message = "W1R3: Password can't be empty"
|
|
|
|
- logger.Log(0, request.Header.Get("user"), errorResponse.Message)
|
|
|
|
|
|
+ }
|
|
|
|
+ errorResponse.Code = http.StatusBadRequest
|
|
|
|
+ if authRequest.ID == "" {
|
|
|
|
+ errorResponse.Message = "W1R3: ID can't be empty"
|
|
|
|
+ logger.Log(0, request.Header.Get("user"), errorResponse.Message)
|
|
|
|
+ logic.ReturnErrorResponse(response, request, errorResponse)
|
|
|
|
+ return
|
|
|
|
+ } else if authRequest.Password == "" {
|
|
|
|
+ errorResponse.Message = "W1R3: Password can't be empty"
|
|
|
|
+ logger.Log(0, request.Header.Get("user"), errorResponse.Message)
|
|
|
|
+ logic.ReturnErrorResponse(response, request, errorResponse)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ var err error
|
|
|
|
+ result, err = logic.GetNodeByID(authRequest.ID)
|
|
|
|
+ if err != nil {
|
|
|
|
+ result, err = logic.GetDeletedNodeByID(authRequest.ID)
|
|
|
|
+ if err != nil {
|
|
|
|
+ errorResponse.Code = http.StatusBadRequest
|
|
|
|
+ errorResponse.Message = err.Error()
|
|
|
|
+ logger.Log(0, request.Header.Get("user"),
|
|
|
|
+ fmt.Sprintf("failed to get node info [%s]: %v", authRequest.ID, err))
|
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
|
return
|
|
return
|
|
- } else {
|
|
|
|
- var err error
|
|
|
|
- result, err = logic.GetNodeByID(authRequest.ID)
|
|
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- if err != nil {
|
|
|
|
- errorResponse.Code = http.StatusBadRequest
|
|
|
|
- errorResponse.Message = err.Error()
|
|
|
|
- logger.Log(0, request.Header.Get("user"),
|
|
|
|
- fmt.Sprintf("failed to get node info [%s]: %v", authRequest.ID, err))
|
|
|
|
- logic.ReturnErrorResponse(response, request, errorResponse)
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
|
|
+ err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password))
|
|
|
|
+ if err != nil {
|
|
|
|
+ errorResponse.Code = http.StatusBadRequest
|
|
|
|
+ errorResponse.Message = err.Error()
|
|
|
|
+ logger.Log(0, request.Header.Get("user"),
|
|
|
|
+ "error validating user password: ", err.Error())
|
|
|
|
+ logic.ReturnErrorResponse(response, request, errorResponse)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // creates network role,node client (added here to resolve any missing configuration in MQ)
|
|
|
|
+ event := mq.MqDynsecPayload{
|
|
|
|
+ Commands: []mq.MqDynSecCmd{
|
|
|
|
+
|
|
|
|
+ {
|
|
|
|
+ Command: mq.CreateRoleCmd,
|
|
|
|
+ RoleName: result.Network,
|
|
|
|
+ Textname: "Network wide role with Acls for nodes",
|
|
|
|
+ Acls: mq.FetchNetworkAcls(result.Network),
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ Command: mq.CreateClientCmd,
|
|
|
|
+ Username: result.ID,
|
|
|
|
+ Password: authRequest.Password,
|
|
|
|
+ Textname: result.Name,
|
|
|
|
+ Roles: []mq.MqDynSecRole{
|
|
|
|
+ {
|
|
|
|
+ Rolename: mq.NodeRole,
|
|
|
|
+ Priority: -1,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ Rolename: result.Network,
|
|
|
|
+ Priority: -1,
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ Groups: make([]mq.MqDynSecGroup, 0),
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
|
|
- err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password))
|
|
|
|
- if err != nil {
|
|
|
|
- errorResponse.Code = http.StatusBadRequest
|
|
|
|
- errorResponse.Message = err.Error()
|
|
|
|
- logger.Log(0, request.Header.Get("user"),
|
|
|
|
- "error validating user password: ", err.Error())
|
|
|
|
- logic.ReturnErrorResponse(response, request, errorResponse)
|
|
|
|
- return
|
|
|
|
- } else {
|
|
|
|
- tokenString, err := logic.CreateJWT(authRequest.ID, authRequest.MacAddress, result.Network)
|
|
|
|
-
|
|
|
|
- if tokenString == "" {
|
|
|
|
- errorResponse.Code = http.StatusBadRequest
|
|
|
|
- errorResponse.Message = "Could not create Token"
|
|
|
|
- logger.Log(0, request.Header.Get("user"),
|
|
|
|
- fmt.Sprintf("%s: %v", errorResponse.Message, err))
|
|
|
|
- logic.ReturnErrorResponse(response, request, errorResponse)
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
|
|
+ if err := mq.PublishEventToDynSecTopic(event); err != nil {
|
|
|
|
+ logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
|
|
|
|
+ event.Commands, err.Error()))
|
|
|
|
+ errorResponse.Code = http.StatusInternalServerError
|
|
|
|
+ errorResponse.Message = fmt.Sprintf("could not create mq client for node [%s]: %v", result.ID, err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
|
|
- var successResponse = models.SuccessResponse{
|
|
|
|
- Code: http.StatusOK,
|
|
|
|
- Message: "W1R3: Device " + authRequest.ID + " Authorized",
|
|
|
|
- Response: models.SuccessfulLoginResponse{
|
|
|
|
- AuthToken: tokenString,
|
|
|
|
- ID: authRequest.ID,
|
|
|
|
- },
|
|
|
|
- }
|
|
|
|
- successJSONResponse, jsonError := json.Marshal(successResponse)
|
|
|
|
-
|
|
|
|
- if jsonError != nil {
|
|
|
|
- errorResponse.Code = http.StatusBadRequest
|
|
|
|
- errorResponse.Message = err.Error()
|
|
|
|
- logger.Log(0, request.Header.Get("user"),
|
|
|
|
- "error marshalling resp: ", err.Error())
|
|
|
|
- logic.ReturnErrorResponse(response, request, errorResponse)
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
- response.WriteHeader(http.StatusOK)
|
|
|
|
- response.Header().Set("Content-Type", "application/json")
|
|
|
|
- response.Write(successJSONResponse)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ tokenString, err := logic.CreateJWT(authRequest.ID, authRequest.MacAddress, result.Network)
|
|
|
|
+ if tokenString == "" {
|
|
|
|
+ errorResponse.Code = http.StatusBadRequest
|
|
|
|
+ errorResponse.Message = "Could not create Token"
|
|
|
|
+ logger.Log(0, request.Header.Get("user"),
|
|
|
|
+ fmt.Sprintf("%s: %v", errorResponse.Message, err))
|
|
|
|
+ logic.ReturnErrorResponse(response, request, errorResponse)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var successResponse = models.SuccessResponse{
|
|
|
|
+ Code: http.StatusOK,
|
|
|
|
+ Message: "W1R3: Device " + authRequest.ID + " Authorized",
|
|
|
|
+ Response: models.SuccessfulLoginResponse{
|
|
|
|
+ AuthToken: tokenString,
|
|
|
|
+ ID: authRequest.ID,
|
|
|
|
+ },
|
|
}
|
|
}
|
|
|
|
+ successJSONResponse, jsonError := json.Marshal(successResponse)
|
|
|
|
+
|
|
|
|
+ if jsonError != nil {
|
|
|
|
+ errorResponse.Code = http.StatusBadRequest
|
|
|
|
+ errorResponse.Message = err.Error()
|
|
|
|
+ logger.Log(0, request.Header.Get("user"),
|
|
|
|
+ "error marshalling resp: ", err.Error())
|
|
|
|
+ logic.ReturnErrorResponse(response, request, errorResponse)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ response.WriteHeader(http.StatusOK)
|
|
|
|
+ response.Header().Set("Content-Type", "application/json")
|
|
|
|
+ response.Write(successJSONResponse)
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
// auth middleware for api calls from nodes where node is has not yet joined the server (register, join)
|
|
// auth middleware for api calls from nodes where node is has not yet joined the server (register, join)
|
|
@@ -226,6 +263,9 @@ func authorize(nodesAllowed, networkCheck bool, authNetwork string, next http.Ha
|
|
if nodesAllowed {
|
|
if nodesAllowed {
|
|
// TODO --- should ensure that node is only operating on itself
|
|
// TODO --- should ensure that node is only operating on itself
|
|
if _, _, _, err := logic.VerifyToken(authToken); err == nil {
|
|
if _, _, _, err := logic.VerifyToken(authToken); err == nil {
|
|
|
|
+
|
|
|
|
+ // this indicates request is from a node
|
|
|
|
+ // used for failover - if a getNode comes from node, this will trigger a metrics wipe
|
|
next.ServeHTTP(w, r)
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -411,6 +451,8 @@ func getNode(w http.ResponseWriter, r *http.Request) {
|
|
// set header.
|
|
// set header.
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
+ nodeRequest := r.Header.Get("requestfrom") == "node"
|
|
|
|
+
|
|
var params = mux.Vars(r)
|
|
var params = mux.Vars(r)
|
|
nodeid := params["nodeid"]
|
|
nodeid := params["nodeid"]
|
|
node, err := logic.GetNodeByID(nodeid)
|
|
node, err := logic.GetNodeByID(nodeid)
|
|
@@ -440,6 +482,12 @@ func getNode(w http.ResponseWriter, r *http.Request) {
|
|
PeerIDs: peerUpdate.PeerIDs,
|
|
PeerIDs: peerUpdate.PeerIDs,
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if servercfg.Is_EE && nodeRequest {
|
|
|
|
+ if err = logic.EnterpriseResetAllPeersFailovers(node.ID, node.Network); err != nil {
|
|
|
|
+ logger.Log(1, "failed to reset failover list during node config pull", node.Name, node.Network)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
logger.Log(2, r.Header.Get("user"), "fetched node", params["nodeid"])
|
|
logger.Log(2, r.Header.Get("user"), "fetched node", params["nodeid"])
|
|
w.WriteHeader(http.StatusOK)
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(response)
|
|
json.NewEncoder(w).Encode(response)
|
|
@@ -585,7 +633,8 @@ func createNode(w http.ResponseWriter, r *http.Request) {
|
|
Mine: node.TrafficKeys.Mine,
|
|
Mine: node.TrafficKeys.Mine,
|
|
Server: key,
|
|
Server: key,
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ // consume password before hashing for mq client creation
|
|
|
|
+ nodePassword := node.Password
|
|
err = logic.CreateNode(&node)
|
|
err = logic.CreateNode(&node)
|
|
if err != nil {
|
|
if err != nil {
|
|
logger.Log(0, r.Header.Get("user"),
|
|
logger.Log(0, r.Header.Get("user"),
|
|
@@ -621,6 +670,44 @@ func createNode(w http.ResponseWriter, r *http.Request) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // Create client for this node in Mq
|
|
|
|
+ event := mq.MqDynsecPayload{
|
|
|
|
+ Commands: []mq.MqDynSecCmd{
|
|
|
|
+ { // delete if any client exists already
|
|
|
|
+ Command: mq.DeleteClientCmd,
|
|
|
|
+ Username: node.ID,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ Command: mq.CreateRoleCmd,
|
|
|
|
+ RoleName: node.Network,
|
|
|
|
+ Textname: "Network wide role with Acls for nodes",
|
|
|
|
+ Acls: mq.FetchNetworkAcls(node.Network),
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ Command: mq.CreateClientCmd,
|
|
|
|
+ Username: node.ID,
|
|
|
|
+ Password: nodePassword,
|
|
|
|
+ Textname: node.Name,
|
|
|
|
+ Roles: []mq.MqDynSecRole{
|
|
|
|
+ {
|
|
|
|
+ Rolename: mq.NodeRole,
|
|
|
|
+ Priority: -1,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ Rolename: node.Network,
|
|
|
|
+ Priority: -1,
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ Groups: make([]mq.MqDynSecGroup, 0),
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := mq.PublishEventToDynSecTopic(event); err != nil {
|
|
|
|
+ logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
|
|
|
|
+ event.Commands, err.Error()))
|
|
|
|
+ }
|
|
|
|
+
|
|
response := models.NodeGet{
|
|
response := models.NodeGet{
|
|
Node: node,
|
|
Node: node,
|
|
Peers: peerUpdate.Peers,
|
|
Peers: peerUpdate.Peers,
|
|
@@ -756,7 +843,13 @@ func createIngressGateway(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Content-Type", "application/json")
|
|
nodeid := params["nodeid"]
|
|
nodeid := params["nodeid"]
|
|
netid := params["network"]
|
|
netid := params["network"]
|
|
- node, err := logic.CreateIngressGateway(netid, nodeid)
|
|
|
|
|
|
+ type failoverData struct {
|
|
|
|
+ Failover bool `json:"failover"`
|
|
|
|
+ }
|
|
|
|
+ var failoverReqBody failoverData
|
|
|
|
+ json.NewDecoder(r.Body).Decode(&failoverReqBody)
|
|
|
|
+
|
|
|
|
+ node, err := logic.CreateIngressGateway(netid, nodeid, failoverReqBody.Failover)
|
|
if err != nil {
|
|
if err != nil {
|
|
logger.Log(0, r.Header.Get("user"),
|
|
logger.Log(0, r.Header.Get("user"),
|
|
fmt.Sprintf("failed to create ingress gateway on node [%s] on network [%s]: %v",
|
|
fmt.Sprintf("failed to create ingress gateway on node [%s] on network [%s]: %v",
|
|
@@ -765,6 +858,12 @@ func createIngressGateway(w http.ResponseWriter, r *http.Request) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if servercfg.Is_EE && failoverReqBody.Failover {
|
|
|
|
+ if err = logic.EnterpriseResetFailoverFunc(node.Network); err != nil {
|
|
|
|
+ logger.Log(1, "failed to reset failover list during failover create", node.Name, node.Network)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid)
|
|
logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid)
|
|
w.WriteHeader(http.StatusOK)
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(node)
|
|
json.NewEncoder(w).Encode(node)
|
|
@@ -788,7 +887,7 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
|
|
var params = mux.Vars(r)
|
|
var params = mux.Vars(r)
|
|
nodeid := params["nodeid"]
|
|
nodeid := params["nodeid"]
|
|
netid := params["network"]
|
|
netid := params["network"]
|
|
- node, err := logic.DeleteIngressGateway(netid, nodeid)
|
|
|
|
|
|
+ node, wasFailover, err := logic.DeleteIngressGateway(netid, nodeid)
|
|
if err != nil {
|
|
if err != nil {
|
|
logger.Log(0, r.Header.Get("user"),
|
|
logger.Log(0, r.Header.Get("user"),
|
|
fmt.Sprintf("failed to delete ingress gateway on node [%s] on network [%s]: %v",
|
|
fmt.Sprintf("failed to delete ingress gateway on node [%s] on network [%s]: %v",
|
|
@@ -797,6 +896,12 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if servercfg.Is_EE && wasFailover {
|
|
|
|
+ if err = logic.EnterpriseResetFailoverFunc(node.Network); err != nil {
|
|
|
|
+ logger.Log(1, "failed to reset failover list during failover create", node.Name, node.Network)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
logger.Log(1, r.Header.Get("user"), "deleted ingress gateway", nodeid)
|
|
logger.Log(1, r.Header.Get("user"), "deleted ingress gateway", nodeid)
|
|
w.WriteHeader(http.StatusOK)
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(node)
|
|
json.NewEncoder(w).Encode(node)
|
|
@@ -880,6 +985,12 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if ifaceDelta && servercfg.Is_EE {
|
|
|
|
+ if err = logic.EnterpriseResetAllPeersFailovers(node.ID, node.Network); err != nil {
|
|
|
|
+ logger.Log(0, "failed to reset failover lists during node update for node", node.Name, node.Network)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
err = logic.UpdateNode(&node, &newNode)
|
|
err = logic.UpdateNode(&node, &newNode)
|
|
if err != nil {
|
|
if err != nil {
|
|
logger.Log(0, r.Header.Get("user"),
|
|
logger.Log(0, r.Header.Get("user"),
|
|
@@ -927,12 +1038,23 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
|
|
// get params
|
|
// get params
|
|
var params = mux.Vars(r)
|
|
var params = mux.Vars(r)
|
|
var nodeid = params["nodeid"]
|
|
var nodeid = params["nodeid"]
|
|
|
|
+ fromNode := r.Header.Get("requestfrom") == "node"
|
|
var node, err = logic.GetNodeByID(nodeid)
|
|
var node, err = logic.GetNodeByID(nodeid)
|
|
if err != nil {
|
|
if err != nil {
|
|
- logger.Log(0, r.Header.Get("user"),
|
|
|
|
- fmt.Sprintf("error fetching node [ %s ] info: %v", nodeid, err))
|
|
|
|
- logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
|
|
|
- return
|
|
|
|
|
|
+ if fromNode {
|
|
|
|
+ node, err = logic.GetDeletedNodeByID(nodeid)
|
|
|
|
+ if err != nil {
|
|
|
|
+ logger.Log(0, r.Header.Get("user"),
|
|
|
|
+ fmt.Sprintf("error fetching node from deleted nodes [ %s ] info: %v", nodeid, err))
|
|
|
|
+ logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ logger.Log(0, r.Header.Get("user"),
|
|
|
|
+ fmt.Sprintf("error fetching node [ %s ] info: %v", nodeid, err))
|
|
|
|
+ logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
|
|
|
+ return
|
|
|
|
+ }
|
|
}
|
|
}
|
|
if isServer(&node) {
|
|
if isServer(&node) {
|
|
err := fmt.Errorf("cannot delete server node")
|
|
err := fmt.Errorf("cannot delete server node")
|
|
@@ -951,14 +1073,35 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
|
|
//send update to node to be deleted before deleting on server otherwise message cannot be sent
|
|
//send update to node to be deleted before deleting on server otherwise message cannot be sent
|
|
node.Action = models.NODE_DELETE
|
|
node.Action = models.NODE_DELETE
|
|
|
|
|
|
- err = logic.DeleteNodeByID(&node, false)
|
|
|
|
|
|
+ err = logic.DeleteNodeByID(&node, fromNode)
|
|
if err != nil {
|
|
if err != nil {
|
|
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
|
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+ if fromNode {
|
|
|
|
+ // deletes node related role and client
|
|
|
|
+ event := mq.MqDynsecPayload{
|
|
|
|
+ Commands: []mq.MqDynSecCmd{
|
|
|
|
+ {
|
|
|
|
+ Command: mq.DeleteClientCmd,
|
|
|
|
+ Username: nodeid,
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
|
|
- logic.ReturnSuccessResponse(w, r, nodeid+" deleted.")
|
|
|
|
|
|
+ if err := mq.PublishEventToDynSecTopic(event); err != nil {
|
|
|
|
+ logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
|
|
|
|
+ event.Commands, err.Error()))
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ if servercfg.Is_EE {
|
|
|
|
+ if err = logic.EnterpriseResetAllPeersFailovers(node.ID, node.Network); err != nil {
|
|
|
|
+ logger.Log(0, "failed to reset failover lists during node delete for node", node.Name, node.Network)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ logic.ReturnSuccessResponse(w, r, nodeid+" deleted.")
|
|
logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
|
|
logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
|
|
runUpdates(&node, false)
|
|
runUpdates(&node, false)
|
|
runForceServerUpdate(&node, false)
|
|
runForceServerUpdate(&node, false)
|