From dea21daa55875689de21a184cf7ee6535f106372 Mon Sep 17 00:00:00 2001 From: Yair Slobodin <154875779+YairSlobodin1@users.noreply.github.com> Date: Sun, 5 Jan 2025 12:39:11 +0200 Subject: [PATCH] Optimize ACL (#243) --- go.mod | 2 +- go.sum | 8 +- pkg/io/commonACL.go | 4 +- pkg/ir/acl.go | 4 + pkg/optimize/acl/acl.go | 77 + pkg/optimize/acl/cubesToRules.go | 91 + pkg/optimize/acl/icmpCubesToRules.go | 67 + pkg/optimize/acl/reduceCubes.go | 60 + pkg/optimize/acl/rulesToCubes.go | 83 + pkg/optimize/acl/tcpudpCubesToRules.go | 76 + pkg/optimize/sg/ipCubesToRules.go | 8 +- test/data/optimize_acl/config_object.json | 1583 +++++++++++++++++ test/data/optimize_acl/conn_spec.json | 135 ++ test/data/optimize_acl/details.txt | 28 + .../config_object.json | 777 ++++++++ .../optimize_acl_anyProtocol/conn_spec.json | 60 + .../data/optimize_acl_anyProtocol/details.txt | 16 + .../acl_protocols_csv/nacl_expected.csv | 24 +- .../acl_protocols_md/nacl_expected.md | 24 +- .../nacl_expected.tf | 20 + .../optimize_acl_csv/nacl_expected.csv | 43 +- .../optimize_acl_json/nacl_expected.json | 685 ++----- .../expected/optimize_acl_md/nacl_expected.md | 34 +- .../expected/optimize_acl_tf/nacl_expected.tf | 287 +-- test/main_test_list.go | 26 +- 25 files changed, 3317 insertions(+), 905 deletions(-) create mode 100644 pkg/optimize/acl/cubesToRules.go create mode 100644 pkg/optimize/acl/icmpCubesToRules.go create mode 100644 pkg/optimize/acl/reduceCubes.go create mode 100644 pkg/optimize/acl/rulesToCubes.go create mode 100644 pkg/optimize/acl/tcpudpCubesToRules.go create mode 100644 test/data/optimize_acl/config_object.json create mode 100644 test/data/optimize_acl/conn_spec.json create mode 100644 test/data/optimize_acl/details.txt create mode 100644 test/data/optimize_acl_anyProtocol/config_object.json create mode 100644 test/data/optimize_acl_anyProtocol/conn_spec.json create mode 100644 test/data/optimize_acl_anyProtocol/details.txt create mode 100644 test/expected/optimize_acl_anyProtocol_tf/nacl_expected.tf diff --git a/go.mod b/go.mod index 8e2539d0..0b20bf00 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.0 require ( github.com/IBM/vpc-go-sdk v0.64.0 github.com/np-guard/cloud-resource-collector v0.17.0 - github.com/np-guard/models v0.5.3 + github.com/np-guard/models v0.5.4 github.com/spf13/cobra v1.8.1 ) diff --git a/go.sum b/go.sum index 95daefad..7404d9e3 100644 --- a/go.sum +++ b/go.sum @@ -134,8 +134,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/np-guard/cloud-resource-collector v0.17.0 h1:QFXrFeF9ZS3P4B2dnZNvpWXLUq/QGPuwDGTjarByCvs= github.com/np-guard/cloud-resource-collector v0.17.0/go.mod h1:vp82iqdSq12EZJxA11oZkVseFVKg0hvPIUA9tVEdnMc= -github.com/np-guard/models v0.5.3 h1:XtpLNTyhU1ptmFrYL3MCZestEvRa0uyiYV7YptIeE/k= -github.com/np-guard/models v0.5.3/go.mod h1:dqRdt5EQID1GmHuYsMOJzg4sS104om6NwEZ6sVO55z8= +github.com/np-guard/models v0.5.4 h1:AoIu+XqQ6cFt67PkaD8NTPjxtDwz4pU2u9ptCrVPImU= +github.com/np-guard/models v0.5.4/go.mod h1:Cj2nHAECvIuNoEBHXyzvauf3jXYgLzjxuHH73COaazE= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -181,8 +181,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= diff --git a/pkg/io/commonACL.go b/pkg/io/commonACL.go index b939e9bb..8cfb40ed 100644 --- a/pkg/io/commonACL.go +++ b/pkg/io/commonACL.go @@ -100,10 +100,12 @@ func printIP(ip *netset.IPBlock, protocol netp.Protocol, isSource bool) (string, return ipString, nil case netp.TCPUDP: r := p.DstPorts() + portsString := "dst ports:" if isSource { r = p.SrcPorts() + portsString = "src ports:" } - return fmt.Sprintf("%v, %v", ipString, printPorts(r)), nil + return fmt.Sprintf("%v, %s %v", ipString, portsString, printPorts(r)), nil case netp.AnyProtocol: return ipString, nil } diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index 9037bd7f..834411e6 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -116,6 +116,10 @@ func NewACL(aclName, subnetName string) *ACL { return &ACL{Name: aclName, Subnets: []string{subnetName}} } +func NewACLRule(action Action, direction Direction, src, dst *netset.IPBlock, p netp.Protocol, e string) *ACLRule { + return &ACLRule{Action: action, Direction: direction, Source: src, Destination: dst, Protocol: p, Explanation: e} +} + func aclSelector(subnetName ID, single bool) string { if single { return fmt.Sprintf("%s/singleACL", VpcFromScopedResource(subnetName)) diff --git a/pkg/optimize/acl/acl.go b/pkg/optimize/acl/acl.go index 5c02005f..da77f55c 100644 --- a/pkg/optimize/acl/acl.go +++ b/pkg/optimize/acl/acl.go @@ -6,8 +6,14 @@ SPDX-License-Identifier: Apache-2.0 package acloptimizer import ( + "fmt" + "log" + + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) type ( @@ -16,6 +22,25 @@ type ( aclName string aclVPC string } + + tcpudpTripleSet = ds.TripleSet[*netset.IPBlock, *netset.IPBlock, *netset.TCPUDPSet] + icmpTripleSet = ds.TripleSet[*netset.IPBlock, *netset.IPBlock, *netset.ICMPSet] + srcDstProduct = ds.Product[*netset.IPBlock, *netset.IPBlock] + srcDstProductLeft = ds.ProductLeft[*netset.IPBlock, *netset.IPBlock] + + aclCubesPerProtocol struct { + tcpAllow tcpudpTripleSet + tcpDeny tcpudpTripleSet + + udpAllow tcpudpTripleSet + udpDeny tcpudpTripleSet + + icmpAllow icmpTripleSet + icmpDeny icmpTripleSet + + // initialized in reduceCubes func + anyProtocolAllow srcDstProduct + } ) func NewACLOptimizer(collection ir.Collection, aclName string) optimize.Optimizer { @@ -27,5 +52,57 @@ func NewACLOptimizer(collection ir.Collection, aclName string) optimize.Optimize } func (a *aclOptimizer) Optimize() (ir.Collection, error) { + if a.aclName != "" { + for _, vpcName := range utils.SortedMapKeys(a.aclCollection.ACLs) { + if a.aclVPC != "" && a.aclVPC != vpcName { + continue + } + if _, ok := a.aclCollection.ACLs[vpcName][a.aclName]; ok { + a.optimizeACL(vpcName, a.aclName) + return a.aclCollection, nil + } + } + return nil, fmt.Errorf("could not find nACL %s", a.aclName) + } + + for _, vpcName := range utils.SortedMapKeys(a.aclCollection.ACLs) { + for _, aclName := range utils.SortedMapKeys(a.aclCollection.ACLs[vpcName]) { + a.optimizeACL(vpcName, aclName) + } + } return a.aclCollection, nil } + +func (a *aclOptimizer) optimizeACL(vpcName, aclName string) { + acl := a.aclCollection.ACLs[vpcName][aclName] + reducedRules := 0 + + // reduce inbound rules first + newInboundRules := a.reduceACLRules(acl.Inbound, ir.Inbound) + if len(acl.Inbound) > len(newInboundRules) { + reducedRules += len(acl.Inbound) - len(newInboundRules) + acl.Inbound = newInboundRules + } + + // reduce outbound rules second + newOutboundRules := a.reduceACLRules(acl.Outbound, ir.Outbound) + if len(acl.Outbound) > len(newOutboundRules) { + reducedRules += len(acl.Outbound) - len(newOutboundRules) + acl.Outbound = newOutboundRules + } + + // print a message to the log + if reducedRules == 0 { + log.Printf("no rules were reduced in acl %s\n", a.aclName) + } else { + log.Printf("the number of rules in acl %s was reduced by %d\n", a.aclName, reducedRules) + } +} + +func (a *aclOptimizer) reduceACLRules(rules []*ir.ACLRule, direction ir.Direction) []*ir.ACLRule { + optimizedRules := aclCubesToRules(aclRulesToCubes(rules), direction) + if len(rules) > len(optimizedRules) { + return optimizedRules + } + return rules +} diff --git a/pkg/optimize/acl/cubesToRules.go b/pkg/optimize/acl/cubesToRules.go new file mode 100644 index 00000000..4121f73b --- /dev/null +++ b/pkg/optimize/acl/cubesToRules.go @@ -0,0 +1,91 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package acloptimizer + +import ( + "slices" + + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" +) + +func aclCubesToRules(cubes *aclCubesPerProtocol, direction ir.Direction) []*ir.ACLRule { + reduceACLCubes(cubes) + tcpRules := tcpudpTriplesToRules(cubes.tcpAllow, direction) + udpRules := tcpudpTriplesToRules(cubes.udpAllow, direction) + icmpRules := icmpTriplesToRules(cubes.icmpAllow, direction) + anyProtocolRules := anyProtocolCubesToRules(cubes.anyProtocolAllow, direction) + return slices.Concat(tcpRules, udpRules, icmpRules, anyProtocolRules) +} + +// same algorithm as sg cubes to rules +func anyProtocolCubesToRules(cubes srcDstProduct, direction ir.Direction) []*ir.ACLRule { + partitions := optimize.SortPartitionsByIPAddrs(cubes.Partitions()) + if len(partitions) == 0 { + return []*ir.ACLRule{} + } + + res := make([]*ir.ACLRule, 0) + activeRules := make([]ds.Pair[*netset.IPBlock, *netset.IPBlock], 0) // Left = first src's IP, Right = dst cidr + + for i := range partitions { + // if it is not possible to continue the rule between the cubes, generate all existing rules + if i > 0 && uncoveredHole(partitions[i-1].Left, partitions[i].Left) { + res = slices.Concat(res, createActiveRules(activeRules, partitions[i-1].Left.LastIPAddressObject(), direction)) + activeRules = make([]ds.Pair[*netset.IPBlock, *netset.IPBlock], 0) + } + + // if there are active rules whose dsts are not fully included in the current cube, they will be created + // also activeDstIPs will be calculated, which is the dstIPs that are still included in the active rules + activeDstIPs := netset.NewIPBlock() + for j, rule := range slices.Backward(activeRules) { + if rule.Right.IsSubset(partitions[i].Right) { + activeDstIPs = activeDstIPs.Union(rule.Right) + } else { + res = createNewRules(rule.Left, partitions[i-1].Left.LastIPAddressObject(), rule.Right, direction) // create active rule + activeRules = slices.Delete(activeRules, j, j+1) + } + } + + // if the current cube contains dstIPs that are not contained in active rules, new rules will be created + for _, dstCidr := range partitions[i].Right.SplitToCidrs() { + if !dstCidr.IsSubset(activeDstIPs) { + rule := ds.Pair[*netset.IPBlock, *netset.IPBlock]{Left: partitions[i].Left.FirstIPAddressObject(), Right: dstCidr} + activeRules = append(activeRules, rule) + } + } + } + // generate all existing rules + return slices.Concat(res, createActiveRules(activeRules, partitions[len(partitions)-1].Left.LastIPAddressObject(), direction)) +} + +func createActiveRules(activeRules []ds.Pair[*netset.IPBlock, *netset.IPBlock], srcLastIP *netset.IPBlock, + direction ir.Direction) []*ir.ACLRule { + res := make([]*ir.ACLRule, 0) + for _, rule := range activeRules { + res = slices.Concat(res, createNewRules(rule.Left, srcLastIP, rule.Right, direction)) + } + return res +} + +func createNewRules(srcStartIP, srcEndIP, dstCidr *netset.IPBlock, direction ir.Direction) []*ir.ACLRule { + src, _ := netset.IPBlockFromIPRange(srcStartIP, srcEndIP) + srcCidrs := src.SplitToCidrs() + + res := make([]*ir.ACLRule, len(srcCidrs)) + for i, srcCidr := range srcCidrs { + res[i] = ir.NewACLRule(ir.Allow, direction, srcCidr, dstCidr, netp.AnyProtocol{}, "") + } + return res +} + +func uncoveredHole(prevSrcIP, currSrcIP *netset.IPBlock) bool { + touching, _ := prevSrcIP.TouchingIPRanges(currSrcIP) + return !touching +} diff --git a/pkg/optimize/acl/icmpCubesToRules.go b/pkg/optimize/acl/icmpCubesToRules.go new file mode 100644 index 00000000..79d7884c --- /dev/null +++ b/pkg/optimize/acl/icmpCubesToRules.go @@ -0,0 +1,67 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package acloptimizer + +import ( + "slices" + + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" +) + +func icmpTriplesToRules(tripleSet icmpTripleSet, direction ir.Direction) []*ir.ACLRule { + partitions := minimalPartitionsICMP(tripleSet) + res := make([]*ir.ACLRule, len(partitions)) + for i, t := range partitions { + res[i] = ir.NewACLRule(ir.Allow, direction, t.S1, t.S2, t.S3, "") + } + return res +} + +func minimalPartitionsICMP(t icmpTripleSet) []ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.ICMP] { + leftPartitions := actualPartitionsICMP(ds.AsLeftTripleSet(t)) + outerPartitions := actualPartitionsICMP(ds.AsOuterTripleSet(t)) + rightPartitions := actualPartitionsICMP(ds.AsRightTripleSet(t)) + + switch { + case len(leftPartitions) <= len(outerPartitions) && len(leftPartitions) <= len(rightPartitions): + return leftPartitions + case len(outerPartitions) <= len(leftPartitions) && len(outerPartitions) <= len(rightPartitions): + return outerPartitions + default: + return rightPartitions + } +} + +func actualPartitionsICMP(t icmpTripleSet) []ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.ICMP] { + res := make([]ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.ICMP], 0) + for _, p := range t.Partitions() { + res = slices.Concat(res, breakICMPTriple(p)) + } + return res +} + +// break multi-cube to regular cube +func breakICMPTriple(t ds.Triple[*netset.IPBlock, *netset.IPBlock, *netset.ICMPSet]) []ds.Triple[*netset.IPBlock, + *netset.IPBlock, netp.ICMP] { + res := make([]ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.ICMP], 0) + + dstCidrs := t.S2.SplitToCidrs() + icmpPartitions := optimize.IcmpsetPartitions(t.S3) + + for _, src := range t.S1.SplitToCidrs() { + for _, dst := range dstCidrs { + for _, icmp := range icmpPartitions { + a := ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.ICMP]{S1: src, S2: dst, S3: icmp} + res = append(res, a) + } + } + } + return res +} diff --git a/pkg/optimize/acl/reduceCubes.go b/pkg/optimize/acl/reduceCubes.go new file mode 100644 index 00000000..fdcd7848 --- /dev/null +++ b/pkg/optimize/acl/reduceCubes.go @@ -0,0 +1,60 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package acloptimizer + +import ( + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/netset" +) + +// reduceACLCubes unifies a (src ip x dst ip) cube, separately allowed for tcp, udp and icmp, into one "any" cube +// (assuming all ports, codes, types) +func reduceACLCubes(aclCubes *aclCubesPerProtocol) { + allTCP := allTCPUDP(aclCubes.tcpAllow) + allUDP := allTCPUDP(aclCubes.udpAllow) + allicmp := allICMP(aclCubes.icmpAllow) + aclCubes.anyProtocolAllow = allTCP.Intersect(allUDP).Intersect(allicmp) + subtractAnyProtocolCubes(aclCubes) +} + +func allTCPUDP(tcpudpAllow ds.TripleSet[*netset.IPBlock, *netset.IPBlock, *netset.TCPUDPSet]) *srcDstProductLeft { + res := ds.NewProductLeft[*netset.IPBlock, *netset.IPBlock]() + allTCPSet := netset.NewAllTCPOnlySet() + allUDPSet := netset.NewAllUDPOnlySet() + for _, p := range tcpudpAllow.Partitions() { + if p.S3.Equal(allTCPSet) || p.S3.Equal(allUDPSet) { // all tcp or udp ports + r := ds.CartesianPairLeft(p.S1, p.S2) + res = res.Union(r).(*srcDstProductLeft) + } + } + return res +} + +func allICMP(icmpAllow ds.TripleSet[*netset.IPBlock, *netset.IPBlock, *netset.ICMPSet]) *srcDstProductLeft { + res := ds.NewProductLeft[*netset.IPBlock, *netset.IPBlock]() + for _, p := range icmpAllow.Partitions() { + if p.S3.IsAll() { // all icmp types and codes + r := ds.CartesianPairLeft(p.S1, p.S2) + res = res.Union(r).(*srcDstProductLeft) + } + } + return res +} + +func subtractAnyProtocolCubes(aclCubes *aclCubesPerProtocol) { + allTcpudp := ds.NewLeftTripleSet[*netset.IPBlock, *netset.IPBlock, *netset.TCPUDPSet]() + allIcmp := ds.NewLeftTripleSet[*netset.IPBlock, *netset.IPBlock, *netset.ICMPSet]() + for _, p := range aclCubes.anyProtocolAllow.Partitions() { + t := ds.CartesianLeftTriple(p.Left, p.Right, netset.AllTCPUDPSet()) + allTcpudp = allTcpudp.Union(t).(*ds.LeftTripleSet[*netset.IPBlock, *netset.IPBlock, *netset.TCPUDPSet]) + i := ds.CartesianLeftTriple(p.Left, p.Right, netset.AllICMPSet()) + allIcmp = allIcmp.Union(i).(*ds.LeftTripleSet[*netset.IPBlock, *netset.IPBlock, *netset.ICMPSet]) + } + + aclCubes.tcpAllow = aclCubes.tcpAllow.Subtract(allTcpudp) + aclCubes.udpAllow = aclCubes.udpAllow.Subtract(allTcpudp) + aclCubes.icmpAllow = aclCubes.icmpAllow.Subtract(allIcmp) +} diff --git a/pkg/optimize/acl/rulesToCubes.go b/pkg/optimize/acl/rulesToCubes.go new file mode 100644 index 00000000..276df53d --- /dev/null +++ b/pkg/optimize/acl/rulesToCubes.go @@ -0,0 +1,83 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package acloptimizer + +import ( + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" +) + +func aclRulesToCubes(rules []*ir.ACLRule) *aclCubesPerProtocol { + res := &aclCubesPerProtocol{ + tcpAllow: ds.NewLeftTripleSet[*netset.IPBlock, *netset.IPBlock, *netset.TCPUDPSet](), + tcpDeny: ds.NewLeftTripleSet[*netset.IPBlock, *netset.IPBlock, *netset.TCPUDPSet](), + udpAllow: ds.NewLeftTripleSet[*netset.IPBlock, *netset.IPBlock, *netset.TCPUDPSet](), + udpDeny: ds.NewLeftTripleSet[*netset.IPBlock, *netset.IPBlock, *netset.TCPUDPSet](), + icmpAllow: ds.NewLeftTripleSet[*netset.IPBlock, *netset.IPBlock, *netset.ICMPSet](), + icmpDeny: ds.NewLeftTripleSet[*netset.IPBlock, *netset.IPBlock, *netset.ICMPSet](), + } + + for _, rule := range rules { + switch p := rule.Protocol.(type) { + case netp.TCPUDP: + if p.ProtocolString() == netp.ProtocolStringTCP { + res.tcpAllow, res.tcpDeny = tcpudpRuleToCubes(res.tcpAllow, res.tcpDeny, rule) + } else { + res.udpAllow, res.udpDeny = tcpudpRuleToCubes(res.udpAllow, res.udpDeny, rule) + } + case netp.ICMP: + icmpRuleToCubes(res, rule) + case netp.AnyProtocol: + anyProtocolRuleToCubes(res, rule) + } + } + return res +} + +func tcpudpRuleToCubes(tcpudpAllow, tcpudpDeny tcpudpTripleSet, rule *ir.ACLRule) (allow, deny tcpudpTripleSet) { + tcpudp := rule.Protocol.(netp.TCPUDP) + tcpudpSrcPorts := tcpudp.SrcPorts() + tcpudpDstPorts := tcpudp.DstPorts() + tcpudpSet := netset.NewTCPorUDPSet(tcpudp.ProtocolString(), tcpudpSrcPorts.Start(), tcpudpSrcPorts.End(), tcpudpDstPorts.Start(), + tcpudpDstPorts.End()) + + ruleCube := ds.CartesianLeftTriple(rule.Source, rule.Destination, tcpudpSet) + if rule.Action == ir.Allow { + r := ruleCube.Subtract(tcpudpDeny) + tcpudpAllow = tcpudpAllow.Union(r) + } else { + r := ruleCube.Subtract(tcpudpAllow) + tcpudpDeny = tcpudpDeny.Union(r) + } + return tcpudpAllow, tcpudpDeny +} + +func icmpRuleToCubes(cubes *aclCubesPerProtocol, rule *ir.ACLRule) { + ruleCube := ds.CartesianLeftTriple(rule.Source, rule.Destination, optimize.IcmpToIcmpSet(rule.Protocol.(netp.ICMP))) + if rule.Action == ir.Allow { + r := ruleCube.Subtract(cubes.icmpDeny) + cubes.icmpAllow = cubes.icmpAllow.Union(r) + } else { + r := ruleCube.Subtract(cubes.icmpAllow) + cubes.icmpDeny = cubes.icmpDeny.Union(r) + } +} + +func anyProtocolRuleToCubes(cubes *aclCubesPerProtocol, rule *ir.ACLRule) { + tcp, _ := netp.NewTCPUDP(true, netp.MinPort, netp.MaxPort, netp.MinPort, netp.MaxPort) // all ports + cubes.tcpAllow, cubes.tcpDeny = tcpudpRuleToCubes(cubes.tcpAllow, cubes.tcpDeny, + ir.NewACLRule(rule.Action, rule.Direction, rule.Source, rule.Destination, tcp, rule.Explanation)) + + udp, _ := netp.NewTCPUDP(false, netp.MinPort, netp.MaxPort, netp.MinPort, netp.MaxPort) // all ports + cubes.udpAllow, cubes.udpDeny = tcpudpRuleToCubes(cubes.udpAllow, cubes.udpDeny, + ir.NewACLRule(rule.Action, rule.Direction, rule.Source, rule.Destination, udp, rule.Explanation)) + + icmp, _ := netp.NewICMPWithoutRFCValidation(nil) // all types and codes + icmpRuleToCubes(cubes, ir.NewACLRule(rule.Action, rule.Direction, rule.Source, rule.Destination, icmp, rule.Explanation)) +} diff --git a/pkg/optimize/acl/tcpudpCubesToRules.go b/pkg/optimize/acl/tcpudpCubesToRules.go new file mode 100644 index 00000000..4054451f --- /dev/null +++ b/pkg/optimize/acl/tcpudpCubesToRules.go @@ -0,0 +1,76 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package acloptimizer + +import ( + "slices" + + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +func tcpudpTriplesToRules(tripleSet tcpudpTripleSet, direction ir.Direction) []*ir.ACLRule { + partitions := minimalPartitionsTCPUDP(tripleSet) + res := make([]*ir.ACLRule, len(partitions)) + for i, t := range partitions { + res[i] = ir.NewACLRule(ir.Allow, direction, t.S1, t.S2, t.S3, "") + } + return res +} + +func minimalPartitionsTCPUDP(t tcpudpTripleSet) []ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.TCPUDP] { + leftPartitions := actualPartitionsTCPUDP(ds.AsLeftTripleSet(t)) + outerPartitions := actualPartitionsTCPUDP(ds.AsOuterTripleSet(t)) + rightPartitions := actualPartitionsTCPUDP(ds.AsRightTripleSet(t)) + + switch { + case len(leftPartitions) <= len(outerPartitions) && len(leftPartitions) <= len(rightPartitions): + return leftPartitions + case len(outerPartitions) <= len(leftPartitions) && len(outerPartitions) <= len(rightPartitions): + return outerPartitions + default: + return rightPartitions + } +} + +func actualPartitionsTCPUDP(t tcpudpTripleSet) []ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.TCPUDP] { + res := make([]ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.TCPUDP], 0) + for _, p := range t.Partitions() { + res = slices.Concat(res, breakTCPUDPTriple(p)) + } + return res +} + +// break multi-cube to regular cube +func breakTCPUDPTriple(t ds.Triple[*netset.IPBlock, *netset.IPBlock, *netset.TCPUDPSet]) []ds.Triple[*netset.IPBlock, + *netset.IPBlock, netp.TCPUDP] { + tcpudpTriples := t.S3.Partitions() + if len(tcpudpTriples) == 0 { + return []ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.TCPUDP]{} + } + + res := make([]ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.TCPUDP], 0) + + dstCidrs := t.S2.SplitToCidrs() + isTCP := tcpudpTriples[0].S1.Elements()[0] == netset.TCPCode + for _, src := range t.S1.SplitToCidrs() { + for _, dst := range dstCidrs { + for _, protocolTriple := range tcpudpTriples { + tcpudpSrcPorts := protocolTriple.S2.Intervals() + tcpudpDstPorts := protocolTriple.S3.Intervals() + for _, srcPorts := range tcpudpSrcPorts { + for _, dstPorts := range tcpudpDstPorts { + p, _ := netp.NewTCPUDP(isTCP, int(srcPorts.Start()), int(srcPorts.End()), int(dstPorts.Start()), int(dstPorts.End())) + res = append(res, ds.Triple[*netset.IPBlock, *netset.IPBlock, netp.TCPUDP]{S1: src, S2: dst, S3: p}) + } + } + } + } + } + return res +} diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go index 8ac89345..f88fc42b 100644 --- a/pkg/optimize/sg/ipCubesToRules.go +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -140,10 +140,12 @@ func createActiveRules(activeRules []ds.Pair[*netset.IPBlock, netp.Protocol], la // createNewRules breaks the startIP-endIP ip range into cidrs and creates SG rules func createNewRules(protocol netp.Protocol, startIP, endIP *netset.IPBlock, direction ir.Direction, l *netset.IPBlock) []*ir.SGRule { - res := make([]*ir.SGRule, 0) ipRange, _ := netset.IPBlockFromIPRange(startIP, endIP) - for _, cidr := range ipRange.SplitToCidrs() { - res = append(res, ir.NewSGRule(direction, cidr, protocol, l, "")) + remoteCidrs := ipRange.SplitToCidrs() + + res := make([]*ir.SGRule, len(remoteCidrs)) + for i, remoteCidr := range remoteCidrs { + res[i] = ir.NewSGRule(direction, remoteCidr, protocol, l, "") } return res } diff --git a/test/data/optimize_acl/config_object.json b/test/data/optimize_acl/config_object.json new file mode 100644 index 00000000..a60ef20b --- /dev/null +++ b/test/data/optimize_acl/config_object.json @@ -0,0 +1,1583 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-06-25T12:20:44.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.249.196.114" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.22.27.101" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.249.81.251" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "disallow-laborious-compress-abiding" + }, + "default_routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "traffic-overeasy-festoonery-illusive", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "elevation-lyricist-elf-hassle" + }, + "dns": { + "enable_hub": false, + "resolution_binding_count": 0, + "resolver": { + "servers": [ + { + "address": "161.26.0.10" + }, + { + "address": "161.26.0.11" + } + ], + "type": "system", + "configuration": "default" + } + }, + "health_reasons": null, + "health_state": "ok", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "vpc", + "status": "available", + "region": "us-south", + "address_prefixes": [ + { + "cidr": "10.240.0.0/18", + "created_at": "2024-06-25T12:20:44.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": true, + "name": "blouse-armchair-fernlike-plus", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.64.0/18", + "created_at": "2024-06-25T12:20:44.000Z", + "has_subnets": true, + "href": "href:20", + "id": "id:21", + "is_default": true, + "name": "stowaway-chatty-opulently-durably", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.128.0/18", + "created_at": "2024-06-25T12:20:44.000Z", + "has_subnets": true, + "href": "href:22", + "id": "id:23", + "is_default": true, + "name": "trifle-renewably-decenary-protector", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [ + "yair" + ] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 251, + "created_at": "2024-06-25T12:22:47.000Z", + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.2.0/24", + "name": "sub1-2", + "network_acl": { + "crn": "fake:crn:1", + "href": "fake:href:1", + "id": "fake:id:1", + "name": "testacl5-vpc--sub1-2" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "traffic-overeasy-festoonery-illusive", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.2.0", + "auto_delete": false, + "created_at": "2024-06-25T12:22:47.000Z", + "href": "href:30", + "id": "id:31", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.2.1", + "auto_delete": false, + "created_at": "2024-06-25T12:22:47.000Z", + "href": "href:32", + "id": "id:33", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.2.2", + "auto_delete": false, + "created_at": "2024-06-25T12:22:47.000Z", + "href": "href:34", + "id": "id:35", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.2.3", + "auto_delete": false, + "created_at": "2024-06-25T12:22:47.000Z", + "href": "href:36", + "id": "id:37", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.2.255", + "auto_delete": false, + "created_at": "2024-06-25T12:22:47.000Z", + "href": "href:38", + "id": "id:39", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "yair" + ] + }, + { + "available_ipv4_address_count": 251, + "created_at": "2024-06-25T12:22:10.000Z", + "crn": "crn:40", + "href": "href:41", + "id": "id:42", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.1.0/24", + "name": "sub1-1", + "network_acl": { + "crn": "fake:crn:23", + "href": "fake:href:23", + "id": "fake:id:23", + "name": "testacl5-vpc--sub1-1" + }, + "public_gateway": { + "crn": "crn:46", + "href": "href:47", + "id": "id:48", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "traffic-overeasy-festoonery-illusive", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.1.0", + "auto_delete": false, + "created_at": "2024-06-25T12:22:10.000Z", + "href": "href:49", + "id": "id:50", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.1.1", + "auto_delete": false, + "created_at": "2024-06-25T12:22:10.000Z", + "href": "href:51", + "id": "id:52", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.1.2", + "auto_delete": false, + "created_at": "2024-06-25T12:22:10.000Z", + "href": "href:53", + "id": "id:54", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.1.3", + "auto_delete": false, + "created_at": "2024-06-25T12:22:10.000Z", + "href": "href:55", + "id": "id:56", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.1.255", + "auto_delete": false, + "created_at": "2024-06-25T12:22:10.000Z", + "href": "href:57", + "id": "id:58", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "yair" + ] + }, + { + "available_ipv4_address_count": 251, + "created_at": "2024-06-25T12:22:04.000Z", + "crn": "crn:59", + "href": "href:60", + "id": "id:61", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.64.0/24", + "name": "sub2-1", + "network_acl": { + "crn": "fake:crn:46", + "href": "fake:href:46", + "id": "fake:id:46", + "name": "testacl5-vpc--sub2-1" + }, + "public_gateway": { + "crn": "crn:65", + "href": "href:66", + "id": "id:67", + "name": "public-gw2", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "traffic-overeasy-festoonery-illusive", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + }, + "reserved_ips": [ + { + "address": "10.240.64.0", + "auto_delete": false, + "created_at": "2024-06-25T12:22:04.000Z", + "href": "href:68", + "id": "id:69", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.64.1", + "auto_delete": false, + "created_at": "2024-06-25T12:22:04.000Z", + "href": "href:70", + "id": "id:71", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.64.2", + "auto_delete": false, + "created_at": "2024-06-25T12:22:04.000Z", + "href": "href:72", + "id": "id:73", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.64.3", + "auto_delete": false, + "created_at": "2024-06-25T12:22:04.000Z", + "href": "href:74", + "id": "id:75", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.64.255", + "auto_delete": false, + "created_at": "2024-06-25T12:22:04.000Z", + "href": "href:76", + "id": "id:77", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "yair" + ] + }, + { + "available_ipv4_address_count": 251, + "created_at": "2024-06-25T12:21:43.000Z", + "crn": "crn:78", + "href": "href:79", + "id": "id:80", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.3.0/24", + "name": "sub1-3", + "network_acl": { + "crn": "fake:crn:52", + "href": "fake:href:52", + "id": "fake:id:52", + "name": "testacl5-vpc--sub1-3" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "traffic-overeasy-festoonery-illusive", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.3.0", + "auto_delete": false, + "created_at": "2024-06-25T12:21:43.000Z", + "href": "href:81", + "id": "id:82", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.3.1", + "auto_delete": false, + "created_at": "2024-06-25T12:21:43.000Z", + "href": "href:83", + "id": "id:84", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.3.2", + "auto_delete": false, + "created_at": "2024-06-25T12:21:43.000Z", + "href": "href:85", + "id": "id:86", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.3.3", + "auto_delete": false, + "created_at": "2024-06-25T12:21:43.000Z", + "href": "href:87", + "id": "id:88", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.3.255", + "auto_delete": false, + "created_at": "2024-06-25T12:21:43.000Z", + "href": "href:89", + "id": "id:90", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "yair" + ] + }, + { + "available_ipv4_address_count": 251, + "created_at": "2024-06-25T12:21:36.000Z", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.65.0/24", + "name": "sub2-2", + "network_acl": { + "crn": "fake:crn:58", + "href": "fake:href:58", + "id": "fake:id:58", + "name": "testacl5-vpc--sub2-2" + }, + "public_gateway": { + "crn": "crn:65", + "href": "href:66", + "id": "id:67", + "name": "public-gw2", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "traffic-overeasy-festoonery-illusive", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + }, + "reserved_ips": [ + { + "address": "10.240.65.0", + "auto_delete": false, + "created_at": "2024-06-25T12:21:36.000Z", + "href": "href:97", + "id": "id:98", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.65.1", + "auto_delete": false, + "created_at": "2024-06-25T12:21:36.000Z", + "href": "href:99", + "id": "id:100", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.65.2", + "auto_delete": false, + "created_at": "2024-06-25T12:21:36.000Z", + "href": "href:101", + "id": "id:102", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.65.3", + "auto_delete": false, + "created_at": "2024-06-25T12:21:36.000Z", + "href": "href:103", + "id": "id:104", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.65.255", + "auto_delete": false, + "created_at": "2024-06-25T12:21:36.000Z", + "href": "href:105", + "id": "id:106", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "yair" + ] + }, + { + "available_ipv4_address_count": 251, + "created_at": "2024-06-25T12:21:20.000Z", + "crn": "crn:107", + "href": "href:108", + "id": "id:109", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.128.0/24", + "name": "sub3-1", + "network_acl": { + "crn": "fake:crn:61", + "href": "fake:href:61", + "id": "fake:id:61", + "name": "testacl5-vpc--sub3-1" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "traffic-overeasy-festoonery-illusive", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "reserved_ips": [ + { + "address": "10.240.128.0", + "auto_delete": false, + "created_at": "2024-06-25T12:21:20.000Z", + "href": "href:113", + "id": "id:114", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.128.1", + "auto_delete": false, + "created_at": "2024-06-25T12:21:20.000Z", + "href": "href:115", + "id": "id:116", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.128.2", + "auto_delete": false, + "created_at": "2024-06-25T12:21:20.000Z", + "href": "href:117", + "id": "id:118", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.128.3", + "auto_delete": false, + "created_at": "2024-06-25T12:21:20.000Z", + "href": "href:119", + "id": "id:120", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.128.255", + "auto_delete": false, + "created_at": "2024-06-25T12:21:20.000Z", + "href": "href:121", + "id": "id:122", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "yair" + ] + } + ], + "public_gateways": [ + { + "created_at": "2024-06-25T12:21:17.000Z", + "crn": "crn:46", + "floating_ip": { + "address": "52.118.146.248", + "crn": "crn:123", + "href": "href:124", + "id": "id:125", + "name": "public-gw1" + }, + "href": "href:47", + "id": "id:48", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "public_gateway", + "status": "available", + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [ + "yair" + ] + }, + { + "created_at": "2024-06-25T12:21:16.000Z", + "crn": "crn:65", + "floating_ip": { + "address": "169.47.95.195", + "crn": "crn:126", + "href": "href:127", + "id": "id:128", + "name": "public-gw2" + }, + "href": "href:66", + "id": "id:67", + "name": "public-gw2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "public_gateway", + "status": "available", + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + }, + "tags": [ + "yair" + ] + } + ], + "floating_ips": [ + { + "address": "52.118.146.248", + "created_at": "2024-06-25T12:21:16.000Z", + "crn": "crn:123", + "href": "href:124", + "id": "id:125", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:47", + "id": "id:48", + "name": "public-gw1", + "resource_type": "public_gateway", + "crn": "crn:46" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + }, + { + "address": "169.47.95.195", + "created_at": "2024-06-25T12:21:16.000Z", + "crn": "crn:126", + "href": "href:127", + "id": "id:128", + "name": "public-gw2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:66", + "id": "id:67", + "name": "public-gw2", + "resource_type": "public_gateway", + "crn": "crn:65" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": null, + "crn": "fake:crn:1", + "href": "fake:href:1", + "id": "fake:id:1", + "name": "testacl5-vpc--sub1-2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "fake:href:3", + "id": "fake:id:3", + "name": "rule19" + }, + "created_at": null, + "destination": "2.2.2.2/32", + "direction": "outbound", + "href": "fake:href:4", + "id": "fake:id:4", + "ip_version": "ipv4", + "name": "rule18", + "source": "10.240.2.0/24", + "destination_port_max": 10, + "destination_port_min": 1, + "protocol": "udp", + "source_port_max": 65535, + "source_port_min": 1 + }, + { + "action": "allow", + "before": { + "href": "fake:href:2", + "id": "fake:id:2", + "name": "rule20" + }, + "created_at": null, + "destination": "2.2.2.2/32", + "direction": "outbound", + "href": "fake:href:3", + "id": "fake:id:3", + "ip_version": "ipv4", + "name": "rule19", + "source": "10.240.2.0/24", + "destination_port_max": 15, + "destination_port_min": 5, + "protocol": "udp", + "source_port_max": 65535, + "source_port_min": 1 + }, + { + "action": "allow", + "created_at": null, + "destination": "2.2.2.2/32", + "direction": "outbound", + "href": "fake:href:2", + "id": "fake:id:2", + "ip_version": "ipv4", + "name": "rule20", + "source": "10.240.2.0/24", + "destination_port_max": 20, + "destination_port_min": 16, + "protocol": "udp", + "source_port_max": 65535, + "source_port_min": 1 + } + ], + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "sub1-2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:23", + "href": "fake:href:23", + "id": "fake:id:23", + "name": "testacl5-vpc--sub1-1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "fake:href:26", + "id": "fake:id:26", + "name": "rule19" + }, + "created_at": null, + "destination": "1.1.1.0/32", + "direction": "outbound", + "href": "fake:href:27", + "id": "fake:id:27", + "ip_version": "ipv4", + "name": "rule18", + "source": "10.240.1.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + }, + { + "action": "allow", + "before": { + "href": "fake:href:24", + "id": "fake:id:24", + "name": "rule21" + }, + "created_at": null, + "destination": "1.1.1.1/32", + "direction": "outbound", + "href": "fake:href:25", + "id": "fake:id:25", + "ip_version": "ipv4", + "name": "rule20", + "source": "10.240.1.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + } + ], + "subnets": [ + { + "crn": "crn:40", + "href": "href:41", + "id": "id:42", + "name": "sub1-1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:46", + "href": "fake:href:46", + "id": "fake:id:46", + "name": "testacl5-vpc--sub2-1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "fake:href:50", + "id": "fake:id:50", + "name": "rule1" + }, + "created_at": null, + "destination": "10.240.64.0/24", + "direction": "inbound", + "href": "fake:href:51", + "id": "fake:id:51", + "ip_version": "ipv4", + "name": "rule0", + "source": "10.240.3.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + }, + { + "action": "allow", + "before": { + "href": "fake:href:48", + "id": "fake:id:48", + "name": "rule3" + }, + "created_at": null, + "destination": "10.240.64.0/24", + "direction": "inbound", + "href": "fake:href:49", + "id": "fake:id:49", + "ip_version": "ipv4", + "name": "rule2", + "source": "10.240.3.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "udp", + "source_port_max": 65535, + "source_port_min": 1 + }, + { + "action": "allow", + "before": { + "href": "fake:href:47", + "id": "fake:id:47", + "name": "rule4" + }, + "created_at": null, + "destination": "10.240.64.0/24", + "direction": "inbound", + "href": "fake:href:48", + "id": "fake:id:48", + "ip_version": "ipv4", + "name": "rule3", + "source": "10.240.3.0/24", + "protocol": "icmp" + } + ], + "subnets": [ + { + "crn": "crn:59", + "href": "href:60", + "id": "id:61", + "name": "sub2-1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:52", + "href": "fake:href:52", + "id": "fake:id:52", + "name": "testacl5-vpc--sub1-3", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "fake:href:56", + "id": "fake:id:56", + "name": "rule1" + }, + "created_at": null, + "destination": "10.240.64.0/24", + "direction": "outbound", + "href": "fake:href:57", + "id": "fake:id:57", + "ip_version": "ipv4", + "name": "rule0", + "source": "10.240.3.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + }, + { + "action": "allow", + "before": { + "href": "fake:href:54", + "id": "fake:id:54", + "name": "rule3" + }, + "created_at": null, + "destination": "10.240.64.0/24", + "direction": "outbound", + "href": "fake:href:55", + "id": "fake:id:55", + "ip_version": "ipv4", + "name": "rule2", + "source": "10.240.3.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "udp", + "source_port_max": 65535, + "source_port_min": 1 + }, + { + "action": "allow", + "before": { + "href": "fake:href:53", + "id": "fake:id:53", + "name": "rule4" + }, + "created_at": null, + "destination": "10.240.64.0/24", + "direction": "outbound", + "href": "fake:href:54", + "id": "fake:id:54", + "ip_version": "ipv4", + "name": "rule3", + "source": "10.240.3.0/24", + "protocol": "icmp" + } + ], + "subnets": [ + { + "crn": "crn:78", + "href": "href:79", + "id": "id:80", + "name": "sub1-3", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:58", + "href": "fake:href:58", + "id": "fake:id:58", + "name": "testacl5-vpc--sub2-2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "deny", + "created_at": null, + "destination": "10.240.128.0/24", + "direction": "outbound", + "href": "fake:href:57", + "id": "fake:id:57", + "ip_version": "ipv4", + "name": "rule0", + "source": "10.240.65.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 10, + "source_port_min": 1 + }, + { + "action": "allow", + "created_at": null, + "destination": "10.240.128.0/24", + "direction": "outbound", + "href": "fake:href:57", + "id": "fake:id:57", + "ip_version": "ipv4", + "name": "rule0", + "source": "10.240.65.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 15, + "source_port_min": 5 + }, + { + "action": "allow", + "created_at": null, + "destination": "10.240.128.0/24", + "direction": "outbound", + "href": "fake:href:57", + "id": "fake:id:57", + "ip_version": "ipv4", + "name": "rule0", + "source": "10.240.65.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 20, + "source_port_min": 16 + } + ], + "subnets": [ + { + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "sub2-2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:61", + "href": "fake:href:61", + "id": "fake:id:61", + "name": "testacl5-vpc--sub3-1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "deny", + "created_at": null, + "destination": "10.240.128.0/24", + "direction": "inbound", + "href": "fake:href:57", + "id": "fake:id:57", + "ip_version": "ipv4", + "name": "rule0", + "source": "10.240.65.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 10, + "source_port_min": 1 + }, + { + "action": "allow", + "created_at": null, + "destination": "10.240.128.0/24", + "direction": "inbound", + "href": "fake:href:57", + "id": "fake:id:57", + "ip_version": "ipv4", + "name": "rule0", + "source": "10.240.65.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 15, + "source_port_min": 5 + }, + { + "action": "allow", + "created_at": null, + "destination": "10.240.128.0/24", + "direction": "inbound", + "href": "fake:href:57", + "id": "fake:id:57", + "ip_version": "ipv4", + "name": "rule0", + "source": "10.240.65.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 20, + "source_port_min": 16 + } + ], + "subnets": [ + { + "crn": "crn:107", + "href": "href:108", + "id": "id:109", + "name": "sub3-1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-06-25T12:21:16.000Z", + "crn": "crn:185", + "href": "href:186", + "id": "id:187", + "name": "sg1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:188", + "id": "id:189", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "inbound", + "href": "href:190", + "id": "id:191", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T12:20:45.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "elevation-lyricist-elf-hassle", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:192", + "id": "id:193", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "inbound", + "href": "href:194", + "id": "id:195", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "elevation-lyricist-elf-hassle" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [], + "instances": [], + "virtual_nis": null, + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-06-25T12:20:45.000Z", + "crn": null, + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "traffic-overeasy-festoonery-illusive", + "resource_group": null, + "resource_type": "routing_table", + "route_direct_link_ingress": false, + "route_internet_ingress": false, + "route_transit_gateway_ingress": false, + "route_vpc_zone_ingress": false, + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "sub1-2", + "resource_type": "subnet" + }, + { + "crn": "crn:40", + "href": "href:41", + "id": "id:42", + "name": "sub1-1", + "resource_type": "subnet" + }, + { + "crn": "crn:59", + "href": "href:60", + "id": "id:61", + "name": "sub2-1", + "resource_type": "subnet" + }, + { + "crn": "crn:78", + "href": "href:79", + "id": "id:80", + "name": "sub1-3", + "resource_type": "subnet" + }, + { + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "sub2-2", + "resource_type": "subnet" + }, + { + "crn": "crn:107", + "href": "href:108", + "id": "id:109", + "name": "sub3-1", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + } + } + ], + "load_balancers": [], + "transit_connections": null, + "transit_gateways": null, + "iks_clusters": [] +} \ No newline at end of file diff --git a/test/data/optimize_acl/conn_spec.json b/test/data/optimize_acl/conn_spec.json new file mode 100644 index 00000000..4956b7db --- /dev/null +++ b/test/data/optimize_acl/conn_spec.json @@ -0,0 +1,135 @@ +{ + "externals": { + "e1": "1.1.1.0/32", + "e2": "1.1.1.1/32", + "e3": "2.2.2.2/32" + }, + "required-connections": [ + { + "src": { + "name": "sub1-1", + "type": "subnet" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "TCP" + } + ] + }, + { + "src": { + "name": "sub1-1", + "type": "subnet" + }, + "dst": { + "name": "e2", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "TCP" + } + ] + }, + { + "src": { + "name": "sub1-2", + "type": "subnet" + }, + "dst": { + "name": "e3", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "UDP", + "min_destination_port": 1, + "max_destination_port": 10 + } + ] + }, + { + "src": { + "name": "sub1-2", + "type": "subnet" + }, + "dst": { + "name": "e3", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "UDP", + "min_destination_port": 5, + "max_destination_port": 15 + } + ] + }, + { + "src": { + "name": "sub1-2", + "type": "subnet" + }, + "dst": { + "name": "e3", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "UDP", + "min_destination_port": 16, + "max_destination_port": 20 + } + ] + }, + { + "src": { + "name": "sub1-3", + "type": "subnet" + }, + "dst": { + "name": "sub2-1", + "type": "subnet" + }, + "allowed-protocols": [ + { + "protocol": "TCP" + } + ] + }, + { + "src": { + "name": "sub1-3", + "type": "subnet" + }, + "dst": { + "name": "sub2-1", + "type": "subnet" + }, + "allowed-protocols": [ + { + "protocol": "UDP" + } + ] + }, + { + "src": { + "name": "sub1-3", + "type": "subnet" + }, + "dst": { + "name": "sub2-1", + "type": "subnet" + }, + "allowed-protocols": [ + { + "protocol": "ICMP" + } + ] + } + ] +} \ No newline at end of file diff --git a/test/data/optimize_acl/details.txt b/test/data/optimize_acl/details.txt new file mode 100644 index 00000000..3cfaab40 --- /dev/null +++ b/test/data/optimize_acl/details.txt @@ -0,0 +1,28 @@ +original config object: acl_testing5 config +please note that the generated config object has been changed! + +######## BEFORE ######## + +sub1-1 --> 1.1.1.0/32 (tcp) +sub1-1 --> 1.1.1.1/32 (tcp) + +sub1-2 --> 2.2.2.2/32 (udp ports 1-10) +sub1-2 --> 2.2.2.2/32 (udp ports 5-15) +sub1-2 --> 2.2.2.2/32 (udp ports 16-20) + +sub1-3 --> sub2-1 (tcp) +sub1-3 --> sub2-1 (udp) +sub1-3 --> sub2-1 (icmp) + +DENY sub2-2 --> sub3-1 (tcp src ports 1-10) +ALLOW sub2-2 --> sub3-1 (tcp src ports 5-15) +ALLOW sub2-2 --> sub3-1 (tcp src ports 16-20) + +######## AFTER (tf, md, json) ######## + +sub1-1 --> 1.1.1.0/31 (tcp) +sub1-2 --> 2.2.2.2/32 (udp 1-20) +sub1-3 --> sub2-1 (any protocol) +sub2-2 --> sub3-1 (tcp ports 11-20) + +in CSV fmt only "testacl5-vpc--sub1-2" nACL is optimized \ No newline at end of file diff --git a/test/data/optimize_acl_anyProtocol/config_object.json b/test/data/optimize_acl_anyProtocol/config_object.json new file mode 100644 index 00000000..819913a0 --- /dev/null +++ b/test/data/optimize_acl_anyProtocol/config_object.json @@ -0,0 +1,777 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-06-25T12:20:44.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.249.196.114" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.22.27.101" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.249.81.251" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "disallow-laborious-compress-abiding" + }, + "default_routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "traffic-overeasy-festoonery-illusive", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "elevation-lyricist-elf-hassle" + }, + "dns": { + "enable_hub": false, + "resolution_binding_count": 0, + "resolver": { + "servers": [ + { + "address": "161.26.0.10" + }, + { + "address": "161.26.0.11" + } + ], + "type": "system", + "configuration": "default" + } + }, + "health_reasons": null, + "health_state": "ok", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "vpc", + "status": "available", + "region": "us-south", + "address_prefixes": [ + { + "cidr": "10.240.0.0/18", + "created_at": "2024-06-25T12:20:44.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": true, + "name": "blouse-armchair-fernlike-plus", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.64.0/18", + "created_at": "2024-06-25T12:20:44.000Z", + "has_subnets": true, + "href": "href:20", + "id": "id:21", + "is_default": true, + "name": "stowaway-chatty-opulently-durably", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.128.0/18", + "created_at": "2024-06-25T12:20:44.000Z", + "has_subnets": true, + "href": "href:22", + "id": "id:23", + "is_default": true, + "name": "trifle-renewably-decenary-protector", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [ + "yair" + ] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 251, + "created_at": "2024-06-25T12:22:47.000Z", + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "ip_version": "ipv4", + "ipv4_cidr_block": "2.2.2.1/32", + "name": "sub1-2", + "network_acl": { + "crn": "fake:crn:1", + "href": "fake:href:1", + "id": "fake:id:1", + "name": "testacl5-vpc--sub1-2" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "traffic-overeasy-festoonery-illusive", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.2.0", + "auto_delete": false, + "created_at": "2024-06-25T12:22:47.000Z", + "href": "href:30", + "id": "id:31", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.2.1", + "auto_delete": false, + "created_at": "2024-06-25T12:22:47.000Z", + "href": "href:32", + "id": "id:33", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.2.2", + "auto_delete": false, + "created_at": "2024-06-25T12:22:47.000Z", + "href": "href:34", + "id": "id:35", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.2.3", + "auto_delete": false, + "created_at": "2024-06-25T12:22:47.000Z", + "href": "href:36", + "id": "id:37", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.2.255", + "auto_delete": false, + "created_at": "2024-06-25T12:22:47.000Z", + "href": "href:38", + "id": "id:39", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "yair" + ] + }, + { + "available_ipv4_address_count": 251, + "created_at": "2024-06-25T12:22:10.000Z", + "crn": "crn:40", + "href": "href:41", + "id": "id:42", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.1.0/24", + "name": "sub1-1", + "network_acl": { + "crn": "fake:crn:4", + "href": "fake:href:4", + "id": "fake:id:4", + "name": "testacl5-vpc--sub1-1" + }, + "public_gateway": { + "crn": "crn:46", + "href": "href:47", + "id": "id:48", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "traffic-overeasy-festoonery-illusive", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.1.0", + "auto_delete": false, + "created_at": "2024-06-25T12:22:10.000Z", + "href": "href:49", + "id": "id:50", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.1.1", + "auto_delete": false, + "created_at": "2024-06-25T12:22:10.000Z", + "href": "href:51", + "id": "id:52", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.1.2", + "auto_delete": false, + "created_at": "2024-06-25T12:22:10.000Z", + "href": "href:53", + "id": "id:54", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.1.3", + "auto_delete": false, + "created_at": "2024-06-25T12:22:10.000Z", + "href": "href:55", + "id": "id:56", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.1.255", + "auto_delete": false, + "created_at": "2024-06-25T12:22:10.000Z", + "href": "href:57", + "id": "id:58", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "yair" + ] + } + ], + "public_gateways": [ + { + "created_at": "2024-06-25T12:21:17.000Z", + "crn": "crn:46", + "floating_ip": { + "address": "52.118.146.248", + "crn": "crn:123", + "href": "href:124", + "id": "id:125", + "name": "public-gw1" + }, + "href": "href:47", + "id": "id:48", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "public_gateway", + "status": "available", + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [ + "yair" + ] + }, + { + "created_at": "2024-06-25T12:21:16.000Z", + "crn": "crn:65", + "floating_ip": { + "address": "169.47.95.195", + "crn": "crn:126", + "href": "href:127", + "id": "id:128", + "name": "public-gw2" + }, + "href": "href:66", + "id": "id:67", + "name": "public-gw2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "public_gateway", + "status": "available", + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + }, + "tags": [ + "yair" + ] + } + ], + "floating_ips": [ + { + "address": "52.118.146.248", + "created_at": "2024-06-25T12:21:16.000Z", + "crn": "crn:123", + "href": "href:124", + "id": "id:125", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:47", + "id": "id:48", + "name": "public-gw1", + "resource_type": "public_gateway", + "crn": "crn:46" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + }, + { + "address": "169.47.95.195", + "created_at": "2024-06-25T12:21:16.000Z", + "crn": "crn:126", + "href": "href:127", + "id": "id:128", + "name": "public-gw2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:66", + "id": "id:67", + "name": "public-gw2", + "resource_type": "public_gateway", + "crn": "crn:65" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": null, + "crn": "fake:crn:4", + "href": "fake:href:4", + "id": "fake:id:4", + "name": "testacl5-vpc--sub1-1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "fake:href:31", + "id": "fake:id:31", + "name": "rule1" + }, + "created_at": null, + "destination": "2.2.2.1/32", + "direction": "outbound", + "href": "fake:href:32", + "id": "fake:id:32", + "ip_version": "ipv4", + "name": "rule0", + "source": "10.240.1.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "fake:href:11", + "id": "fake:id:11", + "name": "rule21" + }, + "created_at": null, + "destination": "1.1.1.0/32", + "direction": "outbound", + "href": "fake:href:12", + "id": "fake:id:12", + "ip_version": "ipv4", + "name": "rule20", + "source": "10.240.1.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "fake:href:9", + "id": "fake:id:9", + "name": "rule23" + }, + "created_at": null, + "destination": "1.1.1.0/31", + "direction": "outbound", + "href": "fake:href:10", + "id": "fake:id:10", + "ip_version": "ipv4", + "name": "rule22", + "source": "10.240.1.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "fake:href:7", + "id": "fake:id:7", + "name": "rule25" + }, + "created_at": null, + "destination": "2.2.2.0/32", + "direction": "outbound", + "href": "fake:href:8", + "id": "fake:id:8", + "ip_version": "ipv4", + "name": "rule24", + "source": "10.240.1.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "fake:href:5", + "id": "fake:id:5", + "name": "rule27" + }, + "created_at": null, + "destination": "2.2.2.2/31", + "direction": "outbound", + "href": "fake:href:6", + "id": "fake:id:6", + "ip_version": "ipv4", + "name": "rule26", + "source": "10.240.1.0/24", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:40", + "href": "href:41", + "id": "id:42", + "name": "sub1-1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-06-25T12:21:16.000Z", + "crn": "crn:185", + "href": "href:186", + "id": "id:187", + "name": "sg1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:188", + "id": "id:189", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "inbound", + "href": "href:190", + "id": "id:191", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T12:20:45.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "elevation-lyricist-elf-hassle", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:192", + "id": "id:193", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "inbound", + "href": "href:194", + "id": "id:195", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "elevation-lyricist-elf-hassle" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [], + "instances": [], + "virtual_nis": null, + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-06-25T12:20:45.000Z", + "crn": null, + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "traffic-overeasy-festoonery-illusive", + "resource_group": null, + "resource_type": "routing_table", + "route_direct_link_ingress": false, + "route_internet_ingress": false, + "route_transit_gateway_ingress": false, + "route_vpc_zone_ingress": false, + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "sub1-2", + "resource_type": "subnet" + }, + { + "crn": "crn:40", + "href": "href:41", + "id": "id:42", + "name": "sub1-1", + "resource_type": "subnet" + }, + { + "crn": "crn:59", + "href": "href:60", + "id": "id:61", + "name": "sub2-1", + "resource_type": "subnet" + }, + { + "crn": "crn:78", + "href": "href:79", + "id": "id:80", + "name": "sub1-3", + "resource_type": "subnet" + }, + { + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "sub2-2", + "resource_type": "subnet" + }, + { + "crn": "crn:107", + "href": "href:108", + "id": "id:109", + "name": "sub3-1", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "testacl5-vpc", + "resource_type": "vpc" + } + } + ], + "load_balancers": [], + "transit_connections": null, + "transit_gateways": null, + "iks_clusters": [] +} \ No newline at end of file diff --git a/test/data/optimize_acl_anyProtocol/conn_spec.json b/test/data/optimize_acl_anyProtocol/conn_spec.json new file mode 100644 index 00000000..8ba749bc --- /dev/null +++ b/test/data/optimize_acl_anyProtocol/conn_spec.json @@ -0,0 +1,60 @@ +{ + "externals": { + "e1": "1.1.1.0/32", + "e2": "1.1.1.0/31", + "e3": "2.2.2.0/32", + "e4": "2.2.2.2/31" + }, + "required-connections": [ + { + "src": { + "name": "sub1-1", + "type": "subnet" + }, + "dst": { + "name": "e1", + "type": "external" + } + }, + { + "src": { + "name": "sub1-1", + "type": "subnet" + }, + "dst": { + "name": "e2", + "type": "external" + } + }, + { + "src": { + "name": "sub1-1", + "type": "subnet" + }, + "dst": { + "name": "e3", + "type": "external" + } + }, + { + "src": { + "name": "sub1-1", + "type": "subnet" + }, + "dst": { + "name": "sub1-2", + "type": "subnet" + } + }, + { + "src": { + "name": "sub1-1", + "type": "subnet" + }, + "dst": { + "name": "e4", + "type": "external" + } + } + ] +} \ No newline at end of file diff --git a/test/data/optimize_acl_anyProtocol/details.txt b/test/data/optimize_acl_anyProtocol/details.txt new file mode 100644 index 00000000..7f049fee --- /dev/null +++ b/test/data/optimize_acl_anyProtocol/details.txt @@ -0,0 +1,16 @@ +original config object: acl_testing5 config +please note that the generated config object has been changed! + +######## BEFORE ######## + +sub1-1 --> 1.1.1.0/32 +sub1-1 --> 1.1.1.0/31 + +sub1-1 --> 2.2.2.0/32 +sub1-1 --> sub1-2 (2.2.2.1/32) +sub1-1 --> 2.2.2.2/31 + +######## AFTER ######## + +sub1-1 --> 1.1.1.0/31 +sub1-1 --> 2.2.2.0/30 diff --git a/test/expected/acl_protocols_csv/nacl_expected.csv b/test/expected/acl_protocols_csv/nacl_expected.csv index 9408a3b9..1d327800 100644 --- a/test/expected/acl_protocols_csv/nacl_expected.csv +++ b/test/expected/acl_protocols_csv/nacl_expected.csv @@ -1,30 +1,30 @@ Acl,Subnet,Direction,Rule priority,Allow or deny,Source,Destination,Protocol,Value,Description -test-vpc0/subnet0,test-vpc0/subnet0,Outbound,1,Allow,"10.240.0.0/24, any port","10.240.1.0/24, any port",TCP,-,Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] -test-vpc0/subnet0,test-vpc0/subnet0,Inbound,2,Allow,"10.240.1.0/24, any port","10.240.0.0/24, any port",TCP,-,Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] +test-vpc0/subnet0,test-vpc0/subnet0,Outbound,1,Allow,"10.240.0.0/24, src ports: any port","10.240.1.0/24, dst ports: any port",TCP,-,Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] +test-vpc0/subnet0,test-vpc0/subnet0,Inbound,2,Allow,"10.240.1.0/24, src ports: any port","10.240.0.0/24, dst ports: any port",TCP,-,Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] test-vpc0/subnet0,test-vpc0/subnet0,Outbound,3,Allow,10.240.0.0/24,10.240.1.0/24,ICMP,"Type: Any, Code: Any",Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] test-vpc0/subnet0,test-vpc0/subnet0,Inbound,4,Allow,10.240.1.0/24,10.240.0.0/24,ICMP,"Type: Any, Code: Any",Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] test-vpc0/subnet0,test-vpc0/subnet0,Outbound,5,Allow,10.240.0.0/24,10.240.9.0/24,ALL,-,Internal. required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] test-vpc0/subnet0,test-vpc0/subnet0,Inbound,6,Allow,10.240.9.0/24,10.240.0.0/24,ALL,-,Internal. response to required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] -test-vpc0/subnet1,test-vpc0/subnet1,Inbound,1,Allow,"10.240.0.0/24, any port","10.240.1.0/24, any port",TCP,-,Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] -test-vpc0/subnet1,test-vpc0/subnet1,Outbound,2,Allow,"10.240.1.0/24, any port","10.240.0.0/24, any port",TCP,-,Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] +test-vpc0/subnet1,test-vpc0/subnet1,Inbound,1,Allow,"10.240.0.0/24, src ports: any port","10.240.1.0/24, dst ports: any port",TCP,-,Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] +test-vpc0/subnet1,test-vpc0/subnet1,Outbound,2,Allow,"10.240.1.0/24, src ports: any port","10.240.0.0/24, dst ports: any port",TCP,-,Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] test-vpc0/subnet1,test-vpc0/subnet1,Inbound,3,Allow,10.240.0.0/24,10.240.1.0/24,ICMP,"Type: Any, Code: Any",Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] test-vpc0/subnet1,test-vpc0/subnet1,Outbound,4,Allow,10.240.1.0/24,10.240.0.0/24,ICMP,"Type: Any, Code: Any",Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] -test-vpc0/subnet2,test-vpc0/subnet2,Outbound,1,Allow,"10.240.4.0/24, any port","10.240.5.0/24, ports 8080-8080",TCP,-,Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] -test-vpc0/subnet2,test-vpc0/subnet2,Inbound,2,Allow,"10.240.5.0/24, ports 8080-8080","10.240.4.0/24, any port",TCP,-,Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] +test-vpc0/subnet2,test-vpc0/subnet2,Outbound,1,Allow,"10.240.4.0/24, src ports: any port","10.240.5.0/24, dst ports: ports 8080-8080",TCP,-,Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] +test-vpc0/subnet2,test-vpc0/subnet2,Inbound,2,Allow,"10.240.5.0/24, src ports: ports 8080-8080","10.240.4.0/24, dst ports: any port",TCP,-,Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] test-vpc0/subnet2,test-vpc0/subnet2,Outbound,3,Allow,10.240.4.0/24,10.240.5.0/24,ICMP,"Type: 3, Code: 2",Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[1] -test-vpc0/subnet3,test-vpc0/subnet3,Inbound,1,Allow,"10.240.4.0/24, any port","10.240.5.0/24, ports 8080-8080",TCP,-,Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] -test-vpc0/subnet3,test-vpc0/subnet3,Outbound,2,Allow,"10.240.5.0/24, ports 8080-8080","10.240.4.0/24, any port",TCP,-,Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] +test-vpc0/subnet3,test-vpc0/subnet3,Inbound,1,Allow,"10.240.4.0/24, src ports: any port","10.240.5.0/24, dst ports: ports 8080-8080",TCP,-,Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] +test-vpc0/subnet3,test-vpc0/subnet3,Outbound,2,Allow,"10.240.5.0/24, src ports: ports 8080-8080","10.240.4.0/24, dst ports: any port",TCP,-,Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] test-vpc0/subnet3,test-vpc0/subnet3,Inbound,3,Allow,10.240.4.0/24,10.240.5.0/24,ICMP,"Type: 3, Code: 2",Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[1] test-vpc0/subnet4,test-vpc0/subnet4,Outbound,1,Allow,10.240.8.0/24,10.240.9.0/24,ICMP,"Type: 15, Code: Any",Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] test-vpc0/subnet4,test-vpc0/subnet4,Inbound,2,Allow,10.240.9.0/24,10.240.8.0/24,ICMP,"Type: 16, Code: Any",Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] -test-vpc0/subnet4,test-vpc0/subnet4,Outbound,3,Allow,"10.240.8.0/24, any port","10.240.9.0/24, any port",UDP,-,Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] +test-vpc0/subnet4,test-vpc0/subnet4,Outbound,3,Allow,"10.240.8.0/24, src ports: any port","10.240.9.0/24, dst ports: any port",UDP,-,Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] test-vpc0/subnet5,test-vpc0/subnet5,Inbound,1,Allow,10.240.8.0/24,10.240.9.0/24,ICMP,"Type: 15, Code: Any",Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] test-vpc0/subnet5,test-vpc0/subnet5,Outbound,2,Allow,10.240.9.0/24,10.240.8.0/24,ICMP,"Type: 16, Code: Any",Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] -test-vpc0/subnet5,test-vpc0/subnet5,Inbound,3,Allow,"10.240.8.0/24, any port","10.240.9.0/24, any port",UDP,-,Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] +test-vpc0/subnet5,test-vpc0/subnet5,Inbound,3,Allow,"10.240.8.0/24, src ports: any port","10.240.9.0/24, dst ports: any port",UDP,-,Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] test-vpc0/subnet5,test-vpc0/subnet5,Inbound,4,Allow,10.240.0.0/24,10.240.9.0/24,ALL,-,Internal. required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] test-vpc0/subnet5,test-vpc0/subnet5,Outbound,5,Allow,10.240.9.0/24,10.240.0.0/24,ALL,-,Internal. response to required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] -test-vpc1/subnet10,test-vpc1/subnet10,Outbound,1,Allow,"10.240.64.0/24, any port","10.240.80.0/24, ports 53-53",UDP,-,Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] -test-vpc1/subnet11,test-vpc1/subnet11,Inbound,1,Allow,"10.240.64.0/24, any port","10.240.80.0/24, ports 53-53",UDP,-,Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] +test-vpc1/subnet10,test-vpc1/subnet10,Outbound,1,Allow,"10.240.64.0/24, src ports: any port","10.240.80.0/24, dst ports: ports 53-53",UDP,-,Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] +test-vpc1/subnet11,test-vpc1/subnet11,Inbound,1,Allow,"10.240.64.0/24, src ports: any port","10.240.80.0/24, dst ports: ports 53-53",UDP,-,Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] test-vpc2/subnet20,test-vpc2/subnet20,Inbound,1,Deny,Any IP,10.240.128.0/24,ALL,-,Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections test-vpc2/subnet20,test-vpc2/subnet20,Outbound,2,Deny,10.240.128.0/24,Any IP,ALL,-,Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections test-vpc3/subnet30,test-vpc3/subnet30,Inbound,1,Deny,Any IP,10.240.192.0/24,ALL,-,Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections diff --git a/test/expected/acl_protocols_md/nacl_expected.md b/test/expected/acl_protocols_md/nacl_expected.md index caf6f035..3faea2f9 100644 --- a/test/expected/acl_protocols_md/nacl_expected.md +++ b/test/expected/acl_protocols_md/nacl_expected.md @@ -1,31 +1,31 @@ | Acl | Subnet | Direction | Rule priority | Allow or deny | Source | Destination | Protocol | Value | Description | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | - | test-vpc0/subnet0 | test-vpc0/subnet0 | Outbound | 1 | Allow | 10.240.0.0/24, any port | 10.240.1.0/24, any port | TCP | - | Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] | - | test-vpc0/subnet0 | test-vpc0/subnet0 | Inbound | 2 | Allow | 10.240.1.0/24, any port | 10.240.0.0/24, any port | TCP | - | Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] | + | test-vpc0/subnet0 | test-vpc0/subnet0 | Outbound | 1 | Allow | 10.240.0.0/24, src ports: any port | 10.240.1.0/24, dst ports: any port | TCP | - | Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] | + | test-vpc0/subnet0 | test-vpc0/subnet0 | Inbound | 2 | Allow | 10.240.1.0/24, src ports: any port | 10.240.0.0/24, dst ports: any port | TCP | - | Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] | | test-vpc0/subnet0 | test-vpc0/subnet0 | Outbound | 3 | Allow | 10.240.0.0/24 | 10.240.1.0/24 | ICMP | Type: Any, Code: Any | Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] | | test-vpc0/subnet0 | test-vpc0/subnet0 | Inbound | 4 | Allow | 10.240.1.0/24 | 10.240.0.0/24 | ICMP | Type: Any, Code: Any | Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] | | test-vpc0/subnet0 | test-vpc0/subnet0 | Outbound | 5 | Allow | 10.240.0.0/24 | 10.240.9.0/24 | ALL | - | Internal. required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] | | test-vpc0/subnet0 | test-vpc0/subnet0 | Inbound | 6 | Allow | 10.240.9.0/24 | 10.240.0.0/24 | ALL | - | Internal. response to required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] | - | test-vpc0/subnet1 | test-vpc0/subnet1 | Inbound | 1 | Allow | 10.240.0.0/24, any port | 10.240.1.0/24, any port | TCP | - | Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] | - | test-vpc0/subnet1 | test-vpc0/subnet1 | Outbound | 2 | Allow | 10.240.1.0/24, any port | 10.240.0.0/24, any port | TCP | - | Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] | + | test-vpc0/subnet1 | test-vpc0/subnet1 | Inbound | 1 | Allow | 10.240.0.0/24, src ports: any port | 10.240.1.0/24, dst ports: any port | TCP | - | Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] | + | test-vpc0/subnet1 | test-vpc0/subnet1 | Outbound | 2 | Allow | 10.240.1.0/24, src ports: any port | 10.240.0.0/24, dst ports: any port | TCP | - | Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] | | test-vpc0/subnet1 | test-vpc0/subnet1 | Inbound | 3 | Allow | 10.240.0.0/24 | 10.240.1.0/24 | ICMP | Type: Any, Code: Any | Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] | | test-vpc0/subnet1 | test-vpc0/subnet1 | Outbound | 4 | Allow | 10.240.1.0/24 | 10.240.0.0/24 | ICMP | Type: Any, Code: Any | Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] | - | test-vpc0/subnet2 | test-vpc0/subnet2 | Outbound | 1 | Allow | 10.240.4.0/24, any port | 10.240.5.0/24, ports 8080-8080 | TCP | - | Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] | - | test-vpc0/subnet2 | test-vpc0/subnet2 | Inbound | 2 | Allow | 10.240.5.0/24, ports 8080-8080 | 10.240.4.0/24, any port | TCP | - | Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] | + | test-vpc0/subnet2 | test-vpc0/subnet2 | Outbound | 1 | Allow | 10.240.4.0/24, src ports: any port | 10.240.5.0/24, dst ports: ports 8080-8080 | TCP | - | Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] | + | test-vpc0/subnet2 | test-vpc0/subnet2 | Inbound | 2 | Allow | 10.240.5.0/24, src ports: ports 8080-8080 | 10.240.4.0/24, dst ports: any port | TCP | - | Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] | | test-vpc0/subnet2 | test-vpc0/subnet2 | Outbound | 3 | Allow | 10.240.4.0/24 | 10.240.5.0/24 | ICMP | Type: 3, Code: 2 | Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[1] | - | test-vpc0/subnet3 | test-vpc0/subnet3 | Inbound | 1 | Allow | 10.240.4.0/24, any port | 10.240.5.0/24, ports 8080-8080 | TCP | - | Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] | - | test-vpc0/subnet3 | test-vpc0/subnet3 | Outbound | 2 | Allow | 10.240.5.0/24, ports 8080-8080 | 10.240.4.0/24, any port | TCP | - | Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] | + | test-vpc0/subnet3 | test-vpc0/subnet3 | Inbound | 1 | Allow | 10.240.4.0/24, src ports: any port | 10.240.5.0/24, dst ports: ports 8080-8080 | TCP | - | Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] | + | test-vpc0/subnet3 | test-vpc0/subnet3 | Outbound | 2 | Allow | 10.240.5.0/24, src ports: ports 8080-8080 | 10.240.4.0/24, dst ports: any port | TCP | - | Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] | | test-vpc0/subnet3 | test-vpc0/subnet3 | Inbound | 3 | Allow | 10.240.4.0/24 | 10.240.5.0/24 | ICMP | Type: 3, Code: 2 | Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[1] | | test-vpc0/subnet4 | test-vpc0/subnet4 | Outbound | 1 | Allow | 10.240.8.0/24 | 10.240.9.0/24 | ICMP | Type: 15, Code: Any | Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] | | test-vpc0/subnet4 | test-vpc0/subnet4 | Inbound | 2 | Allow | 10.240.9.0/24 | 10.240.8.0/24 | ICMP | Type: 16, Code: Any | Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] | - | test-vpc0/subnet4 | test-vpc0/subnet4 | Outbound | 3 | Allow | 10.240.8.0/24, any port | 10.240.9.0/24, any port | UDP | - | Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] | + | test-vpc0/subnet4 | test-vpc0/subnet4 | Outbound | 3 | Allow | 10.240.8.0/24, src ports: any port | 10.240.9.0/24, dst ports: any port | UDP | - | Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] | | test-vpc0/subnet5 | test-vpc0/subnet5 | Inbound | 1 | Allow | 10.240.8.0/24 | 10.240.9.0/24 | ICMP | Type: 15, Code: Any | Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] | | test-vpc0/subnet5 | test-vpc0/subnet5 | Outbound | 2 | Allow | 10.240.9.0/24 | 10.240.8.0/24 | ICMP | Type: 16, Code: Any | Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] | - | test-vpc0/subnet5 | test-vpc0/subnet5 | Inbound | 3 | Allow | 10.240.8.0/24, any port | 10.240.9.0/24, any port | UDP | - | Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] | + | test-vpc0/subnet5 | test-vpc0/subnet5 | Inbound | 3 | Allow | 10.240.8.0/24, src ports: any port | 10.240.9.0/24, dst ports: any port | UDP | - | Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] | | test-vpc0/subnet5 | test-vpc0/subnet5 | Inbound | 4 | Allow | 10.240.0.0/24 | 10.240.9.0/24 | ALL | - | Internal. required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] | | test-vpc0/subnet5 | test-vpc0/subnet5 | Outbound | 5 | Allow | 10.240.9.0/24 | 10.240.0.0/24 | ALL | - | Internal. response to required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] | - | test-vpc1/subnet10 | test-vpc1/subnet10 | Outbound | 1 | Allow | 10.240.64.0/24, any port | 10.240.80.0/24, ports 53-53 | UDP | - | Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] | - | test-vpc1/subnet11 | test-vpc1/subnet11 | Inbound | 1 | Allow | 10.240.64.0/24, any port | 10.240.80.0/24, ports 53-53 | UDP | - | Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] | + | test-vpc1/subnet10 | test-vpc1/subnet10 | Outbound | 1 | Allow | 10.240.64.0/24, src ports: any port | 10.240.80.0/24, dst ports: ports 53-53 | UDP | - | Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] | + | test-vpc1/subnet11 | test-vpc1/subnet11 | Inbound | 1 | Allow | 10.240.64.0/24, src ports: any port | 10.240.80.0/24, dst ports: ports 53-53 | UDP | - | Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] | | test-vpc2/subnet20 | test-vpc2/subnet20 | Inbound | 1 | Deny | Any IP | 10.240.128.0/24 | ALL | - | Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections | | test-vpc2/subnet20 | test-vpc2/subnet20 | Outbound | 2 | Deny | 10.240.128.0/24 | Any IP | ALL | - | Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections | | test-vpc3/subnet30 | test-vpc3/subnet30 | Inbound | 1 | Deny | Any IP | 10.240.192.0/24 | ALL | - | Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections | diff --git a/test/expected/optimize_acl_anyProtocol_tf/nacl_expected.tf b/test/expected/optimize_acl_anyProtocol_tf/nacl_expected.tf new file mode 100644 index 00000000..7592c7b4 --- /dev/null +++ b/test/expected/optimize_acl_anyProtocol_tf/nacl_expected.tf @@ -0,0 +1,20 @@ +# Attached subnets: sub1-1 +resource "ibm_is_network_acl" "testacl5-vpc--sub1-1" { + name = "testacl5-vpc--sub1-1" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_testacl5-vpc_id + rules { + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" + destination = "1.1.1.0/31" + } + rules { + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" + destination = "2.2.2.0/30" + } +} diff --git a/test/expected/optimize_acl_csv/nacl_expected.csv b/test/expected/optimize_acl_csv/nacl_expected.csv index c5162b13..c8d9def5 100644 --- a/test/expected/optimize_acl_csv/nacl_expected.csv +++ b/test/expected/optimize_acl_csv/nacl_expected.csv @@ -1,29 +1,16 @@ Acl,Subnet,Direction,Rule priority,Allow or deny,Source,Destination,Protocol,Value,Description -acl1-1,sub1-1,Inbound,1,Allow,"8.8.8.8, ports 53-53","10.240.1.0/24, any port",UDP,-, -acl1-1,sub1-1,Inbound,2,Allow,"10.240.2.0/23, any port","10.240.1.0/24, any port",TCP,-, -acl1-1,sub1-1,Inbound,3,Allow,10.240.128.0/24,10.240.1.0/24,ICMP,"Type: 0, Code: 0", -acl1-1,sub1-1,Outbound,4,Allow,"10.240.1.0/24, any port","8.8.8.8, ports 53-53",UDP,-, -acl1-1,sub1-1,Outbound,5,Allow,"10.240.1.0/24, any port","10.240.2.0/23, any port",TCP,-, -acl1-1,sub1-1,Outbound,6,Allow,10.240.1.0/24,10.240.128.0/24,ICMP,"Type: 0, Code: 0", -acl1-2,"sub1-2, sub1-3",Inbound,1,Allow,"10.240.1.0/24, any port","10.240.2.0/23, any port",TCP,-, -acl1-2,"sub1-2, sub1-3",Inbound,2,Allow,"10.240.2.0/23, any port","10.240.2.0/23, any port",TCP,-, -acl1-2,"sub1-2, sub1-3",Outbound,3,Allow,"10.240.2.0/23, any port","10.240.1.0/24, any port",TCP,-, -acl1-2,"sub1-2, sub1-3",Outbound,4,Allow,"10.240.2.0/23, any port","10.240.2.0/23, any port",TCP,-, -acl2-1,sub2-1,Inbound,1,Allow,"8.8.8.8, ports 53-53","10.240.64.0/24, any port",UDP,-, -acl2-1,sub2-1,Inbound,2,Allow,10.240.65.0/24,10.240.64.0/24,ALL,-, -acl2-1,sub2-1,Inbound,3,Allow,"10.240.128.0/24, any port","10.240.64.0/24, ports 443-443",TCP,-, -acl2-1,sub2-1,Inbound,4,Allow,10.240.128.0/24,10.240.64.0/24,ICMP,"Type: 0, Code: 0", -acl2-1,sub2-1,Outbound,5,Allow,"10.240.64.0/24, any port","8.8.8.8, ports 53-53",UDP,-, -acl2-1,sub2-1,Outbound,6,Allow,10.240.64.0/24,10.240.65.0/24,ALL,-, -acl2-1,sub2-1,Outbound,7,Allow,"10.240.64.0/24, ports 443-443","10.240.128.0/24, any port",TCP,-, -acl2-1,sub2-1,Outbound,8,Allow,10.240.64.0/24,10.240.128.0/24,ICMP,"Type: 0, Code: 0", -acl2-2,sub2-2,Inbound,1,Allow,10.240.64.0/24,10.240.65.0/24,ALL,-, -acl2-2,sub2-2,Outbound,2,Allow,10.240.65.0/24,10.240.64.0/24,ALL,-, -acl3-1,sub3-1,Inbound,1,Allow,"10.240.64.0/24, ports 443-443","10.240.128.0/24, any port",TCP,-, -acl3-1,sub3-1,Inbound,2,Allow,10.240.64.0/24,10.240.128.0/24,ICMP,"Type: 0, Code: 0", -acl3-1,sub3-1,Inbound,3,Allow,10.240.1.0/24,10.240.128.0/24,ICMP,"Type: 0, Code: 0", -acl3-1,sub3-1,Outbound,4,Allow,"10.240.128.0/24, any port","10.240.64.0/24, ports 443-443",TCP,-, -acl3-1,sub3-1,Outbound,5,Allow,10.240.128.0/24,10.240.64.0/24,ICMP,"Type: 0, Code: 0", -acl3-1,sub3-1,Outbound,6,Allow,10.240.128.0/24,10.240.1.0/24,ICMP,"Type: 0, Code: 0", -disallow-laborious-compress-abiding,,Inbound,1,Allow,Any IP,Any IP,ALL,-, -disallow-laborious-compress-abiding,,Outbound,2,Allow,Any IP,Any IP,ALL,-, +testacl5-vpc--sub1-1,sub1-1,Outbound,1,Allow,"10.240.1.0/24, src ports: any port","1.1.1.0, dst ports: any port",TCP,-, +testacl5-vpc--sub1-1,sub1-1,Outbound,2,Allow,"10.240.1.0/24, src ports: any port","1.1.1.1, dst ports: any port",TCP,-, +testacl5-vpc--sub1-2,sub1-2,Outbound,1,Allow,"10.240.2.0/24, src ports: any port","2.2.2.2, dst ports: ports 1-20",UDP,-, +testacl5-vpc--sub1-3,sub1-3,Outbound,1,Allow,"10.240.3.0/24, src ports: any port","10.240.64.0/24, dst ports: any port",TCP,-, +testacl5-vpc--sub1-3,sub1-3,Outbound,2,Allow,"10.240.3.0/24, src ports: any port","10.240.64.0/24, dst ports: any port",UDP,-, +testacl5-vpc--sub1-3,sub1-3,Outbound,3,Allow,10.240.3.0/24,10.240.64.0/24,ICMP,"Type: Any, Code: Any", +testacl5-vpc--sub2-1,sub2-1,Inbound,1,Allow,"10.240.3.0/24, src ports: any port","10.240.64.0/24, dst ports: any port",TCP,-, +testacl5-vpc--sub2-1,sub2-1,Inbound,2,Allow,"10.240.3.0/24, src ports: any port","10.240.64.0/24, dst ports: any port",UDP,-, +testacl5-vpc--sub2-1,sub2-1,Inbound,3,Allow,10.240.3.0/24,10.240.64.0/24,ICMP,"Type: Any, Code: Any", +testacl5-vpc--sub2-2,sub2-2,Outbound,1,Deny,"10.240.65.0/24, src ports: ports 1-10","10.240.128.0/24, dst ports: any port",TCP,-, +testacl5-vpc--sub2-2,sub2-2,Outbound,2,Allow,"10.240.65.0/24, src ports: ports 5-15","10.240.128.0/24, dst ports: any port",TCP,-, +testacl5-vpc--sub2-2,sub2-2,Outbound,3,Allow,"10.240.65.0/24, src ports: ports 16-20","10.240.128.0/24, dst ports: any port",TCP,-, +testacl5-vpc--sub3-1,sub3-1,Inbound,1,Deny,"10.240.65.0/24, src ports: ports 1-10","10.240.128.0/24, dst ports: any port",TCP,-, +testacl5-vpc--sub3-1,sub3-1,Inbound,2,Allow,"10.240.65.0/24, src ports: ports 5-15","10.240.128.0/24, dst ports: any port",TCP,-, +testacl5-vpc--sub3-1,sub3-1,Inbound,3,Allow,"10.240.65.0/24, src ports: ports 16-20","10.240.128.0/24, dst ports: any port",TCP,-, diff --git a/test/expected/optimize_acl_json/nacl_expected.json b/test/expected/optimize_acl_json/nacl_expected.json index 6f87cea4..f3667edc 100644 --- a/test/expected/optimize_acl_json/nacl_expected.json +++ b/test/expected/optimize_acl_json/nacl_expected.json @@ -140,10 +140,10 @@ "ipv4_cidr_block": "10.240.2.0/24", "name": "sub1-2", "network_acl": { - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1-2" + "crn": "fake:crn:1", + "href": "fake:href:1", + "id": "fake:id:1", + "name": "testacl5-vpc--sub1-2" }, "resource_group": { "href": "href:16", @@ -242,10 +242,10 @@ "ipv4_cidr_block": "10.240.1.0/24", "name": "sub1-1", "network_acl": { - "crn": "crn:43", - "href": "href:44", - "id": "id:45", - "name": "acl1-1" + "crn": "fake:crn:23", + "href": "fake:href:23", + "id": "fake:id:23", + "name": "testacl5-vpc--sub1-1" }, "public_gateway": { "crn": "crn:46", @@ -351,10 +351,10 @@ "ipv4_cidr_block": "10.240.64.0/24", "name": "sub2-1", "network_acl": { - "crn": "crn:62", - "href": "href:63", - "id": "id:64", - "name": "acl2-1" + "crn": "fake:crn:46", + "href": "fake:href:46", + "id": "fake:id:46", + "name": "testacl5-vpc--sub2-1" }, "public_gateway": { "crn": "crn:65", @@ -460,10 +460,10 @@ "ipv4_cidr_block": "10.240.3.0/24", "name": "sub1-3", "network_acl": { - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1-2" + "crn": "fake:crn:52", + "href": "fake:href:52", + "id": "fake:id:52", + "name": "testacl5-vpc--sub1-3" }, "resource_group": { "href": "href:16", @@ -562,10 +562,10 @@ "ipv4_cidr_block": "10.240.65.0/24", "name": "sub2-2", "network_acl": { - "crn": "crn:94", - "href": "href:95", - "id": "id:96", - "name": "acl2-2" + "crn": "fake:crn:58", + "href": "fake:href:58", + "id": "fake:id:58", + "name": "testacl5-vpc--sub2-2" }, "public_gateway": { "crn": "crn:65", @@ -671,10 +671,10 @@ "ipv4_cidr_block": "10.240.128.0/24", "name": "sub3-1", "network_acl": { - "crn": "crn:110", - "href": "href:111", - "id": "id:112", - "name": "acl3-1" + "crn": "fake:crn:61", + "href": "fake:href:61", + "id": "fake:id:61", + "name": "testacl5-vpc--sub3-1" }, "resource_group": { "href": "href:16", @@ -892,11 +892,11 @@ ], "network_acls": [ { - "created_at": "2024-06-25T12:21:16.000Z", - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1-2", + "created_at": null, + "crn": "fake:crn:1", + "href": "fake:href:1", + "id": "fake:id:1", + "name": "testacl5-vpc--sub1-2", "resource_group": { "href": "href:16", "id": "id:17", @@ -905,80 +905,17 @@ "rules": [ { "action": "allow", - "before": { - "href": "href:131", - "id": "id:132", - "name": "o2" - }, - "created_at": "2024-06-25T12:21:16.000Z", - "destination": "10.240.1.0/24", + "created_at": null, + "destination": "2.2.2.2/32", "direction": "outbound", - "href": "href:129", - "id": "id:130", - "ip_version": "ipv4", - "name": "o1", - "source": "10.240.2.0/23", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 65535, - "source_port_min": 1 - }, - { - "action": "allow", - "before": { - "href": "href:133", - "id": "id:134", - "name": "i1" - }, - "created_at": "2024-06-25T12:21:17.000Z", - "destination": "10.240.2.0/23", - "direction": "outbound", - "href": "href:131", - "id": "id:132", - "ip_version": "ipv4", - "name": "o2", - "source": "10.240.2.0/23", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 65535, - "source_port_min": 1 - }, - { - "action": "allow", - "before": { - "href": "href:135", - "id": "id:136", - "name": "i2" - }, - "created_at": "2024-06-25T12:21:17.000Z", - "destination": "10.240.2.0/23", - "direction": "inbound", - "href": "href:133", - "id": "id:134", + "href": "fake:href:1", + "id": "fake:id:1", "ip_version": "ipv4", - "name": "i1", - "source": "10.240.1.0/24", - "destination_port_max": 65535, + "name": "rule0", + "source": "10.240.2.0/24", + "destination_port_max": 20, "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 65535, - "source_port_min": 1 - }, - { - "action": "allow", - "created_at": "2024-06-25T12:21:18.000Z", - "destination": "10.240.2.0/23", - "direction": "inbound", - "href": "href:135", - "id": "id:136", - "ip_version": "ipv4", - "name": "i2", - "source": "10.240.2.0/23", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", + "protocol": "udp", "source_port_max": 65535, "source_port_min": 1 } @@ -990,13 +927,6 @@ "id": "id:26", "name": "sub1-2", "resource_type": "subnet" - }, - { - "crn": "crn:78", - "href": "href:79", - "id": "id:80", - "name": "sub1-3", - "resource_type": "subnet" } ], "vpc": { @@ -1009,11 +939,11 @@ "tags": [] }, { - "created_at": "2024-06-25T12:21:15.000Z", - "crn": "crn:94", - "href": "href:95", - "id": "id:96", - "name": "acl2-2", + "created_at": null, + "crn": "fake:crn:23", + "href": "fake:href:23", + "id": "fake:id:23", + "name": "testacl5-vpc--sub1-1", "resource_group": { "href": "href:16", "id": "id:17", @@ -1022,40 +952,27 @@ "rules": [ { "action": "allow", - "before": { - "href": "href:139", - "id": "id:140", - "name": "i1" - }, - "created_at": "2024-06-25T12:21:16.000Z", - "destination": "10.240.64.0/24", + "created_at": null, + "destination": "1.1.1.0/31", "direction": "outbound", - "href": "href:137", - "id": "id:138", + "href": "fake:href:2", + "id": "fake:id:2", "ip_version": "ipv4", - "name": "o1", - "source": "10.240.65.0/24", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T12:21:16.000Z", - "destination": "10.240.65.0/24", - "direction": "inbound", - "href": "href:139", - "id": "id:140", - "ip_version": "ipv4", - "name": "i1", - "source": "10.240.64.0/24", - "protocol": "all" + "name": "rule0", + "source": "10.240.1.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 } ], "subnets": [ { - "crn": "crn:91", - "href": "href:92", - "id": "id:93", - "name": "sub2-2", + "crn": "crn:40", + "href": "href:41", + "id": "id:42", + "name": "sub1-1", "resource_type": "subnet" } ], @@ -1069,11 +986,11 @@ "tags": [] }, { - "created_at": "2024-06-25T12:21:15.000Z", - "crn": "crn:110", - "href": "href:111", - "id": "id:112", - "name": "acl3-1", + "created_at": null, + "crn": "fake:crn:46", + "href": "fake:href:46", + "id": "fake:id:46", + "name": "testacl5-vpc--sub2-1", "resource_group": { "href": "href:16", "id": "id:17", @@ -1082,124 +999,23 @@ "rules": [ { "action": "allow", - "before": { - "href": "href:143", - "id": "id:144", - "name": "o2" - }, - "created_at": "2024-06-25T12:21:16.000Z", + "created_at": null, "destination": "10.240.64.0/24", - "direction": "outbound", - "href": "href:141", - "id": "id:142", - "ip_version": "ipv4", - "name": "o1", - "source": "10.240.128.0/24", - "destination_port_max": 443, - "destination_port_min": 443, - "protocol": "tcp", - "source_port_max": 65535, - "source_port_min": 1 - }, - { - "action": "allow", - "before": { - "href": "href:145", - "id": "id:146", - "name": "o3" - }, - "created_at": "2024-06-25T12:21:17.000Z", - "destination": "10.240.64.0/24", - "direction": "outbound", - "href": "href:143", - "id": "id:144", - "ip_version": "ipv4", - "name": "o2", - "source": "10.240.128.0/24", - "code": 0, - "protocol": "icmp", - "type": 0 - }, - { - "action": "allow", - "before": { - "href": "href:147", - "id": "id:148", - "name": "i1" - }, - "created_at": "2024-06-25T12:21:17.000Z", - "destination": "10.240.1.0/24", - "direction": "outbound", - "href": "href:145", - "id": "id:146", - "ip_version": "ipv4", - "name": "o3", - "source": "10.240.128.0/24", - "code": 0, - "protocol": "icmp", - "type": 0 - }, - { - "action": "allow", - "before": { - "href": "href:149", - "id": "id:150", - "name": "i2" - }, - "created_at": "2024-06-25T12:21:18.000Z", - "destination": "10.240.128.0/24", "direction": "inbound", - "href": "href:147", - "id": "id:148", + "href": "fake:href:3", + "id": "fake:id:3", "ip_version": "ipv4", - "name": "i1", - "source": "10.240.64.0/24", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 443, - "source_port_min": 443 - }, - { - "action": "allow", - "before": { - "href": "href:151", - "id": "id:152", - "name": "i3" - }, - "created_at": "2024-06-25T12:21:18.000Z", - "destination": "10.240.128.0/24", - "direction": "inbound", - "href": "href:149", - "id": "id:150", - "ip_version": "ipv4", - "name": "i2", - "source": "10.240.64.0/24", - "code": 0, - "protocol": "icmp", - "type": 0 - }, - { - "action": "allow", - "created_at": "2024-06-25T12:21:18.000Z", - "destination": "10.240.128.0/24", - "direction": "inbound", - "href": "href:151", - "id": "id:152", - "ip_version": "ipv4", - "name": "i3", - "source": "10.240.1.0/24", - "code": 0, - "protocol": "icmp", - "type": 0 + "name": "rule0", + "source": "10.240.3.0/24", + "protocol": "all" } ], "subnets": [ { - "crn": "crn:107", - "href": "href:108", - "id": "id:109", - "name": "sub3-1", + "crn": "crn:59", + "href": "href:60", + "id": "id:61", + "name": "sub2-1", "resource_type": "subnet" } ], @@ -1213,11 +1029,11 @@ "tags": [] }, { - "created_at": "2024-06-25T12:21:15.000Z", - "crn": "crn:43", - "href": "href:44", - "id": "id:45", - "name": "acl1-1", + "created_at": null, + "crn": "fake:crn:52", + "href": "fake:href:52", + "id": "fake:id:52", + "name": "testacl5-vpc--sub1-3", "resource_group": { "href": "href:16", "id": "id:17", @@ -1226,128 +1042,23 @@ "rules": [ { "action": "allow", - "before": { - "href": "href:155", - "id": "id:156", - "name": "o2" - }, - "created_at": "2024-06-25T12:21:16.000Z", - "destination": "8.8.8.8/32", - "direction": "outbound", - "href": "href:153", - "id": "id:154", - "ip_version": "ipv4", - "name": "o1", - "source": "10.240.1.0/24", - "destination_port_max": 53, - "destination_port_min": 53, - "protocol": "udp", - "source_port_max": 65535, - "source_port_min": 1 - }, - { - "action": "allow", - "before": { - "href": "href:157", - "id": "id:158", - "name": "o3" - }, - "created_at": "2024-06-25T12:21:17.000Z", - "destination": "10.240.2.0/23", - "direction": "outbound", - "href": "href:155", - "id": "id:156", - "ip_version": "ipv4", - "name": "o2", - "source": "10.240.1.0/24", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 65535, - "source_port_min": 1 - }, - { - "action": "allow", - "before": { - "href": "href:159", - "id": "id:160", - "name": "i1" - }, - "created_at": "2024-06-25T12:21:17.000Z", - "destination": "10.240.128.0/24", + "created_at": null, + "destination": "10.240.64.0/24", "direction": "outbound", - "href": "href:157", - "id": "id:158", - "ip_version": "ipv4", - "name": "o3", - "source": "10.240.1.0/24", - "code": 0, - "protocol": "icmp", - "type": 0 - }, - { - "action": "allow", - "before": { - "href": "href:161", - "id": "id:162", - "name": "i2" - }, - "created_at": "2024-06-25T12:21:18.000Z", - "destination": "10.240.1.0/24", - "direction": "inbound", - "href": "href:159", - "id": "id:160", + "href": "fake:href:4", + "id": "fake:id:4", "ip_version": "ipv4", - "name": "i1", - "source": "8.8.8.8/32", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "udp", - "source_port_max": 53, - "source_port_min": 53 - }, - { - "action": "allow", - "before": { - "href": "href:163", - "id": "id:164", - "name": "i3" - }, - "created_at": "2024-06-25T12:21:18.000Z", - "destination": "10.240.1.0/24", - "direction": "inbound", - "href": "href:161", - "id": "id:162", - "ip_version": "ipv4", - "name": "i2", - "source": "10.240.2.0/23", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 65535, - "source_port_min": 1 - }, - { - "action": "allow", - "created_at": "2024-06-25T12:21:19.000Z", - "destination": "10.240.1.0/24", - "direction": "inbound", - "href": "href:163", - "id": "id:164", - "ip_version": "ipv4", - "name": "i3", - "source": "10.240.128.0/24", - "code": 0, - "protocol": "icmp", - "type": 0 + "name": "rule0", + "source": "10.240.3.0/24", + "protocol": "all" } ], "subnets": [ { - "crn": "crn:40", - "href": "href:41", - "id": "id:42", - "name": "sub1-1", + "crn": "crn:78", + "href": "href:79", + "id": "id:80", + "name": "sub1-3", "resource_type": "subnet" } ], @@ -1361,11 +1072,11 @@ "tags": [] }, { - "created_at": "2024-06-25T12:21:15.000Z", - "crn": "crn:62", - "href": "href:63", - "id": "id:64", - "name": "acl2-1", + "created_at": null, + "crn": "fake:crn:58", + "href": "fake:href:58", + "id": "fake:id:58", + "name": "testacl5-vpc--sub2-2", "resource_group": { "href": "href:16", "id": "id:17", @@ -1374,162 +1085,27 @@ "rules": [ { "action": "allow", - "before": { - "href": "href:167", - "id": "id:168", - "name": "o2" - }, - "created_at": "2024-06-25T12:21:16.000Z", - "destination": "8.8.8.8/32", - "direction": "outbound", - "href": "href:165", - "id": "id:166", - "ip_version": "ipv4", - "name": "o1", - "source": "10.240.64.0/24", - "destination_port_max": 53, - "destination_port_min": 53, - "protocol": "udp", - "source_port_max": 65535, - "source_port_min": 1 - }, - { - "action": "allow", - "before": { - "href": "href:169", - "id": "id:170", - "name": "o3" - }, - "created_at": "2024-06-25T12:21:17.000Z", - "destination": "10.240.65.0/24", - "direction": "outbound", - "href": "href:167", - "id": "id:168", - "ip_version": "ipv4", - "name": "o2", - "source": "10.240.64.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:171", - "id": "id:172", - "name": "o4" - }, - "created_at": "2024-06-25T12:21:17.000Z", - "destination": "10.240.128.0/24", - "direction": "outbound", - "href": "href:169", - "id": "id:170", - "ip_version": "ipv4", - "name": "o3", - "source": "10.240.64.0/24", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 443, - "source_port_min": 443 - }, - { - "action": "allow", - "before": { - "href": "href:173", - "id": "id:174", - "name": "i1" - }, - "created_at": "2024-06-25T12:21:18.000Z", + "created_at": null, "destination": "10.240.128.0/24", "direction": "outbound", - "href": "href:171", - "id": "id:172", + "href": "fake:href:5", + "id": "fake:id:5", "ip_version": "ipv4", - "name": "o4", - "source": "10.240.64.0/24", - "code": 0, - "protocol": "icmp", - "type": 0 - }, - { - "action": "allow", - "before": { - "href": "href:175", - "id": "id:176", - "name": "i2" - }, - "created_at": "2024-06-25T12:21:18.000Z", - "destination": "10.240.64.0/24", - "direction": "inbound", - "href": "href:173", - "id": "id:174", - "ip_version": "ipv4", - "name": "i1", - "source": "8.8.8.8/32", + "name": "rule0", + "source": "10.240.65.0/24", "destination_port_max": 65535, "destination_port_min": 1, - "protocol": "udp", - "source_port_max": 53, - "source_port_min": 53 - }, - { - "action": "allow", - "before": { - "href": "href:177", - "id": "id:178", - "name": "i3" - }, - "created_at": "2024-06-25T12:21:18.000Z", - "destination": "10.240.64.0/24", - "direction": "inbound", - "href": "href:175", - "id": "id:176", - "ip_version": "ipv4", - "name": "i2", - "source": "10.240.65.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:179", - "id": "id:180", - "name": "i4" - }, - "created_at": "2024-06-25T12:21:19.000Z", - "destination": "10.240.64.0/24", - "direction": "inbound", - "href": "href:177", - "id": "id:178", - "ip_version": "ipv4", - "name": "i3", - "source": "10.240.128.0/24", - "destination_port_max": 443, - "destination_port_min": 443, "protocol": "tcp", - "source_port_max": 65535, - "source_port_min": 1 - }, - { - "action": "allow", - "created_at": "2024-06-25T12:21:19.000Z", - "destination": "10.240.64.0/24", - "direction": "inbound", - "href": "href:179", - "id": "id:180", - "ip_version": "ipv4", - "name": "i4", - "source": "10.240.128.0/24", - "code": 0, - "protocol": "icmp", - "type": 0 + "source_port_max": 20, + "source_port_min": 11 } ], "subnets": [ { - "crn": "crn:59", - "href": "href:60", - "id": "id:61", - "name": "sub2-1", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "sub2-2", "resource_type": "subnet" } ], @@ -1543,11 +1119,11 @@ "tags": [] }, { - "created_at": "2024-06-25T12:20:45.000Z", - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "disallow-laborious-compress-abiding", + "created_at": null, + "crn": "fake:crn:61", + "href": "fake:href:61", + "id": "fake:id:61", + "name": "testacl5-vpc--sub3-1", "resource_group": { "href": "href:16", "id": "id:17", @@ -1556,35 +1132,30 @@ "rules": [ { "action": "allow", - "before": { - "href": "href:183", - "id": "id:184", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T12:20:45.000Z", - "destination": "0.0.0.0/0", + "created_at": null, + "destination": "10.240.128.0/24", "direction": "inbound", - "href": "href:181", - "id": "id:182", + "href": "fake:href:6", + "id": "fake:id:6", "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, + "name": "rule0", + "source": "10.240.65.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 20, + "source_port_min": 11 + } + ], + "subnets": [ { - "action": "allow", - "created_at": "2024-06-25T12:20:45.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:183", - "id": "id:184", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" + "crn": "crn:107", + "href": "href:108", + "id": "id:109", + "name": "sub3-1", + "resource_type": "subnet" } ], - "subnets": [], "vpc": { "crn": "crn:1", "href": "href:2", diff --git a/test/expected/optimize_acl_md/nacl_expected.md b/test/expected/optimize_acl_md/nacl_expected.md index d26b2f13..374528f3 100644 --- a/test/expected/optimize_acl_md/nacl_expected.md +++ b/test/expected/optimize_acl_md/nacl_expected.md @@ -1,30 +1,8 @@ | Acl | Subnet | Direction | Rule priority | Allow or deny | Source | Destination | Protocol | Value | Description | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | - | acl1-1 | sub1-1 | Inbound | 1 | Allow | 8.8.8.8, ports 53-53 | 10.240.1.0/24, any port | UDP | - | | - | acl1-1 | sub1-1 | Inbound | 2 | Allow | 10.240.2.0/23, any port | 10.240.1.0/24, any port | TCP | - | | - | acl1-1 | sub1-1 | Inbound | 3 | Allow | 10.240.128.0/24 | 10.240.1.0/24 | ICMP | Type: 0, Code: 0 | | - | acl1-1 | sub1-1 | Outbound | 4 | Allow | 10.240.1.0/24, any port | 8.8.8.8, ports 53-53 | UDP | - | | - | acl1-1 | sub1-1 | Outbound | 5 | Allow | 10.240.1.0/24, any port | 10.240.2.0/23, any port | TCP | - | | - | acl1-1 | sub1-1 | Outbound | 6 | Allow | 10.240.1.0/24 | 10.240.128.0/24 | ICMP | Type: 0, Code: 0 | | - | acl1-2 | sub1-2, sub1-3 | Inbound | 1 | Allow | 10.240.1.0/24, any port | 10.240.2.0/23, any port | TCP | - | | - | acl1-2 | sub1-2, sub1-3 | Inbound | 2 | Allow | 10.240.2.0/23, any port | 10.240.2.0/23, any port | TCP | - | | - | acl1-2 | sub1-2, sub1-3 | Outbound | 3 | Allow | 10.240.2.0/23, any port | 10.240.1.0/24, any port | TCP | - | | - | acl1-2 | sub1-2, sub1-3 | Outbound | 4 | Allow | 10.240.2.0/23, any port | 10.240.2.0/23, any port | TCP | - | | - | acl2-1 | sub2-1 | Inbound | 1 | Allow | 8.8.8.8, ports 53-53 | 10.240.64.0/24, any port | UDP | - | | - | acl2-1 | sub2-1 | Inbound | 2 | Allow | 10.240.65.0/24 | 10.240.64.0/24 | ALL | - | | - | acl2-1 | sub2-1 | Inbound | 3 | Allow | 10.240.128.0/24, any port | 10.240.64.0/24, ports 443-443 | TCP | - | | - | acl2-1 | sub2-1 | Inbound | 4 | Allow | 10.240.128.0/24 | 10.240.64.0/24 | ICMP | Type: 0, Code: 0 | | - | acl2-1 | sub2-1 | Outbound | 5 | Allow | 10.240.64.0/24, any port | 8.8.8.8, ports 53-53 | UDP | - | | - | acl2-1 | sub2-1 | Outbound | 6 | Allow | 10.240.64.0/24 | 10.240.65.0/24 | ALL | - | | - | acl2-1 | sub2-1 | Outbound | 7 | Allow | 10.240.64.0/24, ports 443-443 | 10.240.128.0/24, any port | TCP | - | | - | acl2-1 | sub2-1 | Outbound | 8 | Allow | 10.240.64.0/24 | 10.240.128.0/24 | ICMP | Type: 0, Code: 0 | | - | acl2-2 | sub2-2 | Inbound | 1 | Allow | 10.240.64.0/24 | 10.240.65.0/24 | ALL | - | | - | acl2-2 | sub2-2 | Outbound | 2 | Allow | 10.240.65.0/24 | 10.240.64.0/24 | ALL | - | | - | acl3-1 | sub3-1 | Inbound | 1 | Allow | 10.240.64.0/24, ports 443-443 | 10.240.128.0/24, any port | TCP | - | | - | acl3-1 | sub3-1 | Inbound | 2 | Allow | 10.240.64.0/24 | 10.240.128.0/24 | ICMP | Type: 0, Code: 0 | | - | acl3-1 | sub3-1 | Inbound | 3 | Allow | 10.240.1.0/24 | 10.240.128.0/24 | ICMP | Type: 0, Code: 0 | | - | acl3-1 | sub3-1 | Outbound | 4 | Allow | 10.240.128.0/24, any port | 10.240.64.0/24, ports 443-443 | TCP | - | | - | acl3-1 | sub3-1 | Outbound | 5 | Allow | 10.240.128.0/24 | 10.240.64.0/24 | ICMP | Type: 0, Code: 0 | | - | acl3-1 | sub3-1 | Outbound | 6 | Allow | 10.240.128.0/24 | 10.240.1.0/24 | ICMP | Type: 0, Code: 0 | | - | disallow-laborious-compress-abiding | | Inbound | 1 | Allow | Any IP | Any IP | ALL | - | | - | disallow-laborious-compress-abiding | | Outbound | 2 | Allow | Any IP | Any IP | ALL | - | | + | testacl5-vpc--sub1-1 | sub1-1 | Outbound | 1 | Allow | 10.240.1.0/24, src ports: any port | 1.1.1.0/31, dst ports: any port | TCP | - | | + | testacl5-vpc--sub1-2 | sub1-2 | Outbound | 1 | Allow | 10.240.2.0/24, src ports: any port | 2.2.2.2, dst ports: ports 1-20 | UDP | - | | + | testacl5-vpc--sub1-3 | sub1-3 | Outbound | 1 | Allow | 10.240.3.0/24 | 10.240.64.0/24 | ALL | - | | + | testacl5-vpc--sub2-1 | sub2-1 | Inbound | 1 | Allow | 10.240.3.0/24 | 10.240.64.0/24 | ALL | - | | + | testacl5-vpc--sub2-2 | sub2-2 | Outbound | 1 | Allow | 10.240.65.0/24, src ports: ports 11-20 | 10.240.128.0/24, dst ports: any port | TCP | - | | + | testacl5-vpc--sub3-1 | sub3-1 | Inbound | 1 | Allow | 10.240.65.0/24, src ports: ports 11-20 | 10.240.128.0/24, dst ports: any port | TCP | - | | diff --git a/test/expected/optimize_acl_tf/nacl_expected.tf b/test/expected/optimize_acl_tf/nacl_expected.tf index ed002ae6..a9c5d58a 100644 --- a/test/expected/optimize_acl_tf/nacl_expected.tf +++ b/test/expected/optimize_acl_tf/nacl_expected.tf @@ -1,313 +1,96 @@ # Attached subnets: sub1-1 -resource "ibm_is_network_acl" "acl1-1" { - name = "acl1-1" +resource "ibm_is_network_acl" "testacl5-vpc--sub1-1" { + name = "testacl5-vpc--sub1-1" resource_group = local.acl_synth_resource_group_id vpc = local.acl_synth_testacl5-vpc_id rules { name = "rule0" action = "allow" - direction = "inbound" - source = "8.8.8.8" - destination = "10.240.1.0/24" - udp { - source_port_min = 53 - source_port_max = 53 - } - } - rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.2.0/23" - destination = "10.240.1.0/24" - tcp { - } - } - rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" - destination = "10.240.1.0/24" - icmp { - type = 0 - code = 0 - } - } - rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" - destination = "8.8.8.8" - udp { - port_min = 53 - port_max = 53 - } - } - rules { - name = "rule4" - action = "allow" direction = "outbound" source = "10.240.1.0/24" - destination = "10.240.2.0/23" + destination = "1.1.1.0/31" tcp { } } - rules { - name = "rule5" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" - destination = "10.240.128.0/24" - icmp { - type = 0 - code = 0 - } - } } -# Attached subnets: sub1-2, sub1-3 -resource "ibm_is_network_acl" "acl1-2" { - name = "acl1-2" +# Attached subnets: sub1-2 +resource "ibm_is_network_acl" "testacl5-vpc--sub1-2" { + name = "testacl5-vpc--sub1-2" resource_group = local.acl_synth_resource_group_id vpc = local.acl_synth_testacl5-vpc_id rules { name = "rule0" action = "allow" - direction = "inbound" - source = "10.240.1.0/24" - destination = "10.240.2.0/23" - tcp { - } - } - rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.2.0/23" - destination = "10.240.2.0/23" - tcp { - } - } - rules { - name = "rule2" - action = "allow" direction = "outbound" - source = "10.240.2.0/23" - destination = "10.240.1.0/24" - tcp { - } - } - rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.2.0/23" - destination = "10.240.2.0/23" - tcp { + source = "10.240.2.0/24" + destination = "2.2.2.2" + udp { + port_max = 20 } } } -# Attached subnets: sub2-1 -resource "ibm_is_network_acl" "acl2-1" { - name = "acl2-1" +# Attached subnets: sub1-3 +resource "ibm_is_network_acl" "testacl5-vpc--sub1-3" { + name = "testacl5-vpc--sub1-3" resource_group = local.acl_synth_resource_group_id vpc = local.acl_synth_testacl5-vpc_id rules { name = "rule0" action = "allow" - direction = "inbound" - source = "8.8.8.8" - destination = "10.240.64.0/24" - udp { - source_port_min = 53 - source_port_max = 53 - } - } - rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" - destination = "10.240.64.0/24" - } - rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" - destination = "10.240.64.0/24" - tcp { - port_min = 443 - port_max = 443 - } - } - rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" - destination = "10.240.64.0/24" - icmp { - type = 0 - code = 0 - } - } - rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" - destination = "8.8.8.8" - udp { - port_min = 53 - port_max = 53 - } - } - rules { - name = "rule5" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" - destination = "10.240.65.0/24" - } - rules { - name = "rule6" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" - destination = "10.240.128.0/24" - tcp { - source_port_min = 443 - source_port_max = 443 - } - } - rules { - name = "rule7" - action = "allow" direction = "outbound" - source = "10.240.64.0/24" - destination = "10.240.128.0/24" - icmp { - type = 0 - code = 0 - } + source = "10.240.3.0/24" + destination = "10.240.64.0/24" } } -# Attached subnets: sub2-2 -resource "ibm_is_network_acl" "acl2-2" { - name = "acl2-2" +# Attached subnets: sub2-1 +resource "ibm_is_network_acl" "testacl5-vpc--sub2-1" { + name = "testacl5-vpc--sub2-1" resource_group = local.acl_synth_resource_group_id vpc = local.acl_synth_testacl5-vpc_id rules { name = "rule0" action = "allow" direction = "inbound" - source = "10.240.64.0/24" - destination = "10.240.65.0/24" - } - rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.65.0/24" + source = "10.240.3.0/24" destination = "10.240.64.0/24" } } -# Attached subnets: sub3-1 -resource "ibm_is_network_acl" "acl3-1" { - name = "acl3-1" +# Attached subnets: sub2-2 +resource "ibm_is_network_acl" "testacl5-vpc--sub2-2" { + name = "testacl5-vpc--sub2-2" resource_group = local.acl_synth_resource_group_id vpc = local.acl_synth_testacl5-vpc_id rules { name = "rule0" action = "allow" - direction = "inbound" - source = "10.240.64.0/24" - destination = "10.240.128.0/24" - tcp { - source_port_min = 443 - source_port_max = 443 - } - } - rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" - destination = "10.240.128.0/24" - icmp { - type = 0 - code = 0 - } - } - rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" - destination = "10.240.128.0/24" - icmp { - type = 0 - code = 0 - } - } - rules { - name = "rule3" - action = "allow" direction = "outbound" - source = "10.240.128.0/24" - destination = "10.240.64.0/24" + source = "10.240.65.0/24" + destination = "10.240.128.0/24" tcp { - port_min = 443 - port_max = 443 - } - } - rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" - destination = "10.240.64.0/24" - icmp { - type = 0 - code = 0 - } - } - rules { - name = "rule5" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" - destination = "10.240.1.0/24" - icmp { - type = 0 - code = 0 + source_port_min = 11 + source_port_max = 20 } } } -# No attached subnets -resource "ibm_is_network_acl" "disallow-laborious-compress-abiding" { - name = "disallow-laborious-compress-abiding" +# Attached subnets: sub3-1 +resource "ibm_is_network_acl" "testacl5-vpc--sub3-1" { + name = "testacl5-vpc--sub3-1" resource_group = local.acl_synth_resource_group_id vpc = local.acl_synth_testacl5-vpc_id rules { name = "rule0" action = "allow" direction = "inbound" - source = "0.0.0.0/0" - destination = "0.0.0.0/0" - } - rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "0.0.0.0/0" - destination = "0.0.0.0/0" + source = "10.240.65.0/24" + destination = "10.240.128.0/24" + tcp { + source_port_min = 11 + source_port_max = 20 + } } } diff --git a/test/main_test_list.go b/test/main_test_list.go index 8ac1b34a..2c5d0791 100644 --- a/test/main_test_list.go +++ b/test/main_test_list.go @@ -18,6 +18,8 @@ const ( sgTesting3Config = "%s/sg_testing3/config_object.json" aclTesting4Config = "%s/acl_testing4/config_object.json" aclTesting5Config = "%s/acl_testing5/config_object.json" + optimizeACLConfig = "%s/optimize_acl/config_object.json" + optimizeACLAnyProtocolConfig = "%s/optimize_acl_anyProtocol/config_object.json" optimizeSGProtocolsToAllConfig = "%s/optimize_sg_protocols_to_all/config_object.json" aclExternalsSpec = "%s/acl_externals/conn_spec.json" @@ -503,10 +505,11 @@ func optimizeACLTestsLists() []testCase { { testName: "optimize_acl_csv", args: &command{ - cmd: optimize, - subcmd: acl, - config: aclTesting5Config, - outputFile: "%s/optimize_acl_csv/nacl_expected.csv", + cmd: optimize, + subcmd: acl, + config: optimizeACLConfig, + outputFile: "%s/optimize_acl_csv/nacl_expected.csv", + firewallName: "testacl5-vpc--sub1-2", }, }, { @@ -514,7 +517,7 @@ func optimizeACLTestsLists() []testCase { args: &command{ cmd: optimize, subcmd: acl, - config: aclTesting5Config, + config: optimizeACLConfig, outputFile: "%s/optimize_acl_md/nacl_expected.md", }, }, @@ -523,7 +526,7 @@ func optimizeACLTestsLists() []testCase { args: &command{ cmd: optimize, subcmd: acl, - config: aclTesting5Config, + config: optimizeACLConfig, outputFile: "%s/optimize_acl_tf/nacl_expected.tf", }, }, @@ -532,9 +535,18 @@ func optimizeACLTestsLists() []testCase { args: &command{ cmd: optimize, subcmd: acl, - config: aclTesting5Config, + config: optimizeACLConfig, outputFile: "%s/optimize_acl_json/nacl_expected.json", }, }, + { + testName: "optimize_acl_anyProtocol_tf", + args: &command{ + cmd: optimize, + subcmd: acl, + config: optimizeACLAnyProtocolConfig, + outputFile: "%s/optimize_acl_anyProtocol_tf/nacl_expected.tf", + }, + }, } }