mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-22 00:19:39 +08:00
added basic api endpoints
This commit is contained in:
@@ -1,2 +1 @@
|
||||
10.0.0.1 testnode.skynet
|
||||
10.0.0.2 myhost.skynet
|
||||
10.0.0.2 testnode.skynet myhost.skynet
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/logic/acls"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
@@ -34,6 +35,9 @@ func networkHandlers(r *mux.Router) {
|
||||
r.HandleFunc("/api/networks/{networkname}/keys", securityCheck(false, http.HandlerFunc(createAccessKey))).Methods("POST")
|
||||
r.HandleFunc("/api/networks/{networkname}/keys", securityCheck(false, http.HandlerFunc(getAccessKeys))).Methods("GET")
|
||||
r.HandleFunc("/api/networks/{networkname}/keys/{name}", securityCheck(false, http.HandlerFunc(deleteAccessKey))).Methods("DELETE")
|
||||
r.HandleFunc("/api/networks/{networkname}/acls", securityCheck(true, http.HandlerFunc(updateNetworkACL))).Methods("PUT")
|
||||
r.HandleFunc("/api/networks/{networkname}/acls", securityCheck(true, http.HandlerFunc(getNetworkACL))).Methods("GET")
|
||||
|
||||
}
|
||||
|
||||
//simple get all networks function
|
||||
@@ -231,6 +235,40 @@ func updateNetworkNodeLimit(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(network)
|
||||
}
|
||||
|
||||
func updateNetworkACL(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var params = mux.Vars(r)
|
||||
netname := params["networkname"]
|
||||
var networkACLChange acls.ACLContainer
|
||||
networkACLChange, err := networkACLChange.Get(acls.ContainerID(netname))
|
||||
if err != nil {
|
||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
_ = json.NewDecoder(r.Body).Decode(&networkACLChange)
|
||||
newNetACL, err := networkACLChange.Save(acls.ContainerID(netname))
|
||||
if err != nil {
|
||||
returnErrorResponse(w, r, formatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(newNetACL)
|
||||
}
|
||||
|
||||
func getNetworkACL(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var params = mux.Vars(r)
|
||||
netname := params["networkname"]
|
||||
var networkACL acls.ACLContainer
|
||||
networkACL, err := networkACL.Get(acls.ContainerID(netname))
|
||||
if err != nil {
|
||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(networkACL)
|
||||
}
|
||||
|
||||
// Delete a network
|
||||
// Will stop you if there's any nodes associated
|
||||
func deleteNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
|
@@ -11,6 +11,8 @@ import (
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/logic/acls"
|
||||
nodeacls "github.com/gravitl/netmaker/logic/acls/node-acls"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
@@ -34,7 +36,9 @@ func nodeHandlers(r *mux.Router) {
|
||||
r.HandleFunc("/api/nodes/{network}", createNode).Methods("POST")
|
||||
r.HandleFunc("/api/nodes/adm/{network}/lastmodified", authorize(true, "network", http.HandlerFunc(getLastModified))).Methods("GET")
|
||||
r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods("POST")
|
||||
|
||||
// ACLs
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/acls", authorize(true, "node", http.HandlerFunc(getNodeACL))).Methods("GET")
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/acls", authorize(true, "node", http.HandlerFunc(updateNodeACL))).Methods("PUT")
|
||||
}
|
||||
|
||||
func authenticate(response http.ResponseWriter, request *http.Request) {
|
||||
@@ -339,6 +343,25 @@ func getNode(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(node)
|
||||
}
|
||||
|
||||
// Get an individual node. Nothin fancy here folks.
|
||||
func getNodeACL(w http.ResponseWriter, r *http.Request) {
|
||||
// set header.
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var params = mux.Vars(r)
|
||||
var nodeID = params["nodeid"]
|
||||
var networkID = params["network"]
|
||||
|
||||
nodeACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(networkID), nodeacls.NodeID(nodeID))
|
||||
if err != nil {
|
||||
returnErrorResponse(w, r, formatError(err, "notfound"))
|
||||
return
|
||||
}
|
||||
logger.Log(2, r.Header.Get("user"), "fetched node ACL", params["nodeid"])
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(nodeACL)
|
||||
}
|
||||
|
||||
//Get the time that a network of nodes was last modified.
|
||||
//TODO: This needs to be refactored
|
||||
//Potential way to do this: On UpdateNode, set a new field for "LastModified"
|
||||
@@ -623,6 +646,31 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
|
||||
runForceServerUpdate(&node)
|
||||
}
|
||||
|
||||
func updateNodeACL(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var params = mux.Vars(r)
|
||||
var nodeID = params["nodeid"]
|
||||
var networkID = params["network"]
|
||||
var newNodeACL acls.ACL
|
||||
// we decode our body request params
|
||||
err := json.NewDecoder(r.Body).Decode(&newNodeACL)
|
||||
if err != nil {
|
||||
returnErrorResponse(w, r, formatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
|
||||
newNodeACL, err = nodeacls.UpdateNodeACL(nodeacls.NetworkID(networkID), nodeacls.NodeID(nodeID), newNodeACL)
|
||||
if err != nil {
|
||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
logger.Log(1, r.Header.Get("user"), "updated node ACL for", nodeID, "on network", networkID)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(newNodeACL)
|
||||
}
|
||||
|
||||
func runUpdates(node *models.Node, ifaceDelta bool) {
|
||||
go func() { // don't block http response
|
||||
// publish node update if not server
|
||||
|
@@ -154,19 +154,17 @@ func TestNodeACLs(t *testing.T) {
|
||||
t.Run("acls not present", func(t *testing.T) {
|
||||
currentACL, err := nodeacls.FetchAllACLs(nodeacls.NetworkID(node1.Network))
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, currentACL[acls.AclID(node1.ID)])
|
||||
assert.Nil(t, currentACL[acls.AclID(node2.ID)])
|
||||
assert.NotNil(t, currentACL)
|
||||
node1ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID))
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, node1ACL)
|
||||
assert.EqualError(t, err, "no node ACL present for node "+node1.ID)
|
||||
})
|
||||
t.Run("node acls exists after creates", func(t *testing.T) {
|
||||
node1ACL, err := nodeacls.CreateNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID), acls.Allowed)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, node1ACL)
|
||||
assert.Equal(t, node1ACL[acls.AclID(node2.ID)], acls.NotPresent)
|
||||
node2ACL, err := nodeacls.CreateNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node2.ID), acls.Allowed)
|
||||
assert.Equal(t, acls.Allowed, node1ACL[acls.AclID(node2.ID)])
|
||||
})
|
||||
t.Run("node acls exists after creates", func(t *testing.T) {
|
||||
node1ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID))
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, node1ACL)
|
||||
node2ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node2.Network), nodeacls.NodeID(node2.ID))
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, node2ACL)
|
||||
assert.Equal(t, acls.Allowed, node2ACL[acls.AclID(node1.ID)])
|
||||
@@ -177,11 +175,11 @@ func TestNodeACLs(t *testing.T) {
|
||||
assert.Equal(t, acls.Allowed, node1ACL[acls.AclID(node2.ID)])
|
||||
})
|
||||
t.Run("node acls correct after modify", func(t *testing.T) {
|
||||
node1ACL, err := nodeacls.CreateNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID), acls.Allowed)
|
||||
assert.Nil(t, err)
|
||||
node2ACL, err := nodeacls.CreateNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node2.ID), acls.Allowed)
|
||||
node1ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID))
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, node1ACL)
|
||||
node2ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node2.Network), nodeacls.NodeID(node2.ID))
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, node2ACL)
|
||||
currentACL, err := nodeacls.DisallowNodes(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID), nodeacls.NodeID(node2.ID))
|
||||
assert.Nil(t, err)
|
||||
|
@@ -80,3 +80,8 @@ func RemoveNodeACL(networkID NetworkID, nodeID NodeID) (acls.ACLContainer, error
|
||||
delete(currentNetworkACL, acls.AclID(nodeID))
|
||||
return currentNetworkACL.Save(acls.ContainerID(networkID))
|
||||
}
|
||||
|
||||
// DeleteACLContainer - removes an ACLContainer state from db
|
||||
func DeleteACLContainer(network NetworkID) error {
|
||||
return database.DeleteRecord(database.NODE_ACLS_TABLE_NAME, string(network))
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
nodeacls "github.com/gravitl/netmaker/logic/acls/node-acls"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/validation"
|
||||
@@ -41,6 +42,11 @@ func GetNetworks() ([]models.Network, error) {
|
||||
|
||||
// DeleteNetwork - deletes a network
|
||||
func DeleteNetwork(network string) error {
|
||||
// remove ACL for network
|
||||
err := nodeacls.DeleteACLContainer(nodeacls.NetworkID(network))
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to remove the node acls during network delete for network,", network)
|
||||
}
|
||||
nodeCount, err := GetNetworkNonServerNodeCount(network)
|
||||
if nodeCount == 0 || database.IsEmptyRecord(err) {
|
||||
// delete server nodes first then db records
|
||||
|
@@ -12,6 +12,8 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic/acls"
|
||||
nodeacls "github.com/gravitl/netmaker/logic/acls/node-acls"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
@@ -174,6 +176,41 @@ func UpdateNode(currentNode *models.Node, newNode *models.Node) error {
|
||||
return fmt.Errorf("failed to update node " + currentNode.ID + ", cannot change ID.")
|
||||
}
|
||||
|
||||
// DeleteNodeByID - deletes a node from database or moves into delete nodes table
|
||||
func DeleteNodeByID(node *models.Node, exterminate bool) error {
|
||||
var err error
|
||||
var key = node.ID
|
||||
if !exterminate {
|
||||
node.Action = models.NODE_DELETE
|
||||
nodedata, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = database.Insert(key, string(nodedata), database.DELETED_NODES_TABLE_NAME)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, key); err != nil {
|
||||
logger.Log(2, err.Error())
|
||||
}
|
||||
}
|
||||
if err = database.DeleteRecord(database.NODES_TABLE_NAME, key); err != nil {
|
||||
return err
|
||||
}
|
||||
if servercfg.IsDNSMode() {
|
||||
SetDNS()
|
||||
}
|
||||
|
||||
_, err = nodeacls.RemoveNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID))
|
||||
if err != nil {
|
||||
// ignoring for now, could hit a nil pointer if delete called twice
|
||||
logger.Log(2, "attempted to remove node ACL for node", node.Name, node.ID)
|
||||
}
|
||||
|
||||
return removeLocalServer(node)
|
||||
}
|
||||
|
||||
// IsNodeIDUnique - checks if node id is unique
|
||||
func IsNodeIDUnique(node *models.Node) (bool, error) {
|
||||
_, err := database.FetchRecord(database.NODES_TABLE_NAME, node.ID)
|
||||
@@ -274,6 +311,12 @@ func CreateNode(node *models.Node) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO get template logic to decide initial ACL value
|
||||
_, err = nodeacls.CreateNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID), acls.Allowed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if node.IsPending != "yes" {
|
||||
DecrimentKey(node.Network, node.AccessKey)
|
||||
}
|
||||
|
@@ -17,7 +17,6 @@ import (
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
// IsBase64 - checks if a string is in base64 format
|
||||
@@ -101,34 +100,6 @@ func GenerateCryptoString(n int) (string, error) {
|
||||
return string(ret), nil
|
||||
}
|
||||
|
||||
// DeleteNodeByID - deletes a node from database or moves into delete nodes table
|
||||
func DeleteNodeByID(node *models.Node, exterminate bool) error {
|
||||
var err error
|
||||
var key = node.ID
|
||||
if !exterminate {
|
||||
node.Action = models.NODE_DELETE
|
||||
nodedata, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = database.Insert(key, string(nodedata), database.DELETED_NODES_TABLE_NAME)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, key); err != nil {
|
||||
logger.Log(2, err.Error())
|
||||
}
|
||||
}
|
||||
if err = database.DeleteRecord(database.NODES_TABLE_NAME, key); err != nil {
|
||||
return err
|
||||
}
|
||||
if servercfg.IsDNSMode() {
|
||||
SetDNS()
|
||||
}
|
||||
return removeLocalServer(node)
|
||||
}
|
||||
|
||||
// RandomString - returns a random string in a charset
|
||||
func RandomString(length int) string {
|
||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
|
Reference in New Issue
Block a user