Browse Source

began ACL implementation

0xdcarns 3 years ago
parent
commit
6061ccec76

+ 4 - 0
database/database.go

@@ -50,6 +50,9 @@ const DATABASE_FILENAME = "netmaker.db"
 // GENERATED_TABLE_NAME - stores server generated k/v
 const GENERATED_TABLE_NAME = "generated"
 
+// NODE_ACLS_TABLE_NAME - stores the node ACL rules
+const NODE_ACLS_TABLE_NAME = "nodeacls"
+
 // == ERROR CONSTS ==
 
 // NO_RECORD - no singular result found
@@ -127,6 +130,7 @@ func createTables() {
 	createTable(SERVERCONF_TABLE_NAME)
 	createTable(SERVER_UUID_TABLE_NAME)
 	createTable(GENERATED_TABLE_NAME)
+	createTable(NODE_ACLS_TABLE_NAME)
 }
 
 func createTable(tableName string) error {

+ 60 - 0
logic/acls/node-acls/modify.go

@@ -0,0 +1,60 @@
+package nodeacls
+
+import (
+	"encoding/json"
+
+	"github.com/gravitl/netmaker/database"
+)
+
+// UpsertNodeACL - inserts or updates a node ACL on given network
+func UpsertNodeACL(networkID NetworkID, nodeID NodeID, defaultVal byte) (NodeACL, error) {
+	if defaultVal != NotAllowed && defaultVal != Allowed {
+		defaultVal = NotAllowed
+	}
+	var currentNetworkACL, err = FetchCurrentACL(networkID)
+	if err != nil {
+		return nil, err
+	}
+	var newNodeACL = make(NodeACL)
+	for existingNode := range currentNetworkACL {
+		currentNetworkACL[existingNode][nodeID] = defaultVal
+		newNodeACL[existingNode] = defaultVal
+	}
+	currentNetworkACL[nodeID] = newNodeACL
+	return newNodeACL, nil
+}
+
+// UpsertNetworkACL - Inserts or updates a network ACL given the json string of the ACL and the network name
+// if nil, create it
+func UpsertNetworkACL(networkID NetworkID, networkACL NetworkACL) (NetworkACL, error) {
+	if networkACL == nil {
+		networkACL = make(NetworkACL)
+	}
+	return networkACL, database.Insert(string(networkID), string(convertNetworkACLtoACLJson(&networkACL)), database.NODE_ACLS_TABLE_NAME)
+}
+
+// RemoveNodeACL - removes a specific Node's ACL, returns the NetworkACL and error
+func RemoveNodeACL(networkID NetworkID, nodeID NodeID) (NetworkACL, error) {
+	var currentNeworkACL, err = FetchCurrentACL(networkID)
+	if err != nil {
+		return nil, err
+	}
+	for currentNodeID := range currentNeworkACL {
+		delete(currentNeworkACL[nodeID], currentNodeID)
+	}
+	delete(currentNeworkACL, nodeID)
+	return UpsertNetworkACL(networkID, currentNeworkACL)
+}
+
+// RemoveNetworkACL - just delete the network ACL
+func RemoveNetworkACL(networkID NetworkID) error {
+	return database.DeleteRecord(database.NODE_ACLS_TABLE_NAME, string(networkID))
+}
+
+func convertNetworkACLtoACLJson(networkACL *NetworkACL) ACLJson {
+	data, err := json.Marshal(networkACL)
+	if err != nil {
+		return ""
+	}
+	return ACLJson(data)
+}

+ 60 - 0
logic/acls/node-acls/retrieve.go

@@ -0,0 +1,60 @@
+package nodeacls
+
+import (
+	"encoding/json"
+
+	"github.com/gravitl/netmaker/database"
+)
+
+// AreNodesAllowed - checks if nodes are allowed to communicate in their network ACL
+func AreNodesAllowed(networkID NetworkID, node1, node2 NodeID) bool {
+	var currentNetworkACL, err = FetchCurrentACL(networkID)
+	if err != nil {
+		return false
+	}
+	return currentNetworkACL[node1][node2] == Allowed && currentNetworkACL[node2][node1] == Allowed
+}
+
+// FetchNodeACL - fetches a specific node's ACL in a given network
+func FetchNodeACL(networkID NetworkID, nodeID NodeID) (NodeACL, error) {
+	currentNetACL, err := FetchCurrentACL(networkID)
+	if err != nil {
+		return nil, err
+	}
+	return currentNetACL[nodeID], nil
+}
+
+// FetchNodeACLJson - fetches a node's acl in given network except returns the json string
+func FetchNodeACLJson(networkID NetworkID, nodeID NodeID) (ACLJson, error) {
+	currentNodeACL, err := FetchNodeACL(networkID, nodeID)
+	if err != nil {
+		return "", err
+	}
+	jsonData, err := json.Marshal(&currentNodeACL)
+	if err != nil {
+		return "", err
+	}
+	return ACLJson(jsonData), nil
+}
+
+// FetchCurrentACL - fetches all current node rules in given network ACL
+func FetchCurrentACL(networkID NetworkID) (NetworkACL, error) {
+	aclJson, err := FetchCurrentACLJson(NetworkID(networkID))
+	if err != nil {
+		return nil, err
+	}
+	var currentNetworkACL NetworkACL
+	if err := json.Unmarshal([]byte(aclJson), &currentNetworkACL); err != nil {
+		return nil, err
+	}
+	return currentNetworkACL, nil
+}
+
+// FetchCurrentACLJson - fetch the current ACL of given network except in json string
+func FetchCurrentACLJson(networkID NetworkID) (ACLJson, error) {
+	currentACLs, err := database.FetchRecord(database.NODE_ACLS_TABLE_NAME, string(networkID))
+	if err != nil {
+		return ACLJson(""), err
+	}
+	return ACLJson(currentACLs), nil
+}

+ 27 - 0
logic/acls/node-acls/types.go

@@ -0,0 +1,27 @@
+package nodeacls
+
+var (
+	// NotPresent - 0 - not present (default)
+	NotPresent = byte(0)
+	// NotAllowed - 1 - not allowed access
+	NotAllowed = byte(1) // 1 - not allowed
+	// Allowed - 2 - allowed access
+	Allowed = byte(2)
+)
+
+type (
+	// NodeID - the node id of a given node
+	NodeID string
+
+	// NetworkID - the networkID of a given network
+	NetworkID string
+
+	// NodeACL - the ACL of other nodes in a NetworkACL for a single unique node
+	NodeACL map[NodeID]byte
+
+	// NetworkACL - the total list of all node's ACL in a given network
+	NetworkACL map[NodeID]NodeACL
+
+	// ACLJson - the string representation in JSON of an ACL Node or Network
+	ACLJson string
+)