From 68c70148021ca544c178602a4b524c754df574fe Mon Sep 17 00:00:00 2001 From: 0xdcarns Date: Fri, 25 Feb 2022 14:08:44 -0500 Subject: [PATCH] refactored node functions further --- controllers/config/dnsconfig/netmaker.hosts | 3 +- controllers/node_test.go | 23 ++--- logic/acls/common.go | 94 +++++++++++---------- logic/acls/node-acls/modify.go | 54 ++++++++---- logic/acls/node-acls/retrieve.go | 21 +++-- logic/acls/node-acls/types.go | 2 + 6 files changed, 115 insertions(+), 82 deletions(-) diff --git a/controllers/config/dnsconfig/netmaker.hosts b/controllers/config/dnsconfig/netmaker.hosts index 655eaef6..45eab425 100644 --- a/controllers/config/dnsconfig/netmaker.hosts +++ b/controllers/config/dnsconfig/netmaker.hosts @@ -1,2 +1 @@ -10.0.0.1 testnode.skynet -10.0.0.2 myhost.skynet +10.0.0.2 testnode.skynet myhost.skynet diff --git a/controllers/node_test.go b/controllers/node_test.go index dee08e73..7104a65e 100644 --- a/controllers/node_test.go +++ b/controllers/node_test.go @@ -152,53 +152,48 @@ func TestNodeACLs(t *testing.T) { logic.CreateNode(&node1) logic.CreateNode(&node2) t.Run("acls not present", func(t *testing.T) { - currentACL, err := nodeacls.CreateNetworkACL(nodeacls.NetworkID(node1.Network)) + 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)]) - node1ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node1.Network), acls.AclID(node1.ID)) + 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), acls.AclID(node1.ID), acls.Allowed) + 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), acls.AclID(node2.ID), acls.Allowed) + node2ACL, err := nodeacls.CreateNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node2.ID), acls.Allowed) assert.Nil(t, err) assert.NotNil(t, node2ACL) assert.Equal(t, acls.Allowed, node2ACL[acls.AclID(node1.ID)]) }) t.Run("node acls correct after fetch", func(t *testing.T) { - node1ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node1.Network), acls.AclID(node1.ID)) + node1ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID)) assert.Nil(t, err) assert.Equal(t, acls.Allowed, node1ACL[acls.AclID(node2.ID)]) }) t.Run("node acls correct after modify", func(t *testing.T) { - currentACL, err := nodeacls.CreateNetworkACL(nodeacls.NetworkID(node1.Network)) + node1ACL, err := nodeacls.CreateNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID), acls.Allowed) assert.Nil(t, err) - assert.NotNil(t, currentACL) - node1ACL, err := nodeacls.CreateNodeACL(nodeacls.NetworkID(node1.Network), acls.AclID(node1.ID), acls.Allowed) - assert.Nil(t, err) - node2ACL, err := nodeacls.CreateNodeACL(nodeacls.NetworkID(node1.Network), acls.AclID(node2.ID), acls.Allowed) + node2ACL, err := nodeacls.CreateNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node2.ID), acls.Allowed) assert.Nil(t, err) assert.NotNil(t, node1ACL) assert.NotNil(t, node2ACL) - currentACL, err = nodeacls.FetchCurrentACL(nodeacls.NetworkID(node1.Network)) + currentACL, err := nodeacls.ChangeNodesAccess(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID), nodeacls.NodeID(node2.ID), acls.NotAllowed) assert.Nil(t, err) - currentACL.ChangeNodesAccess(acls.AclID(node1.ID), acls.AclID(node2.ID), acls.NotAllowed) assert.Equal(t, acls.NotAllowed, currentACL[acls.AclID(node1.ID)][acls.AclID(node2.ID)]) assert.Equal(t, acls.NotAllowed, currentACL[acls.AclID(node2.ID)][acls.AclID(node1.ID)]) }) t.Run("node acls removed", func(t *testing.T) { - retNetworkACL, err := nodeacls.RemoveNodeACL(nodeacls.NetworkID(node1.Network), acls.AclID(node1.ID)) + retNetworkACL, err := nodeacls.RemoveNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID)) assert.Nil(t, err) assert.NotNil(t, retNetworkACL) assert.Equal(t, acls.NotPresent, retNetworkACL[acls.AclID(node2.ID)][acls.AclID(node1.ID)]) }) - deleteAllNodes() } diff --git a/logic/acls/common.go b/logic/acls/common.go index 63b2c69a..08bf17a0 100644 --- a/logic/acls/common.go +++ b/logic/acls/common.go @@ -6,34 +6,6 @@ import ( "github.com/gravitl/netmaker/database" ) -// CreateACLContainer - creates an empty ACL list in a given network -func CreateACLContainer(networkID ContainerID) (ACLContainer, error) { - var aclContainer = make(ACLContainer) - return aclContainer, database.Insert(string(networkID), string(convertNetworkACLtoACLJson(aclContainer)), database.NODE_ACLS_TABLE_NAME) -} - -// FetchACLContainer - fetches all current node rules in given network ACL -func FetchACLContainer(networkID ContainerID) (ACLContainer, error) { - aclJson, err := FetchACLContainerJson(ContainerID(networkID)) - if err != nil { - return nil, err - } - var currentNetworkACL ACLContainer - if err := json.Unmarshal([]byte(aclJson), ¤tNetworkACL); err != nil { - return nil, err - } - return currentNetworkACL, nil -} - -// FetchACLContainerJson - fetch the current ACL of given network except in json string -func FetchACLContainerJson(networkID ContainerID) (ACLJson, error) { - currentACLs, err := database.FetchRecord(database.NODE_ACLS_TABLE_NAME, string(networkID)) - if err != nil { - return ACLJson(""), err - } - return ACLJson(currentACLs), nil -} - // == type functions == // ACL.AllowNode - allows a node by ID in memory @@ -52,58 +24,90 @@ func (acl ACL) Remove(ID AclID) { } // ACL.Update - updates a ACL in DB -func (acl ACL) Save(networkID ContainerID, ID AclID) (ACL, error) { - return upsertACL(networkID, ID, acl) +func (acl ACL) Save(containerID ContainerID, ID AclID) (ACL, error) { + return upsertACL(containerID, ID, acl) } -// ACL.IsNodeAllowed - sees if ID is allowed in referring ACL -func (acl ACL) IsNodeAllowed(ID AclID) bool { +// ACL.IsAllowed - sees if ID is allowed in referring ACL +func (acl ACL) IsAllowed(ID AclID) bool { return acl[ID] == Allowed } -// ACLContainer.UpdateNodeACL - saves the state of a ACL in the ACLContainer in memory -func (aclContainer ACLContainer) UpdateNodeACL(ID AclID, acl ACL) ACLContainer { +// ACLContainer.UpdateACL - saves the state of a ACL in the ACLContainer in memory +func (aclContainer ACLContainer) UpdateACL(ID AclID, acl ACL) ACLContainer { aclContainer[ID] = acl return aclContainer } -// ACLContainer.RemoveNodeACL - removes the state of a ACL in the ACLContainer in memory -func (aclContainer ACLContainer) RemoveNodeACL(ID AclID) ACLContainer { +// ACLContainer.RemoveACL - removes the state of a ACL in the ACLContainer in memory +func (aclContainer ACLContainer) RemoveACL(ID AclID) ACLContainer { delete(aclContainer, ID) return aclContainer } -// ACLContainer.ChangeNodesAccess - changes the relationship between two nodes in memory -func (networkACL ACLContainer) ChangeNodesAccess(ID1, ID2 AclID, value byte) { +// ACLContainer.ChangeAccess - changes the relationship between two nodes in memory +func (networkACL ACLContainer) ChangeAccess(ID1, ID2 AclID, value byte) { networkACL[ID1][ID2] = value networkACL[ID2][ID1] = value } // ACLContainer.Save - saves the state of a ACLContainer to the db -func (aclContainer ACLContainer) Save(networkID ContainerID) (ACLContainer, error) { - return upsertACLContainer(networkID, aclContainer) +func (aclContainer ACLContainer) Save(containerID ContainerID) (ACLContainer, error) { + return upsertACLContainer(containerID, aclContainer) +} + +// ACLContainer.New - saves the state of a ACLContainer to the db +func (aclContainer ACLContainer) New(containerID ContainerID) (ACLContainer, error) { + return upsertACLContainer(containerID, nil) +} + +// ACLContainer.Get - saves the state of a ACLContainer to the db +func (aclContainer ACLContainer) Get(containerID ContainerID) (ACLContainer, error) { + return fetchACLContainer(containerID) } // == private == +// fetchACLContainer - fetches all current node rules in given network ACL +func fetchACLContainer(containerID ContainerID) (ACLContainer, error) { + aclJson, err := fetchACLContainerJson(ContainerID(containerID)) + if err != nil { + return nil, err + } + var currentNetworkACL ACLContainer + if err := json.Unmarshal([]byte(aclJson), ¤tNetworkACL); err != nil { + return nil, err + } + return currentNetworkACL, nil +} + +// fetchACLContainerJson - fetch the current ACL of given network except in json string +func fetchACLContainerJson(containerID ContainerID) (ACLJson, error) { + currentACLs, err := database.FetchRecord(database.NODE_ACLS_TABLE_NAME, string(containerID)) + if err != nil { + return ACLJson(""), err + } + return ACLJson(currentACLs), nil +} + // upsertACL - applies a ACL to the db, overwrites or creates -func upsertACL(networkID ContainerID, ID AclID, acl ACL) (ACL, error) { - currentNetACL, err := FetchACLContainer(networkID) +func upsertACL(containerID ContainerID, ID AclID, acl ACL) (ACL, error) { + currentNetACL, err := fetchACLContainer(containerID) if err != nil { return acl, err } currentNetACL[ID] = acl - _, err = upsertACLContainer(networkID, currentNetACL) + _, err = upsertACLContainer(containerID, currentNetACL) return acl, err } // upsertACLContainer - Inserts or updates a network ACL given the json string of the ACL and the network name // if nil, create it -func upsertACLContainer(networkID ContainerID, aclContainer ACLContainer) (ACLContainer, error) { +func upsertACLContainer(containerID ContainerID, aclContainer ACLContainer) (ACLContainer, error) { if aclContainer == nil { aclContainer = make(ACLContainer) } - return aclContainer, database.Insert(string(networkID), string(convertNetworkACLtoACLJson(aclContainer)), database.NODE_ACLS_TABLE_NAME) + return aclContainer, database.Insert(string(containerID), string(convertNetworkACLtoACLJson(aclContainer)), database.NODE_ACLS_TABLE_NAME) } func convertNetworkACLtoACLJson(networkACL ACLContainer) ACLJson { diff --git a/logic/acls/node-acls/modify.go b/logic/acls/node-acls/modify.go index e9a7cdea..847a285a 100644 --- a/logic/acls/node-acls/modify.go +++ b/logic/acls/node-acls/modify.go @@ -5,14 +5,21 @@ import ( "github.com/gravitl/netmaker/logic/acls" ) -// CreateNodeACL - inserts or updates a node ACL on given network +// CreateNodeACL - inserts or updates a node ACL on given network and adds to state func CreateNodeACL(networkID NetworkID, nodeID NodeID, defaultVal byte) (acls.ACL, error) { if defaultVal != acls.NotAllowed && defaultVal != acls.Allowed { defaultVal = acls.NotAllowed } - var currentNetworkACL, err = acls.FetchACLContainer(acls.ContainerID(networkID)) + var currentNetworkACL, err = FetchAllACLs(networkID) if err != nil { - return nil, err + if database.IsEmptyRecord(err) { + currentNetworkACL, err = currentNetworkACL.New(acls.ContainerID(networkID)) + if err != nil { + return nil, err + } + } else { + return nil, err + } } var newNodeACL = make(acls.ACL) for existingNodeID := range currentNetworkACL { @@ -27,22 +34,37 @@ func CreateNodeACL(networkID NetworkID, nodeID NodeID, defaultVal byte) (acls.AC return retNetworkACL[acls.AclID(nodeID)], nil } -// RemoveNodeACL - removes a specific Node's ACL, returns the NetworkACL and error -func RemoveNodeACL(networkID NetworkID, nodeID NodeID) (acls.ACLContainer, error) { - var currentNeworkACL, err = acls.FetchACLContainer(acls.ContainerID(networkID)) +// ChangeNodesAccess - changes relationship between two individual nodes in given network in memory +func ChangeNodesAccess(networkID NetworkID, node1, node2 NodeID, value byte) (acls.ACLContainer, error) { + var currentNetworkACL, err = FetchAllACLs(networkID) if err != nil { return nil, err } - for currentNodeID := range currentNeworkACL { - if NodeID(currentNodeID) != nodeID { - currentNeworkACL[currentNodeID].Remove(acls.AclID(nodeID)) - } - } - delete(currentNeworkACL, acls.AclID(nodeID)) - return currentNeworkACL.Save(acls.ContainerID(networkID)) + currentNetworkACL.ChangeAccess(acls.AclID(node1), acls.AclID(node2), value) + return currentNetworkACL, nil } -// RemoveNetworkACL - just delete the network ACL -func RemoveNetworkACL(networkID NetworkID) error { - return database.DeleteRecord(database.NODE_ACLS_TABLE_NAME, string(networkID)) +// UpdateNodeACL - updates a node's ACL in state +func UpdateNodeACL(networkID NetworkID, nodeID NodeID, acl acls.ACL) (acls.ACL, error) { + var currentNetworkACL, err = FetchAllACLs(networkID) + if err != nil { + return nil, err + } + currentNetworkACL[acls.AclID(nodeID)] = acl + return currentNetworkACL[acls.AclID(nodeID)].Save(acls.ContainerID(networkID), acls.AclID(nodeID)) +} + +// RemoveNodeACL - removes a specific Node's ACL, returns the NetworkACL and error +func RemoveNodeACL(networkID NetworkID, nodeID NodeID) (acls.ACLContainer, error) { + var currentNetworkACL, err = FetchAllACLs(networkID) + if err != nil { + return nil, err + } + for currentNodeID := range currentNetworkACL { + if NodeID(currentNodeID) != nodeID { + currentNetworkACL[currentNodeID].Remove(acls.AclID(nodeID)) + } + } + delete(currentNetworkACL, acls.AclID(nodeID)) + return currentNetworkACL.Save(acls.ContainerID(networkID)) } diff --git a/logic/acls/node-acls/retrieve.go b/logic/acls/node-acls/retrieve.go index 7568516e..c2f4189c 100644 --- a/logic/acls/node-acls/retrieve.go +++ b/logic/acls/node-acls/retrieve.go @@ -9,23 +9,23 @@ import ( // AreNodesAllowed - checks if nodes are allowed to communicate in their network ACL func AreNodesAllowed(networkID NetworkID, node1, node2 NodeID) bool { - var currentNetworkACL, err = acls.FetchACLContainer(acls.ContainerID(networkID)) + var currentNetworkACL, err = FetchAllACLs(networkID) if err != nil { return false } - return currentNetworkACL[acls.AclID(node1)].IsNodeAllowed(acls.AclID(node2)) && currentNetworkACL[acls.AclID(node2)].IsNodeAllowed(acls.AclID(node1)) + return currentNetworkACL[acls.AclID(node1)].IsAllowed(acls.AclID(node2)) && currentNetworkACL[acls.AclID(node2)].IsAllowed(acls.AclID(node1)) } // FetchNodeACL - fetches a specific node's ACL in a given network func FetchNodeACL(networkID NetworkID, nodeID NodeID) (acls.ACL, error) { - currentNetACL, err := acls.FetchACLContainer(acls.ContainerID(networkID)) + var currentNetworkACL, err = FetchAllACLs(networkID) if err != nil { return nil, err } - if currentNetACL[acls.AclID(nodeID)] == nil { + if currentNetworkACL[acls.AclID(nodeID)] == nil { return nil, fmt.Errorf("no node ACL present for node %s", nodeID) } - return currentNetACL[acls.AclID(nodeID)], nil + return currentNetworkACL[acls.AclID(nodeID)], nil } // FetchNodeACLJson - fetches a node's acl in given network except returns the json string @@ -40,3 +40,14 @@ func FetchNodeACLJson(networkID NetworkID, nodeID NodeID) (acls.ACLJson, error) } return acls.ACLJson(jsonData), nil } + +// FetchAllACLs - fetchs all node +func FetchAllACLs(networkID NetworkID) (acls.ACLContainer, error) { + var err error + var currentNetworkACL acls.ACLContainer + currentNetworkACL, err = currentNetworkACL.Get(acls.ContainerID(networkID)) + if err != nil { + return nil, err + } + return currentNetworkACL, nil +} diff --git a/logic/acls/node-acls/types.go b/logic/acls/node-acls/types.go index 3cfc71e9..2c3d825e 100644 --- a/logic/acls/node-acls/types.go +++ b/logic/acls/node-acls/types.go @@ -5,6 +5,8 @@ import ( ) type ( + // NodeACL - interface for NodeACLs + NodeACL acls.ACL // NodeID - node ID for ACLs NodeID acls.AclID // NetworkID - ACL container based on network ID for nodes