From 55b39e4b9eaa2e72a623e0b3b35493b3174b760e Mon Sep 17 00:00:00 2001 From: ola saadi <152963690+olasaadi99@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:56:36 +0200 Subject: [PATCH] 318 improve unittests (#933) * removing function AnalyzeNACLRules and fix tests * unit-tests improvements --- pkg/commonvpc/nacl_analysis.go | 49 ---- pkg/ibmvpc/connectivityAnalysis_test.go | 90 +++--- pkg/ibmvpc/naclAnalysis_test.go | 366 ++++++++++++++++++------ 3 files changed, 327 insertions(+), 178 deletions(-) diff --git a/pkg/commonvpc/nacl_analysis.go b/pkg/commonvpc/nacl_analysis.go index 1e1774043..c5682160f 100644 --- a/pkg/commonvpc/nacl_analysis.go +++ b/pkg/commonvpc/nacl_analysis.go @@ -252,55 +252,6 @@ func initConnectivityResult(connectivityMap map[string]*ConnectivityResult, indx } } -func getConnStr(src, dst, conn string) string { - return fmt.Sprintf("%s => %s : %s\n", src, dst, conn) -} - -// AnalyzeNACLRules todo: this is used only in testing. Did not expand for deny. -func (na *NACLAnalyzer) AnalyzeNACLRules(rules []*NACLRule, subnet *netset.IPBlock, - isIngress bool, subnetDisjointTarget *netset.IPBlock, -) (string, *ConnectivityResult) { - res := []string{} - connResult := &ConnectivityResult{IsIngress: isIngress} - connResult.AllowedConns = map[*netset.IPBlock]*netset.TransportSet{} - connResult.DeniedConns = map[*netset.IPBlock]*netset.TransportSet{} - if subnetDisjointTarget == nil { - connResult = nil - } - if isIngress { - disjointSrcPeers, disjointDstPeers := getDisjointPeersForIngressAnalysis(rules, subnet) - // ingress - for _, src := range disjointSrcPeers { - allowedIngressConns, _, allowRules, _ := GetAllowedXgressConnections(rules, src, subnet, disjointDstPeers, true) - for dst, conn := range allowedIngressConns { - res = append(res, getConnStr(src.ToIPRanges(), dst, common.LongString(conn))) - dstIP, err := netset.IPBlockFromIPRangeStr(dst) - if err == nil && subnetDisjointTarget != nil && subnetDisjointTarget.IsSubset(dstIP) { - connResult.AllowedConns[src] = conn - // the indexing of allowedIngressConns and allowRules are identical - connResult.AllowRules[src] = allowRules[dst] - } - } - } - return strings.Join(res, ""), connResult - } - // egress - disjointSrcPeers, disjointDstPeers := getDisjointPeersForEgressAnalysis(rules, subnet) - for _, dst := range disjointDstPeers { - allowedEgressConns, _, allowRules, _ := GetAllowedXgressConnections(rules, dst, subnet, disjointSrcPeers, false) - for src, conn := range allowedEgressConns { - res = append(res, getConnStr(src, dst.ToIPRanges(), common.LongString(conn))) - srcIP, err := netset.IPBlockFromIPRangeStr(src) - if err == nil && subnetDisjointTarget != nil && subnetDisjointTarget.IsSubset(srcIP) { - connResult.AllowedConns[dst] = conn - // the indexing of allowedEgressConns and allowRules are identical - connResult.AllowRules[dst] = allowRules[src] - } - } - } - return strings.Join(res, ""), connResult -} - // TODO: return a map from each possible subnetDisjointTarget to its ConnectivityResult, instead of a specific ConnectivityResult // get allowed and denied connections (ingress and egress) for a certain subnet to which this nacl is applied func (na *NACLAnalyzer) AnalyzeNACL(subnet *netset.IPBlock) ( diff --git a/pkg/ibmvpc/connectivityAnalysis_test.go b/pkg/ibmvpc/connectivityAnalysis_test.go index 166c42fc9..0acaa5e89 100644 --- a/pkg/ibmvpc/connectivityAnalysis_test.go +++ b/pkg/ibmvpc/connectivityAnalysis_test.go @@ -156,52 +156,74 @@ var nc6 = &naclConfig{ // tests below -var expectedConnStrTest1 = `vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : All Connections -vsi-0-subnet-2[10.240.20.4] => vsi-0-subnet-1[10.240.10.4] : All Connections -` - -func TestAnalyzeConnectivity1(t *testing.T) { - runConnectivityTest(t, tc1, []*naclConfig{nc1}, expectedConnStrTest1) -} - -var expectedConnStrTest2 = `vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : TCP * ; ICMP,UDP -` - -func TestAnalyzeConnectivity2(t *testing.T) { - runConnectivityTest(t, tc1, []*naclConfig{nc2, nc3}, expectedConnStrTest2) +type ConnectivityAnalysisTest struct { + name string + tc *testNodesConfig + ncList []*naclConfig + expectedStrResult string } -var expectedConnStrTest2a = `vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : ICMP -` // ICMP is actually enabled only unidirectional in this case, but responsive analysis does not apply to ICMP - -func TestAnalyzeConnectivity2a(t *testing.T) { - runConnectivityTest(t, tc1, []*naclConfig{nc2a, nc3a}, expectedConnStrTest2a) -} - -var expectedConnStrTest3 = `vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : All Connections +var connectivityAnalysisTests = []*ConnectivityAnalysisTest{ + { + name: "testAnalyzeConnectivity1", + tc: tc1, + ncList: []*naclConfig{nc1}, + expectedStrResult: `vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : All Connections +vsi-0-subnet-2[10.240.20.4] => vsi-0-subnet-1[10.240.10.4] : All Connections +`, + }, + { + name: "testAnalyzeConnectivity2", + tc: tc1, + ncList: []*naclConfig{nc2, nc3}, + expectedStrResult: `vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : TCP * ; ICMP,UDP +`, + }, + { + name: "testAnalyzeConnectivity2a", + tc: tc1, + ncList: []*naclConfig{nc2a, nc3a}, + expectedStrResult: `vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : ICMP +`, // ICMP is actually enabled only unidirectional in this case, but responsive analysis does not apply to ICMP + }, + { + name: "testAnalyzeConnectivity3", + tc: tc1, + ncList: []*naclConfig{nc2, nc4}, + expectedStrResult: `vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : All Connections vsi-0-subnet-2[10.240.20.4] => vsi-0-subnet-1[10.240.10.4] : TCP -` - -func TestAnalyzeConnectivity3(t *testing.T) { - runConnectivityTest(t, tc1, []*naclConfig{nc2, nc4}, expectedConnStrTest3) -} - -var expectedConnStrTest4 = `vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : TCP src-ports: 10-100 dst-ports: 443 +`, + }, + { + name: "testAnalyzeConnectivity4", + tc: tc1, + ncList: []*naclConfig{nc5, nc6}, + expectedStrResult: `vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : TCP src-ports: 10-100 dst-ports: 443 vsi-0-subnet-2[10.240.20.4] => vsi-0-subnet-1[10.240.10.4] : TCP src-ports: 443 dst-ports: 10-100 -` +`, + }, +} -func TestAnalyzeConnectivity4(t *testing.T) { - runConnectivityTest(t, tc1, []*naclConfig{nc5, nc6}, expectedConnStrTest4) +func TestConnectivityAnalysis(t *testing.T) { + // connectivityAnalysisTests is the list of tests to run + for testIdx := range connectivityAnalysisTests { + tt := connectivityAnalysisTests[testIdx] + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + tt.runConnectivityTest(t) + }) + } + fmt.Println("done") } -func runConnectivityTest(t *testing.T, tc *testNodesConfig, ncList []*naclConfig, expectedStrResult string) { - c := createConfigFromTestConfig(tc, ncList) +func (tt *ConnectivityAnalysisTest) runConnectivityTest(t *testing.T) { + c := createConfigFromTestConfig(tt.tc, tt.ncList) connectivity, err := c.GetVPCNetworkConnectivity(false, vpcmodel.NoGroupingNoConsistencyEdges) require.Nil(t, err) connectivityStr := connectivity.String() fmt.Println(connectivityStr) fmt.Println("done") - require.Equal(t, expectedStrResult, connectivityStr) + require.Equal(t, tt.expectedStrResult, connectivityStr) } //////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/pkg/ibmvpc/naclAnalysis_test.go b/pkg/ibmvpc/naclAnalysis_test.go index ff0acd524..0b8f50d23 100644 --- a/pkg/ibmvpc/naclAnalysis_test.go +++ b/pkg/ibmvpc/naclAnalysis_test.go @@ -8,11 +8,16 @@ package ibmvpc import ( "fmt" + "maps" "path/filepath" + "reflect" + "slices" + "sort" "testing" "github.com/stretchr/testify/require" + "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc/testfunc" @@ -45,113 +50,284 @@ func testSingleNACL(nacl *commonvpc.NACL) { } } -func TestGetAllowedXgressConnections(t *testing.T) { - rulesTest1 := []*commonvpc.NACLRule{ - { - Src: newIPBlockFromCIDROrAddressWithoutValidation("1.2.3.4/32"), - Dst: newIPBlockFromCIDROrAddressWithoutValidation("10.0.0.1/32"), - Connections: netset.AllTransports(), - Action: "deny", - }, - { - Src: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), - Dst: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), - Connections: netset.AllTransports(), - Action: "allow", - }, - } - //nolint:all - /*nolint - rulesTest2 := []*NACLRule{ +func TestNaclAnalysis(t *testing.T) { + subnet := newIPBlockFromCIDROrAddressWithoutValidation("10.0.0.0/24") + + tests := []struct { + testName string + naclRules []*commonvpc.NACLRule + expectedConnectivityMap map[string]*commonvpc.ConnectivityResult + }{ { - src: common.FromCidr("1.2.3.4/32"), - dst: common.FromCidr("10.0.0.1/32"), - connections: getTCPconn(80, 80), - action: "allow", + + testName: "naclAnalysis1", + naclRules: []*commonvpc.NACLRule{ + { + Src: newIPBlockFromCIDROrAddressWithoutValidation("1.2.3.4/32"), + Dst: newIPBlockFromCIDROrAddressWithoutValidation("10.0.0.1/32"), + Connections: netset.AllTransports(), + Action: "deny", + }, + { + Src: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), + Dst: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), + Connections: netset.AllTransports(), + Action: "allow", + }, + }, + expectedConnectivityMap: map[string]*commonvpc.ConnectivityResult{ + "10.0.0.0-10.0.0.0": { + IsIngress: true, + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.AllTransports(), + }, + AllowRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {0}, + }, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.NoTransports(), + }, + DenyRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {}, + }, + }, + "10.0.0.1-10.0.0.1": { + IsIngress: true, + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.NoTransports(), + }, + AllowRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {}, + }, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.AllTransports(), + }, + DenyRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {0}, + }, + }, + "10.0.0.2-10.0.0.255": { + IsIngress: true, + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.AllTransports(), + }, + AllowRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {0}, + }, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.NoTransports(), + }, + DenyRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {}, + }, + }, + }, }, { - src: common.FromCidr("1.2.3.4/32"), - dst: common.FromCidr("10.0.0.1/32"), - connections: getTCPconn(1, 100), - action: "deny", + testName: "naclAnalysis2", + naclRules: []*commonvpc.NACLRule{ + { + Src: newIPBlockFromCIDROrAddressWithoutValidation("1.2.3.4/32"), + Dst: newIPBlockFromCIDROrAddressWithoutValidation("10.0.0.1/32"), + Connections: netset.NewTCPTransport(80, 80, netp.MinPort, netp.MaxPort), + Action: "allow", + }, + { + Src: newIPBlockFromCIDROrAddressWithoutValidation("1.2.3.4/32"), + Dst: newIPBlockFromCIDROrAddressWithoutValidation("10.0.0.1/32"), + Connections: netset.NewTCPTransport(1, 100, netp.MinPort, netp.MaxPort), + Action: "deny", + }, + { + Src: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), + Dst: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), + Connections: netset.AllTransports(), + Action: "allow", + }, + }, + expectedConnectivityMap: map[string]*commonvpc.ConnectivityResult{ + "10.0.0.0-10.0.0.0": { + IsIngress: true, + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.AllTransports(), + }, + AllowRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {0}, + }, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.NoTransports(), + }, + DenyRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {}, + }, + }, + "10.0.0.1-10.0.0.1": { + IsIngress: true, + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.NewTCPorUDPTransport( + netp.ProtocolString("TCP"), 80, 80, netp.MinPort, netp.MaxPort).Union( + netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 101, 65535, netp.MinPort, netp.MaxPort).Union( + netset.AllICMPTransport().Union(netset.AllUDPTransport()), + ), + ), + }, + AllowRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {0, 0}, + }, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.NewTCPorUDPTransport( + netp.ProtocolString("TCP"), 1, 79, netp.MinPort, netp.MaxPort).Union( + netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 81, 100, netp.MinPort, netp.MaxPort), + ), + }, + DenyRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {0}, + }, + }, + "10.0.0.2-10.0.0.255": { + IsIngress: true, + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.AllTransports(), + }, + AllowRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {0}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {0}, + }, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): netset.NoTransports(), + }, + DenyRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-1.2.3.3"): {}, + fromIPRangeStrWithoutValidation("1.2.3.5-255.255.255.255"): {}, + fromIPRangeStrWithoutValidation("1.2.3.4-1.2.3.4"): {}, + }, + }, + }, }, { - src: common.FromCidr("0.0.0.0/0"), - dst: common.FromCidr("0.0.0.0/0"), - connections: getAllConnSet(), - action: "allow", + testName: "naclAnalysis3", + naclRules: []*commonvpc.NACLRule{ + { + Dst: newIPBlockFromCIDROrAddressWithoutValidation("1.2.3.4/32"), + Src: newIPBlockFromCIDROrAddressWithoutValidation("10.0.0.1/32"), + Connections: netset.AllTransports(), + Action: "deny", + }, + { + Dst: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), + Src: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), + Connections: netset.AllTransports(), + Action: "allow", + }, + }, + expectedConnectivityMap: map[string]*commonvpc.ConnectivityResult{ + "10.0.0.0-10.0.0.255": { + IsIngress: true, + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-10.0.0.0"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("10.0.0.1-10.0.0.1"): netset.AllTransports(), + fromIPRangeStrWithoutValidation("10.0.0.2-255.255.255.255"): netset.AllTransports(), + }, + AllowRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-10.0.0.0"): {0}, + fromIPRangeStrWithoutValidation("10.0.0.1-10.0.0.1"): {}, + fromIPRangeStrWithoutValidation("10.0.0.2-255.255.255.255"): {0}, + }, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("0.0.0.0-10.0.0.0"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("10.0.0.1-10.0.0.1"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("10.0.0.2-255.255.255.255"): netset.NoTransports(), + }, + DenyRules: map[*netset.IPBlock][]int{ + fromIPRangeStrWithoutValidation("0.0.0.0-10.0.0.0"): {}, + fromIPRangeStrWithoutValidation("10.0.0.1-10.0.0.1"): {}, + fromIPRangeStrWithoutValidation("10.0.0.2-255.255.255.255"): {}, + }, + }, + }, }, } - rulesTest3 := []*NACLRule{ - { - dst: common.FromCidr("1.2.3.4/32"), - src: common.FromCidr("10.0.0.1/32"), - connections: getAllConnSet(), - action: "deny", - }, - { - dst: common.FromCidr("0.0.0.0/0"), - src: common.FromCidr("0.0.0.0/0"), - connections: getAllConnSet(), - action: "allow", - }, + for _, test := range tests { + t.Run(test.testName, func(t *testing.T) { + t.Parallel() + connectivityMap := commonvpc.AnalyzeNACLRulesPerDisjointTargets(test.naclRules, subnet, true) + require.True(t, equalConnectivityMap(connectivityMap, test.expectedConnectivityMap)) + }) } + fmt.Printf("done\n") +} - subnet := common.FromCidr("10.0.0.0/24") - - //res1 := ingressConnResFromInput(rulesTest1, subnet) - res1, _ := AnalyzeNACLRules(rulesTest1, subnet, true, nil) - fmt.Printf("res for test %s:\n%s\n", "rulesTest1", res1) - - //res2 := ingressConnResFromInput(rulesTest2, subnet) - res2, _ := AnalyzeNACLRules(rulesTest2, subnet, true, nil) - fmt.Printf("res for test %s:\n%s\n", "rulesTest2", res2) - - res3, _ := AnalyzeNACLRules(rulesTest3, subnet, false, nil) - fmt.Printf("res for test %s:\n%s\n", "rulesTest3", res3) - */ - - tests := []struct { - testName string - naclRules []*commonvpc.NACLRule - src []string - dst []string - expectedConns []*netset.TransportSet - }{ - { - testName: "a", - naclRules: rulesTest1, - src: []string{"1.1.1.1/32", "1.2.3.4/32", "1.2.3.4/32"}, - dst: []string{"10.0.0.0/24", "10.0.0.1/32", "10.0.0.0/32"}, - expectedConns: []*netset.TransportSet{netset.AllTransports(), netset.NoTransports(), netset.AllTransports()}, - }, +func equalKeys(first, second map[string]*commonvpc.ConnectivityResult) bool { + if len(first) != len(second) { + return false } + keys1 := slices.Collect(maps.Keys(first)) + sort.Strings(keys1) + keys2 := slices.Collect(maps.Keys(second)) + sort.Strings(keys2) + // compare the concatenation result to validate equality of keys sets + return reflect.DeepEqual(keys1, keys2) +} - for _, tt := range tests { - require.Equal(t, len(tt.src), len(tt.dst)) - require.Equal(t, len(tt.src), len(tt.expectedConns)) - for i := range tt.src { - src := newIPBlockFromCIDROrAddressWithoutValidation(tt.src[i]) - dst := newIPBlockFromCIDROrAddressWithoutValidation(tt.dst[i]) - disjointPeers := []*netset.IPBlock{dst} - expectedConn := tt.expectedConns[i] - res, _, _, _ := commonvpc.GetAllowedXgressConnections(tt.naclRules, src, dst, disjointPeers, true) - dstStr := dst.ToIPRanges() - actualConn := res[dstStr] - require.True(t, expectedConn.Equal(actualConn)) +func equalConnectivityMap(connectivityMap, other map[string]*commonvpc.ConnectivityResult) bool { + if !equalKeys(connectivityMap, other) { + return false + } + for ipBlockString, connectivityResult := range connectivityMap { + for otherIPBlockString, expectedConnectivityResult := range other { + if ipBlockString == otherIPBlockString { + if !connectivityResult.Equal(expectedConnectivityResult) { + return false + } + break + } } } - - //nolint:all - /*src := common.FromCidr("1.1.1.1/32") - dst := common.FromCidr("10.0.0.0/24") - disjointPeers := []*netset.IPBlock{dst} - res := commonvpc.GetAllowedXgressConnections(rulesTest1, src, dst, disjointPeers, true) - for d, c := range res { - fmt.Printf("%s => %s : %s\n", src.ToIPAdress(), d, c.String()) - require.True(t, c.Equal(getAllConnSet())) - }*/ - - fmt.Printf("done\n") + return true }