began ACL implementation

This commit is contained in:
0xdcarns 2022-02-23 19:36:48 -05:00 committed by Matthew R. Kasun
parent d322631ebb
commit 09c54b1c61
4 changed files with 151 additions and 0 deletions

View file

@ -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 {

View file

@ -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)
}

View file

@ -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
}

View file

@ -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
)