From 8ae319332b7336f86a23e5f199d064fbe4efaaa9 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 5 Aug 2024 19:01:47 +0300 Subject: [PATCH 001/131] updated subcmds --- cmd/subcmds/optimize.go | 21 +++++++++++++++++++++ cmd/subcmds/optimizeACL.go | 22 ++++++++++++++++++++++ cmd/subcmds/optimizeSG.go | 22 ++++++++++++++++++++++ cmd/subcmds/{format.go => outputFormat.go} | 0 cmd/subcmds/root.go | 6 ++---- cmd/subcmds/{synthesis.go => synth.go} | 17 +++++++++++++++++ cmd/subcmds/{acl.go => synthACL.go} | 2 +- cmd/subcmds/{sg.go => synthSG.go} | 2 +- 8 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 cmd/subcmds/optimize.go create mode 100644 cmd/subcmds/optimizeACL.go create mode 100644 cmd/subcmds/optimizeSG.go rename cmd/subcmds/{format.go => outputFormat.go} (100%) rename cmd/subcmds/{synthesis.go => synth.go} (56%) rename cmd/subcmds/{acl.go => synthACL.go} (93%) rename cmd/subcmds/{sg.go => synthSG.go} (92%) diff --git a/cmd/subcmds/optimize.go b/cmd/subcmds/optimize.go new file mode 100644 index 00000000..cf8ec17e --- /dev/null +++ b/cmd/subcmds/optimize.go @@ -0,0 +1,21 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package subcmds + +import "github.com/spf13/cobra" + +func NewOptimizeCommand(args *inArgs) *cobra.Command { + cmd := &cobra.Command{ + Use: "optimize", + Short: "Optimize is not supported yet", + Long: `Optimize is not supported yet`, + } + + cmd.AddCommand(NewOptimizeACLCommand(args)) + cmd.AddCommand(NewOptimizeSGCommand(args)) + + return cmd +} diff --git a/cmd/subcmds/optimizeACL.go b/cmd/subcmds/optimizeACL.go new file mode 100644 index 00000000..beb8e09b --- /dev/null +++ b/cmd/subcmds/optimizeACL.go @@ -0,0 +1,22 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package subcmds + +import "github.com/spf13/cobra" + +func NewOptimizeACLCommand(args *inArgs) *cobra.Command { + cmd := &cobra.Command{ + Use: "acl", + Short: "OptimizeACL is not supported yet", + Long: `OptimizeACL is not supported yet`, + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { + return nil + }, + } + + return cmd +} diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go new file mode 100644 index 00000000..1c903f83 --- /dev/null +++ b/cmd/subcmds/optimizeSG.go @@ -0,0 +1,22 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package subcmds + +import "github.com/spf13/cobra" + +func NewOptimizeSGCommand(args *inArgs) *cobra.Command { + cmd := &cobra.Command{ + Use: "sg", + Short: "OptimizeSG is not supported yet", + Long: `OptimizeSG is not supported yet`, + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { + return nil + }, + } + + return cmd +} diff --git a/cmd/subcmds/format.go b/cmd/subcmds/outputFormat.go similarity index 100% rename from cmd/subcmds/format.go rename to cmd/subcmds/outputFormat.go diff --git a/cmd/subcmds/root.go b/cmd/subcmds/root.go index c4da0da6..6b01f6c1 100644 --- a/cmd/subcmds/root.go +++ b/cmd/subcmds/root.go @@ -55,12 +55,10 @@ func NewRootCommand() *cobra.Command { rootCmd.PersistentFlags().SortFlags = false _ = rootCmd.MarkPersistentFlagRequired(configFlag) - _ = rootCmd.MarkPersistentFlagRequired(specFlag) - rootCmd.MarkFlagsMutuallyExclusive(outputFileFlag, outputDirFlag) - rootCmd.AddCommand(NewACLCommand(args)) - rootCmd.AddCommand(NewSGCommand(args)) + rootCmd.AddCommand(NewSynthCommand(args)) + // Todo: add optimize command rootCmd.CompletionOptions.HiddenDefaultCmd = true rootCmd.SetHelpCommand(&cobra.Command{Hidden: true}) // disable help command. should use --help flag instead diff --git a/cmd/subcmds/synthesis.go b/cmd/subcmds/synth.go similarity index 56% rename from cmd/subcmds/synthesis.go rename to cmd/subcmds/synth.go index 8b60ac0f..f9240623 100644 --- a/cmd/subcmds/synthesis.go +++ b/cmd/subcmds/synth.go @@ -12,6 +12,23 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/synth" ) +func NewSynthCommand(args *inArgs) *cobra.Command { + cmd := &cobra.Command{ + Use: "synth", + Short: "generate a SG/nACL collection", + Long: `Generate nACLS or Security Groups to only allow the specified connectivity. + should give spec and defs blah blah blah`, + } + + cmd.PersistentFlags().StringVarP(&args.specFile, specFlag, "s", "", "JSON file containing spec file") + _ = cmd.MarkPersistentFlagRequired(specFlag) + + cmd.AddCommand(NewSynthACLCommand(args)) + cmd.AddCommand(NewSynthSGCommand(args)) + + return cmd +} + func synthesis(cmd *cobra.Command, args *inArgs, newSynthesizer func(*ir.Spec, bool) synth.Synthesizer, single bool) error { cmd.SilenceUsage = true // if we got this far, flags are syntactically correct, so no need to print usage spec, err := unmarshal(args) diff --git a/cmd/subcmds/acl.go b/cmd/subcmds/synthACL.go similarity index 93% rename from cmd/subcmds/acl.go rename to cmd/subcmds/synthACL.go index 8c2a9800..4aee4040 100644 --- a/cmd/subcmds/acl.go +++ b/cmd/subcmds/synthACL.go @@ -11,7 +11,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/synth" ) -func NewACLCommand(args *inArgs) *cobra.Command { +func NewSynthACLCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "acl", Short: "Generate Networks ACLs from connectivity specification", diff --git a/cmd/subcmds/sg.go b/cmd/subcmds/synthSG.go similarity index 92% rename from cmd/subcmds/sg.go rename to cmd/subcmds/synthSG.go index e173e39f..88bb4a56 100644 --- a/cmd/subcmds/sg.go +++ b/cmd/subcmds/synthSG.go @@ -11,7 +11,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/synth" ) -func NewSGCommand(args *inArgs) *cobra.Command { +func NewSynthSGCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "sg", Short: "Generate Security Groups from connectivity specification", From 218781609790f9c69511419838d48dd470764b43 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 5 Aug 2024 19:35:26 +0300 Subject: [PATCH 002/131] readme --- README.md | 10 +++++----- cmd/subcmds/root.go | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 09c282dc..382add3f 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ Multi-vpc input is supported. Required connections cannot cross vpc boundaries. ## Usage Use the `vpcgen` CLI tool with one of the following commands to specify the type of network resources to generate. -* `vpcgen sg` - generate Security Groups. -* `vpcgen acl` - generate an nACL for each subnet separately. -* `vpcgen acl --single` - generate a single nACL for all subnets in the same VPC. +* `vpcgen synth sg` - generate Security Groups. +* `vpcgen synth acl` - generate an nACL for each subnet separately. +* `vpcgen synth acl --single` - generate a single nACL for all subnets in the same VPC. ### nACLs Generation Specifying the `--single` flag results in generating a single nACL for all subnets in the same VPC. Otherwise, an nACL is generated for each subnet separately. @@ -55,9 +55,9 @@ make build ## Run an example ```commandline -bin/vpcgen acl -c test/data/acl_testing5/config_object.json -s test/data/acl_testing5/conn_spec.json +bin/vpcgen synth acl -c test/data/acl_testing5/config_object.json -s test/data/acl_testing5/conn_spec.json -bin/vpcgen sg -c test/data/sg_testing3/config_object.json -s test/data/sg_testing3/conn_spec.json +bin/vpcgen synth sg -c test/data/sg_testing3/config_object.json -s test/data/sg_testing3/conn_spec.json ``` **Note**: Windows environment users should replace all `/` with `\`. \ No newline at end of file diff --git a/cmd/subcmds/root.go b/cmd/subcmds/root.go index 6b01f6c1..8c1b6dc5 100644 --- a/cmd/subcmds/root.go +++ b/cmd/subcmds/root.go @@ -44,7 +44,6 @@ func NewRootCommand() *cobra.Command { } rootCmd.PersistentFlags().StringVarP(&args.configFile, configFlag, "c", "", "JSON file containing config spec") - rootCmd.PersistentFlags().StringVarP(&args.specFile, specFlag, "s", "", "JSON file containing spec file") rootCmd.PersistentFlags().StringVarP(&args.outputFmt, outputFmtFlag, "f", "", "Output format; "+mustBeOneOf(outputFormats)) rootCmd.PersistentFlags().StringVarP(&args.outputFile, outputFileFlag, "o", "", "Write all generated resources to the specified file.") rootCmd.PersistentFlags().StringVarP(&args.outputDir, outputDirFlag, "d", "", From 851e02caf6317876d27a41cfa67ce88fcd0fcfac Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 6 Aug 2024 17:17:46 +0300 Subject: [PATCH 003/131] generic --- go.mod | 8 ++ go.sum | 4 +- pkg/io/confio/acl.go | 11 +- pkg/io/confio/conversions.go | 25 +++-- pkg/io/confio/read_defs.go | 14 +-- pkg/io/confio/sg.go | 13 ++- pkg/io/csvio/acl.go | 22 ++-- pkg/io/csvio/common.go | 24 ++-- pkg/io/csvio/sg.go | 26 +++-- pkg/io/jsonio/unmarshal.go | 32 +++--- pkg/io/mdio/acl.go | 22 ++-- pkg/io/mdio/common.go | 24 ++-- pkg/io/mdio/sg.go | 26 +++-- pkg/io/tfio/acl.go | 17 +-- pkg/io/tfio/common.go | 15 ++- pkg/io/tfio/sg.go | 20 ++-- pkg/ir/acl.go | 11 +- pkg/ir/common.go | 9 -- pkg/ir/icmp.go | 105 ------------------ pkg/ir/packet.go | 33 +++--- pkg/ir/sg.go | 6 +- pkg/ir/spec.go | 54 +++++---- pkg/ir/tcpudp.go | 51 --------- pkg/synth/acl.go | 14 +-- pkg/synth/common.go | 4 +- test/data/acl_nif/nacl_expected.tf | 4 - test/data/acl_testing5/nacl_expected.csv | 16 +-- test/data/acl_testing5/nacl_expected.json | 8 -- test/data/acl_testing5/nacl_expected.tf | 8 -- .../acl_testing5/nacl_single_expected.csv | 16 +-- .../acl_testing5/nacl_single_expected.json | 8 -- .../data/acl_testing5/nacl_single_expected.tf | 8 -- test/data/acl_tg_multiple/nacl_expected.json | 8 -- test/data/acl_tg_multiple/nacl_expected.tf | 8 -- .../acl_tg_multiple/nacl_single_expected.tf | 8 -- test/data/acl_tg_multiple/single_test-vpc0.tf | 4 - test/data/acl_tg_multiple/single_test-vpc1.tf | 4 - test/data/acl_tg_multiple/test-vpc0.tf | 4 - test/data/acl_tg_multiple/test-vpc1.tf | 4 - test/data/sg_testing3/sg_expected.csv | 4 +- test/data/sg_tg_multiple/sg_expected.csv | 4 +- test/data/sg_tg_multiple/test-vpc2.csv | 4 +- 42 files changed, 257 insertions(+), 453 deletions(-) delete mode 100644 pkg/ir/icmp.go delete mode 100644 pkg/ir/tcpudp.go diff --git a/go.mod b/go.mod index 4b80005f..25ea19a4 100644 --- a/go.mod +++ b/go.mod @@ -36,3 +36,11 @@ require ( golang.org/x/text v0.16.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) + +// Todo: +// (1) delete the following line when np-guard/models#33 is merged. +// (2) replace lines 137 and 138 in go.sum with +// github.com/np-guard/models v0.3.4 h1:HOhVi6wyGvo+KmYBnQ5Km5HYCF+/PQlDs1v7mL1v05g= +// github.com/np-guard/models v0.3.4/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= +//nolint:gomoddirectives // this line is temporary +replace github.com/np-guard/models => github.com/np-guard/models v0.3.5-0.20240708150421-8d8e4354057d \ No newline at end of file diff --git a/go.sum b/go.sum index de492d00..fd6bc3e4 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.13.0 h1:gjfeGsVYNfWxbsSvkVq4QVtLlrD7ekNUzmb1o7uautw= github.com/np-guard/cloud-resource-collector v0.13.0/go.mod h1:80MUWGvDwN+wt154xgJOAEOGEC12AFJJrlXMvvQwRHw= -github.com/np-guard/models v0.3.4 h1:HOhVi6wyGvo+KmYBnQ5Km5HYCF+/PQlDs1v7mL1v05g= -github.com/np-guard/models v0.3.4/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= +github.com/np-guard/models v0.3.5-0.20240708150421-8d8e4354057d h1:yAmG3W8kUl0GC84dRWcgRK9lBWRkwJkwLnUtwoh1lIY= +github.com/np-guard/models v0.3.5-0.20240708150421-8d8e4354057d/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= 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= diff --git a/pkg/io/confio/acl.go b/pkg/io/confio/acl.go index 095647eb..20f06d1a 100644 --- a/pkg/io/confio/acl.go +++ b/pkg/io/confio/acl.go @@ -12,13 +12,14 @@ import ( "github.com/IBM/vpc-go-sdk/vpcv1" configModel "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" - "github.com/np-guard/models/pkg/ipblock" + "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/utils" ) -func cidr(address *ipblock.IPBlock) *string { +func cidr(address *netset.IPBlock) *string { return utils.Ptr(address.ToCidrListString()) } @@ -30,7 +31,7 @@ func makeACLRuleItem(rule *ir.ACLRule, current, source := cidr(rule.Source) destination := cidr(rule.Destination) switch p := rule.Protocol.(type) { - case ir.TCPUDP: + case netp.TCPUDP: data := tcpudp(p) result := &vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolTcpudp{ Href: current.Href, @@ -50,7 +51,7 @@ func makeACLRuleItem(rule *ir.ACLRule, current, DestinationPortMax: data.DestinationPortMax, } return result - case ir.ICMP: + case netp.ICMP: data := icmp(p) result := &vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolIcmp{ Href: current.Href, @@ -68,7 +69,7 @@ func makeACLRuleItem(rule *ir.ACLRule, current, Code: data.Code, } return result - case ir.AnyProtocol: + case netp.AnyProtocol: data := all() result := &vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolAll{ Href: current.Href, diff --git a/pkg/io/confio/conversions.go b/pkg/io/confio/conversions.go index 9a617c25..6ef6733b 100644 --- a/pkg/io/confio/conversions.go +++ b/pkg/io/confio/conversions.go @@ -11,6 +11,9 @@ import ( "github.com/IBM/vpc-go-sdk/vpcv1" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) @@ -62,12 +65,12 @@ func direction(d ir.Direction) *string { return nil } -func minPort(r ir.PortRange) *int64 { - return utils.Ptr(int64(r.Min)) +func minPort(r interval.Interval) *int64 { + return utils.Ptr(r.Start()) } -func maxPort(r ir.PortRange) *int64 { - return utils.Ptr(int64(r.Max)) +func maxPort(r interval.Interval) *int64 { + return utils.Ptr(r.End()) } type tcpudpData struct { @@ -102,10 +105,10 @@ type allData struct { Protocol *string } -func tcpudp(p ir.TCPUDP) tcpudpData { +func tcpudp(p netp.TCPUDP) tcpudpData { r := p.PortRangePair res := tcpudpData{ - Protocol: utils.Ptr(strings.ToLower(string(p.Protocol))), + Protocol: utils.Ptr(strings.ToLower(string(p.ProtocolString()))), SourcePortMin: minPort(r.SrcPort), SourcePortMax: maxPort(r.SrcPort), DestinationPortMin: minPort(r.DstPort), @@ -114,13 +117,15 @@ func tcpudp(p ir.TCPUDP) tcpudpData { return res } -func icmp(p ir.ICMP) icmpData { +func icmp(p netp.ICMP) icmpData { res := icmpData{ Protocol: utils.Ptr(icmpConst), - Type: utils.Ptr(int64(p.Type)), } - if p.Code != nil { - res.Code = utils.Ptr(int64(*p.Code)) + if p.TypeCode != nil { + res.Type = utils.Ptr(int64(p.TypeCode.Type)) + if p.TypeCode.Code != nil { + res.Code = utils.Ptr(int64(*p.TypeCode.Code)) + } } return res } diff --git a/pkg/io/confio/read_defs.go b/pkg/io/confio/read_defs.go index 5c1c580d..c2fc03b8 100644 --- a/pkg/io/confio/read_defs.go +++ b/pkg/io/confio/read_defs.go @@ -14,7 +14,7 @@ import ( configModel "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -74,9 +74,9 @@ func ReadDefs(filename string) (*ir.ConfigDefs, error) { func parseVPCs(config *configModel.ResourcesContainerModel) (map[ir.ID]*ir.VPCDetails, error) { VPCs := make(map[ir.ID]*ir.VPCDetails, len(config.VpcList)) for _, vpc := range config.VpcList { - addressPrefixes := ipblock.New() + addressPrefixes := netset.NewIPBlock() for _, addressPrefix := range vpc.AddressPrefixes { - address, err := ipblock.FromCidr(*addressPrefix.CIDR) + address, err := netset.IPBlockFromCidr(*addressPrefix.CIDR) if err != nil { return nil, err } @@ -91,7 +91,7 @@ func parseSubnets(config *configModel.ResourcesContainerModel) (map[ir.ID]*ir.Su subnets := make(map[ir.ID]*ir.SubnetDetails, len(config.SubnetList)) for _, subnet := range config.SubnetList { uniqueName := ScopingString(*subnet.VPC.Name, *subnet.Name) - cidr, err := ipblock.FromCidr(*subnet.Ipv4CIDRBlock) + cidr, err := netset.IPBlockFromCidr(*subnet.Ipv4CIDRBlock) if err != nil { return nil, err } @@ -114,7 +114,7 @@ func parseInstancesNifs(config *configModel.ResourcesContainerModel) (instances instanceNifs := make([]ir.ID, len(instance.NetworkInterfaces)) for i := range instance.NetworkInterfaces { nifUniqueName := ScopingString(instanceUniqueName, *instance.NetworkInterfaces[i].Name) - nifIP, err := ipblock.FromIPAddress(*instance.NetworkInterfaces[i].PrimaryIP.Address) + nifIP, err := netset.IPBlockFromIPAddress(*instance.NetworkInterfaces[i].PrimaryIP.Address) if err != nil { return nil, nil, err } @@ -164,7 +164,7 @@ func parseVPEs(config *configModel.ResourcesContainerModel) (vpes map[ir.ID]*ir. VPEName := ScopingString(*subnet.VPC.Name, *t.Name) subnetName := ScopingString(*subnet.VPC.Name, *subnet.Name) uniqueVpeReservedIPName := ScopingString(VPEName, *r.Name) - vpeIP, err := ipblock.FromIPAddress(*r.Address) + vpeIP, err := netset.IPBlockFromIPAddress(*r.Address) if err != nil { return nil, nil, err } @@ -190,7 +190,7 @@ func validateVpcs(vpcs map[ir.ID]*ir.VPCDetails) error { if vpcName1 >= vpcName2 { continue } - if vpcDetails1.AddressPrefixes.Overlap(vpcDetails2.AddressPrefixes) { + if ir.Overlap(vpcDetails1.AddressPrefixes, vpcDetails2.AddressPrefixes) { return fmt.Errorf("vpcs %s and %s have overlapping IP address spaces", vpcName1, vpcName2) } } diff --git a/pkg/io/confio/sg.go b/pkg/io/confio/sg.go index fdd4b561..d9157cb2 100644 --- a/pkg/io/confio/sg.go +++ b/pkg/io/confio/sg.go @@ -12,7 +12,8 @@ import ( "github.com/IBM/vpc-go-sdk/vpcv1" configModel "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" - "github.com/np-guard/models/pkg/ipblock" + "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/utils" @@ -51,7 +52,7 @@ func sgRemote(nameToSGRemoteRef map[string]*vpcv1.SecurityGroupRuleRemoteSecurit rule *ir.SGRule) vpcv1.SecurityGroupRuleRemoteIntf { st := rule.Remote.String() switch t := rule.Remote.(type) { - case *ipblock.IPBlock: + case *netset.IPBlock: if ir.IsIPAddress(t) { return &vpcv1.SecurityGroupRuleRemoteIP{ Address: &st, @@ -70,7 +71,7 @@ func makeSGRuleItem(nameToSGRemoteRef map[string]*vpcv1.SecurityGroupRuleRemoteS rule *ir.SGRule, i int) vpcv1.SecurityGroupRuleIntf { iPVersion := utils.Ptr(ipv4Const) direction := direction(rule.Direction) - cidrAll := ipblock.CidrAll + cidrAll := netset.CidrAll local := &vpcv1.SecurityGroupRuleLocal{ CIDRBlock: &cidrAll, } @@ -78,7 +79,7 @@ func makeSGRuleItem(nameToSGRemoteRef map[string]*vpcv1.SecurityGroupRuleRemoteS remote := sgRemote(nameToSGRemoteRef, rule) switch p := rule.Protocol.(type) { - case ir.TCPUDP: + case netp.TCPUDP: data := tcpudp(p) return &vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp{ Direction: direction, @@ -91,7 +92,7 @@ func makeSGRuleItem(nameToSGRemoteRef map[string]*vpcv1.SecurityGroupRuleRemoteS PortMin: data.remotePortMin(rule.Direction), PortMax: data.remotePortMax(rule.Direction), } - case ir.ICMP: + case netp.ICMP: data := icmp(p) return &vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp{ Direction: direction, @@ -104,7 +105,7 @@ func makeSGRuleItem(nameToSGRemoteRef map[string]*vpcv1.SecurityGroupRuleRemoteS Type: data.Type, Code: data.Code, } - case ir.AnyProtocol: + case netp.AnyProtocol: data := all() return &vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ Direction: direction, diff --git a/pkg/io/csvio/acl.go b/pkg/io/csvio/acl.go index 728caf9f..792f943e 100644 --- a/pkg/io/csvio/acl.go +++ b/pkg/io/csvio/acl.go @@ -10,7 +10,9 @@ import ( "log" "strconv" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -24,12 +26,12 @@ func makeACLTable(t *ir.ACL, subnet string) [][]string { return rows } -func ACLPort(p ir.PortRange) string { +func ACLPort(p interval.Interval) string { switch { - case p.Min == ir.DefaultMinPort && p.Max == ir.DefaultMaxPort: + case p.Start() == netp.MinPort && p.End() == netp.MaxPort: return "any port" //nolint:goconst // independent decision for SG and ACL default: - return fmt.Sprintf("ports %v-%v", p.Min, p.Max) + return fmt.Sprintf("ports %v-%v", p.Start(), p.End()) } } @@ -84,23 +86,23 @@ func makeACLRow(priority int, rule *ir.ACLRule, aclName, subnet string) []string } } -func printIP(ip *ipblock.IPBlock, protocol ir.Protocol, isSource bool) string { +func printIP(ip *netset.IPBlock, protocol netp.Protocol, isSource bool) string { ipString := ip.String() - if ip.Equal(ipblock.GetCidrAll()) { + if ip.Equal(netset.GetCidrAll()) { ipString = "Any IP" //nolint:goconst // independent decision for SG and ACL } switch p := protocol.(type) { - case ir.ICMP: + case netp.ICMP: return ipString - case ir.TCPUDP: - var r ir.PortRange + case netp.TCPUDP: + var r interval.Interval if isSource { r = p.PortRangePair.SrcPort } else { r = p.PortRangePair.DstPort } return fmt.Sprintf("%v, %v", ipString, ACLPort(r)) - case ir.AnyProtocol: + case netp.AnyProtocol: return ipString default: log.Panicf("Impossible protocol %v", p) diff --git a/pkg/io/csvio/common.go b/pkg/io/csvio/common.go index 4302526c..41cd664d 100644 --- a/pkg/io/csvio/common.go +++ b/pkg/io/csvio/common.go @@ -13,6 +13,8 @@ import ( "strconv" "strings" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -38,29 +40,29 @@ func direction(d ir.Direction) string { return "Outbound" } -func printICMPTypeCode(protocol ir.Protocol) string { - p, ok := protocol.(ir.ICMP) +func printICMPTypeCode(protocol netp.Protocol) string { + p, ok := protocol.(netp.ICMP) if !ok { return nonIcmp } icmpType := anyIcmpValue icmpCode := anyIcmpValue - if p.ICMPCodeType != nil { - icmpType = strconv.Itoa(p.Type) - if p.Code != nil { - icmpCode = strconv.Itoa(*p.Code) + if typeCode := p.ICMPTypeCode(); typeCode != nil { + icmpType = strconv.Itoa(typeCode.Type) + if typeCode.Code != nil { + icmpCode = strconv.Itoa(*typeCode.Code) } } return fmt.Sprintf("Type: %v, Code: %v", icmpType, icmpCode) } -func printProtocolName(protocol ir.Protocol) string { +func printProtocolName(protocol netp.Protocol) string { switch p := protocol.(type) { - case ir.ICMP: + case netp.ICMP: return "ICMP" - case ir.TCPUDP: - return strings.ToUpper(string(p.Protocol)) - case ir.AnyProtocol: + case netp.TCPUDP: + return strings.ToUpper(string(p.ProtocolString())) + case netp.AnyProtocol: return anyProtocol } return "" diff --git a/pkg/io/csvio/sg.go b/pkg/io/csvio/sg.go index a83ab41d..2e438ec1 100644 --- a/pkg/io/csvio/sg.go +++ b/pkg/io/csvio/sg.go @@ -9,7 +9,9 @@ import ( "fmt" "log" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -60,18 +62,18 @@ func makeSGTable(t *ir.SG, sgName ir.SGName) [][]string { return rows } -func sGPort(p ir.PortRange) string { +func sGPort(p interval.Interval) string { switch { - case p.Min == ir.DefaultMinPort && p.Max == ir.DefaultMaxPort: + case p.Start() == netp.MinPort && p.End() == netp.MaxPort: return "any port" default: - return fmt.Sprintf("Ports %v-%v", p.Min, p.Max) + return fmt.Sprintf("ports %v-%v", p.Start(), p.End()) } } func sGRemoteType(t ir.RemoteType) string { switch tr := t.(type) { - case *ipblock.IPBlock: + case *netset.IPBlock: if ir.IsIPAddress(tr) { return "IP address" } @@ -85,9 +87,9 @@ func sGRemoteType(t ir.RemoteType) string { func sgRemote(r ir.RemoteType) string { switch tr := r.(type) { - case *ipblock.IPBlock: + case *netset.IPBlock: s := tr.String() - if s == ipblock.CidrAll { + if s == netset.CidrAll { return "Any IP" } return s @@ -99,19 +101,19 @@ func sgRemote(r ir.RemoteType) string { return "" } -func printProtocolParams(protocol ir.Protocol, isSource bool) string { +func printProtocolParams(protocol netp.Protocol, isSource bool) string { switch p := protocol.(type) { - case ir.ICMP: + case netp.ICMP: return printICMPTypeCode(protocol) - case ir.TCPUDP: - var r ir.PortRange + case netp.TCPUDP: + var r interval.Interval if isSource { r = p.PortRangePair.SrcPort } else { r = p.PortRangePair.DstPort } return sGPort(r) - case ir.AnyProtocol: + case netp.AnyProtocol: return "" default: log.Panicf("Impossible protocol %v", p) diff --git a/pkg/io/jsonio/unmarshal.go b/pkg/io/jsonio/unmarshal.go index 7422e7a4..87a843cc 100644 --- a/pkg/io/jsonio/unmarshal.go +++ b/pkg/io/jsonio/unmarshal.go @@ -11,7 +11,9 @@ import ( "fmt" "os" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" @@ -109,9 +111,9 @@ func parseCidrSegments(jsonSegments spec.SpecSegments, configDefs *ir.ConfigDefs result := make(map[ir.ID]*ir.CidrSegmentDetails) for segmentName, segment := range cidrSegments { // each cidr saves the contained subnets - segmentMap := make(map[*ipblock.IPBlock]ir.CIDRDetails) + segmentMap := make(map[*netset.IPBlock]ir.CIDRDetails) for _, cidr := range segment { - c, err := ipblock.FromCidr(cidr) + c, err := netset.IPBlockFromCidr(cidr) if err != nil { return nil, err } @@ -137,7 +139,7 @@ func parseCidrSegments(jsonSegments spec.SpecSegments, configDefs *ir.ConfigDefs func translateExternals(m map[string]string) (map[ir.ID]*ir.ExternalDetails, error) { result := make(map[ir.ID]*ir.ExternalDetails) for k, v := range m { - address, err := ipblock.FromCidrOrAddress(v) + address, err := netset.IPBlockFromCidrOrAddress(v) if err != nil { return nil, err } @@ -261,26 +263,26 @@ func translateProtocols(protocols spec.ProtocolList) ([]ir.TrackedProtocol, erro if len(protocols) != 1 { return nil, fmt.Errorf("when allowing any protocol, no more protocols can be defined") } - result[i].Protocol = ir.AnyProtocol{} + result[i].Protocol = netp.AnyProtocol{} case spec.Icmp: if p.Type == nil { if p.Code != nil { return nil, fmt.Errorf("defining ICMP code for unspecified ICMP type is not allowed") } - result[i].Protocol = ir.TrackedProtocol{Protocol: ir.ICMP{}} + result[i].Protocol = ir.TrackedProtocol{Protocol: netp.ICMP{}} } else { - err := ir.ValidateICMP(*p.Type, *p.Code) + icmp, err := netp.ICMPFromTypeAndCode(p.Type, p.Code) if err != nil { return nil, err } - result[i].Protocol = ir.ICMP{ICMPCodeType: &ir.ICMPCodeType{Type: *p.Type, Code: p.Code}} + result[i].Protocol = icmp } case spec.TcpUdp: - result[i].Protocol = ir.TCPUDP{ - Protocol: ir.TransportLayerProtocolName(p.Protocol), - PortRangePair: ir.PortRangePair{ - SrcPort: ir.PortRange{Min: p.MinSourcePort, Max: p.MaxSourcePort}, - DstPort: ir.PortRange{Min: p.MinDestinationPort, Max: p.MaxDestinationPort}, + result[i].Protocol = netp.TCPUDP{ + IsTCP: p.Protocol == spec.TcpUdpProtocolTCP, + PortRangePair: netp.PortRangePair{ + SrcPort: interval.New(int64(p.MinSourcePort), int64(p.MaxSourcePort)), + DstPort: interval.New(int64(p.MinDestinationPort), int64(p.MaxDestinationPort)), }, } default: @@ -356,10 +358,10 @@ func unmarshal(filename string) (*spec.Spec, error) { return jsonSpec, err } -func parseOverlappingVpcs(cidr *ipblock.IPBlock, vpcs map[ir.ID]*ir.VPCDetails) []ir.ID { +func parseOverlappingVpcs(cidr *netset.IPBlock, vpcs map[ir.ID]*ir.VPCDetails) []ir.ID { result := make([]ir.ID, 0) for vpcName, vpcDetails := range vpcs { - if vpcDetails.AddressPrefixes.Overlap(cidr) { + if ir.Overlap(vpcDetails.AddressPrefixes, cidr) { result = append(result, vpcName) } } diff --git a/pkg/io/mdio/acl.go b/pkg/io/mdio/acl.go index 11f693c6..18c010e7 100644 --- a/pkg/io/mdio/acl.go +++ b/pkg/io/mdio/acl.go @@ -10,7 +10,9 @@ import ( "log" "strconv" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -24,12 +26,12 @@ func makeACLTable(t *ir.ACL, subnet string) [][]string { return rows } -func ACLPort(p ir.PortRange) string { +func ACLPort(p interval.Interval) string { switch { - case p.Min == ir.DefaultMinPort && p.Max == ir.DefaultMaxPort: + case p.Start() == netp.MinPort && p.End() == netp.MaxPort: return "any port" //nolint:goconst // independent decision for SG and ACL default: - return fmt.Sprintf("ports %v-%v", p.Min, p.Max) + return fmt.Sprintf("ports %v", p) } } @@ -101,23 +103,23 @@ func makeACLRow(priority int, rule *ir.ACLRule, aclName, subnet string) []string } } -func printIP(ip *ipblock.IPBlock, protocol ir.Protocol, isSource bool) string { +func printIP(ip *netset.IPBlock, protocol netp.Protocol, isSource bool) string { ipString := ip.String() - if ip.Equal(ipblock.GetCidrAll()) { + if ip.Equal(netset.GetCidrAll()) { ipString = "Any IP" //nolint:goconst // independent decision for SG and ACL } switch p := protocol.(type) { - case ir.ICMP: + case netp.ICMP: return ipString - case ir.TCPUDP: - var r ir.PortRange + case netp.TCPUDP: + var r interval.Interval if isSource { r = p.PortRangePair.SrcPort } else { r = p.PortRangePair.DstPort } return fmt.Sprintf("%v, %v", ipString, ACLPort(r)) - case ir.AnyProtocol: + case netp.AnyProtocol: return ipString default: log.Panicf("Impossible protocol %v", p) diff --git a/pkg/io/mdio/common.go b/pkg/io/mdio/common.go index 5aa6aa41..abfb24a8 100644 --- a/pkg/io/mdio/common.go +++ b/pkg/io/mdio/common.go @@ -13,6 +13,8 @@ import ( "strconv" "strings" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -51,29 +53,29 @@ func direction(d ir.Direction) string { return "Outbound" } -func printICMPTypeCode(protocol ir.Protocol) string { - p, ok := protocol.(ir.ICMP) +func printICMPTypeCode(protocol netp.Protocol) string { + p, ok := protocol.(netp.ICMP) if !ok { return nonIcmp } icmpType := anyIcmpValue icmpCode := anyIcmpValue - if p.ICMPCodeType != nil { - icmpType = strconv.Itoa(p.Type) - if p.Code != nil { - icmpCode = strconv.Itoa(*p.Code) + if typeCode := p.ICMPTypeCode(); typeCode != nil { + icmpType = strconv.Itoa(typeCode.Type) + if typeCode.Code != nil { + icmpCode = strconv.Itoa(*typeCode.Code) } } return fmt.Sprintf("Type: %v, Code: %v", icmpType, icmpCode) } -func printProtocolName(protocol ir.Protocol) string { +func printProtocolName(protocol netp.Protocol) string { switch p := protocol.(type) { - case ir.ICMP: + case netp.ICMP: return "ICMP" - case ir.TCPUDP: - return strings.ToUpper(string(p.Protocol)) - case ir.AnyProtocol: + case netp.TCPUDP: + return strings.ToUpper(string(p.ProtocolString())) + case netp.AnyProtocol: return anyProtocol } return "" diff --git a/pkg/io/mdio/sg.go b/pkg/io/mdio/sg.go index 5a59c3fd..aea44185 100644 --- a/pkg/io/mdio/sg.go +++ b/pkg/io/mdio/sg.go @@ -9,7 +9,9 @@ import ( "fmt" "log" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -74,18 +76,18 @@ func makeSGTable(t *ir.SG, sgName ir.SGName) [][]string { return rows } -func sGPort(p ir.PortRange) string { +func sGPort(p interval.Interval) string { switch { - case p.Min == ir.DefaultMinPort && p.Max == ir.DefaultMaxPort: + case p.Start() == netp.MinPort && p.End() == netp.MaxPort: return "any port" default: - return fmt.Sprintf("Ports %v-%v", p.Min, p.Max) + return fmt.Sprintf("ports %v-%v", p.Start(), p.End()) } } func sGRemoteType(t ir.RemoteType) string { switch tr := t.(type) { - case *ipblock.IPBlock: + case *netset.IPBlock: if ir.IsIPAddress(tr) { return "IP address" } @@ -99,9 +101,9 @@ func sGRemoteType(t ir.RemoteType) string { func sgRemote(r ir.RemoteType) string { switch tr := r.(type) { - case *ipblock.IPBlock: + case *netset.IPBlock: s := tr.String() - if s == ipblock.CidrAll { + if s == netset.CidrAll { return "Any IP" } return s @@ -113,19 +115,19 @@ func sgRemote(r ir.RemoteType) string { return "" } -func printProtocolParams(protocol ir.Protocol, isSource bool) string { +func printProtocolParams(protocol netp.Protocol, isSource bool) string { switch p := protocol.(type) { - case ir.ICMP: + case netp.ICMP: return printICMPTypeCode(protocol) - case ir.TCPUDP: - var r ir.PortRange + case netp.TCPUDP: + var r interval.Interval if isSource { r = p.PortRangePair.SrcPort } else { r = p.PortRangePair.DstPort } return sGPort(r) - case ir.AnyProtocol: + case netp.AnyProtocol: return "" default: log.Panicf("Impossible protocol %v", p) diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index 9106f392..e3427b1c 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -10,7 +10,8 @@ import ( "fmt" "strings" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/tfio/tf" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" @@ -27,22 +28,22 @@ func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string) error { return err } -func aclProtocol(t ir.Protocol) []tf.Block { +func aclProtocol(t netp.Protocol) []tf.Block { switch p := t.(type) { - case ir.TCPUDP: + case netp.TCPUDP: return []tf.Block{{ - Name: strings.ToLower(string(p.Protocol)), + Name: strings.ToLower(string(p.ProtocolString())), Arguments: append( portRange(p.PortRangePair.DstPort, "port"), portRange(p.PortRangePair.SrcPort, "source_port")..., ), }} - case ir.ICMP: + case netp.ICMP: return []tf.Block{{ Name: "icmp", - Arguments: codeTypeArguments(p.ICMPCodeType), + Arguments: codeTypeArguments(p.ICMPTypeCode()), }} - case ir.AnyProtocol: + case netp.AnyProtocol: return []tf.Block{} } return nil @@ -102,7 +103,7 @@ func aclCollection(t *ir.ACLCollection, vpc string) *tf.ConfigFile { } } -func subnetCidr(acl *ir.ACL) *ipblock.IPBlock { +func subnetCidr(acl *ir.ACL) *netset.IPBlock { if len(acl.Internal) > 0 { return acl.Internal[0].Target() } diff --git a/pkg/io/tfio/common.go b/pkg/io/tfio/common.go index 42a0dcfd..00b9d2b7 100644 --- a/pkg/io/tfio/common.go +++ b/pkg/io/tfio/common.go @@ -14,6 +14,9 @@ import ( "regexp" "strconv" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/vpc-network-config-synthesis/pkg/io/tfio/tf" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -27,18 +30,18 @@ func NewWriter(w io.Writer) *Writer { return &Writer{w: bufio.NewWriter(w)} } -func portRange(r ir.PortRange, prefix string) []tf.Argument { +func portRange(r interval.Interval, prefix string) []tf.Argument { var arguments []tf.Argument - if r.Min != ir.DefaultMinPort { - arguments = append(arguments, tf.Argument{Name: prefix + "_min", Value: strconv.Itoa(r.Min)}) + if r.Start() != netp.MinPort { + arguments = append(arguments, tf.Argument{Name: prefix + "_min", Value: strconv.Itoa(int(r.Start()))}) } - if r.Max != ir.DefaultMaxPort { - arguments = append(arguments, tf.Argument{Name: prefix + "_max", Value: strconv.Itoa(r.Max)}) + if r.End() != netp.MaxPort { + arguments = append(arguments, tf.Argument{Name: prefix + "_max", Value: strconv.Itoa(int(r.End()))}) } return arguments } -func codeTypeArguments(ct *ir.ICMPCodeType) []tf.Argument { +func codeTypeArguments(ct *netp.ICMPTypeCode) []tf.Argument { var arguments []tf.Argument if ct != nil { arguments = append(arguments, tf.Argument{Name: "type", Value: strconv.Itoa(ct.Type)}) diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index b23df0e1..7ad0aa29 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -10,7 +10,9 @@ import ( "log" "strings" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/tfio/tf" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" @@ -29,7 +31,7 @@ func (w *Writer) WriteSG(c *ir.SGCollection, vpc string) error { func value(x interface{}) string { switch v := x.(type) { - case *ipblock.IPBlock: + case *netset.IPBlock: return quote(v.String()) case ir.SGName: return ir.ChangeScoping(fmt.Sprintf("ibm_is_security_group.%v.id", v)) @@ -39,25 +41,25 @@ func value(x interface{}) string { return "" } -func sgProtocol(t ir.Protocol, d ir.Direction) []tf.Block { +func sgProtocol(t netp.Protocol, d ir.Direction) []tf.Block { switch p := t.(type) { - case ir.TCPUDP: - var remotePort ir.PortRange + case netp.TCPUDP: + var remotePort interval.Interval if d == ir.Inbound { remotePort = p.PortRangePair.SrcPort } else { remotePort = p.PortRangePair.DstPort } return []tf.Block{{ - Name: strings.ToLower(string(p.Protocol)), + Name: strings.ToLower(string(p.ProtocolString())), Arguments: portRange(remotePort, "port"), }} - case ir.ICMP: + case netp.ICMP: return []tf.Block{{ Name: "icmp", - Arguments: codeTypeArguments(p.ICMPCodeType), + Arguments: codeTypeArguments(p.ICMPTypeCode()), }} - case ir.AnyProtocol: + case netp.AnyProtocol: return []tf.Block{} } return nil diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index 7b2de229..cf6ed062 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -9,7 +9,8 @@ import ( "fmt" "reflect" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) @@ -24,9 +25,9 @@ const ( type ACLRule struct { Action Action Direction Direction - Source *ipblock.IPBlock - Destination *ipblock.IPBlock - Protocol Protocol + Source *netset.IPBlock + Destination *netset.IPBlock + Protocol netp.Protocol Explanation string } @@ -61,7 +62,7 @@ func (r *ACLRule) mustSupersede(other *ACLRule) bool { return res } -func (r *ACLRule) Target() *ipblock.IPBlock { +func (r *ACLRule) Target() *netset.IPBlock { if r.Direction == Inbound { return r.Destination } diff --git a/pkg/ir/common.go b/pkg/ir/common.go index 64ac7072..e10b1265 100644 --- a/pkg/ir/common.go +++ b/pkg/ir/common.go @@ -12,15 +12,6 @@ const ( Inbound Direction = "inbound" ) -type Protocol interface { - // InverseDirection returns the response expected for a request made using this protocol - InverseDirection() Protocol -} - -type AnyProtocol struct{} - -func (t AnyProtocol) InverseDirection() Protocol { return AnyProtocol{} } - type Writer interface { ACLWriter SGWriter diff --git a/pkg/ir/icmp.go b/pkg/ir/icmp.go deleted file mode 100644 index 903538bc..00000000 --- a/pkg/ir/icmp.go +++ /dev/null @@ -1,105 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package ir - -import ( - "fmt" - "log" - "slices" -) - -type ICMPCodeType struct { - // ICMP type allowed. - Type int - - // ICMP code allowed. If omitted, any code is allowed - Code *int -} - -type ICMP struct { - *ICMPCodeType -} - -func (t ICMP) InverseDirection() Protocol { - if t.ICMPCodeType == nil { - return nil - } - - if invType := inverseICMPType(t.Type); invType != undefinedICMP { - return ICMP{ICMPCodeType: &ICMPCodeType{Type: invType, Code: t.Code}} - } - return nil -} - -// Based on https://datatracker.ietf.org/doc/html/rfc792 - -const ( - echoReply = 0 - destinationUnreachable = 3 - sourceQuench = 4 - redirect = 5 - echo = 8 - timeExceeded = 11 - parameterProblem = 12 - timestamp = 13 - timestampReply = 14 - informationRequest = 15 - informationReply = 16 - - undefinedICMP = -2 -) - -// inverseICMPType returns the reply type for request type and vice versa. -// When there is no inverse, returns undefinedICMP -func inverseICMPType(t int) int { - switch t { - case echo: - return echoReply - case echoReply: - return echo - - case timestamp: - return timestampReply - case timestampReply: - return timestamp - - case informationRequest: - return informationReply - case informationReply: - return informationRequest - - case destinationUnreachable, sourceQuench, redirect, timeExceeded, parameterProblem: - return undefinedICMP - default: - log.Panicf("Impossible ICMP type: %v", t) - } - return undefinedICMP -} - -//nolint:revive // magic numbers are fine here -func ValidateICMP(t, c int) error { - possibleCodes := map[int][]int{ - echoReply: {0}, - destinationUnreachable: {0, 1, 2, 3, 4, 5}, - sourceQuench: {0}, - redirect: {0, 1, 2, 3}, - echo: {0}, - timeExceeded: {0, 1}, - parameterProblem: {0}, - timestamp: {0}, - timestampReply: {0}, - informationRequest: {0}, - informationReply: {0}, - } - options, ok := possibleCodes[t] - if !ok { - return fmt.Errorf("invalid ICMP type %v", t) - } - if !slices.Contains(options, c) { - return fmt.Errorf("ICMP code %v is invalid for ICMP type %v", c, t) - } - return nil -} diff --git a/pkg/ir/packet.go b/pkg/ir/packet.go index 818fa2f3..1d70ed69 100644 --- a/pkg/ir/packet.go +++ b/pkg/ir/packet.go @@ -9,12 +9,13 @@ import ( "fmt" "log" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" ) type Packet struct { - Src, Dst *ipblock.IPBlock - Protocol Protocol + Src, Dst *netset.IPBlock + Protocol netp.Protocol Explanation string } @@ -39,42 +40,42 @@ func packetACLRule(packet *Packet, direction Direction, action Action) *ACLRule // makeDenyInternal prevents allowing external communications from accidentally allowing internal communications too func makeDenyInternal() []ACLRule { - cidr1, err := ipblock.FromCidr("10.0.0.0/8") + cidr1, err := netset.IPBlockFromCidr("10.0.0.0/8") if err != nil { log.Fatal(err) } - cidr2, err := ipblock.FromCidr("172.16.0.0/12") + cidr2, err := netset.IPBlockFromCidr("172.16.0.0/12") if err != nil { log.Fatal(err) } - cidr3, err := ipblock.FromCidr("192.168.0.0/16") + cidr3, err := netset.IPBlockFromCidr("192.168.0.0/16") if err != nil { log.Fatal(err) } - localCidrs := []*ipblock.IPBlock{cidr1, cidr2, cidr3} // https://datatracker.ietf.org/doc/html/rfc1918#section-3 + localCidrs := []*netset.IPBlock{cidr1, cidr2, cidr3} // https://datatracker.ietf.org/doc/html/rfc1918#section-3 var denyInternal []ACLRule - for i, anyLocalCidrSrc := range localCidrs { - for j, anyLocalCidrDst := range localCidrs { + for i, localSrc := range localCidrs { + for j, localDst := range localCidrs { explanation := fmt.Sprintf("Deny other internal communication; see rfc1918#3; item %v,%v", i, j) denyInternal = append(denyInternal, - *packetACLRule(&Packet{Src: anyLocalCidrSrc, Dst: anyLocalCidrDst, Protocol: AnyProtocol{}, Explanation: explanation}, Outbound, Deny), - *packetACLRule(&Packet{Src: anyLocalCidrDst, Dst: anyLocalCidrSrc, Protocol: AnyProtocol{}, Explanation: explanation}, Inbound, Deny), + *packetACLRule(&Packet{Src: localSrc, Dst: localDst, Protocol: netp.AnyProtocol{}, Explanation: explanation}, Outbound, Deny), + *packetACLRule(&Packet{Src: localDst, Dst: localSrc, Protocol: netp.AnyProtocol{}, Explanation: explanation}, Inbound, Deny), ) } } return denyInternal } -func DenyAllSend(subnetName ID, cidr *ipblock.IPBlock) *ACLRule { +func DenyAllSend(subnetName ID, cidr *netset.IPBlock) *ACLRule { explanation := DenyAllExplanation(subnetName, cidr) - return packetACLRule(&Packet{Src: cidr, Dst: ipblock.GetCidrAll(), Protocol: AnyProtocol{}, Explanation: explanation}, Outbound, Deny) + return packetACLRule(&Packet{Src: cidr, Dst: netset.GetCidrAll(), Protocol: netp.AnyProtocol{}, Explanation: explanation}, Outbound, Deny) } -func DenyAllReceive(subnetName ID, cidr *ipblock.IPBlock) *ACLRule { +func DenyAllReceive(subnetName ID, cidr *netset.IPBlock) *ACLRule { explanation := DenyAllExplanation(subnetName, cidr) - return packetACLRule(&Packet{Src: ipblock.GetCidrAll(), Dst: cidr, Protocol: AnyProtocol{}, Explanation: explanation}, Inbound, Deny) + return packetACLRule(&Packet{Src: netset.GetCidrAll(), Dst: cidr, Protocol: netp.AnyProtocol{}, Explanation: explanation}, Inbound, Deny) } -func DenyAllExplanation(subnetName ID, cidr *ipblock.IPBlock) string { +func DenyAllExplanation(subnetName ID, cidr *netset.IPBlock) string { return fmt.Sprintf("Deny all communication; subnet %s[%s] does not have required connections", subnetName, cidr.String()) } diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 56617a11..4035ea69 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -9,6 +9,8 @@ import ( "fmt" "reflect" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) @@ -31,13 +33,13 @@ func (s SGName) String() string { type RemoteType interface { fmt.Stringer - // *ipblock.IPBlock | SGName + // *netset.IPBlock | SGName } type SGRule struct { Direction Direction Remote RemoteType - Protocol Protocol + Protocol netp.Protocol Explanation string } diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index 2ca236d6..6e3c58aa 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -12,7 +12,8 @@ import ( "sort" "strings" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" ) const MaximalIPv4PrefixLength = 32 @@ -47,14 +48,14 @@ type ( Name string // list of CIDR / Ip addresses. - IPAddrs []*ipblock.IPBlock + IPAddrs []*netset.IPBlock // Type of resource Type ResourceType } TrackedProtocol struct { - Protocol + netp.Protocol Origin fmt.Stringer } @@ -88,20 +89,20 @@ type ( } VPCDetails struct { - AddressPrefixes *ipblock.IPBlock + AddressPrefixes *netset.IPBlock // tg // lb } SubnetDetails struct { NamedEntity - CIDR *ipblock.IPBlock + CIDR *netset.IPBlock VPC ID } NifDetails struct { NamedEntity - IP *ipblock.IPBlock + IP *netset.IPBlock VPC ID Instance ID Subnet ID @@ -115,7 +116,7 @@ type ( VPEReservedIPsDetails struct { NamedEntity - IP *ipblock.IPBlock + IP *netset.IPBlock VPEName ID Subnet ID VPC ID @@ -133,7 +134,7 @@ type ( } CidrSegmentDetails struct { - Cidrs map[*ipblock.IPBlock]CIDRDetails + Cidrs map[*netset.IPBlock]CIDRDetails } CIDRDetails struct { @@ -142,7 +143,7 @@ type ( } ExternalDetails struct { - ExternalAddrs *ipblock.IPBlock + ExternalAddrs *netset.IPBlock } Named interface { @@ -150,7 +151,7 @@ type ( } NWResource interface { - Address() *ipblock.IPBlock + Address() *netset.IPBlock } ResourceVpc interface { @@ -162,19 +163,19 @@ func (n *NamedEntity) Name() string { return string(*n) } -func (s *SubnetDetails) Address() *ipblock.IPBlock { +func (s *SubnetDetails) Address() *netset.IPBlock { return s.CIDR } -func (n *NifDetails) Address() *ipblock.IPBlock { +func (n *NifDetails) Address() *netset.IPBlock { return n.IP } -func (v *VPEReservedIPsDetails) Address() *ipblock.IPBlock { +func (v *VPEReservedIPsDetails) Address() *netset.IPBlock { return v.IP } -func (e *ExternalDetails) Address() *ipblock.IPBlock { +func (e *ExternalDetails) Address() *netset.IPBlock { return e.ExternalAddrs } @@ -225,14 +226,14 @@ func getResourceVPCs[T ResourceVpc](m map[ID]T, name string) []ID { func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (Resource, error) { if details, ok := m[name]; ok { - return Resource{name, []*ipblock.IPBlock{details.Address()}, t}, nil + return Resource{name, []*netset.IPBlock{details.Address()}, t}, nil } return Resource{}, resourceNotFoundError(name, t) } func (s *Definitions) lookupInstance(name string) (Resource, error) { if instanceDetails, ok := s.Instances[name]; ok { - ips := make([]*ipblock.IPBlock, len(instanceDetails.Nifs)) + ips := make([]*netset.IPBlock, len(instanceDetails.Nifs)) for i, elemName := range instanceDetails.Nifs { nif, err := s.Lookup(ResourceTypeNIF, elemName) if err != nil { @@ -251,7 +252,7 @@ func (s *Definitions) lookupVPE(name string) (Resource, error) { if !ok { return Resource{}, resourceNotFoundError(name, ResourceTypeVPE) } - ips := make([]*ipblock.IPBlock, len(VPEDetails.VPEReservedIPs)) + ips := make([]*netset.IPBlock, len(VPEDetails.VPEReservedIPs)) for i, vpeEndPoint := range VPEDetails.VPEReservedIPs { ips[i] = s.VPEReservedIPs[vpeEndPoint].IP } @@ -260,7 +261,7 @@ func (s *Definitions) lookupVPE(name string) (Resource, error) { func (s *Definitions) lookupSubnetSegment(name string) (Resource, error) { if subnetSegmentDetails, ok := s.SubnetSegments[name]; ok { - cidrs := make([]*ipblock.IPBlock, len(subnetSegmentDetails.Subnets)) + cidrs := make([]*netset.IPBlock, len(subnetSegmentDetails.Subnets)) for i, subnetName := range subnetSegmentDetails.Subnets { subnet, err := s.Lookup(ResourceTypeSubnet, subnetName) if err != nil { @@ -279,7 +280,7 @@ func (s *Definitions) lookupCidrSegment(name string) (Resource, error) { if !ok { return Resource{}, containerNotFoundError(name, ResourceTypeSegment) } - cidrs := make([]*ipblock.IPBlock, len(cidrSegmentDetails.Cidrs)) + cidrs := make([]*netset.IPBlock, len(cidrSegmentDetails.Cidrs)) i := 0 for cidr := range cidrSegmentDetails.Cidrs { cidrs[i] = cidr @@ -348,7 +349,7 @@ func (s *Definitions) ValidateConnection(srcVPCs, dstVPCs []ID) error { return nil } -func inverseLookup[T NWResource](m map[ID]T, address *ipblock.IPBlock) (result string, ok bool) { +func inverseLookup[T NWResource](m map[ID]T, address *netset.IPBlock) (result string, ok bool) { for name, details := range m { if details.Address().Equal(address) { return name, true @@ -357,7 +358,7 @@ func inverseLookup[T NWResource](m map[ID]T, address *ipblock.IPBlock) (result s return "", false } -func (s *ConfigDefs) NIFFromIP(ip *ipblock.IPBlock) (string, bool) { +func (s *ConfigDefs) NIFFromIP(ip *netset.IPBlock) (string, bool) { return inverseLookup(s.NIFs, ip) } @@ -365,10 +366,10 @@ type Reader interface { ReadSpec(filename string, defs *ConfigDefs) (*Spec, error) } -func (s *ConfigDefs) SubnetsContainedInCidr(cidr ipblock.IPBlock) ([]ID, error) { +func (s *ConfigDefs) SubnetsContainedInCidr(cidr netset.IPBlock) ([]ID, error) { var containedSubnets []string for subnet, subnetDetails := range s.Subnets { - if subnetDetails.CIDR.ContainedIn(&cidr) { + if subnetDetails.CIDR.IsSubset(&cidr) { containedSubnets = append(containedSubnets, subnet) } } @@ -406,7 +407,7 @@ func VpcFromScopedResource(resource ID) ID { return ScopingComponents(resource)[0] } -func IsIPAddress(address *ipblock.IPBlock) bool { +func IsIPAddress(address *netset.IPBlock) bool { prefixLength, err := address.PrefixLength() if err != nil { log.Fatal(err) @@ -417,3 +418,8 @@ func IsIPAddress(address *ipblock.IPBlock) bool { func ChangeScoping(s string) string { return strings.ReplaceAll(s, "/", "--") } + +// Todo: move this function to models repo (as a method) +func Overlap(a, b *netset.IPBlock) bool { + return !a.Intersect(b).IsEmpty() +} diff --git a/pkg/ir/tcpudp.go b/pkg/ir/tcpudp.go deleted file mode 100644 index a9a74180..00000000 --- a/pkg/ir/tcpudp.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package ir - -import "log" - -type TransportLayerProtocolName string - -const ( - TCP TransportLayerProtocolName = "TCP" - UDP TransportLayerProtocolName = "UDP" -) - -const DefaultMinPort = 1 -const DefaultMaxPort = 65535 - -type PortRange struct { - // Minimal port; default is DefaultMinPort - Min int - - // Maximal port; default is DefaultMaxPort - Max int -} - -type PortRangePair struct { - SrcPort PortRange - DstPort PortRange -} - -type TCPUDP struct { - Protocol TransportLayerProtocolName - PortRangePair PortRangePair -} - -func (t TCPUDP) InverseDirection() Protocol { - switch t.Protocol { - case TCP: - return TCPUDP{ - Protocol: TCP, - PortRangePair: PortRangePair{SrcPort: t.PortRangePair.DstPort, DstPort: t.PortRangePair.SrcPort}, - } - case UDP: - return nil - default: - log.Panicf("Impossible protocol: %v", t.Protocol) - } - return nil -} diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index 352f43e2..46201f1e 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -10,7 +10,7 @@ import ( "fmt" "log" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -78,7 +78,7 @@ func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection) { // if the src in internal, rule(s) will be created to allow traffic. // if the protocol allows response, more rules will be created. func (a *ACLSynthesizer) allowConnectionFromSrc(conn *ir.Connection, trackedProtocol ir.TrackedProtocol, - srcSubnets []*namedAddrs, dstCidr *ipblock.IPBlock) { + srcSubnets []*namedAddrs, dstCidr *netset.IPBlock) { internalSrc, _, internal := internalConn(conn) if !internalSrc { @@ -101,7 +101,7 @@ func (a *ACLSynthesizer) allowConnectionFromSrc(conn *ir.Connection, trackedProt // if the dst in internal, rule(s) will be created to allow traffic. // if the protocol allows response, more rules will be created. func (a *ACLSynthesizer) allowConnectionToDst(conn *ir.Connection, trackedProtocol ir.TrackedProtocol, - dstSubnets []*namedAddrs, srcCidr *ipblock.IPBlock) { + dstSubnets []*namedAddrs, srcCidr *netset.IPBlock) { _, internalDst, internal := internalConn(conn) if !internalDst { @@ -134,7 +134,7 @@ func (a *ACLSynthesizer) generateACLRulesForBlockedSubnets() { // convert src and dst resources to namedAddrs slices to make it more convenient to go through the addrs and add // the rule to the relevant acl. Note: in case where the resource in a nif, src/dst will be updated to be its subnet. -func adjustResource(s *ir.Definitions, addrs *ipblock.IPBlock, resource ir.Resource) ([]*namedAddrs, *ipblock.IPBlock) { +func adjustResource(s *ir.Definitions, addrs *netset.IPBlock, resource ir.Resource) ([]*namedAddrs, *netset.IPBlock) { switch resource.Type { case ir.ResourceTypeSubnet: return adjustSubnet(s, addrs, resource.Name), addrs @@ -149,7 +149,7 @@ func adjustResource(s *ir.Definitions, addrs *ipblock.IPBlock, resource ir.Resou return []*namedAddrs{}, nil // shouldn't happen } -func adjustSubnet(s *ir.Definitions, addrs *ipblock.IPBlock, resourceName string) []*namedAddrs { +func adjustSubnet(s *ir.Definitions, addrs *netset.IPBlock, resourceName string) []*namedAddrs { // Todo: Handle the case where there is a subnet and a subnetSegment with the same name if subnetDetails, ok := s.Subnets[resourceName]; ok { // resource is a subnet return []*namedAddrs{{Name: resourceName, Addrs: subnetDetails.Address()}} @@ -163,7 +163,7 @@ func adjustSubnet(s *ir.Definitions, addrs *ipblock.IPBlock, resourceName string return []*namedAddrs{} // shouldn't happen } -func adjustCidrSegment(s *ir.Definitions, cidr *ipblock.IPBlock, resourceName string) []*namedAddrs { +func adjustCidrSegment(s *ir.Definitions, cidr *netset.IPBlock, resourceName string) []*namedAddrs { cidrSegmentDetails := s.CidrSegments[resourceName] cidrDetails := cidrSegmentDetails.Cidrs[cidr] result := make([]*namedAddrs, len(cidrDetails.ContainedSubnets)) @@ -173,7 +173,7 @@ func adjustCidrSegment(s *ir.Definitions, cidr *ipblock.IPBlock, resourceName st return result } -func expandNifToSubnet(s *ir.Definitions, addr *ipblock.IPBlock) []*namedAddrs { +func expandNifToSubnet(s *ir.Definitions, addr *netset.IPBlock) []*namedAddrs { nifName, _ := s.NIFFromIP(addr) // already checked before (Lookup function) that the NIF exists subnetName := s.NIFs[nifName].Subnet subnetCidr := s.Subnets[subnetName].Address() diff --git a/pkg/synth/common.go b/pkg/synth/common.go index 01faf137..9833c121 100644 --- a/pkg/synth/common.go +++ b/pkg/synth/common.go @@ -8,7 +8,7 @@ package synth import ( "fmt" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -20,7 +20,7 @@ type ( namedAddrs struct { Name ir.ID - Addrs *ipblock.IPBlock + Addrs *netset.IPBlock } explanation struct { diff --git a/test/data/acl_nif/nacl_expected.tf b/test/data/acl_nif/nacl_expected.tf index 28738340..5d999aac 100644 --- a/test/data/acl_nif/nacl_expected.tf +++ b/test/data/acl_nif/nacl_expected.tf @@ -12,7 +12,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { destination = "10.240.0.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet4)->(instance test-vpc0/vsi0-subnet0); allowed-protocols[0] @@ -24,7 +23,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { destination = "10.240.8.0/24" icmp { type = 8 - code = 0 } } } @@ -116,7 +114,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { destination = "10.240.0.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet4)->(instance test-vpc0/vsi0-subnet0); allowed-protocols[0] @@ -128,7 +125,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { destination = "10.240.8.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[1]: (nif test-vpc0/vsi0-subnet1/scale-clambake-endearing-abridged)->(subnet test-vpc0/subnet4); allowed-protocols[0] diff --git a/test/data/acl_testing5/nacl_expected.csv b/test/data/acl_testing5/nacl_expected.csv index f3f0f5fa..0ccc67b6 100644 --- a/test/data/acl_testing5/nacl_expected.csv +++ b/test/data/acl_testing5/nacl_expected.csv @@ -1,8 +1,8 @@ Acl,Subnet,Direction,Rule priority,Allow or deny,Protocol,Source,Destination,Value,Description acl-testacl5-vpc/sub1-1,testacl5-vpc/sub1-1,Outbound,1,Allow,ALL,10.240.1.0/24,10.240.64.0/24,-,Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] acl-testacl5-vpc/sub1-1,testacl5-vpc/sub1-1,Inbound,2,Allow,ALL,10.240.64.0/24,10.240.1.0/24,-,Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] -acl-testacl5-vpc/sub1-1,testacl5-vpc/sub1-1,Outbound,3,Allow,ICMP,10.240.1.0/24,10.240.128.0/24,"Type: 0, Code: 0",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/sub1-1,testacl5-vpc/sub1-1,Inbound,4,Allow,ICMP,10.240.128.0/24,10.240.1.0/24,"Type: 8, Code: 0",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/sub1-1,testacl5-vpc/sub1-1,Outbound,3,Allow,ICMP,10.240.1.0/24,10.240.128.0/24,"Type: 0, Code: Any",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/sub1-1,testacl5-vpc/sub1-1,Inbound,4,Allow,ICMP,10.240.128.0/24,10.240.1.0/24,"Type: 8, Code: Any",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] acl-testacl5-vpc/sub1-1,testacl5-vpc/sub1-1,Outbound,5,Allow,TCP,"10.240.1.0/24, any port","10.240.2.0/24, any port",-,Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] acl-testacl5-vpc/sub1-1,testacl5-vpc/sub1-1,Inbound,6,Allow,TCP,"10.240.2.0/24, any port","10.240.1.0/24, any port",-,Internal. response to required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] acl-testacl5-vpc/sub1-1,testacl5-vpc/sub1-1,Outbound,7,Allow,TCP,"10.240.1.0/24, any port","10.240.3.0/24, any port",-,Internal. required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] @@ -36,8 +36,8 @@ acl-testacl5-vpc/sub1-3,testacl5-vpc/sub1-3,Inbound,3,Allow,TCP,"10.240.2.0/24, acl-testacl5-vpc/sub1-3,testacl5-vpc/sub1-3,Outbound,4,Allow,TCP,"10.240.3.0/24, any port","10.240.2.0/24, any port",-,Internal. response to required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Inbound,1,Allow,ALL,10.240.1.0/24,10.240.64.0/24,-,Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Outbound,2,Allow,ALL,10.240.64.0/24,10.240.1.0/24,-,Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] -acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Outbound,3,Allow,ICMP,10.240.64.0/24,10.240.128.0/24,"Type: 0, Code: 0",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Inbound,4,Allow,ICMP,10.240.128.0/24,10.240.64.0/24,"Type: 8, Code: 0",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Outbound,3,Allow,ICMP,10.240.64.0/24,10.240.128.0/24,"Type: 0, Code: Any",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Inbound,4,Allow,ICMP,10.240.128.0/24,10.240.64.0/24,"Type: 8, Code: Any",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Outbound,5,Allow,ALL,10.240.64.0/24,10.240.65.0/24,-,Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Inbound,6,Allow,ALL,10.240.65.0/24,10.240.64.0/24,-,Internal. response to required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Inbound,7,Allow,TCP,"10.240.128.0/24, any port","10.240.64.0/24, ports 443-443",-,Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] @@ -63,9 +63,9 @@ acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Inbound,26,Deny,ALL,192.168.0.0/16,1 acl-testacl5-vpc/sub2-1,testacl5-vpc/sub2-1,Outbound,27,Allow,UDP,"10.240.64.0/24, any port","8.8.8.8, ports 53-53",-,External. required-connections[1]: (segment need-dns)->(external dns); allowed-protocols[0] acl-testacl5-vpc/sub2-2,testacl5-vpc/sub2-2,Inbound,1,Allow,ALL,10.240.64.0/24,10.240.65.0/24,-,Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] acl-testacl5-vpc/sub2-2,testacl5-vpc/sub2-2,Outbound,2,Allow,ALL,10.240.65.0/24,10.240.64.0/24,-,Internal. response to required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] -acl-testacl5-vpc/sub3-1,testacl5-vpc/sub3-1,Inbound,1,Allow,ICMP,10.240.1.0/24,10.240.128.0/24,"Type: 0, Code: 0",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/sub3-1,testacl5-vpc/sub3-1,Outbound,2,Allow,ICMP,10.240.128.0/24,10.240.1.0/24,"Type: 8, Code: 0",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/sub3-1,testacl5-vpc/sub3-1,Inbound,3,Allow,ICMP,10.240.64.0/24,10.240.128.0/24,"Type: 0, Code: 0",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/sub3-1,testacl5-vpc/sub3-1,Outbound,4,Allow,ICMP,10.240.128.0/24,10.240.64.0/24,"Type: 8, Code: 0",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/sub3-1,testacl5-vpc/sub3-1,Inbound,1,Allow,ICMP,10.240.1.0/24,10.240.128.0/24,"Type: 0, Code: Any",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/sub3-1,testacl5-vpc/sub3-1,Outbound,2,Allow,ICMP,10.240.128.0/24,10.240.1.0/24,"Type: 8, Code: Any",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/sub3-1,testacl5-vpc/sub3-1,Inbound,3,Allow,ICMP,10.240.64.0/24,10.240.128.0/24,"Type: 0, Code: Any",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/sub3-1,testacl5-vpc/sub3-1,Outbound,4,Allow,ICMP,10.240.128.0/24,10.240.64.0/24,"Type: 8, Code: Any",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] acl-testacl5-vpc/sub3-1,testacl5-vpc/sub3-1,Outbound,5,Allow,TCP,"10.240.128.0/24, any port","10.240.64.0/24, ports 443-443",-,Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] acl-testacl5-vpc/sub3-1,testacl5-vpc/sub3-1,Inbound,6,Allow,TCP,"10.240.64.0/24, ports 443-443","10.240.128.0/24, any port",-,Internal. response to required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] diff --git a/test/data/acl_testing5/nacl_expected.json b/test/data/acl_testing5/nacl_expected.json index 22f73491..92a4c2ae 100644 --- a/test/data/acl_testing5/nacl_expected.json +++ b/test/data/acl_testing5/nacl_expected.json @@ -1758,7 +1758,6 @@ "ip_version": "ipv4", "name": "rule2", "source": "10.240.1.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -1777,7 +1776,6 @@ "ip_version": "ipv4", "name": "rule3", "source": "10.240.128.0/24", - "code": 0, "protocol": "icmp", "type": 8 }, @@ -2267,7 +2265,6 @@ "ip_version": "ipv4", "name": "rule2", "source": "10.240.64.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -2286,7 +2283,6 @@ "ip_version": "ipv4", "name": "rule3", "source": "10.240.128.0/24", - "code": 0, "protocol": "icmp", "type": 8 }, @@ -2904,7 +2900,6 @@ "ip_version": "ipv4", "name": "rule0", "source": "10.240.1.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -2923,7 +2918,6 @@ "ip_version": "ipv4", "name": "rule1", "source": "10.240.128.0/24", - "code": 0, "protocol": "icmp", "type": 8 }, @@ -2942,7 +2936,6 @@ "ip_version": "ipv4", "name": "rule2", "source": "10.240.64.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -2961,7 +2954,6 @@ "ip_version": "ipv4", "name": "rule3", "source": "10.240.128.0/24", - "code": 0, "protocol": "icmp", "type": 8 }, diff --git a/test/data/acl_testing5/nacl_expected.tf b/test/data/acl_testing5/nacl_expected.tf index 869e03f2..69925897 100644 --- a/test/data/acl_testing5/nacl_expected.tf +++ b/test/data/acl_testing5/nacl_expected.tf @@ -28,7 +28,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { destination = "10.240.128.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -40,7 +39,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { destination = "10.240.1.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] @@ -365,7 +363,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { destination = "10.240.128.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -377,7 +374,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] @@ -615,7 +611,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { destination = "10.240.128.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -627,7 +622,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { destination = "10.240.1.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -639,7 +633,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { destination = "10.240.128.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -651,7 +644,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] diff --git a/test/data/acl_testing5/nacl_single_expected.csv b/test/data/acl_testing5/nacl_single_expected.csv index f988c39d..8ce037d1 100644 --- a/test/data/acl_testing5/nacl_single_expected.csv +++ b/test/data/acl_testing5/nacl_single_expected.csv @@ -3,14 +3,14 @@ acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,1,Allow,ALL,10.240.1. acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,2,Allow,ALL,10.240.64.0/24,10.240.1.0/24,-,Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,3,Allow,ALL,10.240.1.0/24,10.240.64.0/24,-,Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,4,Allow,ALL,10.240.64.0/24,10.240.1.0/24,-,Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] -acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,5,Allow,ICMP,10.240.1.0/24,10.240.128.0/24,"Type: 0, Code: 0",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,6,Allow,ICMP,10.240.128.0/24,10.240.1.0/24,"Type: 8, Code: 0",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,7,Allow,ICMP,10.240.1.0/24,10.240.128.0/24,"Type: 0, Code: 0",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,8,Allow,ICMP,10.240.128.0/24,10.240.1.0/24,"Type: 8, Code: 0",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,9,Allow,ICMP,10.240.64.0/24,10.240.128.0/24,"Type: 0, Code: 0",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,10,Allow,ICMP,10.240.128.0/24,10.240.64.0/24,"Type: 8, Code: 0",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,11,Allow,ICMP,10.240.64.0/24,10.240.128.0/24,"Type: 0, Code: 0",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] -acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,12,Allow,ICMP,10.240.128.0/24,10.240.64.0/24,"Type: 8, Code: 0",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,5,Allow,ICMP,10.240.1.0/24,10.240.128.0/24,"Type: 0, Code: Any",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,6,Allow,ICMP,10.240.128.0/24,10.240.1.0/24,"Type: 8, Code: Any",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,7,Allow,ICMP,10.240.1.0/24,10.240.128.0/24,"Type: 0, Code: Any",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,8,Allow,ICMP,10.240.128.0/24,10.240.1.0/24,"Type: 8, Code: Any",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,9,Allow,ICMP,10.240.64.0/24,10.240.128.0/24,"Type: 0, Code: Any",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,10,Allow,ICMP,10.240.128.0/24,10.240.64.0/24,"Type: 8, Code: Any",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,11,Allow,ICMP,10.240.64.0/24,10.240.128.0/24,"Type: 0, Code: Any",Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] +acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,12,Allow,ICMP,10.240.128.0/24,10.240.64.0/24,"Type: 8, Code: Any",Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Outbound,13,Allow,TCP,"10.240.1.0/24, any port","10.240.2.0/24, any port",-,Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,14,Allow,TCP,"10.240.2.0/24, any port","10.240.1.0/24, any port",-,Internal. response to required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] acl-testacl5-vpc/singleACL,testacl5-vpc/singleACL,Inbound,15,Allow,TCP,"10.240.1.0/24, any port","10.240.2.0/24, any port",-,Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] diff --git a/test/data/acl_testing5/nacl_single_expected.json b/test/data/acl_testing5/nacl_single_expected.json index 446037d3..c60b8d79 100644 --- a/test/data/acl_testing5/nacl_single_expected.json +++ b/test/data/acl_testing5/nacl_single_expected.json @@ -1682,7 +1682,6 @@ "ip_version": "ipv4", "name": "rule4", "source": "10.240.1.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -1701,7 +1700,6 @@ "ip_version": "ipv4", "name": "rule5", "source": "10.240.128.0/24", - "code": 0, "protocol": "icmp", "type": 8 }, @@ -1720,7 +1718,6 @@ "ip_version": "ipv4", "name": "rule6", "source": "10.240.1.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -1739,7 +1736,6 @@ "ip_version": "ipv4", "name": "rule7", "source": "10.240.128.0/24", - "code": 0, "protocol": "icmp", "type": 8 }, @@ -1758,7 +1754,6 @@ "ip_version": "ipv4", "name": "rule8", "source": "10.240.64.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -1777,7 +1772,6 @@ "ip_version": "ipv4", "name": "rule9", "source": "10.240.128.0/24", - "code": 0, "protocol": "icmp", "type": 8 }, @@ -1796,7 +1790,6 @@ "ip_version": "ipv4", "name": "rule10", "source": "10.240.64.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -1815,7 +1808,6 @@ "ip_version": "ipv4", "name": "rule11", "source": "10.240.128.0/24", - "code": 0, "protocol": "icmp", "type": 8 }, diff --git a/test/data/acl_testing5/nacl_single_expected.tf b/test/data/acl_testing5/nacl_single_expected.tf index 1a9f0301..5e3a1e07 100644 --- a/test/data/acl_testing5/nacl_single_expected.tf +++ b/test/data/acl_testing5/nacl_single_expected.tf @@ -43,7 +43,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { destination = "10.240.128.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -55,7 +54,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { destination = "10.240.1.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -67,7 +65,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { destination = "10.240.128.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -79,7 +76,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { destination = "10.240.1.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -91,7 +87,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { destination = "10.240.128.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -103,7 +98,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -115,7 +109,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { destination = "10.240.128.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] @@ -127,7 +120,6 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] diff --git a/test/data/acl_tg_multiple/nacl_expected.json b/test/data/acl_tg_multiple/nacl_expected.json index 97dc909e..bccff41e 100644 --- a/test/data/acl_tg_multiple/nacl_expected.json +++ b/test/data/acl_tg_multiple/nacl_expected.json @@ -2500,7 +2500,6 @@ "ip_version": "ipv4", "name": "rule0", "source": "10.240.8.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -2514,7 +2513,6 @@ "ip_version": "ipv4", "name": "rule1", "source": "10.240.9.0/24", - "code": 0, "protocol": "icmp", "type": 8 } @@ -2713,7 +2711,6 @@ "ip_version": "ipv4", "name": "rule0", "source": "10.240.64.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -2727,7 +2724,6 @@ "ip_version": "ipv4", "name": "rule1", "source": "10.240.80.0/24", - "code": 0, "protocol": "icmp", "type": 8 } @@ -2858,7 +2854,6 @@ "ip_version": "ipv4", "name": "rule0", "source": "10.240.64.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -2872,7 +2867,6 @@ "ip_version": "ipv4", "name": "rule1", "source": "10.240.80.0/24", - "code": 0, "protocol": "icmp", "type": 8 } @@ -3102,7 +3096,6 @@ "ip_version": "ipv4", "name": "rule0", "source": "10.240.8.0/24", - "code": 0, "protocol": "icmp", "type": 0 }, @@ -3116,7 +3109,6 @@ "ip_version": "ipv4", "name": "rule1", "source": "10.240.9.0/24", - "code": 0, "protocol": "icmp", "type": 8 } diff --git a/test/data/acl_tg_multiple/nacl_expected.tf b/test/data/acl_tg_multiple/nacl_expected.tf index 0fa5cc1d..3f3a8fd5 100644 --- a/test/data/acl_tg_multiple/nacl_expected.tf +++ b/test/data/acl_tg_multiple/nacl_expected.tf @@ -136,7 +136,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { destination = "10.240.9.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] @@ -148,7 +147,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { destination = "10.240.8.0/24" icmp { type = 8 - code = 0 } } } @@ -167,7 +165,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { destination = "10.240.9.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] @@ -179,7 +176,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { destination = "10.240.8.0/24" icmp { type = 8 - code = 0 } } } @@ -198,7 +194,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { destination = "10.240.80.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] @@ -210,7 +205,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } } @@ -229,7 +223,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { destination = "10.240.80.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] @@ -241,7 +234,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } } diff --git a/test/data/acl_tg_multiple/nacl_single_expected.tf b/test/data/acl_tg_multiple/nacl_single_expected.tf index 046a8f41..09a80278 100644 --- a/test/data/acl_tg_multiple/nacl_single_expected.tf +++ b/test/data/acl_tg_multiple/nacl_single_expected.tf @@ -92,7 +92,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--singleACL" { destination = "10.240.9.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] @@ -104,7 +103,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--singleACL" { destination = "10.240.8.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] @@ -116,7 +114,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--singleACL" { destination = "10.240.9.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] @@ -128,7 +125,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--singleACL" { destination = "10.240.8.0/24" icmp { type = 8 - code = 0 } } # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections @@ -163,7 +159,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--singleACL" { destination = "10.240.80.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] @@ -175,7 +170,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--singleACL" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] @@ -187,7 +181,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--singleACL" { destination = "10.240.80.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] @@ -199,7 +192,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--singleACL" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } } diff --git a/test/data/acl_tg_multiple/single_test-vpc0.tf b/test/data/acl_tg_multiple/single_test-vpc0.tf index 3850c1f2..c9ea8d01 100644 --- a/test/data/acl_tg_multiple/single_test-vpc0.tf +++ b/test/data/acl_tg_multiple/single_test-vpc0.tf @@ -91,7 +91,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--singleACL" { destination = "10.240.9.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] @@ -103,7 +102,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--singleACL" { destination = "10.240.8.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] @@ -115,7 +113,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--singleACL" { destination = "10.240.9.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] @@ -127,7 +124,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--singleACL" { destination = "10.240.8.0/24" icmp { type = 8 - code = 0 } } # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections diff --git a/test/data/acl_tg_multiple/single_test-vpc1.tf b/test/data/acl_tg_multiple/single_test-vpc1.tf index 340977f5..c8303eee 100644 --- a/test/data/acl_tg_multiple/single_test-vpc1.tf +++ b/test/data/acl_tg_multiple/single_test-vpc1.tf @@ -11,7 +11,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--singleACL" { destination = "10.240.80.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] @@ -23,7 +22,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--singleACL" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] @@ -35,7 +33,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--singleACL" { destination = "10.240.80.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] @@ -47,7 +44,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--singleACL" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } } diff --git a/test/data/acl_tg_multiple/test-vpc0.tf b/test/data/acl_tg_multiple/test-vpc0.tf index e8d70969..2a26d9dd 100644 --- a/test/data/acl_tg_multiple/test-vpc0.tf +++ b/test/data/acl_tg_multiple/test-vpc0.tf @@ -136,7 +136,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { destination = "10.240.9.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] @@ -148,7 +147,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { destination = "10.240.8.0/24" icmp { type = 8 - code = 0 } } } @@ -167,7 +165,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { destination = "10.240.9.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] @@ -179,7 +176,6 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { destination = "10.240.8.0/24" icmp { type = 8 - code = 0 } } } diff --git a/test/data/acl_tg_multiple/test-vpc1.tf b/test/data/acl_tg_multiple/test-vpc1.tf index 29667206..62ada153 100644 --- a/test/data/acl_tg_multiple/test-vpc1.tf +++ b/test/data/acl_tg_multiple/test-vpc1.tf @@ -12,7 +12,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { destination = "10.240.80.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] @@ -24,7 +23,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } } @@ -43,7 +41,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { destination = "10.240.80.0/24" icmp { type = 0 - code = 0 } } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] @@ -55,7 +52,6 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { destination = "10.240.64.0/24" icmp { type = 8 - code = 0 } } } diff --git a/test/data/sg_testing3/sg_expected.csv b/test/data/sg_testing3/sg_expected.csv index 95afca81..73c2c2b8 100644 --- a/test/data/sg_testing3/sg_expected.csv +++ b/test/data/sg_testing3/sg_expected.csv @@ -2,11 +2,11 @@ SG,Direction,Remote type,Remote,Protocol,Protocol params,Description test-vpc/be,Inbound,Security group,test-vpc/fe,TCP,any port,Internal. required-connections[2]: (instance test-vpc/fe)->(instance test-vpc/be); allowed-protocols[0] test-vpc/be,Outbound,Security group,test-vpc/opa,ALL,,Internal. required-connections[3]: (instance test-vpc/be)->(instance test-vpc/opa); allowed-protocols[0] test-vpc/be,Outbound,Security group,test-vpc/policydb-endpoint-gateway,ALL,,Internal. required-connections[4]: (instance test-vpc/be)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] -test-vpc/fe,Inbound,Security group,test-vpc/proxy,TCP,Ports 9000-9000,Internal. required-connections[1]: (instance test-vpc/proxy)->(instance test-vpc/fe); allowed-protocols[0] +test-vpc/fe,Inbound,Security group,test-vpc/proxy,TCP,ports 9000-9000,Internal. required-connections[1]: (instance test-vpc/proxy)->(instance test-vpc/fe); allowed-protocols[0] test-vpc/fe,Outbound,Security group,test-vpc/be,TCP,any port,Internal. required-connections[2]: (instance test-vpc/fe)->(instance test-vpc/be); allowed-protocols[0] test-vpc/opa,Inbound,Security group,test-vpc/be,ALL,,Internal. required-connections[3]: (instance test-vpc/be)->(instance test-vpc/opa); allowed-protocols[0] test-vpc/opa,Outbound,Security group,test-vpc/policydb-endpoint-gateway,ALL,,Internal. required-connections[5]: (instance test-vpc/opa)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] test-vpc/policydb-endpoint-gateway,Inbound,Security group,test-vpc/be,ALL,,Internal. required-connections[4]: (instance test-vpc/be)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] test-vpc/policydb-endpoint-gateway,Inbound,Security group,test-vpc/opa,ALL,,Internal. required-connections[5]: (instance test-vpc/opa)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] test-vpc/proxy,Inbound,CIDR block,Any IP,ALL,,External. required-connections[0]: (external public internet)->(instance test-vpc/proxy); allowed-protocols[0] -test-vpc/proxy,Outbound,Security group,test-vpc/fe,TCP,Ports 9000-9000,Internal. required-connections[1]: (instance test-vpc/proxy)->(instance test-vpc/fe); allowed-protocols[0] +test-vpc/proxy,Outbound,Security group,test-vpc/fe,TCP,ports 9000-9000,Internal. required-connections[1]: (instance test-vpc/proxy)->(instance test-vpc/fe); allowed-protocols[0] diff --git a/test/data/sg_tg_multiple/sg_expected.csv b/test/data/sg_tg_multiple/sg_expected.csv index 56d977fb..90127d5d 100644 --- a/test/data/sg_tg_multiple/sg_expected.csv +++ b/test/data/sg_tg_multiple/sg_expected.csv @@ -3,5 +3,5 @@ test-vpc0/vsi0-subnet0,Outbound,Security group,test-vpc0/vsi1-subnet4,ALL,,Inter test-vpc0/vsi1-subnet4,Inbound,Security group,test-vpc0/vsi0-subnet0,ALL,,Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi1-subnet4); allowed-protocols[0] test-vpc1/vsi0-subnet10,Outbound,Security group,test-vpc1/vsi0-subnet11,TCP,any port,Internal. required-connections[2]: (instance test-vpc1/vsi0-subnet10)->(instance test-vpc1/vsi0-subnet11); allowed-protocols[0] test-vpc1/vsi0-subnet11,Inbound,Security group,test-vpc1/vsi0-subnet10,TCP,any port,Internal. required-connections[2]: (instance test-vpc1/vsi0-subnet10)->(instance test-vpc1/vsi0-subnet11); allowed-protocols[0] -test-vpc2/vsi0-subnet20,Outbound,Security group,test-vpc2/vsi2-subnet20,TCP,Ports 53-53,Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] -test-vpc2/vsi2-subnet20,Inbound,Security group,test-vpc2/vsi0-subnet20,TCP,Ports 53-53,Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] +test-vpc2/vsi0-subnet20,Outbound,Security group,test-vpc2/vsi2-subnet20,TCP,ports 53-53,Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] +test-vpc2/vsi2-subnet20,Inbound,Security group,test-vpc2/vsi0-subnet20,TCP,ports 53-53,Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] diff --git a/test/data/sg_tg_multiple/test-vpc2.csv b/test/data/sg_tg_multiple/test-vpc2.csv index bc3f05dd..ec9047cf 100644 --- a/test/data/sg_tg_multiple/test-vpc2.csv +++ b/test/data/sg_tg_multiple/test-vpc2.csv @@ -1,3 +1,3 @@ SG,Direction,Remote type,Remote,Protocol,Protocol params,Description -test-vpc2/vsi0-subnet20,Outbound,Security group,test-vpc2/vsi2-subnet20,TCP,Ports 53-53,Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] -test-vpc2/vsi2-subnet20,Inbound,Security group,test-vpc2/vsi0-subnet20,TCP,Ports 53-53,Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] +test-vpc2/vsi0-subnet20,Outbound,Security group,test-vpc2/vsi2-subnet20,TCP,ports 53-53,Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] +test-vpc2/vsi2-subnet20,Inbound,Security group,test-vpc2/vsi0-subnet20,TCP,ports 53-53,Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] From 4aeaef5820f8c115407875861cdb96871cddc9a1 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Sun, 18 Aug 2024 16:27:10 +0300 Subject: [PATCH 004/131] updated --- go.mod | 6 +++--- go.sum | 4 ++-- pkg/io/confio/conversions.go | 20 ++++++-------------- pkg/io/confio/read_defs.go | 2 +- pkg/io/csvio/acl.go | 4 ++-- pkg/io/csvio/sg.go | 4 ++-- pkg/io/jsonio/unmarshal.go | 29 ++++++++++------------------- pkg/io/mdio/acl.go | 4 ++-- pkg/io/mdio/sg.go | 4 ++-- pkg/io/tfio/acl.go | 4 ++-- pkg/io/tfio/sg.go | 4 ++-- pkg/ir/spec.go | 5 ----- 12 files changed, 34 insertions(+), 56 deletions(-) diff --git a/go.mod b/go.mod index 41c8b9f7..67a05b1b 100644 --- a/go.mod +++ b/go.mod @@ -37,10 +37,10 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect ) -// Todo: +// Todo: // (1) delete the following line when np-guard/models#33 is merged. -// (2) replace lines 137 and 138 in go.sum with +// (2) replace lines 137 and 138 in go.sum with // github.com/np-guard/models v0.3.4 h1:HOhVi6wyGvo+KmYBnQ5Km5HYCF+/PQlDs1v7mL1v05g= // github.com/np-guard/models v0.3.4/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= //nolint:gomoddirectives // this line is temporary -replace github.com/np-guard/models => github.com/np-guard/models v0.3.5-0.20240708150421-8d8e4354057d \ No newline at end of file +replace github.com/np-guard/models => github.com/np-guard/models v0.3.5-0.20240818081750-bb83d7f53d64 diff --git a/go.sum b/go.sum index dce9b4ea..31405b5e 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.14.0 h1:MBPtPBYVCQoMfUkn/wODpF7SRpJ9TlOfMszO8N0PePo= github.com/np-guard/cloud-resource-collector v0.14.0/go.mod h1:klCHnNnuuVcCtGQHA7R1a8fqnvfMCk/5Jdld6V7sN2A= -github.com/np-guard/models v0.3.5-0.20240708150421-8d8e4354057d h1:yAmG3W8kUl0GC84dRWcgRK9lBWRkwJkwLnUtwoh1lIY= -github.com/np-guard/models v0.3.5-0.20240708150421-8d8e4354057d/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= +github.com/np-guard/models v0.3.5-0.20240818081750-bb83d7f53d64 h1:e3Fljv3NXu8UogaS4mq8TVqzfga/AuHElL8j0EQLrXw= +github.com/np-guard/models v0.3.5-0.20240818081750-bb83d7f53d64/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= 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= diff --git a/pkg/io/confio/conversions.go b/pkg/io/confio/conversions.go index 6ef6733b..d1788e2f 100644 --- a/pkg/io/confio/conversions.go +++ b/pkg/io/confio/conversions.go @@ -11,7 +11,6 @@ import ( "github.com/IBM/vpc-go-sdk/vpcv1" - "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" @@ -65,14 +64,6 @@ func direction(d ir.Direction) *string { return nil } -func minPort(r interval.Interval) *int64 { - return utils.Ptr(r.Start()) -} - -func maxPort(r interval.Interval) *int64 { - return utils.Ptr(r.End()) -} - type tcpudpData struct { Protocol *string SourcePortMin *int64 @@ -106,13 +97,14 @@ type allData struct { } func tcpudp(p netp.TCPUDP) tcpudpData { - r := p.PortRangePair + srcPorts := p.SrcPorts() + dstPorts := p.DstPorts() res := tcpudpData{ Protocol: utils.Ptr(strings.ToLower(string(p.ProtocolString()))), - SourcePortMin: minPort(r.SrcPort), - SourcePortMax: maxPort(r.SrcPort), - DestinationPortMin: minPort(r.DstPort), - DestinationPortMax: maxPort(r.DstPort), + SourcePortMin: utils.Ptr(srcPorts.Start()), + SourcePortMax: utils.Ptr(srcPorts.End()), + DestinationPortMin: utils.Ptr(dstPorts.Start()), + DestinationPortMax: utils.Ptr(dstPorts.End()), } return res } diff --git a/pkg/io/confio/read_defs.go b/pkg/io/confio/read_defs.go index c2fc03b8..6c1d68b6 100644 --- a/pkg/io/confio/read_defs.go +++ b/pkg/io/confio/read_defs.go @@ -190,7 +190,7 @@ func validateVpcs(vpcs map[ir.ID]*ir.VPCDetails) error { if vpcName1 >= vpcName2 { continue } - if ir.Overlap(vpcDetails1.AddressPrefixes, vpcDetails2.AddressPrefixes) { + if vpcDetails1.AddressPrefixes.Overlap(vpcDetails2.AddressPrefixes) { return fmt.Errorf("vpcs %s and %s have overlapping IP address spaces", vpcName1, vpcName2) } } diff --git a/pkg/io/csvio/acl.go b/pkg/io/csvio/acl.go index 792f943e..a5e9c00e 100644 --- a/pkg/io/csvio/acl.go +++ b/pkg/io/csvio/acl.go @@ -97,9 +97,9 @@ func printIP(ip *netset.IPBlock, protocol netp.Protocol, isSource bool) string { case netp.TCPUDP: var r interval.Interval if isSource { - r = p.PortRangePair.SrcPort + r = p.SrcPorts() } else { - r = p.PortRangePair.DstPort + r = p.DstPorts() } return fmt.Sprintf("%v, %v", ipString, ACLPort(r)) case netp.AnyProtocol: diff --git a/pkg/io/csvio/sg.go b/pkg/io/csvio/sg.go index 2e438ec1..7c8993fc 100644 --- a/pkg/io/csvio/sg.go +++ b/pkg/io/csvio/sg.go @@ -108,9 +108,9 @@ func printProtocolParams(protocol netp.Protocol, isSource bool) string { case netp.TCPUDP: var r interval.Interval if isSource { - r = p.PortRangePair.SrcPort + r = p.SrcPorts() } else { - r = p.PortRangePair.DstPort + r = p.DstPorts() } return sGPort(r) case netp.AnyProtocol: diff --git a/pkg/io/jsonio/unmarshal.go b/pkg/io/jsonio/unmarshal.go index 87a843cc..689073ee 100644 --- a/pkg/io/jsonio/unmarshal.go +++ b/pkg/io/jsonio/unmarshal.go @@ -11,7 +11,6 @@ import ( "fmt" "os" - "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" @@ -265,26 +264,18 @@ func translateProtocols(protocols spec.ProtocolList) ([]ir.TrackedProtocol, erro } result[i].Protocol = netp.AnyProtocol{} case spec.Icmp: - if p.Type == nil { - if p.Code != nil { - return nil, fmt.Errorf("defining ICMP code for unspecified ICMP type is not allowed") - } - result[i].Protocol = ir.TrackedProtocol{Protocol: netp.ICMP{}} - } else { - icmp, err := netp.ICMPFromTypeAndCode(p.Type, p.Code) - if err != nil { - return nil, err - } - result[i].Protocol = icmp + icmp, err := netp.ICMPFromTypeAndCode(p.Type, p.Code) + if err != nil { + return nil, err } + result[i].Protocol = icmp case spec.TcpUdp: - result[i].Protocol = netp.TCPUDP{ - IsTCP: p.Protocol == spec.TcpUdpProtocolTCP, - PortRangePair: netp.PortRangePair{ - SrcPort: interval.New(int64(p.MinSourcePort), int64(p.MaxSourcePort)), - DstPort: interval.New(int64(p.MinDestinationPort), int64(p.MaxDestinationPort)), - }, + tcpudp, err := netp.NewTCPUDP(p.Protocol == spec.TcpUdpProtocolTCP, p.MinSourcePort, p.MaxSourcePort, + p.MinDestinationPort, p.MaxDestinationPort) + if err != nil { + return nil, err } + result[i].Protocol = tcpudp default: return nil, fmt.Errorf("impossible protocol: %v", p) } @@ -361,7 +352,7 @@ func unmarshal(filename string) (*spec.Spec, error) { func parseOverlappingVpcs(cidr *netset.IPBlock, vpcs map[ir.ID]*ir.VPCDetails) []ir.ID { result := make([]ir.ID, 0) for vpcName, vpcDetails := range vpcs { - if ir.Overlap(vpcDetails.AddressPrefixes, cidr) { + if vpcDetails.AddressPrefixes.Overlap(cidr) { result = append(result, vpcName) } } diff --git a/pkg/io/mdio/acl.go b/pkg/io/mdio/acl.go index 18c010e7..e593de0e 100644 --- a/pkg/io/mdio/acl.go +++ b/pkg/io/mdio/acl.go @@ -114,9 +114,9 @@ func printIP(ip *netset.IPBlock, protocol netp.Protocol, isSource bool) string { case netp.TCPUDP: var r interval.Interval if isSource { - r = p.PortRangePair.SrcPort + r = p.SrcPorts() } else { - r = p.PortRangePair.DstPort + r = p.DstPorts() } return fmt.Sprintf("%v, %v", ipString, ACLPort(r)) case netp.AnyProtocol: diff --git a/pkg/io/mdio/sg.go b/pkg/io/mdio/sg.go index aea44185..c8ee6f77 100644 --- a/pkg/io/mdio/sg.go +++ b/pkg/io/mdio/sg.go @@ -122,9 +122,9 @@ func printProtocolParams(protocol netp.Protocol, isSource bool) string { case netp.TCPUDP: var r interval.Interval if isSource { - r = p.PortRangePair.SrcPort + r = p.SrcPorts() } else { - r = p.PortRangePair.DstPort + r = p.DstPorts() } return sGPort(r) case netp.AnyProtocol: diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index e3427b1c..e6d36637 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -34,8 +34,8 @@ func aclProtocol(t netp.Protocol) []tf.Block { return []tf.Block{{ Name: strings.ToLower(string(p.ProtocolString())), Arguments: append( - portRange(p.PortRangePair.DstPort, "port"), - portRange(p.PortRangePair.SrcPort, "source_port")..., + portRange(p.DstPorts(), "port"), + portRange(p.SrcPorts(), "source_port")..., ), }} case netp.ICMP: diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 7ad0aa29..74e796fb 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -46,9 +46,9 @@ func sgProtocol(t netp.Protocol, d ir.Direction) []tf.Block { case netp.TCPUDP: var remotePort interval.Interval if d == ir.Inbound { - remotePort = p.PortRangePair.SrcPort + remotePort = p.SrcPorts() } else { - remotePort = p.PortRangePair.DstPort + remotePort = p.DstPorts() } return []tf.Block{{ Name: strings.ToLower(string(p.ProtocolString())), diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index 6e3c58aa..a72cba91 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -418,8 +418,3 @@ func IsIPAddress(address *netset.IPBlock) bool { func ChangeScoping(s string) string { return strings.ReplaceAll(s, "/", "--") } - -// Todo: move this function to models repo (as a method) -func Overlap(a, b *netset.IPBlock) bool { - return !a.Intersect(b).IsEmpty() -} From cec430ec7602fdb9bc095c6d71b529f75d372136 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 11:56:18 +0300 Subject: [PATCH 005/131] use ipblock size --- pkg/io/confio/sg.go | 2 +- pkg/io/csvio/sg.go | 4 ++-- pkg/io/mdio/sg.go | 4 ++-- pkg/ir/spec.go | 11 ----------- 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/pkg/io/confio/sg.go b/pkg/io/confio/sg.go index df0ed02b..ee551214 100644 --- a/pkg/io/confio/sg.go +++ b/pkg/io/confio/sg.go @@ -53,7 +53,7 @@ func sgRemote(nameToSGRemoteRef map[string]*vpcv1.SecurityGroupRuleRemoteSecurit st := rule.Remote.String() switch t := rule.Remote.(type) { case *netset.IPBlock: - if ir.IsIPAddress(t) { + if t.Size() == 1 { // single IP address return &vpcv1.SecurityGroupRuleRemoteIP{ Address: &st, } diff --git a/pkg/io/csvio/sg.go b/pkg/io/csvio/sg.go index 1f6b194c..a10dc8db 100644 --- a/pkg/io/csvio/sg.go +++ b/pkg/io/csvio/sg.go @@ -72,9 +72,9 @@ func sGPort(p interval.Interval) string { } func sGRemoteType(t ir.RemoteType) string { - switch tr := t.(type) { + switch t := t.(type) { case *netset.IPBlock: - if ir.IsIPAddress(tr) { + if t.Size() == 1 { return "IP address" } return "CIDR block" diff --git a/pkg/io/mdio/sg.go b/pkg/io/mdio/sg.go index 7f8d5b26..044ddbca 100644 --- a/pkg/io/mdio/sg.go +++ b/pkg/io/mdio/sg.go @@ -86,9 +86,9 @@ func sGPort(p interval.Interval) string { } func sGRemoteType(t ir.RemoteType) string { - switch tr := t.(type) { + switch t := t.(type) { case *netset.IPBlock: - if ir.IsIPAddress(tr) { + if t.Size() == 1 { return "IP address" } return "CIDR block" diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index a72cba91..472b7b10 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -8,7 +8,6 @@ package ir import ( "fmt" - "log" "sort" "strings" @@ -16,8 +15,6 @@ import ( "github.com/np-guard/models/pkg/netset" ) -const MaximalIPv4PrefixLength = 32 - type ( ID = string NamedEntity string @@ -407,14 +404,6 @@ func VpcFromScopedResource(resource ID) ID { return ScopingComponents(resource)[0] } -func IsIPAddress(address *netset.IPBlock) bool { - prefixLength, err := address.PrefixLength() - if err != nil { - log.Fatal(err) - } - return prefixLength == MaximalIPv4PrefixLength -} - func ChangeScoping(s string) string { return strings.ReplaceAll(s, "/", "--") } From b8ee61b569febf4d23d5f412692b092f9cb48e0e Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 12:08:54 +0300 Subject: [PATCH 006/131] minor changes --- cmd/subcmds/optimize.go | 5 ++--- cmd/subcmds/optimizeSG.go | 4 ++-- pkg/io/confio/parse_defs.go | 6 +----- pkg/synth/sg.go | 2 +- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/cmd/subcmds/optimize.go b/cmd/subcmds/optimize.go index cf8ec17e..877662a9 100644 --- a/cmd/subcmds/optimize.go +++ b/cmd/subcmds/optimize.go @@ -10,11 +10,10 @@ import "github.com/spf13/cobra" func NewOptimizeCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "optimize", - Short: "Optimize is not supported yet", - Long: `Optimize is not supported yet`, + Short: "optimization of existing SG (nACLS are not supported yet)", + Long: `optimization of existing SG (nACLS are not supported yet)`, } - cmd.AddCommand(NewOptimizeACLCommand(args)) cmd.AddCommand(NewOptimizeSGCommand(args)) return cmd diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go index 1c903f83..cc0e1e23 100644 --- a/cmd/subcmds/optimizeSG.go +++ b/cmd/subcmds/optimizeSG.go @@ -10,8 +10,8 @@ import "github.com/spf13/cobra" func NewOptimizeSGCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "sg", - Short: "OptimizeSG is not supported yet", - Long: `OptimizeSG is not supported yet`, + Short: "OptimizeSG attempts to reduce the number of security group rules in a SG without changing the semantic.", + Long: `OptimizeSG attempts to reduce the number of security group rules in a SG without changing the semantic.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { return nil diff --git a/pkg/io/confio/parse_defs.go b/pkg/io/confio/parse_defs.go index 3b2705d9..86ba8a95 100644 --- a/pkg/io/confio/parse_defs.go +++ b/pkg/io/confio/parse_defs.go @@ -41,10 +41,6 @@ func ReadDefs(filename string) (*ir.ConfigDefs, error) { if err != nil { return nil, err } - err = validateVpcs(vpcs) - if err != nil { - return nil, err - } return &ir.ConfigDefs{ VPCs: vpcs, @@ -69,7 +65,7 @@ func parseVPCs(config *configModel.ResourcesContainerModel) (map[ir.ID]*ir.VPCDe } VPCs[*vpc.Name] = &ir.VPCDetails{AddressPrefixes: addressPrefixes} } - return VPCs, nil + return VPCs, validateVpcs(VPCs) } func parseSubnets(config *configModel.ResourcesContainerModel) (map[ir.ID]*ir.SubnetDetails, error) { diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index d829d68d..054171cf 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -93,7 +93,7 @@ func (s *SGSynthesizer) allowConnectionFromSrc(conn *ir.Connection, trackedProto sgSrc.Add(rule) } -// if the dst in internal, a rule will be created to allow traffic. +// if the dst is internal, a rule will be created to allow traffic. func (s *SGSynthesizer) allowConnectionToDst(conn *ir.Connection, trackedProtocol ir.TrackedProtocol, srcEndpoint, dstEndpoint *namedAddrs) { _, internalDst, internal := internalConn(conn) From c1179412cf8930f6a1e1cb52fcd411af4599db4d Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 12:39:00 +0300 Subject: [PATCH 007/131] template --- cmd/subcmds/optimizeOutput.go | 14 ++++++++++++++ cmd/subcmds/optimizeSG.go | 24 +++++++++++++++++++++++- cmd/subcmds/root.go | 2 ++ pkg/io/confio/parse_sgs.go | 12 ++++++++++++ pkg/optimize.go/sg.go | 14 ++++++++++++++ 5 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 cmd/subcmds/optimizeOutput.go create mode 100644 pkg/io/confio/parse_sgs.go create mode 100644 pkg/optimize.go/sg.go diff --git a/cmd/subcmds/optimizeOutput.go b/cmd/subcmds/optimizeOutput.go new file mode 100644 index 00000000..dfeddc37 --- /dev/null +++ b/cmd/subcmds/optimizeOutput.go @@ -0,0 +1,14 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package subcmds + +import ( + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +func writeOptimizeOutput(args *inArgs, sgs map[ir.SGName]*ir.SG) error { + return nil +} diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go index cc0e1e23..8cdeec92 100644 --- a/cmd/subcmds/optimizeSG.go +++ b/cmd/subcmds/optimizeSG.go @@ -5,7 +5,14 @@ SPDX-License-Identifier: Apache-2.0 package subcmds -import "github.com/spf13/cobra" +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/io/confio" + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize.go" +) func NewOptimizeSGCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ @@ -18,5 +25,20 @@ func NewOptimizeSGCommand(args *inArgs) *cobra.Command { }, } + cmd.Flags().StringVarP(&args.sgName, sgNameFlag, "s", "", "which SG to optimize") + _ = cmd.MarkFlagRequired(sgNameFlag) // Todo: delete this line. if sgName flag is not supplied - optimize all SGs + return cmd } + +func optimization(cmd *cobra.Command, args *inArgs) error { + cmd.SilenceUsage = true // if we got this far, flags are syntactically correct, so no need to print usage + sgs, err := confio.ReadSGs(args.configFile) + if err != nil { + return fmt.Errorf("could not parse config file %v: %w", args.configFile, err) + } + if optimize.ReduceSGRules(sgs, args.sgName) != nil { + return err + } + return writeOptimizeOutput(args, sgs) +} diff --git a/cmd/subcmds/root.go b/cmd/subcmds/root.go index 281c66b5..471b55d5 100644 --- a/cmd/subcmds/root.go +++ b/cmd/subcmds/root.go @@ -19,6 +19,7 @@ const ( outputFileFlag = "output-file" outputDirFlag = "output-dir" prefixFlag = "prefix" + sgNameFlag = "sg-name" singleACLFlag = "single" localsFlag = "locals" ) @@ -30,6 +31,7 @@ type inArgs struct { outputFile string outputDir string prefix string + sgName string singleacl bool locals bool } diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go new file mode 100644 index 00000000..fa6f7685 --- /dev/null +++ b/pkg/io/confio/parse_sgs.go @@ -0,0 +1,12 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package confio + +import "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + +func ReadSGs(filename string) (map[ir.SGName]*ir.SG, error) { + return map[ir.SGName]*ir.SG{}, nil +} diff --git a/pkg/optimize.go/sg.go b/pkg/optimize.go/sg.go new file mode 100644 index 00000000..897c76f8 --- /dev/null +++ b/pkg/optimize.go/sg.go @@ -0,0 +1,14 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import ( + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +func ReduceSGRules(sgs map[ir.SGName]*ir.SG, sgName string) error { + return nil +} From 7e70c95d8dfa34965b0bc820097faf1736d01cb5 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 12:40:46 +0300 Subject: [PATCH 008/131] fixed --- pkg/io/confio/parse_sgs.go | 161 ++++++++++++++++++++++++++++++++++++- pkg/ir/sg.go | 2 + pkg/utils/utils.go | 16 ++++ 3 files changed, 177 insertions(+), 2 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index fa6f7685..96d5038d 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -5,8 +5,165 @@ SPDX-License-Identifier: Apache-2.0 package confio -import "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +import ( + "fmt" + "reflect" + vpc1 "github.com/IBM/vpc-go-sdk/vpcv1" + + "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/utils" +) + +// ReadSG translates SGs from a config_object file to map[ir.SGName]*SG func ReadSGs(filename string) (map[ir.SGName]*ir.SG, error) { - return map[ir.SGName]*ir.SG{}, nil + config, err := readModel(filename) + if err != nil { + return nil, err + } + result := make(map[ir.SGName]*ir.SG, len(config.SecurityGroupList)) + + for _, sg := range config.SecurityGroupList { + inbound, outbound, err := translateSGRules(&sg.SecurityGroup) + if err != nil { + return nil, err + } + if sg.Name != nil { + result[ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, OutboundRules: outbound} + } + } + return result, nil +} + +// parse security rules, splitted into ingress and egress rules +func translateSGRules(sg *vpc1.SecurityGroup) (ingressRules, egressRules []ir.SGRule, err error) { + ingressRules = []ir.SGRule{} + egressRules = []ir.SGRule{} + for index := range sg.Rules { + rule, err := translateSGRule(sg, index) + if err != nil { + return nil, nil, err + } + if rule.Direction == ir.Inbound { + ingressRules = append(ingressRules, rule) + } else { + egressRules = append(egressRules, rule) + } + } + return ingressRules, egressRules, nil +} + +// translateSGRule translates a security group rule to ir.SGRule +func translateSGRule(sg *vpc1.SecurityGroup, index int) (sgRule ir.SGRule, err error) { + fmt.Printf("Type of sgRule[%d]: %s \n", index, reflect.TypeOf(sg.Rules[index])) + switch r := sg.Rules[index].(type) { + case *vpc1.SecurityGroupRuleSecurityGroupRuleProtocolAll: + return translateSGRuleProtocolAll(r) + case *vpc1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp: + return translateSGRuleProtocolTCPUDP(r) + case *vpc1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp: + return translateSGRuleProtocolIcmp(r) + } + return ir.SGRule{}, fmt.Errorf("error parsing rule number %d in %s sg", index, *sg.Name) +} + +func translateSGRuleProtocolAll(rule *vpc1.SecurityGroupRuleSecurityGroupRuleProtocolAll) (sgRule ir.SGRule, err error) { + direction, err := translateDirection(*rule.Direction) + if err != nil { + return ir.SGRule{}, err + } + remote, err := translateRemote(rule.Remote) + if err != nil { + return ir.SGRule{}, err + } + local, err := translateLocal(rule.Local) + if err != nil { + return ir.SGRule{}, err + } + return ir.SGRule{Direction: direction, Remote: remote, Protocol: netp.AnyProtocol{}, Local: local}, nil +} + +func translateSGRuleProtocolTCPUDP(rule *vpc1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (sgRule ir.SGRule, err error) { + direction, err := translateDirection(*rule.Direction) + if err != nil { + return ir.SGRule{}, err + } + remote, err := translateRemote(rule.Remote) + if err != nil { + return ir.SGRule{}, err + } + local, err := translateLocal(rule.Local) + if err != nil { + return ir.SGRule{}, err + } + protocol, err := translateProtocolTCPUDP(rule) + if err != nil { + return ir.SGRule{}, err + } + return ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil +} + +func translateSGRuleProtocolIcmp(rule *vpc1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp) (sgRule ir.SGRule, err error) { + direction, err := translateDirection(*rule.Direction) + if err != nil { + return ir.SGRule{}, err + } + remote, err := translateRemote(rule.Remote) + if err != nil { + return ir.SGRule{}, err + } + local, err := translateLocal(rule.Local) + if err != nil { + return ir.SGRule{}, err + } + protocol, err := netp.ICMPFromTypeAndCode64(rule.Type, rule.Code) + if err != nil { + return ir.SGRule{}, err + } + return ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil +} + +func translateDirection(direction string) (ir.Direction, error) { + if direction == "inbound" { + return ir.Inbound, nil + } else if direction == "outbound" { + return ir.Outbound, nil + } + return ir.Inbound, fmt.Errorf("a SG rule direction must be either inbound or outbound") +} + +func translateRemote(remote vpc1.SecurityGroupRuleRemoteIntf) (ir.RemoteType, error) { + if r, ok := remote.(*vpc1.SecurityGroupRuleRemote); ok { + switch { + case r.CIDRBlock != nil: + return netset.IPBlockFromCidr(*r.CIDRBlock) + case r.Address != nil: + return netset.IPBlockFromIPAddress(*r.Address) + case r.Name != nil: + return ir.SGName(*r.Name), nil + } + } + return nil, fmt.Errorf("unexpected SG rule remote") +} + +func translateLocal(local vpc1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, error) { + if l, ok := local.(*vpc1.SecurityGroupRuleLocal); ok { + if l.CIDRBlock != nil { + return netset.IPBlockFromCidr(*l.CIDRBlock) + } + if l.Address != nil { + return netset.IPBlockFromIPAddress(*l.CIDRBlock) + } + } + return nil, fmt.Errorf("error parsing Local field") +} + +func translateProtocolTCPUDP(rule *vpc1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (netp.Protocol, error) { + isTCP := *rule.Protocol == string(netp.ProtocolStringTCP) + minDstPort := utils.GetProperty(rule.PortMin, netp.MinPort) + maxDstPort := utils.GetProperty(rule.PortMax, netp.MaxPort) + return netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(minDstPort), int(maxDstPort)) } diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 7c42fe01..5cf895ec 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -10,6 +10,7 @@ import ( "reflect" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) @@ -40,6 +41,7 @@ type SGRule struct { Direction Direction Remote RemoteType Protocol netp.Protocol + Local *netset.IPBlock Explanation string } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index acf9e3d2..ede1bb67 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -31,3 +31,19 @@ func SortedAllInnerMapsKeys[T, K cmp.Ordered, V any](m map[K]map[T]V) []T { slices.Sort(keys) return keys } + +// GetProperty returns pointer p if it is valid, else it returns the provided default value +// used to get min/max port or icmp type +func GetProperty(p *int64, defaultP int64) int64 { + if p == nil { + return defaultP + } + return *p +} + +func Int64PointerToIntPointer(v *int64) *int { + if v == nil { + return nil + } + return Ptr(int(*v)) +} From 19123f98c2a850278ee832c61f548c5aa81d54c3 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 12:44:49 +0300 Subject: [PATCH 009/131] minor change --- pkg/io/confio/parse_sgs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index 96d5038d..daf044cc 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -24,8 +24,8 @@ func ReadSGs(filename string) (map[ir.SGName]*ir.SG, error) { if err != nil { return nil, err } - result := make(map[ir.SGName]*ir.SG, len(config.SecurityGroupList)) + result := make(map[ir.SGName]*ir.SG, len(config.SecurityGroupList)) for _, sg := range config.SecurityGroupList { inbound, outbound, err := translateSGRules(&sg.SecurityGroup) if err != nil { From 067edfe6abbdcabcc200d8d0d89b3753c8ebaf84 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 12:59:00 +0300 Subject: [PATCH 010/131] another change --- cmd/subcmds/optimizeOutput.go | 2 +- pkg/optimize.go/sg.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/subcmds/optimizeOutput.go b/cmd/subcmds/optimizeOutput.go index dfeddc37..9ac7f8ce 100644 --- a/cmd/subcmds/optimizeOutput.go +++ b/cmd/subcmds/optimizeOutput.go @@ -9,6 +9,6 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func writeOptimizeOutput(args *inArgs, sgs map[ir.SGName]*ir.SG) error { +func writeOptimizeOutput(_ *inArgs, _ map[ir.SGName]*ir.SG) error { return nil } diff --git a/pkg/optimize.go/sg.go b/pkg/optimize.go/sg.go index 897c76f8..cc4ddbb2 100644 --- a/pkg/optimize.go/sg.go +++ b/pkg/optimize.go/sg.go @@ -9,6 +9,6 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func ReduceSGRules(sgs map[ir.SGName]*ir.SG, sgName string) error { +func ReduceSGRules(_ map[ir.SGName]*ir.SG, _ string) error { return nil } From 2b7f244db852b6c29894752d91b4cd3e1cf5fc4c Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 14:29:32 +0300 Subject: [PATCH 011/131] added synth prefix --- cmd/subcmds/{output.go => synthOutput.go} | 2 +- pkg/io/confio/acl.go | 2 +- pkg/io/confio/sg.go | 2 +- pkg/io/csvio/acl.go | 2 +- pkg/io/csvio/common.go | 2 +- pkg/io/csvio/sg.go | 2 +- pkg/io/mdio/acl.go | 2 +- pkg/io/mdio/common.go | 2 +- pkg/io/mdio/sg.go | 2 +- pkg/io/tfio/acl.go | 2 +- pkg/io/tfio/common.go | 2 +- pkg/io/tfio/sg.go | 2 +- pkg/ir/sg.go | 56 ++++++++++++----------- 13 files changed, 41 insertions(+), 39 deletions(-) rename cmd/subcmds/{output.go => synthOutput.go} (97%) diff --git a/cmd/subcmds/output.go b/cmd/subcmds/synthOutput.go similarity index 97% rename from cmd/subcmds/output.go rename to cmd/subcmds/synthOutput.go index aa817b7e..ff694c47 100644 --- a/cmd/subcmds/output.go +++ b/cmd/subcmds/synthOutput.go @@ -85,7 +85,7 @@ func writeToFile(outputFile string, data *bytes.Buffer) error { return os.WriteFile(outputFile, data.Bytes(), defaultFilePermission) } -func pickWriter(args *inArgs, data *bytes.Buffer) (ir.Writer, error) { +func pickWriter(args *inArgs, data *bytes.Buffer) (ir.SynthWriter, error) { w := bufio.NewWriter(data) switch args.outputFmt { case tfOutputFormat: diff --git a/pkg/io/confio/acl.go b/pkg/io/confio/acl.go index 20f06d1a..09231c65 100644 --- a/pkg/io/confio/acl.go +++ b/pkg/io/confio/acl.go @@ -169,7 +169,7 @@ func subnetRef(subnet *configModel.Subnet) *vpcv1.SubnetReference { } } -func (w *Writer) WriteACL(collection *ir.ACLCollection, _ string) error { +func (w *Writer) WriteSynthACL(collection *ir.ACLCollection, _ string) error { updateACL(w.model, collection) return w.writeModel() } diff --git a/pkg/io/confio/sg.go b/pkg/io/confio/sg.go index ee551214..cadf8232 100644 --- a/pkg/io/confio/sg.go +++ b/pkg/io/confio/sg.go @@ -245,7 +245,7 @@ func updateSG(model *configModel.ResourcesContainerModel, collection *ir.SGColle globalIndex = 0 // making test results more predictable } -func (w *Writer) WriteSG(collection *ir.SGCollection, _ string) error { +func (w *Writer) WriteSynthSG(collection *ir.SGCollection, _ string) error { updateSG(w.model, collection) return w.writeModel() } diff --git a/pkg/io/csvio/acl.go b/pkg/io/csvio/acl.go index a5e9c00e..47e9b5ea 100644 --- a/pkg/io/csvio/acl.go +++ b/pkg/io/csvio/acl.go @@ -36,7 +36,7 @@ func ACLPort(p interval.Interval) string { } // Write prints an entire collection of acls as a single CSV table. -func (w *Writer) WriteACL(collection *ir.ACLCollection, vpc string) error { +func (w *Writer) WriteSynthACL(collection *ir.ACLCollection, vpc string) error { if err := w.w.WriteAll(aclHeader()); err != nil { return err } diff --git a/pkg/io/csvio/common.go b/pkg/io/csvio/common.go index 41cd664d..c61e180e 100644 --- a/pkg/io/csvio/common.go +++ b/pkg/io/csvio/common.go @@ -18,7 +18,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -// Writer implements ir.Writer +// Writer implements ir.SynthWriter type Writer struct { w *csv.Writer } diff --git a/pkg/io/csvio/sg.go b/pkg/io/csvio/sg.go index a10dc8db..78fa772c 100644 --- a/pkg/io/csvio/sg.go +++ b/pkg/io/csvio/sg.go @@ -16,7 +16,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { +func (w *Writer) WriteSynthSG(collection *ir.SGCollection, vpc string) error { if err := w.w.WriteAll(sgHeader()); err != nil { return err } diff --git a/pkg/io/mdio/acl.go b/pkg/io/mdio/acl.go index e593de0e..34fd55c7 100644 --- a/pkg/io/mdio/acl.go +++ b/pkg/io/mdio/acl.go @@ -36,7 +36,7 @@ func ACLPort(p interval.Interval) string { } // Write prints an entire collection of acls as a single MD table. -func (w *Writer) WriteACL(collection *ir.ACLCollection, vpc string) error { +func (w *Writer) WriteSynthACL(collection *ir.ACLCollection, vpc string) error { if err := w.writeAll(aclHeader()); err != nil { return err } diff --git a/pkg/io/mdio/common.go b/pkg/io/mdio/common.go index abfb24a8..fad3d774 100644 --- a/pkg/io/mdio/common.go +++ b/pkg/io/mdio/common.go @@ -20,7 +20,7 @@ import ( const leftAlign = " :--- " -// Writer implements ir.Writer +// Writer implements ir.SynthWriter type Writer struct { w *bufio.Writer } diff --git a/pkg/io/mdio/sg.go b/pkg/io/mdio/sg.go index 044ddbca..8535fb19 100644 --- a/pkg/io/mdio/sg.go +++ b/pkg/io/mdio/sg.go @@ -16,7 +16,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { +func (w *Writer) WriteSynthSG(collection *ir.SGCollection, vpc string) error { if err := w.writeAll(sgHeader()); err != nil { return err } diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index e6d36637..b09e3a11 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -18,7 +18,7 @@ import ( ) // WriteACL prints an entire collection of acls as a sequence of terraform resources. -func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string) error { +func (w *Writer) WriteSynthACL(c *ir.ACLCollection, vpc string) error { output := aclCollection(c, vpc).Print() _, err := w.w.WriteString(output) if err != nil { diff --git a/pkg/io/tfio/common.go b/pkg/io/tfio/common.go index 00b9d2b7..60b9f1da 100644 --- a/pkg/io/tfio/common.go +++ b/pkg/io/tfio/common.go @@ -21,7 +21,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -// Writer implements ir.Writer +// Writer implements ir.SynthWriter type Writer struct { w *bufio.Writer } diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 1958ec24..6cd5447d 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -19,7 +19,7 @@ import ( ) // WriteSG prints an entire collection of Security Groups as a sequence of terraform resources. -func (w *Writer) WriteSG(c *ir.SGCollection, vpc string) error { +func (w *Writer) WriteSynthSG(c *ir.SGCollection, vpc string) error { output := sgCollection(c, vpc).Print() _, err := w.w.WriteString(output) if err != nil { diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 5cf895ec..b9783071 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -26,37 +26,39 @@ const ( SGResourceFileShareMountTarget SGResource = "fsmt" ) -type SGName string +type ( + SGName string -func (s SGName) String() string { - return string(s) -} + RemoteType interface { + fmt.Stringer + // *netset.IPBlock | SGName + } -type RemoteType interface { - fmt.Stringer - // *netset.IPBlock | SGName -} + SGRule struct { + Direction Direction + Remote RemoteType + Protocol netp.Protocol + Local *netset.IPBlock + Explanation string + } -type SGRule struct { - Direction Direction - Remote RemoteType - Protocol netp.Protocol - Local *netset.IPBlock - Explanation string -} + SG struct { + InboundRules []SGRule + OutboundRules []SGRule + Attached []ID + } -type SG struct { - InboundRules []SGRule - OutboundRules []SGRule - Attached []ID -} + SGCollection struct { + SGs map[ID]map[SGName]*SG + } -type SGCollection struct { - SGs map[ID]map[SGName]*SG -} + SynthSGWriter interface { + WriteSynthSG(sgColl *SGCollection, vpc string) error + } +) -type SGWriter interface { - WriteSG(sgColl *SGCollection, vpc string) error +func (s SGName) String() string { + return string(s) } func (r *SGRule) isRedundant(rules []SGRule) bool { @@ -110,8 +112,8 @@ func (a *SG) AllRules() []SGRule { return append(a.InboundRules, a.OutboundRules...) } -func (c *SGCollection) Write(w Writer, vpc string) error { - return w.WriteSG(c, vpc) +func (c *SGCollection) Write(w SynthWriter, vpc string) error { + return w.WriteSynthSG(c, vpc) } func (c *SGCollection) SortedSGNames(vpc ID) []SGName { From 8203f7884c890c1c243b51024674a2d54e0b4275 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 14:45:58 +0300 Subject: [PATCH 012/131] unexported two functions --- pkg/io/csvio/acl.go | 32 ++++++++++++++++---------------- pkg/io/csvio/sg.go | 8 ++++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/pkg/io/csvio/acl.go b/pkg/io/csvio/acl.go index 47e9b5ea..308910a1 100644 --- a/pkg/io/csvio/acl.go +++ b/pkg/io/csvio/acl.go @@ -17,6 +17,20 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) +// Write prints an entire collection of acls as a single CSV table. +func (w *Writer) WriteSynthACL(collection *ir.ACLCollection, vpc string) error { + if err := w.w.WriteAll(aclHeader()); err != nil { + return err + } + for _, subnet := range collection.SortedACLSubnets(vpc) { + vpcName := ir.VpcFromScopedResource(subnet) + if err := w.w.WriteAll(makeACLTable(collection.ACLs[vpcName][subnet], subnet)); err != nil { + return err + } + } + return nil +} + func makeACLTable(t *ir.ACL, subnet string) [][]string { rules := t.Rules() rows := make([][]string, len(rules)) @@ -26,7 +40,7 @@ func makeACLTable(t *ir.ACL, subnet string) [][]string { return rows } -func ACLPort(p interval.Interval) string { +func aclPort(p interval.Interval) string { switch { case p.Start() == netp.MinPort && p.End() == netp.MaxPort: return "any port" //nolint:goconst // independent decision for SG and ACL @@ -35,20 +49,6 @@ func ACLPort(p interval.Interval) string { } } -// Write prints an entire collection of acls as a single CSV table. -func (w *Writer) WriteSynthACL(collection *ir.ACLCollection, vpc string) error { - if err := w.w.WriteAll(aclHeader()); err != nil { - return err - } - for _, subnet := range collection.SortedACLSubnets(vpc) { - vpcName := ir.VpcFromScopedResource(subnet) - if err := w.w.WriteAll(makeACLTable(collection.ACLs[vpcName][subnet], subnet)); err != nil { - return err - } - } - return nil -} - func action(a ir.Action) string { if a == ir.Deny { return "Deny" @@ -101,7 +101,7 @@ func printIP(ip *netset.IPBlock, protocol netp.Protocol, isSource bool) string { } else { r = p.DstPorts() } - return fmt.Sprintf("%v, %v", ipString, ACLPort(r)) + return fmt.Sprintf("%v, %v", ipString, aclPort(r)) case netp.AnyProtocol: return ipString default: diff --git a/pkg/io/csvio/sg.go b/pkg/io/csvio/sg.go index 78fa772c..aa320afe 100644 --- a/pkg/io/csvio/sg.go +++ b/pkg/io/csvio/sg.go @@ -45,7 +45,7 @@ func makeSGRow(rule *ir.SGRule, sgName ir.SGName) []string { return []string{ string(sgName), direction(rule.Direction), - sGRemoteType(rule.Remote), + sgRemoteType(rule.Remote), sgRemote(rule.Remote), printProtocolName(rule.Protocol), printProtocolParams(rule.Protocol, rule.Direction == ir.Inbound), @@ -62,7 +62,7 @@ func makeSGTable(t *ir.SG, sgName ir.SGName) [][]string { return rows } -func sGPort(p interval.Interval) string { +func sgPort(p interval.Interval) string { switch { case p.Start() == netp.MinPort && p.End() == netp.MaxPort: return "any port" @@ -71,7 +71,7 @@ func sGPort(p interval.Interval) string { } } -func sGRemoteType(t ir.RemoteType) string { +func sgRemoteType(t ir.RemoteType) string { switch t := t.(type) { case *netset.IPBlock: if t.Size() == 1 { @@ -112,7 +112,7 @@ func printProtocolParams(protocol netp.Protocol, isSource bool) string { } else { r = p.DstPorts() } - return sGPort(r) + return sgPort(r) case netp.AnyProtocol: return "" default: From 5fbeefc1455268fb3a99ed2bc33a2e2154f51c93 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 14:47:59 +0300 Subject: [PATCH 013/131] wip --- pkg/io/confio/common.go | 2 +- pkg/ir/acl.go | 54 +++++++++++++++++++++-------------------- pkg/ir/common.go | 16 ++++++------ test/end_to_end_test.go | 2 +- 4 files changed, 39 insertions(+), 35 deletions(-) diff --git a/pkg/io/confio/common.go b/pkg/io/confio/common.go index e3e86f61..97aa4274 100644 --- a/pkg/io/confio/common.go +++ b/pkg/io/confio/common.go @@ -12,7 +12,7 @@ import ( configModel "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" ) -// Writer implements ir.Writer +// Writer implements ir.SynthWriter type Writer struct { w *bufio.Writer model *configModel.ResourcesContainerModel diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index 41248c82..993e5047 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -15,36 +15,38 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -type Action string +type ( + Action string + + ACLRule struct { + Action Action + Direction Direction + Source *netset.IPBlock + Destination *netset.IPBlock + Protocol netp.Protocol + Explanation string + } + + ACL struct { + Subnet string + Internal []ACLRule + External []ACLRule + } + + ACLCollection struct { + ACLs map[ID]map[string]*ACL + } + + SynthACLWriter interface { + WriteSynthACL(aclColl *ACLCollection, vpc string) error + } +) const ( Allow Action = "allow" Deny Action = "deny" ) -type ACLRule struct { - Action Action - Direction Direction - Source *netset.IPBlock - Destination *netset.IPBlock - Protocol netp.Protocol - Explanation string -} - -type ACL struct { - Subnet string - Internal []ACLRule - External []ACLRule -} - -type ACLCollection struct { - ACLs map[ID]map[string]*ACL -} - -type ACLWriter interface { - WriteACL(aclColl *ACLCollection, vpc string) error -} - func (r *ACLRule) isRedundant(rules []ACLRule) bool { for i := range rules { if rules[i].mustSupersede(r) { @@ -123,8 +125,8 @@ func (c *ACLCollection) LookupOrCreate(name string) *ACL { return newACL } -func (c *ACLCollection) Write(w Writer, vpc string) error { - return w.WriteACL(c, vpc) +func (c *ACLCollection) Write(w SynthWriter, vpc string) error { + return w.WriteSynthACL(c, vpc) } func (c *ACLCollection) SortedACLSubnets(vpc string) []string { diff --git a/pkg/ir/common.go b/pkg/ir/common.go index e10b1265..17b2a69d 100644 --- a/pkg/ir/common.go +++ b/pkg/ir/common.go @@ -5,18 +5,20 @@ SPDX-License-Identifier: Apache-2.0 package ir -type Direction string +type ( + Direction string + + SynthWriter interface { + SynthACLWriter + SynthSGWriter + } +) const ( Outbound Direction = "outbound" Inbound Direction = "inbound" ) -type Writer interface { - ACLWriter - SGWriter -} - type Collection interface { - Write(writer Writer, vpc string) error + Write(writer SynthWriter, vpc string) error } diff --git a/test/end_to_end_test.go b/test/end_to_end_test.go index 695a98d5..484ec4c0 100644 --- a/test/end_to_end_test.go +++ b/test/end_to_end_test.go @@ -146,7 +146,7 @@ func shrinkWhitespace(s string) string { func write(collection ir.Collection, outputFormat, conn, vpc string) (text string, err error) { buf := new(bytes.Buffer) - var writer ir.Writer + var writer ir.SynthWriter switch outputFormat { case "csv": writer = csvio.NewWriter(buf) From 19c5483b9cfdf69dda87c3cf35a0bb646b915f3b Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 14:49:27 +0300 Subject: [PATCH 014/131] rename folder name --- pkg/{optimize.go => optimize}/sg.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pkg/{optimize.go => optimize}/sg.go (100%) diff --git a/pkg/optimize.go/sg.go b/pkg/optimize/sg.go similarity index 100% rename from pkg/optimize.go/sg.go rename to pkg/optimize/sg.go From 74737e7b523a2965cd0310d1c60a323df1d484fc Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 14:52:00 +0300 Subject: [PATCH 015/131] renaming --- cmd/subcmds/optimizeSG.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go index 8cdeec92..ac3c4fdc 100644 --- a/cmd/subcmds/optimizeSG.go +++ b/cmd/subcmds/optimizeSG.go @@ -11,7 +11,7 @@ import ( "github.com/spf13/cobra" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/confio" - "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize.go" + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" ) func NewOptimizeSGCommand(args *inArgs) *cobra.Command { From 02030aca2af8c3896f5a4a7ccd68547eaa609f6a Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 15:32:22 +0300 Subject: [PATCH 016/131] updated --- pkg/io/confio/parse_sgs.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index daf044cc..a079f9c0 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -19,20 +19,25 @@ import ( ) // ReadSG translates SGs from a config_object file to map[ir.SGName]*SG -func ReadSGs(filename string) (map[ir.SGName]*ir.SG, error) { +func ReadSGs(filename string) (*ir.SGCollection, error) { config, err := readModel(filename) if err != nil { return nil, err } - result := make(map[ir.SGName]*ir.SG, len(config.SecurityGroupList)) + result := ir.NewSGCollection() + for _, sg := range config.SecurityGroupList { inbound, outbound, err := translateSGRules(&sg.SecurityGroup) if err != nil { return nil, err } if sg.Name != nil { - result[ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, OutboundRules: outbound} + vpcName := *sg.VPC.Name + if result.SGs[vpcName] == nil { + result.SGs[vpcName] = make(map[ir.SGName]*ir.SG) + } + result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, OutboundRules: outbound} } } return result, nil From 4fb97b4d18cd3e12a305b9207e87e0124ad534ed Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 15:33:50 +0300 Subject: [PATCH 017/131] updated template --- cmd/subcmds/optimizeOutput.go | 2 +- cmd/subcmds/optimizeSG.go | 2 +- cmd/subcmds/root.go | 2 +- pkg/io/confio/parse_sgs.go | 4 ++-- pkg/optimize/sg.go | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/subcmds/optimizeOutput.go b/cmd/subcmds/optimizeOutput.go index 9ac7f8ce..af92e337 100644 --- a/cmd/subcmds/optimizeOutput.go +++ b/cmd/subcmds/optimizeOutput.go @@ -9,6 +9,6 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func writeOptimizeOutput(_ *inArgs, _ map[ir.SGName]*ir.SG) error { +func writeOptimizeOutput(_ *inArgs, _ ir.Collection) error { return nil } diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go index ac3c4fdc..57ee6c32 100644 --- a/cmd/subcmds/optimizeSG.go +++ b/cmd/subcmds/optimizeSG.go @@ -21,7 +21,7 @@ func NewOptimizeSGCommand(args *inArgs) *cobra.Command { Long: `OptimizeSG attempts to reduce the number of security group rules in a SG without changing the semantic.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { - return nil + return optimization(cmd, args) }, } diff --git a/cmd/subcmds/root.go b/cmd/subcmds/root.go index 471b55d5..1f47e591 100644 --- a/cmd/subcmds/root.go +++ b/cmd/subcmds/root.go @@ -60,7 +60,7 @@ func NewRootCommand() *cobra.Command { rootCmd.MarkFlagsMutuallyExclusive(outputFileFlag, outputDirFlag) rootCmd.AddCommand(NewSynthCommand(args)) - // Todo: add optimize command + rootCmd.AddCommand(NewOptimizeCommand(args)) rootCmd.CompletionOptions.HiddenDefaultCmd = true rootCmd.SetHelpCommand(&cobra.Command{Hidden: true}) // disable help command. should use --help flag instead diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index fa6f7685..b7892297 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -7,6 +7,6 @@ package confio import "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" -func ReadSGs(filename string) (map[ir.SGName]*ir.SG, error) { - return map[ir.SGName]*ir.SG{}, nil +func ReadSGs(filename string) (*ir.SGCollection, error) { + return nil, nil } diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index cc4ddbb2..f3301962 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -9,6 +9,6 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func ReduceSGRules(_ map[ir.SGName]*ir.SG, _ string) error { +func ReduceSGRules(_ *ir.SGCollection, _ string) error { return nil } From 0c9cfe29f5f7591ca8660ae1ef5b97d1c17e9281 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 26 Aug 2024 17:27:34 +0300 Subject: [PATCH 018/131] wip --- cmd/subcmds/optimizeOutput.go | 24 ++++++++++++++- cmd/subcmds/optimizeSG.go | 3 +- cmd/subcmds/outputCommon.go | 58 +++++++++++++++++++++++++++++++++++ cmd/subcmds/synthOutput.go | 56 ++++++--------------------------- pkg/io/tfio/acl.go | 4 +++ pkg/io/tfio/sg.go | 4 +++ pkg/ir/acl.go | 10 +++++- pkg/ir/common.go | 17 +++++++--- pkg/ir/sg.go | 10 +++++- pkg/synth/acl.go | 2 +- pkg/synth/common.go | 2 +- pkg/synth/sg.go | 2 +- test/end_to_end_test.go | 8 ++--- 13 files changed, 139 insertions(+), 61 deletions(-) create mode 100644 cmd/subcmds/outputCommon.go diff --git a/cmd/subcmds/optimizeOutput.go b/cmd/subcmds/optimizeOutput.go index af92e337..1d20542c 100644 --- a/cmd/subcmds/optimizeOutput.go +++ b/cmd/subcmds/optimizeOutput.go @@ -6,9 +6,31 @@ SPDX-License-Identifier: Apache-2.0 package subcmds import ( + "bufio" + "bytes" + "fmt" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/io/tfio" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func writeOptimizeOutput(_ *inArgs, _ ir.Collection) error { +func writeOptimizeOutput(args *inArgs, collection ir.OptimizeCollection, vpcNames []string) error { + if err := checkOutputFlags(args); err != nil { + return err + } + _, isACLCollection := collection.(*ir.ACLCollection) + if err := writeLocals(args, vpcNames, isACLCollection); err != nil { + return err + } return nil } + +func pickOptimizeWriter(args *inArgs, data *bytes.Buffer) (ir.SynthWriter, error) { + w := bufio.NewWriter(data) + switch args.outputFmt { + case tfOutputFormat: + return tfio.NewWriter(w), nil + default: + return nil, fmt.Errorf("bad output format: %q", args.outputFmt) + } +} diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go index 57ee6c32..53f83477 100644 --- a/cmd/subcmds/optimizeSG.go +++ b/cmd/subcmds/optimizeSG.go @@ -12,6 +12,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/io/confio" "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) func NewOptimizeSGCommand(args *inArgs) *cobra.Command { @@ -40,5 +41,5 @@ func optimization(cmd *cobra.Command, args *inArgs) error { if optimize.ReduceSGRules(sgs, args.sgName) != nil { return err } - return writeOptimizeOutput(args, sgs) + return writeOptimizeOutput(args, sgs, utils.MapKeys(sgs.SGs)) } diff --git a/cmd/subcmds/outputCommon.go b/cmd/subcmds/outputCommon.go new file mode 100644 index 00000000..d663670c --- /dev/null +++ b/cmd/subcmds/outputCommon.go @@ -0,0 +1,58 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package subcmds + +import ( + "bytes" + "fmt" + "os" + "path/filepath" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/io/tfio" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +func checkOutputFlags(args *inArgs) error { + if err := updateOutputFormat(args); err != nil { + return err + } + if args.outputDir != "" && args.outputFmt == apiOutputFormat { + return fmt.Errorf("-d cannot be used with format json") + } + return nil +} + +func writeToFile(outputFile string, data *bytes.Buffer) error { + if outputFile == "" { + fmt.Println(data.String()) + return nil + } + return os.WriteFile(outputFile, data.Bytes(), defaultFilePermission) +} + +func writeLocals(args *inArgs, vpcNames []ir.ID, isACL bool) error { + if !args.locals { + return nil + } + if args.outputFmt != tfOutputFormat { + return fmt.Errorf("--locals flag requires setting the output format to tf") + } + + var data *bytes.Buffer + var err error + if data, err = tfio.WriteLocals(vpcNames, isACL); err != nil { + return err + } + + outputFile := "" + suffix := "/locals.tf" + if args.outputDir != "" { + outputFile = args.outputDir + suffix + } else if args.outputFile != "" { + outputFile = filepath.Dir(args.outputFile) + suffix + } + return writeToFile(outputFile, data) +} diff --git a/cmd/subcmds/synthOutput.go b/cmd/subcmds/synthOutput.go index ff694c47..c1ba8a0d 100644 --- a/cmd/subcmds/synthOutput.go +++ b/cmd/subcmds/synthOutput.go @@ -10,7 +10,6 @@ import ( "bytes" "fmt" "os" - "path/filepath" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/confio" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/csvio" @@ -23,26 +22,24 @@ import ( const defaultFilePermission = 0o644 const defaultDirectoryPermission = 0o755 -func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error { - if err := updateOutputFormat(args); err != nil { +func writeOutput(args *inArgs, collection ir.SynthCollection, vpcNames []ir.ID) error { + if err := checkOutputFlags(args); err != nil { return err } - if args.outputDir != "" && args.outputFmt == apiOutputFormat { - return fmt.Errorf("-d cannot be used with format json") - } if args.outputDir != "" { // create the directory if needed if err := os.MkdirAll(args.outputDir, defaultDirectoryPermission); err != nil { return err } } - if err := writeLocals(args, collection, vpcNames); err != nil { + _, isACLCollection := collection.(*ir.ACLCollection) + if err := writeLocals(args, vpcNames, isACLCollection); err != nil { return err } var data *bytes.Buffer var err error if args.outputDir == "" { - if data, err = writeCollection(args, collection, ""); err != nil { + if data, err = writeSynthCollection(args, collection, ""); err != nil { return err } return writeToFile(args.outputFile, data) @@ -55,7 +52,7 @@ func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error if args.prefix != "" { args.outputFile = args.outputDir + "/" + args.prefix + "_" + suffix } - if data, err = writeCollection(args, collection, vpc); err != nil { + if data, err = writeSynthCollection(args, collection, vpc); err != nil { return err } if err := writeToFile(args.outputFile, data); err != nil { @@ -65,27 +62,19 @@ func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error return nil } -func writeCollection(args *inArgs, collection ir.Collection, vpc string) (*bytes.Buffer, error) { +func writeSynthCollection(args *inArgs, collection ir.SynthCollection, vpc string) (*bytes.Buffer, error) { var data bytes.Buffer - writer, err := pickWriter(args, &data) + writer, err := pickSynthWriter(args, &data) if err != nil { return nil, err } - if err := collection.Write(writer, vpc); err != nil { + if err := collection.WriteSynth(writer, vpc); err != nil { return nil, err } return &data, nil } -func writeToFile(outputFile string, data *bytes.Buffer) error { - if outputFile == "" { - fmt.Println(data.String()) - return nil - } - return os.WriteFile(outputFile, data.Bytes(), defaultFilePermission) -} - -func pickWriter(args *inArgs, data *bytes.Buffer) (ir.SynthWriter, error) { +func pickSynthWriter(args *inArgs, data *bytes.Buffer) (ir.SynthWriter, error) { w := bufio.NewWriter(data) switch args.outputFmt { case tfOutputFormat: @@ -100,28 +89,3 @@ func pickWriter(args *inArgs, data *bytes.Buffer) (ir.SynthWriter, error) { return nil, fmt.Errorf("bad output format: %q", args.outputFmt) } } - -func writeLocals(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error { - if !args.locals { - return nil - } - if args.outputFmt != tfOutputFormat { - return fmt.Errorf("--locals flag requires setting the output format to tf") - } - - _, isACLCollection := collection.(*ir.ACLCollection) - var data *bytes.Buffer - var err error - if data, err = tfio.WriteLocals(vpcNames, isACLCollection); err != nil { - return err - } - - outputFile := "" - suffix := "/locals.tf" - if args.outputDir != "" { - outputFile = args.outputDir + suffix - } else if args.outputFile != "" { - outputFile = filepath.Dir(args.outputFile) + suffix - } - return writeToFile(outputFile, data) -} diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index b09e3a11..1c0d7cda 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -28,6 +28,10 @@ func (w *Writer) WriteSynthACL(c *ir.ACLCollection, vpc string) error { return err } +func (w *Writer) WriteOptimizeACL(c *ir.ACLCollection) error { + return nil +} + func aclProtocol(t netp.Protocol) []tf.Block { switch p := t.(type) { case netp.TCPUDP: diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 6cd5447d..ddb66ac7 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -29,6 +29,10 @@ func (w *Writer) WriteSynthSG(c *ir.SGCollection, vpc string) error { return err } +func (w *Writer) WriteOptimizeSG(c *ir.SGCollection, vpc string) error { + return nil +} + func value(x interface{}) string { switch v := x.(type) { case *netset.IPBlock: diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index 993e5047..9075a28e 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -40,6 +40,10 @@ type ( SynthACLWriter interface { WriteSynthACL(aclColl *ACLCollection, vpc string) error } + + OptimizeACLWriter interface { + WriteOptimizeACL(aclColl *ACLCollection) error + } ) const ( @@ -125,10 +129,14 @@ func (c *ACLCollection) LookupOrCreate(name string) *ACL { return newACL } -func (c *ACLCollection) Write(w SynthWriter, vpc string) error { +func (c *ACLCollection) WriteSynth(w SynthWriter, vpc string) error { return w.WriteSynthACL(c, vpc) } +func (c *ACLCollection) WriteOptimize(w OptimizeWriter) error { + return w.WriteOptimizeACL(c) +} + func (c *ACLCollection) SortedACLSubnets(vpc string) []string { if vpc == "" { return utils.SortedAllInnerMapsKeys(c.ACLs) diff --git a/pkg/ir/common.go b/pkg/ir/common.go index 17b2a69d..5f9fddd8 100644 --- a/pkg/ir/common.go +++ b/pkg/ir/common.go @@ -8,17 +8,26 @@ package ir type ( Direction string + SynthCollection interface { + WriteSynth(writer SynthWriter, vpc string) error + } + + OptimizeCollection interface { + WriteOptimize(writer OptimizeWriter) error + } + SynthWriter interface { SynthACLWriter SynthSGWriter } + + OptimizeWriter interface { + OptimizeACLWriter + OptimizeSGWriter + } ) const ( Outbound Direction = "outbound" Inbound Direction = "inbound" ) - -type Collection interface { - Write(writer SynthWriter, vpc string) error -} diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index b9783071..917125e3 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -55,6 +55,10 @@ type ( SynthSGWriter interface { WriteSynthSG(sgColl *SGCollection, vpc string) error } + + OptimizeSGWriter interface { + WriteOptimizeSG(sgColl *SGCollection) error + } ) func (s SGName) String() string { @@ -112,10 +116,14 @@ func (a *SG) AllRules() []SGRule { return append(a.InboundRules, a.OutboundRules...) } -func (c *SGCollection) Write(w SynthWriter, vpc string) error { +func (c *SGCollection) WriteSynth(w SynthWriter, vpc string) error { return w.WriteSynthSG(c, vpc) } +func (c *SGCollection) WriteOptimize(w OptimizeWriter) error { + return w.WriteOptimizeSG(c) +} + func (c *SGCollection) SortedSGNames(vpc ID) []SGName { if vpc == "" { return utils.SortedAllInnerMapsKeys(c.SGs) diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index ab16eb35..50e999fd 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -28,7 +28,7 @@ func NewACLSynthesizer(s *ir.Spec, single bool) Synthesizer { return &ACLSynthesizer{spec: s, singleACL: single, result: ir.NewACLCollection()} } -func (a *ACLSynthesizer) Synth() ir.Collection { +func (a *ACLSynthesizer) Synth() ir.SynthCollection { return a.makeACL() } diff --git a/pkg/synth/common.go b/pkg/synth/common.go index 9833c121..5ce7b220 100644 --- a/pkg/synth/common.go +++ b/pkg/synth/common.go @@ -15,7 +15,7 @@ import ( type ( Synthesizer interface { - Synth() ir.Collection + Synth() ir.SynthCollection } namedAddrs struct { diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 054171cf..13938223 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -23,7 +23,7 @@ func NewSGSynthesizer(s *ir.Spec, _ bool) Synthesizer { return &SGSynthesizer{spec: s, result: ir.NewSGCollection()} } -func (s *SGSynthesizer) Synth() ir.Collection { +func (s *SGSynthesizer) Synth() ir.SynthCollection { return s.makeSG() } diff --git a/test/end_to_end_test.go b/test/end_to_end_test.go index 484ec4c0..a3cceeb4 100644 --- a/test/end_to_end_test.go +++ b/test/end_to_end_test.go @@ -144,7 +144,7 @@ func shrinkWhitespace(s string) string { return regexp.MustCompile(`[ \t]+`).ReplaceAllString(s, " ") } -func write(collection ir.Collection, outputFormat, conn, vpc string) (text string, err error) { +func write(collection ir.SynthCollection, outputFormat, conn, vpc string) (text string, err error) { buf := new(bytes.Buffer) var writer ir.SynthWriter switch outputFormat { @@ -160,7 +160,7 @@ func write(collection ir.Collection, outputFormat, conn, vpc string) (text strin if err != nil { return "", err } - err = collection.Write(writer, vpc) + err = collection.WriteSynth(writer, vpc) if err != nil { return "", err } @@ -175,7 +175,7 @@ func readExpectedFile(filename string) string { return shrinkWhitespace(string(buf)) } -func writeSingleFile(testCase TestCase, t *testing.T, collection ir.Collection) { +func writeSingleFile(testCase TestCase, t *testing.T, collection ir.SynthCollection) { actual, err := write(collection, testCase.outputFormat, fmt.Sprintf("../test/%s", testCase.resolve(defaultConfigName)), "") if err != nil { t.Fatal(err) @@ -188,7 +188,7 @@ func writeSingleFile(testCase TestCase, t *testing.T, collection ir.Collection) } } -func writeMultipleFiles(testCase TestCase, t *testing.T, collection ir.Collection, s *ir.Spec) { +func writeMultipleFiles(testCase TestCase, t *testing.T, collection ir.SynthCollection, s *ir.Spec) { for vpcName := range s.Defs.VPCs { actual, err := write(collection, testCase.outputFormat, fmt.Sprintf("../test/%s", testCase.resolve(defaultConfigName)), vpcName) if err != nil { From eebd628a1ff4be48a286ca963910e8ec6bbb2f21 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 27 Aug 2024 14:56:06 +0300 Subject: [PATCH 019/131] template --- cmd/subcmds/optimize.go | 23 ++++++++++++++++- cmd/subcmds/optimizeOutput.go | 20 +++++++++++++-- cmd/subcmds/optimizeSG.go | 22 +--------------- cmd/subcmds/outputCommon.go | 3 +++ cmd/subcmds/root.go | 48 +++++++++++++++++------------------ cmd/subcmds/synth.go | 7 +++++ pkg/io/tfio/common.go | 2 +- pkg/io/tfio/sg.go | 2 +- pkg/ir/acl.go | 4 +++ pkg/ir/sg.go | 4 +++ pkg/optimize/common.go | 19 ++++++++++++++ pkg/optimize/sg.go | 26 ++++++++++++++++++- 12 files changed, 129 insertions(+), 51 deletions(-) create mode 100644 pkg/optimize/common.go diff --git a/cmd/subcmds/optimize.go b/cmd/subcmds/optimize.go index 877662a9..4b215fe1 100644 --- a/cmd/subcmds/optimize.go +++ b/cmd/subcmds/optimize.go @@ -5,7 +5,13 @@ SPDX-License-Identifier: Apache-2.0 package subcmds -import "github.com/spf13/cobra" +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" +) func NewOptimizeCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ @@ -14,7 +20,22 @@ func NewOptimizeCommand(args *inArgs) *cobra.Command { Long: `optimization of existing SG (nACLS are not supported yet)`, } + // flags + cmd.Flags().StringVarP(&args.firewallName, firewallNameFlag, "s", "", "which vpcFirewall to optimize") + + // flags settings + _ = cmd.MarkPersistentFlagRequired(firewallNameFlag) // temporary + + // sub cmds cmd.AddCommand(NewOptimizeSGCommand(args)) return cmd } + +func optimization(cmd *cobra.Command, args *inArgs, newOptimizer optimize.Optimizer) error { + cmd.SilenceUsage = true // if we got this far, flags are syntactically correct, so no need to print usage + if err := newOptimizer.ParseCollection(args.configFile); err != nil { + return fmt.Errorf("could not parse config file %v: %w", args.configFile, err) + } + return writeOptimizeOutput(args, newOptimizer.Optimize(), newOptimizer.VpcNames()) +} diff --git a/cmd/subcmds/optimizeOutput.go b/cmd/subcmds/optimizeOutput.go index 1d20542c..2b602f1c 100644 --- a/cmd/subcmds/optimizeOutput.go +++ b/cmd/subcmds/optimizeOutput.go @@ -22,10 +22,26 @@ func writeOptimizeOutput(args *inArgs, collection ir.OptimizeCollection, vpcName if err := writeLocals(args, vpcNames, isACLCollection); err != nil { return err } - return nil + data, err := writeOptimizeCollection(args, collection) + if err != nil { + return err + } + return writeToFile(args.outputFile, data) +} + +func writeOptimizeCollection(args *inArgs, collection ir.OptimizeCollection) (*bytes.Buffer, error) { + var data bytes.Buffer + writer, err := pickOptimizeWriter(args, &data) + if err != nil { + return nil, err + } + if err := collection.WriteOptimize(writer); err != nil { + return nil, err + } + return &data, nil } -func pickOptimizeWriter(args *inArgs, data *bytes.Buffer) (ir.SynthWriter, error) { +func pickOptimizeWriter(args *inArgs, data *bytes.Buffer) (ir.OptimizeWriter, error) { w := bufio.NewWriter(data) switch args.outputFmt { case tfOutputFormat: diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go index 53f83477..6a07c367 100644 --- a/cmd/subcmds/optimizeSG.go +++ b/cmd/subcmds/optimizeSG.go @@ -6,13 +6,9 @@ SPDX-License-Identifier: Apache-2.0 package subcmds import ( - "fmt" - "github.com/spf13/cobra" - "github.com/np-guard/vpc-network-config-synthesis/pkg/io/confio" "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" - "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) func NewOptimizeSGCommand(args *inArgs) *cobra.Command { @@ -22,24 +18,8 @@ func NewOptimizeSGCommand(args *inArgs) *cobra.Command { Long: `OptimizeSG attempts to reduce the number of security group rules in a SG without changing the semantic.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { - return optimization(cmd, args) + return optimization(cmd, args, optimize.NewSGOptimizer(args.firewallName)) }, } - - cmd.Flags().StringVarP(&args.sgName, sgNameFlag, "s", "", "which SG to optimize") - _ = cmd.MarkFlagRequired(sgNameFlag) // Todo: delete this line. if sgName flag is not supplied - optimize all SGs - return cmd } - -func optimization(cmd *cobra.Command, args *inArgs) error { - cmd.SilenceUsage = true // if we got this far, flags are syntactically correct, so no need to print usage - sgs, err := confio.ReadSGs(args.configFile) - if err != nil { - return fmt.Errorf("could not parse config file %v: %w", args.configFile, err) - } - if optimize.ReduceSGRules(sgs, args.sgName) != nil { - return err - } - return writeOptimizeOutput(args, sgs, utils.MapKeys(sgs.SGs)) -} diff --git a/cmd/subcmds/outputCommon.go b/cmd/subcmds/outputCommon.go index d663670c..55872136 100644 --- a/cmd/subcmds/outputCommon.go +++ b/cmd/subcmds/outputCommon.go @@ -16,6 +16,9 @@ import ( ) func checkOutputFlags(args *inArgs) error { + if args.outputDir != "" && args.outputFile != "" { + return fmt.Errorf("only one of -d and -o can be supplied") + } if err := updateOutputFormat(args); err != nil { return err } diff --git a/cmd/subcmds/root.go b/cmd/subcmds/root.go index 1f47e591..a6e13486 100644 --- a/cmd/subcmds/root.go +++ b/cmd/subcmds/root.go @@ -13,27 +13,27 @@ import ( ) const ( - configFlag = "config" - specFlag = "spec" - outputFmtFlag = "format" - outputFileFlag = "output-file" - outputDirFlag = "output-dir" - prefixFlag = "prefix" - sgNameFlag = "sg-name" - singleACLFlag = "single" - localsFlag = "locals" + configFlag = "config" + specFlag = "spec" + outputFmtFlag = "format" + outputFileFlag = "output-file" + outputDirFlag = "output-dir" + prefixFlag = "prefix" + firewallNameFlag = "firewall-name" + singleACLFlag = "single" + localsFlag = "locals" ) type inArgs struct { - configFile string - specFile string - outputFmt string - outputFile string - outputDir string - prefix string - sgName string - singleacl bool - locals bool + configFile string + specFile string + outputFmt string + outputFile string + outputDir string + prefix string + firewallName string + singleacl bool + locals bool } func NewRootCommand() *cobra.Command { @@ -45,25 +45,25 @@ func NewRootCommand() *cobra.Command { Long: `Tool for automatic synthesis of VPC network configurations, namely Network ACLs and Security Groups.`, } + // flags rootCmd.PersistentFlags().StringVarP(&args.configFile, configFlag, "c", "", "JSON file containing a configuration object of existing resources") rootCmd.PersistentFlags().StringVarP(&args.outputFmt, outputFmtFlag, "f", "", "Output format; "+mustBeOneOf(outputFormats)) rootCmd.PersistentFlags().StringVarP(&args.outputFile, outputFileFlag, "o", "", "Write all generated resources to the specified file.") - rootCmd.PersistentFlags().StringVarP(&args.outputDir, outputDirFlag, "d", "", - "Write generated resources to files in the specified directory, one file per VPC.") - rootCmd.PersistentFlags().StringVarP(&args.prefix, prefixFlag, "p", "", "The prefix of the files that will be created.") rootCmd.PersistentFlags().BoolVarP(&args.locals, localsFlag, "l", false, "whether to generate a locals.tf file (only possible when the output format is tf)") - rootCmd.PersistentFlags().SortFlags = false + // flags set for all commands + rootCmd.PersistentFlags().SortFlags = false _ = rootCmd.MarkPersistentFlagRequired(configFlag) - rootCmd.MarkFlagsMutuallyExclusive(outputFileFlag, outputDirFlag) + // sub cmds rootCmd.AddCommand(NewSynthCommand(args)) rootCmd.AddCommand(NewOptimizeCommand(args)) + // disable help command. should use --help flag instead rootCmd.CompletionOptions.HiddenDefaultCmd = true - rootCmd.SetHelpCommand(&cobra.Command{Hidden: true}) // disable help command. should use --help flag instead + rootCmd.SetHelpCommand(&cobra.Command{Hidden: true}) return rootCmd } diff --git a/cmd/subcmds/synth.go b/cmd/subcmds/synth.go index 04e4cc1c..b0b2210b 100644 --- a/cmd/subcmds/synth.go +++ b/cmd/subcmds/synth.go @@ -21,9 +21,16 @@ func NewSynthCommand(args *inArgs) *cobra.Command { --config and --spec parameters must be supplied.`, } + // flags cmd.PersistentFlags().StringVarP(&args.specFile, specFlag, "s", "", "JSON file containing spec file") + cmd.PersistentFlags().StringVarP(&args.outputDir, outputDirFlag, "d", "", + "Write generated resources to files in the specified directory, one file per VPC.") + cmd.PersistentFlags().StringVarP(&args.prefix, prefixFlag, "p", "", "The prefix of the files that will be created.") + + // flags settings _ = cmd.MarkPersistentFlagRequired(specFlag) + // sub cmds cmd.AddCommand(NewSynthACLCommand(args)) cmd.AddCommand(NewSynthSGCommand(args)) diff --git a/pkg/io/tfio/common.go b/pkg/io/tfio/common.go index 60b9f1da..7726b591 100644 --- a/pkg/io/tfio/common.go +++ b/pkg/io/tfio/common.go @@ -21,7 +21,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -// Writer implements ir.SynthWriter +// Writer implements ir.SynthWriter and ir.OptimizeWriter type Writer struct { w *bufio.Writer } diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index ddb66ac7..981f44cb 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -29,7 +29,7 @@ func (w *Writer) WriteSynthSG(c *ir.SGCollection, vpc string) error { return err } -func (w *Writer) WriteOptimizeSG(c *ir.SGCollection, vpc string) error { +func (w *Writer) WriteOptimizeSG(c *ir.SGCollection) error { return nil } diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index 9075a28e..094ee726 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -129,6 +129,10 @@ func (c *ACLCollection) LookupOrCreate(name string) *ACL { return newACL } +func (c *ACLCollection) VpcNames() []string { + return utils.MapKeys(c.ACLs) +} + func (c *ACLCollection) WriteSynth(w SynthWriter, vpc string) error { return w.WriteSynthACL(c, vpc) } diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 917125e3..f92d94e8 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -116,6 +116,10 @@ func (a *SG) AllRules() []SGRule { return append(a.InboundRules, a.OutboundRules...) } +func (c *SGCollection) VpcNames() []string { + return utils.MapKeys(c.SGs) +} + func (c *SGCollection) WriteSynth(w SynthWriter, vpc string) error { return w.WriteSynthSG(c, vpc) } diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go new file mode 100644 index 00000000..d0aa9e52 --- /dev/null +++ b/pkg/optimize/common.go @@ -0,0 +1,19 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + +type Optimizer interface { + // read the collection from the config object file + ParseCollection(filename string) error + + // optimize number of SG/nACL rules + Optimize() ir.OptimizeCollection + + // returns a slice of all vpc names. used to generate locals file + VpcNames() []string +} diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index f3301962..4c74a514 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -6,9 +6,33 @@ SPDX-License-Identifier: Apache-2.0 package optimize import ( + "github.com/np-guard/vpc-network-config-synthesis/pkg/io/confio" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -func ReduceSGRules(_ *ir.SGCollection, _ string) error { +type SGOptimizer struct { + sgCollection *ir.SGCollection + sgName string +} + +func NewSGOptimizer(sgName string) Optimizer { + return &SGOptimizer{sgCollection: nil, sgName: sgName} +} + +func (s *SGOptimizer) ParseCollection(filename string) error { + c, err := confio.ReadSGs(filename) + if err != nil { + return err + } + s.sgCollection = c return nil } + +func (s *SGOptimizer) Optimize() ir.OptimizeCollection { + return s.sgCollection +} + +func (s *SGOptimizer) VpcNames() []string { + return utils.MapKeys(s.sgCollection.SGs) +} From 26473b326f930a9b34d054add9a954084888f15e Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 28 Aug 2024 16:32:19 +0300 Subject: [PATCH 020/131] done --- cmd/subcmds/synth.go | 2 +- pkg/io/confio/parse_sgs.go | 4 ++- pkg/io/tfio/acl.go | 2 +- pkg/io/tfio/sg.go | 57 ++++++++++++++++++++++++-------------- pkg/ir/acl.go | 18 ++++++------ pkg/ir/sg.go | 10 ++++--- 6 files changed, 56 insertions(+), 37 deletions(-) diff --git a/cmd/subcmds/synth.go b/cmd/subcmds/synth.go index b0b2210b..71d94e01 100644 --- a/cmd/subcmds/synth.go +++ b/cmd/subcmds/synth.go @@ -44,5 +44,5 @@ func synthesis(cmd *cobra.Command, args *inArgs, newSynthesizer func(*ir.Spec, b return err } synthesizer := newSynthesizer(spec, single) - return writeOutput(args, synthesizer.Synth(), utils.MapKeys(spec.Defs.ConfigDefs.VPCs)) + return writeOutput(args, synthesizer.Synth(), utils.SortedMapKeys(spec.Defs.ConfigDefs.VPCs)) } diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index ce685abd..8d8eac44 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -35,7 +35,9 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { if result.SGs[vpcName] == nil { result.SGs[vpcName] = make(map[ir.SGName]*ir.SG) } - result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, OutboundRules: outbound} + sgName := ir.SGName(*sg.Name) + result.SGs[vpcName][sgName] = &ir.SG{SGName: sgName, VpcName: vpcName, + InboundRules: inbound, OutboundRules: outbound} } } return result, nil diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index 1c0d7cda..9a91f680 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -29,7 +29,7 @@ func (w *Writer) WriteSynthACL(c *ir.ACLCollection, vpc string) error { } func (w *Writer) WriteOptimizeACL(c *ir.ACLCollection) error { - return nil + return fmt.Errorf("OptimizeACL is not supported yet") } func aclProtocol(t netp.Protocol) []tf.Block { diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 981f44cb..8f5a6fd7 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -18,9 +18,17 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -// WriteSG prints an entire collection of Security Groups as a sequence of terraform resources. func (w *Writer) WriteSynthSG(c *ir.SGCollection, vpc string) error { - output := sgCollection(c, vpc).Print() + return w.writeSGCollection(c, vpc, true) +} + +func (w *Writer) WriteOptimizeSG(c *ir.SGCollection) error { + return w.writeSGCollection(c, "", false) +} + +// writeSGCollection prints an entire collection of Security Groups as a sequence of terraform resources. +func (w *Writer) writeSGCollection(c *ir.SGCollection, vpc string, writeComments bool) error { + output := sgCollection(c, vpc, writeComments).Print() _, err := w.w.WriteString(output) if err != nil { return err @@ -29,10 +37,6 @@ func (w *Writer) WriteSynthSG(c *ir.SGCollection, vpc string) error { return err } -func (w *Writer) WriteOptimizeSG(c *ir.SGCollection) error { - return nil -} - func value(x interface{}) string { switch v := x.(type) { case *netset.IPBlock: @@ -69,13 +73,17 @@ func sgProtocol(t netp.Protocol, d ir.Direction) []tf.Block { return nil } -func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) tf.Block { +func sgRule(rule *ir.SGRule, sgName ir.SGName, i int, writeComment bool) tf.Block { ruleName := fmt.Sprintf("%v-%v", sgName, i) verifyName(ruleName) + comment := "" + if writeComment { + comment = fmt.Sprintf("# %v", rule.Explanation) + } return tf.Block{ Name: "resource", Labels: []string{quote("ibm_is_security_group_rule"), ir.ChangeScoping(quote(ruleName))}, - Comment: fmt.Sprintf("# %v", rule.Explanation), + Comment: comment, Arguments: []tf.Argument{ {Name: "group", Value: value(sgName)}, {Name: "direction", Value: quote(direction(rule.Direction))}, @@ -85,7 +93,8 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) tf.Block { } } -func sg(sgName, comment string) tf.Block { +func sgBlock(sg *ir.SG, comment string) tf.Block { + sgName := sg.SGName.String() verifyName(sgName) return tf.Block{ Name: "resource", //nolint:revive // obvious false positive @@ -94,22 +103,28 @@ func sg(sgName, comment string) tf.Block { Arguments: []tf.Argument{ {Name: "name", Value: ir.ChangeScoping(quote("sg-" + sgName))}, {Name: "resource_group", Value: "local.sg_synth_resource_group_id"}, - {Name: "vpc", Value: fmt.Sprintf("local.sg_synth_%s_id", ir.VpcFromScopedResource(sgName))}, + {Name: "vpc", Value: fmt.Sprintf("local.sg_synth_%s_id", sg.VpcName)}, }, } } -func sgCollection(t *ir.SGCollection, vpc string) *tf.ConfigFile { - var resources []tf.Block //nolint:prealloc // nontrivial to calculate, and an unlikely performance bottleneck - for _, sgName := range t.SortedSGNames(vpc) { - comment := "" - vpcName := ir.VpcFromScopedResource(string(sgName)) - rules := t.SGs[vpcName][sgName].AllRules() - comment = fmt.Sprintf("\n### SG attached to %v", sgName) - resources = append(resources, sg(sgName.String(), comment)) - for i := range rules { - rule := sgRule(&rules[i], sgName, i) - resources = append(resources, rule) +func sgCollection(t *ir.SGCollection, vpc string, writeComments bool) *tf.ConfigFile { + var resources []tf.Block + for _, vpcName := range t.VpcNames() { + if vpc != vpcName && vpc != "" { + continue + } + for _, sgName := range t.SortedSGNames(vpcName) { + sg := t.SGs[vpcName][sgName] + comment := "\n" + if writeComments { + comment = fmt.Sprintf("\n### SG attached to %v", sgName) + } + resources = append(resources, sgBlock(sg, comment)) + rules := sg.AllRules() + for i := range rules { + resources = append(resources, sgRule(&rules[i], sgName, i, writeComments)) + } } } return &tf.ConfigFile{ diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index 094ee726..81c621be 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -29,6 +29,7 @@ type ( ACL struct { Subnet string + VpcName string Internal []ACLRule External []ACLRule } @@ -111,26 +112,25 @@ func NewACLCollection() *ACLCollection { return &ACLCollection{ACLs: map[ID]map[string]*ACL{}} } -func NewACL() *ACL { - return &ACL{Internal: []ACLRule{}, External: []ACLRule{}} +func NewACL(subnet, vpcName string) *ACL { + return &ACL{Subnet: subnet, VpcName: vpcName, Internal: []ACLRule{}, External: []ACLRule{}} } -func (c *ACLCollection) LookupOrCreate(name string) *ACL { - vpcName := VpcFromScopedResource(name) - if acl, ok := c.ACLs[vpcName][name]; ok { +func (c *ACLCollection) LookupOrCreate(subnet string) *ACL { + vpcName := VpcFromScopedResource(subnet) + if acl, ok := c.ACLs[vpcName][subnet]; ok { return acl } - newACL := NewACL() - newACL.Subnet = name + newACL := NewACL(subnet, vpcName) if c.ACLs[vpcName] == nil { c.ACLs[vpcName] = make(map[string]*ACL) } - c.ACLs[vpcName][name] = newACL + c.ACLs[vpcName][subnet] = newACL return newACL } func (c *ACLCollection) VpcNames() []string { - return utils.MapKeys(c.ACLs) + return utils.SortedMapKeys(c.ACLs) } func (c *ACLCollection) WriteSynth(w SynthWriter, vpc string) error { diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index f92d94e8..e1d2f0a3 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -43,6 +43,8 @@ type ( } SG struct { + SGName SGName + VpcName string InboundRules []SGRule OutboundRules []SGRule Attached []ID @@ -82,8 +84,8 @@ func (r *SGRule) mustSupersede(other *SGRule) bool { return res } -func NewSG() *SG { - return &SG{InboundRules: []SGRule{}, OutboundRules: []SGRule{}, Attached: []ID{}} +func NewSG(vpcName string, sgName SGName) *SG { + return &SG{SGName: sgName, VpcName: vpcName, InboundRules: []SGRule{}, OutboundRules: []SGRule{}, Attached: []ID{}} } func NewSGCollection() *SGCollection { @@ -95,7 +97,7 @@ func (c *SGCollection) LookupOrCreate(name SGName) *SG { if sg, ok := c.SGs[vpcName][name]; ok { return sg } - newSG := NewSG() + newSG := NewSG(vpcName, name) if c.SGs[vpcName] == nil { c.SGs[vpcName] = make(map[SGName]*SG) } @@ -117,7 +119,7 @@ func (a *SG) AllRules() []SGRule { } func (c *SGCollection) VpcNames() []string { - return utils.MapKeys(c.SGs) + return utils.SortedMapKeys(c.SGs) } func (c *SGCollection) WriteSynth(w SynthWriter, vpc string) error { From 010ee9da864cbb6abaf4848328d8f7d7fa57b480 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Sun, 1 Sep 2024 17:36:07 +0300 Subject: [PATCH 021/131] fixed --- cmd/subcmds/optimize.go | 2 +- cmd/subcmds/outputCommon.go | 2 + cmd/subcmds/synthOutput.go | 1 - pkg/io/confio/parse_sgs.go | 21 +++- pkg/optimize/sg.go | 199 ++++++++++++++++++++++++++++++++++-- 5 files changed, 213 insertions(+), 12 deletions(-) diff --git a/cmd/subcmds/optimize.go b/cmd/subcmds/optimize.go index 4b215fe1..fe137a15 100644 --- a/cmd/subcmds/optimize.go +++ b/cmd/subcmds/optimize.go @@ -21,7 +21,7 @@ func NewOptimizeCommand(args *inArgs) *cobra.Command { } // flags - cmd.Flags().StringVarP(&args.firewallName, firewallNameFlag, "s", "", "which vpcFirewall to optimize") + cmd.PersistentFlags().StringVarP(&args.firewallName, firewallNameFlag, "n", "", "which vpcFirewall to optimize") // flags settings _ = cmd.MarkPersistentFlagRequired(firewallNameFlag) // temporary diff --git a/cmd/subcmds/outputCommon.go b/cmd/subcmds/outputCommon.go index 55872136..aa399315 100644 --- a/cmd/subcmds/outputCommon.go +++ b/cmd/subcmds/outputCommon.go @@ -15,6 +15,8 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) +const defaultFilePermission = 0o644 + func checkOutputFlags(args *inArgs) error { if args.outputDir != "" && args.outputFile != "" { return fmt.Errorf("only one of -d and -o can be supplied") diff --git a/cmd/subcmds/synthOutput.go b/cmd/subcmds/synthOutput.go index c1ba8a0d..12e0670b 100644 --- a/cmd/subcmds/synthOutput.go +++ b/cmd/subcmds/synthOutput.go @@ -19,7 +19,6 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -const defaultFilePermission = 0o644 const defaultDirectoryPermission = 0o755 func writeOutput(args *inArgs, collection ir.SynthCollection, vpcNames []ir.ID) error { diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index 8d8eac44..f50f6cc2 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -154,19 +154,34 @@ func translateRemote(remote vpcv1.SecurityGroupRuleRemoteIntf) (ir.RemoteType, e } func translateLocal(local vpcv1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, error) { + var err error + var ipAddrs *netset.IPBlock + if l, ok := local.(*vpcv1.SecurityGroupRuleLocal); ok { if l.CIDRBlock != nil { - return netset.IPBlockFromCidr(*l.CIDRBlock) + ipAddrs, err = netset.IPBlockFromCidr(*l.CIDRBlock) } if l.Address != nil { - return netset.IPBlockFromIPAddress(*l.CIDRBlock) + ipAddrs, err = netset.IPBlockFromIPAddress(*l.CIDRBlock) + } + if err != nil { + return nil, err } + return verifyLocalsValue(ipAddrs) } return nil, fmt.Errorf("error parsing Local field") } +// temporary +func verifyLocalsValue(ipAddrs *netset.IPBlock) (*netset.IPBlock, error) { + if !ipAddrs.Equal(netset.GetCidrAll()) { + return nil, fmt.Errorf("only 0.0.0.0/32 CIDR block is supported for locals values") + } + return ipAddrs, nil +} + func translateProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (netp.Protocol, error) { - isTCP := *rule.Protocol == string(netp.ProtocolStringTCP) + isTCP := *rule.Protocol == "tcp" minDstPort := utils.GetProperty(rule.PortMin, netp.MinPort) maxDstPort := utils.GetProperty(rule.PortMax, netp.MaxPort) return netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(minDstPort), int(maxDstPort)) diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index 4c74a514..5b62b170 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -6,20 +6,42 @@ SPDX-License-Identifier: Apache-2.0 package optimize import ( + "log" + "sort" + + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/io/confio" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -type SGOptimizer struct { - sgCollection *ir.SGCollection - sgName string -} +type ( + SGOptimizer struct { + sgCollection *ir.SGCollection + sgName ir.SGName + } + + sgRuleGroups struct { + tcpToAddrs []ir.SGRule + tcpToSG []ir.SGRule + udpToAddrs []ir.SGRule + udpToSG []ir.SGRule + icmpToAddrs []ir.SGRule + icmpToSG []ir.SGRule + allToAddrs []ir.SGRule + allToSG []ir.SGRule + } +) func NewSGOptimizer(sgName string) Optimizer { - return &SGOptimizer{sgCollection: nil, sgName: sgName} + return &SGOptimizer{sgCollection: nil, sgName: ir.SGName(sgName)} } +// read SGs from config file func (s *SGOptimizer) ParseCollection(filename string) error { c, err := confio.ReadSGs(filename) if err != nil { @@ -29,10 +51,173 @@ func (s *SGOptimizer) ParseCollection(filename string) error { return nil } +// returns a sorted slice of the vpc names +func (s *SGOptimizer) VpcNames() []string { + return utils.SortedMapKeys(s.sgCollection.SGs) +} + +// Optimize attempts to reduce thr number of SG rules +// the algorithm attempts to reduce both inbound and outbound rules separately +// A message is printed to the log at the end of the algorithm func (s *SGOptimizer) Optimize() ir.OptimizeCollection { + for vpcName := range s.sgCollection.SGs { + var sg *ir.SG + var ok bool + if sg, ok = s.sgCollection.SGs[vpcName][s.sgName]; !ok && s.sgName != "" { + continue + } + reducedRules := 0 + newInboundRules := s.reduceSGRules(sg.InboundRules, ir.Inbound) + if len(sg.InboundRules) > len(newInboundRules) { + reducedRules += len(sg.InboundRules) - len(newInboundRules) + s.sgCollection.SGs[vpcName][s.sgName].InboundRules = newInboundRules + } + newOutboundRules := s.reduceSGRules(sg.OutboundRules, ir.Outbound) + if len(sg.OutboundRules) > len(newOutboundRules) { + reducedRules += len(sg.OutboundRules) - len(newOutboundRules) + s.sgCollection.SGs[vpcName][s.sgName].OutboundRules = newOutboundRules + } + + switch { + case reducedRules == 0: + log.Printf("no rules were reduced in sg %s", string(s.sgName)) + case reducedRules == 1: + log.Printf("1 rule was reduced in sg %s", string(s.sgName)) + default: + log.Printf("%d rules were reduced in sg %s", reducedRules, string(s.sgName)) + } + } return s.sgCollection } -func (s *SGOptimizer) VpcNames() []string { - return utils.MapKeys(s.sgCollection.SGs) +// divideSGRules divides the rules into groups based on their protocol and remote +// and attempts to reduce each group separately +func (s *SGOptimizer) reduceSGRules(rules []ir.SGRule, direction ir.Direction) []ir.SGRule { + ruleGroups := divideSGRules(rules) + tcpToAddrs := s.reduceSGRulesTcpudpToAddrs(rulesToIPAddrsToPortsSpan(ruleGroups.tcpToAddrs), direction, true) + tcpToSg := s.reduceSGRulesTcpudpToSG(rulesToSGToPortsSpan(rules), direction, true) + return append(tcpToAddrs, tcpToSg...) +} + +// reduceSGRulesTcpudpToAddrs attempts to reduce the number of rules of tcp/udp rules with ipAddrs as remote +func (s *SGOptimizer) reduceSGRulesTcpudpToAddrs(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], + direction ir.Direction, isTCP bool) []ir.SGRule { + result := make([]ir.SGRule, len(span)) + for i := range span { + for _, dstPorts := range span[i].Right.Intervals() { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) + rule := ir.SGRule{ + Direction: direction, + Remote: span[i].Left, + Protocol: p, + Local: netset.GetCidrAll(), + } + result[i] = rule + } + } + return result +} + +// reduceSGRulesTcpudpToAddrs attempts to reduce the number of rules of tcp/udp rules with a sg as remote +func (s *SGOptimizer) reduceSGRulesTcpudpToSG(span map[ir.SGName]*interval.CanonicalSet, direction ir.Direction, isTCP bool) []ir.SGRule { + result := make([]ir.SGRule, 0) + for sgName, intervals := range span { + for _, dstPorts := range intervals.Intervals() { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) + rule := ir.SGRule{ + Direction: direction, + Remote: sgName, + Protocol: p, + Local: netset.GetCidrAll(), + } + result = append(result, rule) + } + } + return result +} + +// converts []ir.SGRule (where all rules or either TCP/UDP but not both) to a span of (IPBlock X ports) +func rulesToIPAddrsToPortsSpan(rules []ir.SGRule) (p []ds.Pair[*netset.IPBlock, *interval.CanonicalSet]) { + span := ds.NewProductLeft[*netset.IPBlock, *interval.CanonicalSet]() + for i := range rules { + p := rules[i].Protocol.(netp.TCPUDP) // already checked + r := ds.CartesianPairLeft(rules[i].Remote.(*netset.IPBlock), p.DstPorts().ToSet()) + span = span.Union(r).(*ds.ProductLeft[*netset.IPBlock, *interval.CanonicalSet]) + } + return sortPartitionsByIPAddrs(span.Partitions()) +} + +// converts []ir.SGRule (where all rules or either TCP/UDP but not both) to a span intervals for each remote +func rulesToSGToPortsSpan(rules []ir.SGRule) map[ir.SGName]*interval.CanonicalSet { + result := make(map[ir.SGName]*interval.CanonicalSet) + for i := range rules { + p := rules[i].Protocol.(netp.TCPUDP) // already checked + remote := rules[i].Remote.(ir.SGName) // already checked + if result[remote] == nil { + result[remote] = interval.NewCanonicalSet() + } + result[remote].AddInterval(p.DstPorts()) + } + return result +} + +// each IPBlock is a single CIDR/IP address. The IPBlocks are disjoint. +func sortPartitionsByIPAddrs(p []ds.Pair[*netset.IPBlock, *interval.CanonicalSet]) []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] { + cmp := func(i, j int) bool { return p[i].Left.FirstIPAddress() < p[j].Left.FirstIPAddress() } + sort.Slice(p, cmp) + return p +} + +// divide SGCollection to TCP/UDP/ICMP/ProtocolALL X SGRemote/IPAddrs rules +func divideSGRules(rules []ir.SGRule) *sgRuleGroups { + tcpAddrs := make([]ir.SGRule, 0) + tcpSG := make([]ir.SGRule, 0) + udpAddrs := make([]ir.SGRule, 0) + udpSG := make([]ir.SGRule, 0) + icmpAddrs := make([]ir.SGRule, 0) + icmpSG := make([]ir.SGRule, 0) + allAddrs := make([]ir.SGRule, 0) + allSG := make([]ir.SGRule, 0) + + for _, rule := range rules { + // TCP rule + if p, ok := rule.Protocol.(netp.TCPUDP); ok && p.ProtocolString() == "TCP" { + if _, ok := rule.Remote.(*netset.IPBlock); ok { + tcpAddrs = append(tcpAddrs, rule) + } else { + tcpSG = append(tcpSG, rule) + } + } + + // UDP rule + if p, ok := rule.Protocol.(netp.TCPUDP); ok && p.ProtocolString() == "UDP" { + if _, ok := rule.Remote.(*netset.IPBlock); ok { + udpAddrs = append(udpAddrs, rule) + } else { + udpSG = append(udpSG, rule) + } + } + + // ICMP rule + if _, ok := rule.Protocol.(netp.ICMP); ok { + if _, ok := rule.Remote.(*netset.IPBlock); ok { + icmpAddrs = append(icmpAddrs, rule) + } else { + icmpSG = append(icmpSG, rule) + } + } + + // all protocol rules + if _, ok := rule.Protocol.(netp.AnyProtocol); ok { + if _, ok := rule.Remote.(*netset.IPBlock); ok { + allAddrs = append(allAddrs, rule) + } else { + allSG = append(allSG, rule) + } + } + } + return utils.Ptr(sgRuleGroups{tcpToAddrs: tcpAddrs, tcpToSG: tcpSG, + udpToAddrs: udpAddrs, udpToSG: udpSG, + icmpToAddrs: icmpAddrs, icmpToSG: icmpSG, + allToAddrs: allAddrs, allToSG: allSG}) } From 524956c866f88fd9dd35c2d9f8aada6b328f3879 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 2 Sep 2024 11:18:01 +0300 Subject: [PATCH 022/131] fixed --- pkg/optimize/sg.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index 5b62b170..b4ecabee 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -63,7 +63,7 @@ func (s *SGOptimizer) Optimize() ir.OptimizeCollection { for vpcName := range s.sgCollection.SGs { var sg *ir.SG var ok bool - if sg, ok = s.sgCollection.SGs[vpcName][s.sgName]; !ok && s.sgName != "" { + if sg, ok = s.sgCollection.SGs[vpcName][s.sgName]; !ok { continue } reducedRules := 0 @@ -78,6 +78,7 @@ func (s *SGOptimizer) Optimize() ir.OptimizeCollection { s.sgCollection.SGs[vpcName][s.sgName].OutboundRules = newOutboundRules } + // print a message to the log switch { case reducedRules == 0: log.Printf("no rules were reduced in sg %s", string(s.sgName)) From 02231d33a43ba5d13b495bf17c41d54a94f13ab1 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 2 Sep 2024 11:23:31 +0300 Subject: [PATCH 023/131] use ToIPAddressString --- pkg/io/confio/sg.go | 2 +- pkg/io/csvio/sg.go | 2 +- pkg/io/mdio/sg.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/io/confio/sg.go b/pkg/io/confio/sg.go index ee551214..656ec479 100644 --- a/pkg/io/confio/sg.go +++ b/pkg/io/confio/sg.go @@ -53,7 +53,7 @@ func sgRemote(nameToSGRemoteRef map[string]*vpcv1.SecurityGroupRuleRemoteSecurit st := rule.Remote.String() switch t := rule.Remote.(type) { case *netset.IPBlock: - if t.Size() == 1 { // single IP address + if ipString := t.ToIPAddressString(); ipString != "" { // single IP address return &vpcv1.SecurityGroupRuleRemoteIP{ Address: &st, } diff --git a/pkg/io/csvio/sg.go b/pkg/io/csvio/sg.go index a10dc8db..3a958754 100644 --- a/pkg/io/csvio/sg.go +++ b/pkg/io/csvio/sg.go @@ -74,7 +74,7 @@ func sGPort(p interval.Interval) string { func sGRemoteType(t ir.RemoteType) string { switch t := t.(type) { case *netset.IPBlock: - if t.Size() == 1 { + if ipString := t.ToIPAddressString(); ipString != "" { return "IP address" } return "CIDR block" diff --git a/pkg/io/mdio/sg.go b/pkg/io/mdio/sg.go index 044ddbca..8750af42 100644 --- a/pkg/io/mdio/sg.go +++ b/pkg/io/mdio/sg.go @@ -88,7 +88,7 @@ func sGPort(p interval.Interval) string { func sGRemoteType(t ir.RemoteType) string { switch t := t.(type) { case *netset.IPBlock: - if t.Size() == 1 { + if ipString := t.ToIPAddressString(); ipString != "" { return "IP address" } return "CIDR block" From aabe195c7783b8cbf5c4fd88c4215af447c1ee62 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 2 Sep 2024 18:32:34 +0300 Subject: [PATCH 024/131] wip --- pkg/optimize/common.go | 22 ++++++- pkg/optimize/icmp.go | 45 +++++++++++++ pkg/optimize/sg.go | 115 +++++++++++++++------------------- pkg/optimize/sgRulesToSpan.go | 76 ++++++++++++++++++++++ pkg/optimize/spanToSGRules.go | 73 +++++++++++++++++++++ 5 files changed, 267 insertions(+), 64 deletions(-) create mode 100644 pkg/optimize/icmp.go create mode 100644 pkg/optimize/sgRulesToSpan.go create mode 100644 pkg/optimize/spanToSGRules.go diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index d0aa9e52..5d1beb8c 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -5,7 +5,16 @@ SPDX-License-Identifier: Apache-2.0 package optimize -import "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +import ( + "sort" + + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) type Optimizer interface { // read the collection from the config object file @@ -17,3 +26,14 @@ type Optimizer interface { // returns a slice of all vpc names. used to generate locals file VpcNames() []string } + +// each IPBlock is a single CIDR/IP address. The IPBlocks are disjoint. +func sortPartitionsByIPAddrs(p []ds.Pair[*netset.IPBlock, *interval.CanonicalSet]) []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] { + cmp := func(i, j int) bool { return p[i].Left.FirstIPAddress() < p[j].Left.FirstIPAddress() } + sort.Slice(p, cmp) + return p +} + +func allPorts(ports *interval.CanonicalSet) bool { + return ports.Equal(netp.AllPorts().ToSet()) +} diff --git a/pkg/optimize/icmp.go b/pkg/optimize/icmp.go new file mode 100644 index 00000000..f4fb3a68 --- /dev/null +++ b/pkg/optimize/icmp.go @@ -0,0 +1,45 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import ( + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +type icmp struct { + allowed map[int]bool // type X code X allow/deny +} + +func newIcmp() *icmp { + return &icmp{} +} + +func (i *icmp) add(*netp.ICMPTypeCode) { + +} + +func (i *icmp) allCodes(t int) bool { + return true +} + +func (i *icmp) allTypesAndCodes() bool { + return true +} + +func (i *icmp) toSGRulestoSG(sgName *ir.SGName) []ir.SGRule { + return []ir.SGRule{} +} + +func (i *icmp) toSGRulestoIPAddrs(ipAddrs *netset.IPBlock) []ir.SGRule { + return []ir.SGRule{} +} + +func (i *icmp) all() bool { + return false +} diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index b4ecabee..6d824d8a 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -7,9 +7,7 @@ package optimize import ( "log" - "sort" - "github.com/np-guard/models/pkg/ds" "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" @@ -35,6 +33,10 @@ type ( allToAddrs []ir.SGRule allToSG []ir.SGRule } + + sgRemotePortsSpan map[*ir.SGName]*interval.CanonicalSet + sgRemoteIcmpSpan map[*ir.SGName]*icmp + sgRemoteAllSpan []*ir.SGName ) func NewSGOptimizer(sgName string) Optimizer { @@ -67,11 +69,15 @@ func (s *SGOptimizer) Optimize() ir.OptimizeCollection { continue } reducedRules := 0 + + // reduce inbound rules first newInboundRules := s.reduceSGRules(sg.InboundRules, ir.Inbound) if len(sg.InboundRules) > len(newInboundRules) { reducedRules += len(sg.InboundRules) - len(newInboundRules) s.sgCollection.SGs[vpcName][s.sgName].InboundRules = newInboundRules } + + // reduce outbound rules second newOutboundRules := s.reduceSGRules(sg.OutboundRules, ir.Outbound) if len(sg.OutboundRules) > len(newOutboundRules) { reducedRules += len(sg.OutboundRules) - len(newOutboundRules) @@ -95,78 +101,61 @@ func (s *SGOptimizer) Optimize() ir.OptimizeCollection { // and attempts to reduce each group separately func (s *SGOptimizer) reduceSGRules(rules []ir.SGRule, direction ir.Direction) []ir.SGRule { ruleGroups := divideSGRules(rules) - tcpToAddrs := s.reduceSGRulesTcpudpToAddrs(rulesToIPAddrsToPortsSpan(ruleGroups.tcpToAddrs), direction, true) - tcpToSg := s.reduceSGRulesTcpudpToSG(rulesToSGToPortsSpan(rules), direction, true) - return append(tcpToAddrs, tcpToSg...) + + // rules with SG as a remote + tcpToSGSpan := tcpudpRulesToSGToPortsSpan(ruleGroups.tcpToSG) + udpToSGSpan := tcpudpRulesToSGToPortsSpan(ruleGroups.udpToSG) + icmpToSGSpan := icmpRulesToSGToIcmpSpan(ruleGroups.icmpToSG) + protocolAllToSGSpan := allProtocolRulesToSGToSpan(ruleGroups.allToSG) + rulesToSG := reduceSGRulesToSG(tcpToSGSpan, udpToSGSpan, icmpToSGSpan, protocolAllToSGSpan, direction) + + // rules with IPBlock as a remote + tcpToIPAddrsSpan := tcpudpRulesToIPAddrsToPortsSpan(ruleGroups.tcpToAddrs) + udpToIPAddrsSpan := tcpudpRulesToIPAddrsToPortsSpan(ruleGroups.udpToAddrs) + icmpToAddrsSpan := icmpRulesToIPAddrsToIcmpSpan(ruleGroups.icmpToSG) + protocolAllToIPAddrsSpan := allProtocolRulesToIPAddrsToSpan(ruleGroups.allToAddrs) + rulesToIPAddrs := reduceSGRulesToIPAddrs(tcpToIPAddrsSpan, udpToIPAddrsSpan, icmpToAddrsSpan, protocolAllToIPAddrsSpan, direction) + + // append both slices together + return append(rulesToSG, rulesToIPAddrs...) } -// reduceSGRulesTcpudpToAddrs attempts to reduce the number of rules of tcp/udp rules with ipAddrs as remote -func (s *SGOptimizer) reduceSGRulesTcpudpToAddrs(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], - direction ir.Direction, isTCP bool) []ir.SGRule { - result := make([]ir.SGRule, len(span)) - for i := range span { - for _, dstPorts := range span[i].Right.Intervals() { - p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) - rule := ir.SGRule{ - Direction: direction, - Remote: span[i].Left, - Protocol: p, - Local: netset.GetCidrAll(), - } - result[i] = rule - } +func reduceSGRulesToSG(tcp, udp sgRemotePortsSpan, icmp sgRemoteIcmpSpan, all sgRemoteAllSpan, direction ir.Direction) []ir.SGRule { + // delete other protocols if all protocol rule exists + for _, sgName := range all { + delete(tcp, sgName) + delete(udp, sgName) + delete(icmp, sgName) } - return result -} -// reduceSGRulesTcpudpToAddrs attempts to reduce the number of rules of tcp/udp rules with a sg as remote -func (s *SGOptimizer) reduceSGRulesTcpudpToSG(span map[ir.SGName]*interval.CanonicalSet, direction ir.Direction, isTCP bool) []ir.SGRule { - result := make([]ir.SGRule, 0) - for sgName, intervals := range span { - for _, dstPorts := range intervals.Intervals() { - p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) - rule := ir.SGRule{ - Direction: direction, - Remote: sgName, - Protocol: p, - Local: netset.GetCidrAll(), + // merge tcp, udp and icmp rules into all protocol rule + for sgName, tcpPorts := range tcp { + if udpPorts, ok := udp[sgName]; ok { + if i, ok := icmp[sgName]; ok { + if i.all() && allPorts(tcpPorts) && allPorts(udpPorts) { // all tcp&udp ports and all icmp types&codes + delete(tcp, sgName) + delete(udp, sgName) + delete(icmp, sgName) + all = append(all, sgName) + } } - result = append(result, rule) } } - return result -} -// converts []ir.SGRule (where all rules or either TCP/UDP but not both) to a span of (IPBlock X ports) -func rulesToIPAddrsToPortsSpan(rules []ir.SGRule) (p []ds.Pair[*netset.IPBlock, *interval.CanonicalSet]) { - span := ds.NewProductLeft[*netset.IPBlock, *interval.CanonicalSet]() - for i := range rules { - p := rules[i].Protocol.(netp.TCPUDP) // already checked - r := ds.CartesianPairLeft(rules[i].Remote.(*netset.IPBlock), p.DstPorts().ToSet()) - span = span.Union(r).(*ds.ProductLeft[*netset.IPBlock, *interval.CanonicalSet]) - } - return sortPartitionsByIPAddrs(span.Partitions()) -} + // convert to spans to SG rules + tcpRules := tcpudpToSGSpanToSGRules(tcp, direction, true) + udpRules := tcpudpToSGSpanToSGRules(tcp, direction, false) + icmpRules := icmpToSGSpanToSGRules(icmp, direction) + protocolAll := protocolAllToSGSpanToSGRules(all, direction) -// converts []ir.SGRule (where all rules or either TCP/UDP but not both) to a span intervals for each remote -func rulesToSGToPortsSpan(rules []ir.SGRule) map[ir.SGName]*interval.CanonicalSet { - result := make(map[ir.SGName]*interval.CanonicalSet) - for i := range rules { - p := rules[i].Protocol.(netp.TCPUDP) // already checked - remote := rules[i].Remote.(ir.SGName) // already checked - if result[remote] == nil { - result[remote] = interval.NewCanonicalSet() - } - result[remote].AddInterval(p.DstPorts()) - } - return result + // merge all rules together + tcpudp := append(tcpRules, udpRules...) + icmpAll := append(icmpRules, protocolAll...) + return append(tcpudp, icmpAll...) } -// each IPBlock is a single CIDR/IP address. The IPBlocks are disjoint. -func sortPartitionsByIPAddrs(p []ds.Pair[*netset.IPBlock, *interval.CanonicalSet]) []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] { - cmp := func(i, j int) bool { return p[i].Left.FirstIPAddress() < p[j].Left.FirstIPAddress() } - sort.Slice(p, cmp) - return p +func reduceSGRulesToIPAddrs() []ir.SGRule { + return []ir.SGRule{} } // divide SGCollection to TCP/UDP/ICMP/ProtocolALL X SGRemote/IPAddrs rules diff --git a/pkg/optimize/sgRulesToSpan.go b/pkg/optimize/sgRulesToSpan.go new file mode 100644 index 00000000..61066a36 --- /dev/null +++ b/pkg/optimize/sgRulesToSpan.go @@ -0,0 +1,76 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import ( + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/interval" + "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/utils" +) + +// Rules with SG remote +func tcpudpRulesToSGToPortsSpan(rules []ir.SGRule) map[*ir.SGName]*interval.CanonicalSet { + result := make(map[*ir.SGName]*interval.CanonicalSet) + for i := range rules { + p := rules[i].Protocol.(netp.TCPUDP) // already checked + remote := utils.Ptr(rules[i].Remote.(ir.SGName)) // already checked + if result[remote] == nil { + result[remote] = interval.NewCanonicalSet() + } + result[remote].AddInterval(p.DstPorts()) + } + return result +} + +func icmpRulesToSGToIcmpSpan(rules []ir.SGRule) map[*ir.SGName]*icmp { + result := make(map[*ir.SGName]*icmp) + for i := range rules { + p := rules[i].Protocol.(netp.ICMP) // already checked + remote := utils.Ptr(rules[i].Remote.(ir.SGName)) // already checked + if result[remote] == nil { + result[remote] = newIcmp() + } + result[remote].add(p.TypeCode) + } + return result +} + +func allProtocolRulesToSGToSpan(rules []ir.SGRule) []*ir.SGName { + result := make([]*ir.SGName, len(rules)) + for i := range rules { + result[i] = rules[i].Remote.(*ir.SGName) + } + return result +} + +// Rules with IPAddrs remote + +// converts []ir.SGRule (where all rules or either TCP/UDP but not both) to a span of (IPBlock X ports) +func tcpudpRulesToIPAddrsToPortsSpan(rules []ir.SGRule) (p []ds.Pair[*netset.IPBlock, *interval.CanonicalSet]) { + span := ds.NewProductLeft[*netset.IPBlock, *interval.CanonicalSet]() + for i := range rules { + p := rules[i].Protocol.(netp.TCPUDP) // already checked + r := ds.CartesianPairLeft(rules[i].Remote.(*netset.IPBlock), p.DstPorts().ToSet()) + span = span.Union(r).(*ds.ProductLeft[*netset.IPBlock, *interval.CanonicalSet]) + } + return sortPartitionsByIPAddrs(span.Partitions()) +} + +func icmpRulesToIPAddrsToIcmpSpan(rules []ir.SGRule) bool { + return true +} + +func allProtocolRulesToIPAddrsToSpan(rules []ir.SGRule) []*netset.IPBlock { + result := make([]*netset.IPBlock, len(rules)) + for i := range rules { + result[i] = rules[i].Remote.(*netset.IPBlock) + } + return result // should sort !! +} diff --git a/pkg/optimize/spanToSGRules.go b/pkg/optimize/spanToSGRules.go new file mode 100644 index 00000000..0c37bbb4 --- /dev/null +++ b/pkg/optimize/spanToSGRules.go @@ -0,0 +1,73 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import ( + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +// SG remote +func tcpudpToSGSpanToSGRules(span map[*ir.SGName]*interval.CanonicalSet, direction ir.Direction, isTCP bool) []ir.SGRule { + result := make([]ir.SGRule, 0) + for sgName, intervals := range span { + for _, dstPorts := range intervals.Intervals() { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) + rule := ir.SGRule{ + Direction: direction, + Remote: sgName, + Protocol: p, + Local: netset.GetCidrAll(), + } + result = append(result, rule) + } + } + return result +} + +func icmpToSGSpanToSGRules(span map[*ir.SGName]*icmp, direction ir.Direction) []ir.SGRule { + result := make([]ir.SGRule, 0) + for sgName, icmp := range span { + result = append(result, icmp.toSGRulestoSG(sgName)...) + } + return result +} + +func protocolAllToSGSpanToSGRules(span []*ir.SGName, direction ir.Direction) []ir.SGRule { + result := make([]ir.SGRule, len(span)) + for i, sgName := range span { + result[i] = ir.SGRule{ + Direction: direction, + Remote: sgName, + Protocol: netp.AnyProtocol{}, + Local: netset.GetCidrAll(), + } + } + return result +} + +// IPAddrs remote +func tcpudpToIPAddrsSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], + direction ir.Direction, isTCP bool) []ir.SGRule { + result := make([]ir.SGRule, len(span)) + for i := range span { + for _, dstPorts := range span[i].Right.Intervals() { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) + rule := ir.SGRule{ + Direction: direction, + Remote: span[i].Left, + Protocol: p, + Local: netset.GetCidrAll(), + } + result[i] = rule + } + } + return result +} From b16364501f027b7d5acde2f39a4f15de02355994 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 3 Sep 2024 17:31:03 +0300 Subject: [PATCH 025/131] wip --- pkg/optimize/common.go | 10 ++- pkg/optimize/icmp.go | 19 ++--- pkg/optimize/ip.go | 15 ++++ pkg/optimize/sg.go | 152 ++++++++++++++++++++-------------- pkg/optimize/sgRulesToSpan.go | 27 ++++-- pkg/optimize/spanToSGRules.go | 12 ++- 6 files changed, 152 insertions(+), 83 deletions(-) create mode 100644 pkg/optimize/ip.go diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index 5d1beb8c..46c0070a 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -27,13 +27,19 @@ type Optimizer interface { VpcNames() []string } -// each IPBlock is a single CIDR/IP address. The IPBlocks are disjoint. -func sortPartitionsByIPAddrs(p []ds.Pair[*netset.IPBlock, *interval.CanonicalSet]) []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] { +// each IPBlock is a single CIDR. The CIDRs are disjoint. +func sortPartitionsByIPAddrs[T any](p []ds.Pair[*netset.IPBlock, T]) []ds.Pair[*netset.IPBlock, T] { cmp := func(i, j int) bool { return p[i].Left.FirstIPAddress() < p[j].Left.FirstIPAddress() } sort.Slice(p, cmp) return p } +func sortIPBlockSlice(s []*netset.IPBlock) []*netset.IPBlock { + cmp := func(i, j int) bool { return s[i].FirstIPAddress() < s[j].FirstIPAddress() } + sort.Slice(s, cmp) + return s +} + func allPorts(ports *interval.CanonicalSet) bool { return ports.Equal(netp.AllPorts().ToSet()) } diff --git a/pkg/optimize/icmp.go b/pkg/optimize/icmp.go index f4fb3a68..3633a5a1 100644 --- a/pkg/optimize/icmp.go +++ b/pkg/optimize/icmp.go @@ -13,7 +13,7 @@ import ( ) type icmp struct { - allowed map[int]bool // type X code X allow/deny + allowed map[int]bool // type x code X allow/deny } func newIcmp() *icmp { @@ -24,22 +24,19 @@ func (i *icmp) add(*netp.ICMPTypeCode) { } -func (i *icmp) allCodes(t int) bool { - return true -} - -func (i *icmp) allTypesAndCodes() bool { - return true +func (i *icmp) all() bool { + return false } -func (i *icmp) toSGRulestoSG(sgName *ir.SGName) []ir.SGRule { +func (i *icmp) toSGRulestoSG(sgName *ir.SGName, direction ir.Direction) []ir.SGRule { return []ir.SGRule{} } -func (i *icmp) toSGRulestoIPAddrs(ipAddrs *netset.IPBlock) []ir.SGRule { +func (i *icmp) toSGRulestoIPAddrs(ipAddrs *netset.IPBlock, direction ir.Direction) []ir.SGRule { return []ir.SGRule{} } -func (i *icmp) all() bool { - return false +// returns true if i is a subset of other +func (i *icmp) subset(other *icmp) bool { + return true } diff --git a/pkg/optimize/ip.go b/pkg/optimize/ip.go new file mode 100644 index 00000000..87c32c45 --- /dev/null +++ b/pkg/optimize/ip.go @@ -0,0 +1,15 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import "github.com/np-guard/models/pkg/netset" + +// temporary file, should be implement in models repo + +// given a Date: Sun, 8 Sep 2024 14:13:22 +0300 Subject: [PATCH 026/131] wip --- pkg/ir/sg.go | 5 ++ pkg/optimize/icmp.go | 42 ----------- pkg/optimize/ip.go | 63 ++++++++++++++-- pkg/optimize/sg.go | 42 +++++------ pkg/optimize/sgRulesToSpan.go | 35 +++++---- pkg/optimize/spanToSGRules.go | 134 ++++++++++++++++++++++++++-------- pkg/utils/utils.go | 8 ++ 7 files changed, 213 insertions(+), 116 deletions(-) delete mode 100644 pkg/optimize/icmp.go diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index e1d2f0a3..83bb7413 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -84,6 +84,11 @@ func (r *SGRule) mustSupersede(other *SGRule) bool { return res } +func NewSGRule(direction Direction, remote RemoteType, p netp.Protocol, local *netset.IPBlock, e string) SGRule { + return SGRule{Direction: direction, Remote: remote, Protocol: p, + Local: local, Explanation: e} +} + func NewSG(vpcName string, sgName SGName) *SG { return &SG{SGName: sgName, VpcName: vpcName, InboundRules: []SGRule{}, OutboundRules: []SGRule{}, Attached: []ID{}} } diff --git a/pkg/optimize/icmp.go b/pkg/optimize/icmp.go deleted file mode 100644 index 3633a5a1..00000000 --- a/pkg/optimize/icmp.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package optimize - -import ( - "github.com/np-guard/models/pkg/netp" - "github.com/np-guard/models/pkg/netset" - - "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" -) - -type icmp struct { - allowed map[int]bool // type x code X allow/deny -} - -func newIcmp() *icmp { - return &icmp{} -} - -func (i *icmp) add(*netp.ICMPTypeCode) { - -} - -func (i *icmp) all() bool { - return false -} - -func (i *icmp) toSGRulestoSG(sgName *ir.SGName, direction ir.Direction) []ir.SGRule { - return []ir.SGRule{} -} - -func (i *icmp) toSGRulestoIPAddrs(ipAddrs *netset.IPBlock, direction ir.Direction) []ir.SGRule { - return []ir.SGRule{} -} - -// returns true if i is a subset of other -func (i *icmp) subset(other *icmp) bool { - return true -} diff --git a/pkg/optimize/ip.go b/pkg/optimize/ip.go index 87c32c45..348b8aa8 100644 --- a/pkg/optimize/ip.go +++ b/pkg/optimize/ip.go @@ -5,11 +5,64 @@ SPDX-License-Identifier: Apache-2.0 package optimize -import "github.com/np-guard/models/pkg/netset" +import ( + "log" + "strings" -// temporary file, should be implement in models repo + "github.com/np-guard/models/pkg/netset" +) -// given a 0 && !touching(span[i-1].Left, span[i].Left) { // if the CIDRS are not touching + for _, r := range rules { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.End())) + for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } + + rules = []ds.Pair[*netset.IPBlock, *interval.Interval]{} + continue + } + + activePorts := interval.NewCanonicalSet() + for _, r := range rules { + if !r.Right.ToSet().IsSubset(span[i].Right) { // close old rules + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.End())) + for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } else { + activePorts.AddInterval(*r.Right) + } + } + + // open new rules + for _, ports := range span[i].Right.Intervals() { + if !ports.ToSet().IsSubset(activePorts) { // it does not contained in other rules + r := ds.Pair[*netset.IPBlock, *interval.Interval]{Left: FirstIPAddress(span[i].Left), Right: &ports} + rules = append(rules, r) } - result[i] = rule } } + + // close all old rules + for _, r := range rules { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.Start())) + for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[len(span)-1].Left))) { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } + return result } -func icmpToIPAddrsSpanToSGRules(span []ds.Pair[*netset.IPBlock, *icmp], direction ir.Direction) []ir.SGRule { +func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], _ []*netset.IPBlock, direction ir.Direction) []ir.SGRule { + rules := []ds.Pair[*netset.IPBlock, *netp.ICMP]{} result := make([]ir.SGRule, 0) + + for i := range span { + if i > 0 && !touching(span[i-1].Left, span[i].Left) { // if the CIDRS are not touching + for _, r := range rules { + p, _ := netp.NewICMP(r.Right.TypeCode) + for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } + + rules = []ds.Pair[*netset.IPBlock, *netp.ICMP]{} + continue + } + + activeICMP := netset.EmptyICMPSet() + for _, r := range rules { + ruleIcmpSet := netset.NewICMPSet(*r.Right) + if !ruleIcmpSet.IsSubset(span[i].Right) { // close old rules + p, _ := netp.NewICMP(r.Right.TypeCode) + for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } else { + activeICMP.Union(ruleIcmpSet) + } + } + + // new rules + for _, p := range span[i].Right.Partitions() { + if !netset.NewICMPSet(p).IsSubset(activeICMP) { // it does not contained in other rules + r := ds.Pair[*netset.IPBlock, *netp.ICMP]{Left: FirstIPAddress(span[i].Left), Right: &p} + rules = append(rules, r) + } + } + } + + // close all rules + for _, r := range rules { + p, _ := netp.NewICMP(r.Right.TypeCode) + for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[len(span)-1].Left))) { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } + return result } -func allToIPAddrsSpanToSGRules(span []*netset.IPBlock, direction ir.Direction) []ir.SGRule { +func allSpanToSGRules(span []*netset.IPBlock, direction ir.Direction) []ir.SGRule { result := make([]ir.SGRule, 0) + for _, ipAddrs := range span { + for _, cidr := range ToCidrs(ipAddrs) { + result = append(result, ir.NewSGRule(direction, cidr, netp.AnyProtocol{}, netset.GetCidrAll(), "")) + } + } return result } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index ede1bb67..ab4783d5 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -47,3 +47,11 @@ func Int64PointerToIntPointer(v *int64) *int { } return Ptr(int(*v)) } + +func ToPtrSlice[T any](s []T) []*T { + res := make([]*T, len(s)) + for i := range s { + res[i] = Ptr(s[i]) + } + return res +} From c4f9ed43ad57e36d41c99a205fb3de0d1aa46029 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Sun, 8 Sep 2024 14:20:38 +0300 Subject: [PATCH 027/131] wip --- pkg/optimize/sg.go | 5 +++-- pkg/optimize/spanToSGRules.go | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index 35f8a570..11ad8e42 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -130,7 +130,7 @@ func (s *SGOptimizer) reduceSGRules(rules []ir.SGRule, direction ir.Direction) [ } func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGRule { - // delete other protocols if all protocol rule exists + // delete other protocols rules if all protocol rule exists for _, sgName := range spans.all { delete(spans.tcp, sgName) delete(spans.udp, sgName) @@ -151,7 +151,7 @@ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGR } } - // convert to spans to SG rules + // convert spans to SG rules tcpRules := tcpudpSGSpanToSGRules(spans.tcp, direction, true) udpRules := tcpudpSGSpanToSGRules(spans.tcp, direction, false) icmpRules := icmpSGSpanToSGRules(spans.icmp, direction) @@ -166,6 +166,7 @@ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGR func reduceSGRulesToIPAddrs(spans *sgRulesToIPAddrsSpans, direction ir.Direction) []ir.SGRule { // Todo: check if we can replace tcp, udp, icmp with protocol all + // spans to SG rules tcpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, true) udpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, false) icmpRules := icmpSpanToSGRules(spans.icmp, spans.all, direction) diff --git a/pkg/optimize/spanToSGRules.go b/pkg/optimize/spanToSGRules.go index 021e5760..ab12f467 100644 --- a/pkg/optimize/spanToSGRules.go +++ b/pkg/optimize/spanToSGRules.go @@ -76,9 +76,9 @@ func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSe } } - // open new rules + // new rules for _, ports := range span[i].Right.Intervals() { - if !ports.ToSet().IsSubset(activePorts) { // it does not contained in other rules + if !ports.ToSet().IsSubset(activePorts) { // it is not contained in other rules r := ds.Pair[*netset.IPBlock, *interval.Interval]{Left: FirstIPAddress(span[i].Left), Right: &ports} rules = append(rules, r) } @@ -128,7 +128,7 @@ func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], _ []*ne // new rules for _, p := range span[i].Right.Partitions() { - if !netset.NewICMPSet(p).IsSubset(activeICMP) { // it does not contained in other rules + if !netset.NewICMPSet(p).IsSubset(activeICMP) { r := ds.Pair[*netset.IPBlock, *netp.ICMP]{Left: FirstIPAddress(span[i].Left), Right: &p} rules = append(rules, r) } From 820a023d8ffbed35e09484ef1235c3c8c4356b1d Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Sun, 8 Sep 2024 16:03:45 +0300 Subject: [PATCH 028/131] check protocol is not nil --- pkg/synth/sg.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index d829d68d..7da07bd4 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -105,13 +105,16 @@ func (s *SGSynthesizer) allowConnectionToDst(conn *ir.Connection, trackedProtoco sgDstName := ir.SGName(dstEndpoint.Name) sgDst := s.result.LookupOrCreate(sgDstName) sgDst.Attached = []ir.ID{ir.ID(sgDstName)} - rule := &ir.SGRule{ - Remote: sgRemote(&s.spec.Defs, srcEndpoint), - Direction: ir.Inbound, - Protocol: trackedProtocol.Protocol.InverseDirection(), - Explanation: reason, + if p := trackedProtocol.Protocol.InverseDirection(); p != nil { + rule := &ir.SGRule{ + Remote: sgRemote(&s.spec.Defs, srcEndpoint), + Direction: ir.Inbound, + Protocol: trackedProtocol.Protocol.InverseDirection(), + Explanation: reason, + } + sgDst.Add(rule) } - sgDst.Add(rule) + } // generate SGs for blocked endpoints (endpoints that do not appear in Spec) From 92866896736e85314974cb80f0f4d1f77a065f86 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 9 Sep 2024 11:27:29 +0300 Subject: [PATCH 029/131] inbound udp --- pkg/synth/sg.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 7da07bd4..0dc2f560 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -8,6 +8,7 @@ package synth import ( "log" + "github.com/np-guard/models/pkg/netp" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -105,16 +106,20 @@ func (s *SGSynthesizer) allowConnectionToDst(conn *ir.Connection, trackedProtoco sgDstName := ir.SGName(dstEndpoint.Name) sgDst := s.result.LookupOrCreate(sgDstName) sgDst.Attached = []ir.ID{ir.ID(sgDstName)} - if p := trackedProtocol.Protocol.InverseDirection(); p != nil { - rule := &ir.SGRule{ - Remote: sgRemote(&s.spec.Defs, srcEndpoint), - Direction: ir.Inbound, - Protocol: trackedProtocol.Protocol.InverseDirection(), - Explanation: reason, - } - sgDst.Add(rule) + + // udp protocol does not have inverse direction + inverseP := trackedProtocol.Protocol.InverseDirection() + if p, ok := trackedProtocol.Protocol.(netp.TCPUDP); ok && p.ProtocolString() == netp.ProtocolStringUDP { + inverseP, _ = netp.NewTCPUDP(false, netp.MinPort, netp.MaxPort, netp.MinPort, netp.MaxPort) } + rule := &ir.SGRule{ + Remote: sgRemote(&s.spec.Defs, srcEndpoint), + Direction: ir.Inbound, + Protocol: inverseP, + Explanation: reason, + } + sgDst.Add(rule) } // generate SGs for blocked endpoints (endpoints that do not appear in Spec) From a7f68f57921dc5d6e4d1f3de8917a6776afc832f Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 11 Sep 2024 11:51:36 +0300 Subject: [PATCH 030/131] lint --- pkg/synth/sg.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 9e4d65c4..285b0185 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -114,7 +114,6 @@ func (s *SGSynthesizer) allowConnectionToDst(conn *ir.Connection, trackedProtoco } sgDst.Add(rule) } - } // generate SGs for blocked endpoints (endpoints that do not appear in Spec) From d25bf9c9854626d47a69e37e4c235473134df588 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 11 Sep 2024 12:03:18 +0300 Subject: [PATCH 031/131] make mod --- go.mod | 10 +--------- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 86b90cca..9d963915 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.0 require ( github.com/IBM/vpc-go-sdk v0.56.0 github.com/np-guard/cloud-resource-collector v0.14.0 - github.com/np-guard/models v0.3.4 + github.com/np-guard/models v0.4.1-0.20240911081500-0a30b7aefb6f github.com/spf13/cobra v1.8.1 ) @@ -35,11 +35,3 @@ require ( golang.org/x/text v0.16.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) - -// Todo: -// (1) delete the following line when np-guard/models#33 is merged. -// (2) replace lines 137 and 138 in go.sum with -// github.com/np-guard/models v0.3.4 h1:HOhVi6wyGvo+KmYBnQ5Km5HYCF+/PQlDs1v7mL1v05g= -// github.com/np-guard/models v0.3.4/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= -//nolint:gomoddirectives // this line is temporary -replace github.com/np-guard/models => github.com/np-guard/models v0.3.5-0.20240818081750-bb83d7f53d64 diff --git a/go.sum b/go.sum index 1b2f9689..b5750e7b 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.14.0 h1:MBPtPBYVCQoMfUkn/wODpF7SRpJ9TlOfMszO8N0PePo= github.com/np-guard/cloud-resource-collector v0.14.0/go.mod h1:klCHnNnuuVcCtGQHA7R1a8fqnvfMCk/5Jdld6V7sN2A= -github.com/np-guard/models v0.3.5-0.20240818081750-bb83d7f53d64 h1:e3Fljv3NXu8UogaS4mq8TVqzfga/AuHElL8j0EQLrXw= -github.com/np-guard/models v0.3.5-0.20240818081750-bb83d7f53d64/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= +github.com/np-guard/models v0.4.1-0.20240911081500-0a30b7aefb6f h1:gjmcxRRtiBjDO1mo2XC3yL9KnLM3KvZ/3Ulehv5Cn1c= +github.com/np-guard/models v0.4.1-0.20240911081500-0a30b7aefb6f/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= 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= From dc400bf66d1730ccdedc1c851f40b4e4ff957ae5 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 11 Sep 2024 12:08:23 +0300 Subject: [PATCH 032/131] update --- go.sum | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/go.sum b/go.sum index d5ebcf50..bfbf57e0 100644 --- a/go.sum +++ b/go.sum @@ -132,17 +132,10 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -<<<<<<< HEAD -github.com/np-guard/cloud-resource-collector v0.14.0 h1:MBPtPBYVCQoMfUkn/wODpF7SRpJ9TlOfMszO8N0PePo= -github.com/np-guard/cloud-resource-collector v0.14.0/go.mod h1:klCHnNnuuVcCtGQHA7R1a8fqnvfMCk/5Jdld6V7sN2A= -github.com/np-guard/models v0.4.1-0.20240911081500-0a30b7aefb6f h1:gjmcxRRtiBjDO1mo2XC3yL9KnLM3KvZ/3Ulehv5Cn1c= -github.com/np-guard/models v0.4.1-0.20240911081500-0a30b7aefb6f/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= -======= github.com/np-guard/cloud-resource-collector v0.15.0 h1:jkmxql6D1uBr/qmSOsBzUgeDxlUXSCe7dBKfqfK+QZ4= github.com/np-guard/cloud-resource-collector v0.15.0/go.mod h1:klCHnNnuuVcCtGQHA7R1a8fqnvfMCk/5Jdld6V7sN2A= -github.com/np-guard/models v0.4.0 h1:lU9XymcjwOJ5RQdVpziurqBmcLtlKVIQxVUwm+qMczk= -github.com/np-guard/models v0.4.0/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= ->>>>>>> main +github.com/np-guard/models v0.4.1-0.20240911081500-0a30b7aefb6f h1:gjmcxRRtiBjDO1mo2XC3yL9KnLM3KvZ/3Ulehv5Cn1c= +github.com/np-guard/models v0.4.1-0.20240911081500-0a30b7aefb6f/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= 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= From 8e5cb2d2a8ffbeba1f4a0ff62da52b1fefd104dc Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 11 Sep 2024 18:18:15 +0300 Subject: [PATCH 033/131] wip --- pkg/optimize/sg.go | 29 ++++++--- pkg/optimize/sgRulesToSpan.go | 117 ++++++++++++++++++++++++++++------ pkg/optimize/spanToSGRules.go | 4 +- 3 files changed, 118 insertions(+), 32 deletions(-) diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index 11ad8e42..aa944db2 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -37,9 +37,9 @@ type ( } sgRulesToSGSpans struct { - tcp map[*ir.SGName]*interval.CanonicalSet - udp map[*ir.SGName]*interval.CanonicalSet - icmp map[*ir.SGName]*netset.ICMPSet + tcp map[ir.SGName]*interval.CanonicalSet + udp map[ir.SGName]*interval.CanonicalSet + icmp map[ir.SGName]*netset.ICMPSet all []*ir.SGName } @@ -132,9 +132,9 @@ func (s *SGOptimizer) reduceSGRules(rules []ir.SGRule, direction ir.Direction) [ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGRule { // delete other protocols rules if all protocol rule exists for _, sgName := range spans.all { - delete(spans.tcp, sgName) - delete(spans.udp, sgName) - delete(spans.icmp, sgName) + delete(spans.tcp, *sgName) + delete(spans.udp, *sgName) + delete(spans.icmp, *sgName) } // merge tcp, udp and icmp rules into all protocol rule @@ -145,7 +145,7 @@ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGR delete(spans.tcp, sgName) delete(spans.udp, sgName) delete(spans.icmp, sgName) - spans.all = append(spans.all, sgName) + spans.all = append(spans.all, utils.Ptr(sgName)) } } } @@ -153,7 +153,7 @@ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGR // convert spans to SG rules tcpRules := tcpudpSGSpanToSGRules(spans.tcp, direction, true) - udpRules := tcpudpSGSpanToSGRules(spans.tcp, direction, false) + udpRules := tcpudpSGSpanToSGRules(spans.udp, direction, false) icmpRules := icmpSGSpanToSGRules(spans.icmp, direction) protocolAll := protocolAllSGSpanToSGRules(spans.all, direction) @@ -166,9 +166,20 @@ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGR func reduceSGRulesToIPAddrs(spans *sgRulesToIPAddrsSpans, direction ir.Direction) []ir.SGRule { // Todo: check if we can replace tcp, udp, icmp with protocol all + for i, p := range spans.tcp { + log.Println("pair ", i) + + log.Print("l: ", p.Left.String()) + log.Println("intervals: ") + for _, interval := range p.Right.Intervals() { + log.Println(interval.String()) + } + log.Println("\n\n") + } + // spans to SG rules tcpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, true) - udpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, false) + udpRules := tcpudpIPSpanToSGRules(spans.udp, spans.all, direction, false) icmpRules := icmpSpanToSGRules(spans.icmp, spans.all, direction) allRules := allSpanToSGRules(spans.all, direction) diff --git a/pkg/optimize/sgRulesToSpan.go b/pkg/optimize/sgRulesToSpan.go index 4a61d241..79eb0757 100644 --- a/pkg/optimize/sgRulesToSpan.go +++ b/pkg/optimize/sgRulesToSpan.go @@ -24,11 +24,11 @@ func sgRulesToSGToSpans(rules *sgRulesPerProtocol) *sgRulesToSGSpans { return &sgRulesToSGSpans{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} } -func tcpudpRulesToSGToPortsSpan(rules []ir.SGRule) map[*ir.SGName]*interval.CanonicalSet { - result := make(map[*ir.SGName]*interval.CanonicalSet) +func tcpudpRulesToSGToPortsSpan(rules []ir.SGRule) map[ir.SGName]*interval.CanonicalSet { + result := make(map[ir.SGName]*interval.CanonicalSet) for i := range rules { - p := rules[i].Protocol.(netp.TCPUDP) // already checked - remote := utils.Ptr(rules[i].Remote.(ir.SGName)) // already checked + p := rules[i].Protocol.(netp.TCPUDP) // already checked + remote := rules[i].Remote.(ir.SGName) // already checked if result[remote] == nil { result[remote] = interval.NewCanonicalSet() } @@ -37,11 +37,11 @@ func tcpudpRulesToSGToPortsSpan(rules []ir.SGRule) map[*ir.SGName]*interval.Cano return result } -func icmpRulesToSGToSpan(rules []ir.SGRule) map[*ir.SGName]*netset.ICMPSet { - result := make(map[*ir.SGName]*netset.ICMPSet) +func icmpRulesToSGToSpan(rules []ir.SGRule) map[ir.SGName]*netset.ICMPSet { + result := make(map[ir.SGName]*netset.ICMPSet) for i := range rules { - p := rules[i].Protocol.(netp.ICMP) // already checked - remote := utils.Ptr(rules[i].Remote.(ir.SGName)) // already checked + p := rules[i].Protocol.(netp.ICMP) // already checked + remote := rules[i].Remote.(ir.SGName) // already checked if result[remote] == nil { result[remote] = netset.EmptyICMPSet() } @@ -68,25 +68,26 @@ func sgRulesToIPAddrsToSpans(rules *sgRulesPerProtocol) *sgRulesToIPAddrsSpans { return &sgRulesToIPAddrsSpans{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} } -// converts []ir.SGRule (where all rules or either TCP/UDP but not both) to a span of (IPBlock X ports) +// converts []ir.SGRule (where all rules or either TCP/UDP but not both) to a span of (IPBlock X ports). +// all IPBlocks are disjoint. func tcpudpRulesToIPAddrsToPortsSpan(rules []ir.SGRule) []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] { - span := ds.NewProductLeft[*netset.IPBlock, *interval.CanonicalSet]() - for i := range rules { - p := rules[i].Protocol.(netp.TCPUDP) // already checked - r := ds.CartesianPairLeft(rules[i].Remote.(*netset.IPBlock), p.DstPorts().ToSet()) - span = span.Union(r).(*ds.ProductLeft[*netset.IPBlock, *interval.CanonicalSet]) + span := tcpudpMapSpan(rules) + result := ds.NewProductLeft[*netset.IPBlock, *interval.CanonicalSet]() + for ipblock, portsSet := range span { + r := ds.CartesianPairLeft(ipblock, portsSet) + result = result.Union(r).(*ds.ProductLeft[*netset.IPBlock, *interval.CanonicalSet]) } - return sortPartitionsByIPAddrs(span.Partitions()) + return sortPartitionsByIPAddrs(result.Partitions()) } func icmpRulesToIPAddrsToSpan(rules []ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.ICMPSet] { - span := ds.NewProductLeft[*netset.IPBlock, *netset.ICMPSet]() - for i := range rules { - p := rules[i].Protocol.(netp.ICMP) // already checked - r := ds.CartesianPairLeft(rules[i].Remote.(*netset.IPBlock), netset.NewICMPSet(p)) - span = span.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.ICMPSet]) + span := icmpMapSpan((rules)) + result := ds.NewProductLeft[*netset.IPBlock, *netset.ICMPSet]() + for ipblock, icmpSet := range span { + r := ds.CartesianPairLeft(ipblock, icmpSet) + result = result.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.ICMPSet]) } - return sortPartitionsByIPAddrs(span.Partitions()) + return sortPartitionsByIPAddrs(result.Partitions()) } func allProtocolRulesToIPAddrsToSpan(rules []ir.SGRule) []*netset.IPBlock { @@ -96,3 +97,77 @@ func allProtocolRulesToIPAddrsToSpan(rules []ir.SGRule) []*netset.IPBlock { } return sortIPBlockSlice(res.Split()) } + +// Help functions +func tcpudpMapSpan(rules []ir.SGRule) map[*netset.IPBlock]*interval.CanonicalSet { + span := make(map[*netset.IPBlock]*interval.CanonicalSet, 0) // all keys are disjoint + for i := range rules { + p := rules[i].Protocol.(netp.TCPUDP) // already checked + portsSet := p.DstPorts().ToSet() + ruleIP := rules[i].Remote.(*netset.IPBlock) // already checked + + if ports, ok := span[ruleIP]; ok { + span[ruleIP] = ports.Union(portsSet) + continue + } + + newMap := make(map[*netset.IPBlock]*interval.CanonicalSet, 0) + for ipblock := range span { + if ipblock.Overlap(ruleIP) { + overlappingIPs := ruleIP.Subtract(ipblock) + for _, ip := range overlappingIPs.Split() { + newMap[ip] = span[ipblock].Copy().Union(portsSet) + } + notOverlappingIPs := ipblock.Subtract(overlappingIPs) + for _, ip := range notOverlappingIPs.Split() { + newMap[ip] = span[ipblock].Copy() + } + } + } + span = mergeTcpudpMaps(span, newMap) + } + return span +} + +func icmpMapSpan(rules []ir.SGRule) map[*netset.IPBlock]*netset.ICMPSet { + span := make(map[*netset.IPBlock]*netset.ICMPSet, 0) // all keys are disjoint + for i := range rules { + icmpSet := netset.NewICMPSet(rules[i].Protocol.(netp.ICMP)) // already checked + ruleIP := rules[i].Remote.(*netset.IPBlock) // already checked + + if ports, ok := span[ruleIP]; ok { + span[ruleIP] = ports.Union(icmpSet) + continue + } + + newMap := make(map[*netset.IPBlock]*netset.ICMPSet, 0) + for ipblock := range span { + if ipblock.Overlap(ruleIP) { + overlappingIPs := ruleIP.Subtract(ipblock) + for _, ip := range overlappingIPs.Split() { + newMap[ip] = span[ipblock].Copy().Union(icmpSet) + } + notOverlappingIPs := ipblock.Subtract(overlappingIPs) + for _, ip := range notOverlappingIPs.Split() { + newMap[ip] = span[ipblock].Copy() + } + } + } + span = mergeIcmpMaps(span, newMap) + } + return span +} + +func mergeTcpudpMaps(m1, m2 map[*netset.IPBlock]*interval.CanonicalSet) map[*netset.IPBlock]*interval.CanonicalSet { + for ipblock, portsSet := range m2 { + m1[ipblock] = portsSet.Copy() + } + return m1 +} + +func mergeIcmpMaps(m1, m2 map[*netset.IPBlock]*netset.ICMPSet) map[*netset.IPBlock]*netset.ICMPSet { + for ipblock, portsSet := range m2 { + m1[ipblock] = portsSet.Copy() + } + return m1 +} diff --git a/pkg/optimize/spanToSGRules.go b/pkg/optimize/spanToSGRules.go index ab12f467..1866ac99 100644 --- a/pkg/optimize/spanToSGRules.go +++ b/pkg/optimize/spanToSGRules.go @@ -15,7 +15,7 @@ import ( ) // SG remote -func tcpudpSGSpanToSGRules(span map[*ir.SGName]*interval.CanonicalSet, direction ir.Direction, isTCP bool) []ir.SGRule { +func tcpudpSGSpanToSGRules(span map[ir.SGName]*interval.CanonicalSet, direction ir.Direction, isTCP bool) []ir.SGRule { result := make([]ir.SGRule, 0) for sgName, intervals := range span { for _, dstPorts := range intervals.Intervals() { @@ -26,7 +26,7 @@ func tcpudpSGSpanToSGRules(span map[*ir.SGName]*interval.CanonicalSet, direction return result } -func icmpSGSpanToSGRules(span map[*ir.SGName]*netset.ICMPSet, direction ir.Direction) []ir.SGRule { +func icmpSGSpanToSGRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Direction) []ir.SGRule { result := make([]ir.SGRule, 0) for sgName, icmpSet := range span { for _, icmp := range icmpSet.Partitions() { From a86172246fa89a4a15090174b07af48858c91ed8 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Thu, 12 Sep 2024 15:11:08 +0300 Subject: [PATCH 034/131] wip --- pkg/optimize/common.go | 6 --- pkg/optimize/ip.go | 8 +++ pkg/optimize/sg.go | 4 +- pkg/optimize/sgRulesToSpan.go | 96 ++++++++++++++--------------------- pkg/optimize/spanToSGRules.go | 26 +++++----- pkg/utils/utils.go | 10 ++++ 6 files changed, 70 insertions(+), 80 deletions(-) diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index 46c0070a..1f95beab 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -34,12 +34,6 @@ func sortPartitionsByIPAddrs[T any](p []ds.Pair[*netset.IPBlock, T]) []ds.Pair[* return p } -func sortIPBlockSlice(s []*netset.IPBlock) []*netset.IPBlock { - cmp := func(i, j int) bool { return s[i].FirstIPAddress() < s[j].FirstIPAddress() } - sort.Slice(s, cmp) - return s -} - func allPorts(ports *interval.CanonicalSet) bool { return ports.Equal(netp.AllPorts().ToSet()) } diff --git a/pkg/optimize/ip.go b/pkg/optimize/ip.go index 348b8aa8..89bf4e9f 100644 --- a/pkg/optimize/ip.go +++ b/pkg/optimize/ip.go @@ -66,3 +66,11 @@ func FirstIPAddress(i *netset.IPBlock) *netset.IPBlock { } return ipblock } + +func NextIP(ip *netset.IPBlock) *netset.IPBlock { + return ip +} + +func BeforeIP(ip *netset.IPBlock) *netset.IPBlock { + return ip +} diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index aa944db2..14621bd8 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -47,7 +47,7 @@ type ( tcp []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] udp []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] icmp []ds.Pair[*netset.IPBlock, *netset.ICMPSet] - all []*netset.IPBlock + all *netset.IPBlock } ) @@ -181,7 +181,7 @@ func reduceSGRulesToIPAddrs(spans *sgRulesToIPAddrsSpans, direction ir.Direction tcpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, true) udpRules := tcpudpIPSpanToSGRules(spans.udp, spans.all, direction, false) icmpRules := icmpSpanToSGRules(spans.icmp, spans.all, direction) - allRules := allSpanToSGRules(spans.all, direction) + allRules := allSpanIPToSGRules(spans.all, direction) tcpudp := append(tcpRules, udpRules...) //nolint:gocritic // should merge all rules together icmpAll := append(icmpRules, allRules...) //nolint:gocritic // should merge all rules together diff --git a/pkg/optimize/sgRulesToSpan.go b/pkg/optimize/sgRulesToSpan.go index 79eb0757..0edbbc88 100644 --- a/pkg/optimize/sgRulesToSpan.go +++ b/pkg/optimize/sgRulesToSpan.go @@ -6,6 +6,8 @@ SPDX-License-Identifier: Apache-2.0 package optimize import ( + "log" + "github.com/np-guard/models/pkg/ds" "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" @@ -68,6 +70,14 @@ func sgRulesToIPAddrsToSpans(rules *sgRulesPerProtocol) *sgRulesToIPAddrsSpans { return &sgRulesToIPAddrsSpans{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} } +func allProtocolRulesToIPAddrsToSpan(rules []ir.SGRule) *netset.IPBlock { + res := netset.NewIPBlock() + for i := range rules { + res.Union(rules[i].Remote.(*netset.IPBlock)) + } + return res +} + // converts []ir.SGRule (where all rules or either TCP/UDP but not both) to a span of (IPBlock X ports). // all IPBlocks are disjoint. func tcpudpRulesToIPAddrsToPortsSpan(rules []ir.SGRule) []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] { @@ -90,41 +100,13 @@ func icmpRulesToIPAddrsToSpan(rules []ir.SGRule) []ds.Pair[*netset.IPBlock, *net return sortPartitionsByIPAddrs(result.Partitions()) } -func allProtocolRulesToIPAddrsToSpan(rules []ir.SGRule) []*netset.IPBlock { - res := netset.NewIPBlock() - for i := range rules { - res.Union(rules[i].Remote.(*netset.IPBlock)) - } - return sortIPBlockSlice(res.Split()) -} - // Help functions func tcpudpMapSpan(rules []ir.SGRule) map[*netset.IPBlock]*interval.CanonicalSet { span := make(map[*netset.IPBlock]*interval.CanonicalSet, 0) // all keys are disjoint for i := range rules { - p := rules[i].Protocol.(netp.TCPUDP) // already checked - portsSet := p.DstPorts().ToSet() - ruleIP := rules[i].Remote.(*netset.IPBlock) // already checked - - if ports, ok := span[ruleIP]; ok { - span[ruleIP] = ports.Union(portsSet) - continue - } - - newMap := make(map[*netset.IPBlock]*interval.CanonicalSet, 0) - for ipblock := range span { - if ipblock.Overlap(ruleIP) { - overlappingIPs := ruleIP.Subtract(ipblock) - for _, ip := range overlappingIPs.Split() { - newMap[ip] = span[ipblock].Copy().Union(portsSet) - } - notOverlappingIPs := ipblock.Subtract(overlappingIPs) - for _, ip := range notOverlappingIPs.Split() { - newMap[ip] = span[ipblock].Copy() - } - } - } - span = mergeTcpudpMaps(span, newMap) + portsSet := rules[i].Protocol.(netp.TCPUDP).DstPorts().ToSet() // already checked + ruleIP := rules[i].Remote.(*netset.IPBlock) // already checked + span = updateSpan(span, portsSet, ruleIP) } return span } @@ -134,40 +116,36 @@ func icmpMapSpan(rules []ir.SGRule) map[*netset.IPBlock]*netset.ICMPSet { for i := range rules { icmpSet := netset.NewICMPSet(rules[i].Protocol.(netp.ICMP)) // already checked ruleIP := rules[i].Remote.(*netset.IPBlock) // already checked - - if ports, ok := span[ruleIP]; ok { - span[ruleIP] = ports.Union(icmpSet) - continue - } - - newMap := make(map[*netset.IPBlock]*netset.ICMPSet, 0) - for ipblock := range span { - if ipblock.Overlap(ruleIP) { - overlappingIPs := ruleIP.Subtract(ipblock) - for _, ip := range overlappingIPs.Split() { - newMap[ip] = span[ipblock].Copy().Union(icmpSet) - } - notOverlappingIPs := ipblock.Subtract(overlappingIPs) - for _, ip := range notOverlappingIPs.Split() { - newMap[ip] = span[ipblock].Copy() - } - } - } - span = mergeIcmpMaps(span, newMap) + span = updateSpan(span, icmpSet, ruleIP) } return span } -func mergeTcpudpMaps(m1, m2 map[*netset.IPBlock]*interval.CanonicalSet) map[*netset.IPBlock]*interval.CanonicalSet { - for ipblock, portsSet := range m2 { - m1[ipblock] = portsSet.Copy() +func updateSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleSet T, ruleIP *netset.IPBlock) map[*netset.IPBlock]T { + if protocolSet, ok := span[ruleIP]; ok { + span[ruleIP] = protocolSet.Union(ruleSet) + return span } - return m1 + var k float32 + k = 32.2 + log.Print(k) + return utils.MergeSetMaps(span, addRuleToSpan(span, ruleIP, ruleSet)) + } -func mergeIcmpMaps(m1, m2 map[*netset.IPBlock]*netset.ICMPSet) map[*netset.IPBlock]*netset.ICMPSet { - for ipblock, portsSet := range m2 { - m1[ipblock] = portsSet.Copy() +func addRuleToSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleIP *netset.IPBlock, ruleSet T) map[*netset.IPBlock]T { + result := make(map[*netset.IPBlock]T, 0) + for ipblock := range span { + if ipblock.Overlap(ruleIP) { + overlappingIPs := ruleIP.Subtract(ipblock) + for _, ip := range overlappingIPs.Split() { + result[ip] = span[ipblock].Copy().Union(ruleSet) + } + notOverlappingIPs := ipblock.Subtract(overlappingIPs) + for _, ip := range notOverlappingIPs.Split() { + result[ip] = span[ipblock].Copy() + } + } } - return m1 + return result } diff --git a/pkg/optimize/spanToSGRules.go b/pkg/optimize/spanToSGRules.go index 1866ac99..41cfe744 100644 --- a/pkg/optimize/spanToSGRules.go +++ b/pkg/optimize/spanToSGRules.go @@ -46,13 +46,23 @@ func protocolAllSGSpanToSGRules(span []*ir.SGName, direction ir.Direction) []ir. } // IPAddrs remote -func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], _ []*netset.IPBlock, +func allSpanIPToSGRules(span *netset.IPBlock, direction ir.Direction) []ir.SGRule { + result := make([]ir.SGRule, 0) + for _, cidr := range ToCidrs(span) { + result = append(result, ir.NewSGRule(direction, cidr, netp.AnyProtocol{}, netset.GetCidrAll(), "")) + } + return result +} + +func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], allSpan *netset.IPBlock, direction ir.Direction, isTCP bool) []ir.SGRule { rules := []ds.Pair[*netset.IPBlock, *interval.Interval]{} // start ip and ports result := make([]ir.SGRule, 0) for i := range span { - if i > 0 && !touching(span[i-1].Left, span[i].Left) { // if the CIDRS are not touching + // should be here if i > 0 + // hole := IPBlockFromRange(NextIP(LastIPAddress(span[i-1].Left)), BeforeIP(FirstIPAddress(span[i].Left))) + if i > 0 && !touching(span[i-1].Left, span[i].Left) { // if the CIDRS are not touching and there is no all rule for _, r := range rules { p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.End())) for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { @@ -96,7 +106,7 @@ func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSe return result } -func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], _ []*netset.IPBlock, direction ir.Direction) []ir.SGRule { +func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allSpan *netset.IPBlock, direction ir.Direction) []ir.SGRule { rules := []ds.Pair[*netset.IPBlock, *netp.ICMP]{} result := make([]ir.SGRule, 0) @@ -145,13 +155,3 @@ func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], _ []*ne return result } - -func allSpanToSGRules(span []*netset.IPBlock, direction ir.Direction) []ir.SGRule { - result := make([]ir.SGRule, 0) - for _, ipAddrs := range span { - for _, cidr := range ToCidrs(ipAddrs) { - result = append(result, ir.NewSGRule(direction, cidr, netp.AnyProtocol{}, netset.GetCidrAll(), "")) - } - } - return result -} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index ab4783d5..c867fc55 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -9,6 +9,8 @@ import ( "cmp" "maps" "slices" + + "github.com/np-guard/models/pkg/ds" ) func Ptr[T any](t T) *T { @@ -55,3 +57,11 @@ func ToPtrSlice[T any](s []T) []*T { } return res } + +// m1 does not have any key of m2 +func MergeSetMaps[T comparable, K ds.Set[K]](m1, m2 map[T]K) map[T]K { + for key, val := range m2 { + m1[key] = val.Copy() + } + return m1 +} From 380c62e9cb3c812555e35c563e4a8860b3160b31 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Thu, 12 Sep 2024 15:42:33 +0300 Subject: [PATCH 035/131] fixed --- pkg/io/confio/parse_sgs.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index ce685abd..f97cdb6d 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -152,19 +152,33 @@ func translateRemote(remote vpcv1.SecurityGroupRuleRemoteIntf) (ir.RemoteType, e } func translateLocal(local vpcv1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, error) { + var err error + var ipAddrs *netset.IPBlock if l, ok := local.(*vpcv1.SecurityGroupRuleLocal); ok { if l.CIDRBlock != nil { - return netset.IPBlockFromCidr(*l.CIDRBlock) + ipAddrs, err = netset.IPBlockFromCidr(*l.CIDRBlock) } if l.Address != nil { - return netset.IPBlockFromIPAddress(*l.CIDRBlock) + ipAddrs, err = netset.IPBlockFromIPAddress(*l.CIDRBlock) } + if err != nil { + return nil, err + } + return verifyLocalValue(ipAddrs) } return nil, fmt.Errorf("error parsing Local field") } +// temporary - first version of optimization requires that local value will be 0.0.0.0/32 +func verifyLocalValue(ipAddrs *netset.IPBlock) (*netset.IPBlock, error) { + if !ipAddrs.Equal(netset.GetCidrAll()) { + return nil, fmt.Errorf("only 0.0.0.0/32 CIDR block is supported for local values") + } + return ipAddrs, nil +} + func translateProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (netp.Protocol, error) { - isTCP := *rule.Protocol == string(netp.ProtocolStringTCP) + isTCP := *rule.Protocol == "tcp" minDstPort := utils.GetProperty(rule.PortMin, netp.MinPort) maxDstPort := utils.GetProperty(rule.PortMax, netp.MaxPort) return netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(minDstPort), int(maxDstPort)) From 197ed317f695b0c621b5c58766bc4c06f8348217 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Thu, 12 Sep 2024 15:47:21 +0300 Subject: [PATCH 036/131] fixed --- cmd/subcmds/optimize.go | 2 +- cmd/subcmds/outputCommon.go | 2 ++ cmd/subcmds/synthOutput.go | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/subcmds/optimize.go b/cmd/subcmds/optimize.go index 4b215fe1..fe137a15 100644 --- a/cmd/subcmds/optimize.go +++ b/cmd/subcmds/optimize.go @@ -21,7 +21,7 @@ func NewOptimizeCommand(args *inArgs) *cobra.Command { } // flags - cmd.Flags().StringVarP(&args.firewallName, firewallNameFlag, "s", "", "which vpcFirewall to optimize") + cmd.PersistentFlags().StringVarP(&args.firewallName, firewallNameFlag, "n", "", "which vpcFirewall to optimize") // flags settings _ = cmd.MarkPersistentFlagRequired(firewallNameFlag) // temporary diff --git a/cmd/subcmds/outputCommon.go b/cmd/subcmds/outputCommon.go index 55872136..aa399315 100644 --- a/cmd/subcmds/outputCommon.go +++ b/cmd/subcmds/outputCommon.go @@ -15,6 +15,8 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) +const defaultFilePermission = 0o644 + func checkOutputFlags(args *inArgs) error { if args.outputDir != "" && args.outputFile != "" { return fmt.Errorf("only one of -d and -o can be supplied") diff --git a/cmd/subcmds/synthOutput.go b/cmd/subcmds/synthOutput.go index c1ba8a0d..12e0670b 100644 --- a/cmd/subcmds/synthOutput.go +++ b/cmd/subcmds/synthOutput.go @@ -19,7 +19,6 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -const defaultFilePermission = 0o644 const defaultDirectoryPermission = 0o755 func writeOutput(args *inArgs, collection ir.SynthCollection, vpcNames []ir.ID) error { From 9078e5c96b896eac2829630547c24ec0ec5006cf Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Thu, 12 Sep 2024 16:02:03 +0300 Subject: [PATCH 037/131] wip --- pkg/optimize/ip.go | 2 ++ pkg/optimize/sg.go | 13 +------------ pkg/optimize/sgRulesToSpan.go | 6 ------ pkg/optimize/spanToSGRules.go | 7 +++---- 4 files changed, 6 insertions(+), 22 deletions(-) diff --git a/pkg/optimize/ip.go b/pkg/optimize/ip.go index 89bf4e9f..3f61e621 100644 --- a/pkg/optimize/ip.go +++ b/pkg/optimize/ip.go @@ -67,10 +67,12 @@ func FirstIPAddress(i *netset.IPBlock) *netset.IPBlock { return ipblock } +// should implement func NextIP(ip *netset.IPBlock) *netset.IPBlock { return ip } +// should implement func BeforeIP(ip *netset.IPBlock) *netset.IPBlock { return ip } diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index 14621bd8..be1df47c 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -164,18 +164,7 @@ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGR } func reduceSGRulesToIPAddrs(spans *sgRulesToIPAddrsSpans, direction ir.Direction) []ir.SGRule { - // Todo: check if we can replace tcp, udp, icmp with protocol all - - for i, p := range spans.tcp { - log.Println("pair ", i) - - log.Print("l: ", p.Left.String()) - log.Println("intervals: ") - for _, interval := range p.Right.Intervals() { - log.Println(interval.String()) - } - log.Println("\n\n") - } + // Todo: check if we can replace tcp, udp, icmp with protocol all. Maybe we should not? // spans to SG rules tcpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, true) diff --git a/pkg/optimize/sgRulesToSpan.go b/pkg/optimize/sgRulesToSpan.go index 0edbbc88..ac37cf4c 100644 --- a/pkg/optimize/sgRulesToSpan.go +++ b/pkg/optimize/sgRulesToSpan.go @@ -6,8 +6,6 @@ SPDX-License-Identifier: Apache-2.0 package optimize import ( - "log" - "github.com/np-guard/models/pkg/ds" "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" @@ -126,11 +124,7 @@ func updateSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleSet T, ruleIP *nets span[ruleIP] = protocolSet.Union(ruleSet) return span } - var k float32 - k = 32.2 - log.Print(k) return utils.MergeSetMaps(span, addRuleToSpan(span, ruleIP, ruleSet)) - } func addRuleToSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleIP *netset.IPBlock, ruleSet T) map[*netset.IPBlock]T { diff --git a/pkg/optimize/spanToSGRules.go b/pkg/optimize/spanToSGRules.go index 41cfe744..d0e87c15 100644 --- a/pkg/optimize/spanToSGRules.go +++ b/pkg/optimize/spanToSGRules.go @@ -54,14 +54,13 @@ func allSpanIPToSGRules(span *netset.IPBlock, direction ir.Direction) []ir.SGRul return result } -func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], allSpan *netset.IPBlock, +func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], _ *netset.IPBlock, direction ir.Direction, isTCP bool) []ir.SGRule { rules := []ds.Pair[*netset.IPBlock, *interval.Interval]{} // start ip and ports result := make([]ir.SGRule, 0) for i := range span { - // should be here if i > 0 - // hole := IPBlockFromRange(NextIP(LastIPAddress(span[i-1].Left)), BeforeIP(FirstIPAddress(span[i].Left))) + // maybe all protocol rule covers the hole if i > 0 && !touching(span[i-1].Left, span[i].Left) { // if the CIDRS are not touching and there is no all rule for _, r := range rules { p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.End())) @@ -106,7 +105,7 @@ func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSe return result } -func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allSpan *netset.IPBlock, direction ir.Direction) []ir.SGRule { +func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], _ *netset.IPBlock, direction ir.Direction) []ir.SGRule { rules := []ds.Pair[*netset.IPBlock, *netp.ICMP]{} result := make([]ir.SGRule, 0) From dfb8a7dd33d624cf35ba4c810f7b0dba9e566af8 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Thu, 12 Sep 2024 16:03:58 +0300 Subject: [PATCH 038/131] wip --- pkg/optimize/sg.go | 2 +- pkg/optimize/spanToSGRules.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index be1df47c..36870b76 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -164,7 +164,7 @@ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGR } func reduceSGRulesToIPAddrs(spans *sgRulesToIPAddrsSpans, direction ir.Direction) []ir.SGRule { - // Todo: check if we can replace tcp, udp, icmp with protocol all. Maybe we should not? + // Todo: check if we can replace tcp, udp, icmp with protocol all. Should we? // spans to SG rules tcpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, true) diff --git a/pkg/optimize/spanToSGRules.go b/pkg/optimize/spanToSGRules.go index d0e87c15..01fb437a 100644 --- a/pkg/optimize/spanToSGRules.go +++ b/pkg/optimize/spanToSGRules.go @@ -75,7 +75,7 @@ func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSe activePorts := interval.NewCanonicalSet() for _, r := range rules { - if !r.Right.ToSet().IsSubset(span[i].Right) { // close old rules + if !r.Right.ToSet().IsSubset(span[i].Right) { // create rules p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.End())) for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) @@ -94,7 +94,7 @@ func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSe } } - // close all old rules + // create the rest of the rules for _, r := range rules { p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.Start())) for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[len(span)-1].Left))) { @@ -125,7 +125,7 @@ func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], _ *nets activeICMP := netset.EmptyICMPSet() for _, r := range rules { ruleIcmpSet := netset.NewICMPSet(*r.Right) - if !ruleIcmpSet.IsSubset(span[i].Right) { // close old rules + if !ruleIcmpSet.IsSubset(span[i].Right) { // create rules p, _ := netp.NewICMP(r.Right.TypeCode) for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) @@ -144,7 +144,7 @@ func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], _ *nets } } - // close all rules + // create the rest of the rules for _, r := range rules { p, _ := netp.NewICMP(r.Right.TypeCode) for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[len(span)-1].Left))) { From 88951493fe9f1c37758becbac0b6ecddeb539662 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Thu, 12 Sep 2024 16:53:12 +0300 Subject: [PATCH 039/131] implement ip functions --- pkg/optimize/ip.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/optimize/ip.go b/pkg/optimize/ip.go index 3f61e621..0c51dff4 100644 --- a/pkg/optimize/ip.go +++ b/pkg/optimize/ip.go @@ -67,12 +67,14 @@ func FirstIPAddress(i *netset.IPBlock) *netset.IPBlock { return ipblock } -// should implement +// ip is not 255.255.255.255 func NextIP(ip *netset.IPBlock) *netset.IPBlock { - return ip + other := netset.GetCidrAll().Subtract(ip) + return FirstIPAddress(other.Split()[1]) } -// should implement +// ip is not 0.0.0.0 func BeforeIP(ip *netset.IPBlock) *netset.IPBlock { - return ip + other := netset.GetCidrAll().Subtract(ip) + return LastIPAddress(other.Split()[0]) } From c8fe2d726d8451a9299d9399e3672953c23d03cf Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Thu, 12 Sep 2024 17:19:50 +0300 Subject: [PATCH 040/131] all protocol rule covers the holes --- pkg/optimize/spanToSGRules.go | 47 +++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/pkg/optimize/spanToSGRules.go b/pkg/optimize/spanToSGRules.go index 01fb437a..15310e4d 100644 --- a/pkg/optimize/spanToSGRules.go +++ b/pkg/optimize/spanToSGRules.go @@ -54,23 +54,27 @@ func allSpanIPToSGRules(span *netset.IPBlock, direction ir.Direction) []ir.SGRul return result } -func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], _ *netset.IPBlock, +func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], allSpan *netset.IPBlock, direction ir.Direction, isTCP bool) []ir.SGRule { rules := []ds.Pair[*netset.IPBlock, *interval.Interval]{} // start ip and ports result := make([]ir.SGRule, 0) for i := range span { - // maybe all protocol rule covers the hole - if i > 0 && !touching(span[i-1].Left, span[i].Left) { // if the CIDRS are not touching and there is no all rule - for _, r := range rules { - p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.End())) - for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + if i > 0 { + prevIPBlock := span[i-1].Left + currIPBlock := span[i].Left + if !touching(prevIPBlock, currIPBlock) { // the cidrs are not touching + hole := IPBlockFromRange(NextIP(prevIPBlock), BeforeIP(currIPBlock)) + if !hole.IsSubset(allSpan) { // there in no all rule covering the hole + for _, r := range rules { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.End())) + for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } + rules = []ds.Pair[*netset.IPBlock, *interval.Interval]{} } } - - rules = []ds.Pair[*netset.IPBlock, *interval.Interval]{} - continue } activePorts := interval.NewCanonicalSet() @@ -105,21 +109,26 @@ func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSe return result } -func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], _ *netset.IPBlock, direction ir.Direction) []ir.SGRule { +func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allSpan *netset.IPBlock, direction ir.Direction) []ir.SGRule { rules := []ds.Pair[*netset.IPBlock, *netp.ICMP]{} result := make([]ir.SGRule, 0) for i := range span { - if i > 0 && !touching(span[i-1].Left, span[i].Left) { // if the CIDRS are not touching - for _, r := range rules { - p, _ := netp.NewICMP(r.Right.TypeCode) - for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + if i > 0 { + prevIPBlock := span[i-1].Left + currIPBlock := span[i].Left + if !touching(prevIPBlock, currIPBlock) { // the cidrs are not touching + hole := IPBlockFromRange(NextIP(prevIPBlock), BeforeIP(currIPBlock)) + if !hole.IsSubset(allSpan) { // there in no all rule covering the hole + for _, r := range rules { + p, _ := netp.NewICMP(r.Right.TypeCode) + for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } + rules = []ds.Pair[*netset.IPBlock, *netp.ICMP]{} } } - - rules = []ds.Pair[*netset.IPBlock, *netp.ICMP]{} - continue } activeICMP := netset.EmptyICMPSet() From 0a0decdbfa213b8c0f4c19a54bb11c70a5b3ace7 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 24 Sep 2024 09:44:06 +0300 Subject: [PATCH 041/131] wip --- pkg/optimize/sg.go | 21 ++++++++------------- pkg/optimize/sgRulesToSpan.go | 29 ++++++++++++++++------------- pkg/optimize/spanToSGRules.go | 13 +++++++++++++ 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index 36870b76..1e0cec3a 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -155,16 +155,15 @@ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGR tcpRules := tcpudpSGSpanToSGRules(spans.tcp, direction, true) udpRules := tcpudpSGSpanToSGRules(spans.udp, direction, false) icmpRules := icmpSGSpanToSGRules(spans.icmp, direction) - protocolAll := protocolAllSGSpanToSGRules(spans.all, direction) + allRules := protocolAllSGSpanToSGRules(spans.all, direction) - // merge all rules together - tcpudp := append(tcpRules, udpRules...) //nolint:gocritic // should merge all rules together - icmpAll := append(icmpRules, protocolAll...) //nolint:gocritic // should merge all rules together - return append(tcpudp, icmpAll...) + // return all rules + return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) } func reduceSGRulesToIPAddrs(spans *sgRulesToIPAddrsSpans, direction ir.Direction) []ir.SGRule { - // Todo: check if we can replace tcp, udp, icmp with protocol all. Should we? + // observation: It pays to switch to all protocol rule when we have rules that cover all other protocols + // on exactly the same cidr (only one protocol can exceed). // spans to SG rules tcpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, true) @@ -172,10 +171,8 @@ func reduceSGRulesToIPAddrs(spans *sgRulesToIPAddrsSpans, direction ir.Direction icmpRules := icmpSpanToSGRules(spans.icmp, spans.all, direction) allRules := allSpanIPToSGRules(spans.all, direction) - tcpudp := append(tcpRules, udpRules...) //nolint:gocritic // should merge all rules together - icmpAll := append(icmpRules, allRules...) //nolint:gocritic // should merge all rules together - - return append(tcpudp, icmpAll...) + // return all rules + return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) } // divide SGCollection to TCP/UDP/ICMP/ProtocolALL X SGRemote/IPAddrs rules @@ -226,7 +223,5 @@ func divideSGRules(rules []ir.SGRule) *sgRuleGroups { } func (s *sgRulesPerProtocol) allRules() []ir.SGRule { - tcpudp := append(s.tcp, s.udp...) //nolint:gocritic // should merge all rules together - icmpAll := append(s.icmp, s.all...) //nolint:gocritic // should merge all rules together - return append(tcpudp, icmpAll...) + return append(s.tcp, append(s.udp, append(s.icmp, s.all...)...)...) } diff --git a/pkg/optimize/sgRulesToSpan.go b/pkg/optimize/sgRulesToSpan.go index ac37cf4c..a9779988 100644 --- a/pkg/optimize/sgRulesToSpan.go +++ b/pkg/optimize/sgRulesToSpan.go @@ -124,22 +124,25 @@ func updateSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleSet T, ruleIP *nets span[ruleIP] = protocolSet.Union(ruleSet) return span } - return utils.MergeSetMaps(span, addRuleToSpan(span, ruleIP, ruleSet)) + span, newMap := addRuleToSpan(span, ruleIP, ruleSet) + return utils.MergeSetMaps(span, newMap) } -func addRuleToSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleIP *netset.IPBlock, ruleSet T) map[*netset.IPBlock]T { - result := make(map[*netset.IPBlock]T, 0) +func addRuleToSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleIP *netset.IPBlock, ruleSet T) (s, res map[*netset.IPBlock]T) { + res = make(map[*netset.IPBlock]T, 0) for ipblock := range span { - if ipblock.Overlap(ruleIP) { - overlappingIPs := ruleIP.Subtract(ipblock) - for _, ip := range overlappingIPs.Split() { - result[ip] = span[ipblock].Copy().Union(ruleSet) - } - notOverlappingIPs := ipblock.Subtract(overlappingIPs) - for _, ip := range notOverlappingIPs.Split() { - result[ip] = span[ipblock].Copy() - } + if !ipblock.Overlap(ruleIP) { + continue } + overlappingIPs := ruleIP.Subtract(ipblock) + for _, ip := range overlappingIPs.Split() { + res[ip] = span[ipblock].Copy().Union(ruleSet) + } + notOverlappingIPs := ipblock.Subtract(overlappingIPs) + for _, ip := range notOverlappingIPs.Split() { + res[ip] = span[ipblock].Copy() + } + delete(span, ipblock) } - return result + return span, res } diff --git a/pkg/optimize/spanToSGRules.go b/pkg/optimize/spanToSGRules.go index 15310e4d..b4a680be 100644 --- a/pkg/optimize/spanToSGRules.go +++ b/pkg/optimize/spanToSGRules.go @@ -109,6 +109,19 @@ func tcpudpIPSpanToSGRules(span []ds.Pair[*netset.IPBlock, *interval.CanonicalSe return result } +// problem: where should I end the rule? +// func createTcpudpRules(rules []ds.Pair[*netset.IPBlock, *interval.Interval], span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], +// direction ir.Direction, isTCP bool) (res []ir.SGRule) { +// res = make([]ir.SGRule, 0) +// for _, r := range rules { +// p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.Start())) +// for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[len(span)-1].Left))) { +// res = append(res, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) +// } +// } +// return res +// } + func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allSpan *netset.IPBlock, direction ir.Direction) []ir.SGRule { rules := []ds.Pair[*netset.IPBlock, *netp.ICMP]{} result := make([]ir.SGRule, 0) From cf119cce1b5d86e3cfe51518019855f8df40b846 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 24 Sep 2024 12:22:10 +0300 Subject: [PATCH 042/131] wip --- pkg/optimize/common.go | 4 ++++ pkg/optimize/sg.go | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index 1f95beab..e817d161 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -34,6 +34,10 @@ func sortPartitionsByIPAddrs[T any](p []ds.Pair[*netset.IPBlock, T]) []ds.Pair[* return p } +// func less(i, j *netset.IPBlock) bool { +// return i.FirstIPAddress() < j.FirstIPAddress() +// } + func allPorts(ports *interval.CanonicalSet) bool { return ports.Equal(netp.AllPorts().ToSet()) } diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index 1e0cec3a..52eebfce 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -162,8 +162,7 @@ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGR } func reduceSGRulesToIPAddrs(spans *sgRulesToIPAddrsSpans, direction ir.Direction) []ir.SGRule { - // observation: It pays to switch to all protocol rule when we have rules that cover all other protocols - // on exactly the same cidr (only one protocol can exceed). + spans = compressToAllProtocolRule(spans) // spans to SG rules tcpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, true) @@ -222,6 +221,38 @@ func divideSGRules(rules []ir.SGRule) *sgRuleGroups { return &sgRuleGroups{rulesToSG: rulesToSG, rulesToIPAddrs: rulesToIPAddrs} } +// observation: It pays to switch to all protocol rule when we have rules that cover all other protocols +// on exactly the same cidr (only one protocol can exceed). +func compressToAllProtocolRule(span *sgRulesToIPAddrsSpans) *sgRulesToIPAddrsSpans { + t := 0 + u := 0 + i := 0 + + for t != len(span.tcp) && u != len(span.udp) && i != len(span.icmp) { + if !allPorts(span.tcp[t].Right) { + t++ + continue + } + if !allPorts(span.udp[u].Right) { + u++ + continue + } + if !span.icmp[i].Right.Equal(netset.AllICMPSet()) { + i++ + continue + } + + if span.tcp[t].Left.Equal(span.udp[u].Left) && span.tcp[t].Left.Equal(span.icmp[i].Left) { + span.all = span.all.Union(span.tcp[t].Left.Copy()) + span.tcp = append(span.tcp[:t], span.tcp[t+1:]...) + span.udp = append(span.udp[:u], span.udp[u+1:]...) + span.icmp = append(span.icmp[:i], span.icmp[i+1:]...) + } + } + + return span +} + func (s *sgRulesPerProtocol) allRules() []ir.SGRule { return append(s.tcp, append(s.udp, append(s.icmp, s.all...)...)...) } From a51e158d4a8b57d136bfb131c54b6d5a16064e53 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 24 Sep 2024 15:43:13 +0300 Subject: [PATCH 043/131] documentation --- pkg/optimize/compressRules.go | 75 +++++++++++++++++++ pkg/optimize/ip.go | 1 + .../{spanToSGRules.go => ipSpanToSGRules.go} | 31 -------- pkg/optimize/sg.go | 62 ++------------- ...{sgRulesToSpan.go => sgRulesToIPToSpan.go} | 74 ++++++------------ pkg/optimize/sgRulesToSGToSpan.go | 62 +++++++++++++++ pkg/optimize/sgSpanToSGRules.go | 47 ++++++++++++ pkg/synth/sg.go | 1 + 8 files changed, 216 insertions(+), 137 deletions(-) create mode 100644 pkg/optimize/compressRules.go rename pkg/optimize/{spanToSGRules.go => ipSpanToSGRules.go} (82%) rename pkg/optimize/{sgRulesToSpan.go => sgRulesToIPToSpan.go} (64%) create mode 100644 pkg/optimize/sgRulesToSGToSpan.go create mode 100644 pkg/optimize/sgSpanToSGRules.go diff --git a/pkg/optimize/compressRules.go b/pkg/optimize/compressRules.go new file mode 100644 index 00000000..67757fc8 --- /dev/null +++ b/pkg/optimize/compressRules.go @@ -0,0 +1,75 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import ( + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" +) + +func compressSpansToSG(spans *sgSpansToSGPerProtocol) *sgSpansToSGPerProtocol { + spans = deleteOtherProtocolIfAllProtocolExists(spans) + return compressThreeProtocolsToAllProtocol(spans) +} + +// delete other protocols rules if all protocol rule exists +func deleteOtherProtocolIfAllProtocolExists(spans *sgSpansToSGPerProtocol) *sgSpansToSGPerProtocol { + for _, sgName := range spans.all { + delete(spans.tcp, *sgName) + delete(spans.udp, *sgName) + delete(spans.icmp, *sgName) + } + return spans +} + +// merge tcp, udp and icmp rules into all protocol rule +func compressThreeProtocolsToAllProtocol(spans *sgSpansToSGPerProtocol) *sgSpansToSGPerProtocol { + for sgName, tcpPorts := range spans.tcp { + if udpPorts, ok := spans.udp[sgName]; ok { + if ic, ok := spans.icmp[sgName]; ok { + if ic.Equal(netset.AllICMPSet()) && allPorts(tcpPorts) && allPorts(udpPorts) { // all tcp&udp ports and all icmp types&codes + delete(spans.tcp, sgName) + delete(spans.udp, sgName) + delete(spans.icmp, sgName) + spans.all = append(spans.all, utils.Ptr(sgName)) + } + } + } + } + return spans +} + +// observation: It pays to switch to all protocol rule when we have rules that cover all other protocols +// on exactly the same cidr (only one protocol can exceed). +func compressToAllProtocolRule(span *sgSpansToIPPerProtocol) *sgSpansToIPPerProtocol { + t := 0 + u := 0 + i := 0 + + for t != len(span.tcp) && u != len(span.udp) && i != len(span.icmp) { + if !allPorts(span.tcp[t].Right) { + t++ + continue + } + if !allPorts(span.udp[u].Right) { + u++ + continue + } + if !span.icmp[i].Right.Equal(netset.AllICMPSet()) { + i++ + continue + } + + if span.tcp[t].Left.Equal(span.udp[u].Left) && span.tcp[t].Left.Equal(span.icmp[i].Left) { + span.all = span.all.Union(span.tcp[t].Left.Copy()) + span.tcp = append(span.tcp[:t], span.tcp[t+1:]...) + span.udp = append(span.udp[:u], span.udp[u+1:]...) + span.icmp = append(span.icmp[:i], span.icmp[i+1:]...) + } + } + + return span +} diff --git a/pkg/optimize/ip.go b/pkg/optimize/ip.go index 0c51dff4..c1a844af 100644 --- a/pkg/optimize/ip.go +++ b/pkg/optimize/ip.go @@ -23,6 +23,7 @@ func touching(a, b *netset.IPBlock) bool { return len(ranges) == 1 } +// last IP address of a cidr func LastIPAddress(i *netset.IPBlock) *netset.IPBlock { IPRanges := i.ToIPRanges() ranges := strings.Split(IPRanges, commaSeparator) diff --git a/pkg/optimize/spanToSGRules.go b/pkg/optimize/ipSpanToSGRules.go similarity index 82% rename from pkg/optimize/spanToSGRules.go rename to pkg/optimize/ipSpanToSGRules.go index b4a680be..f031abee 100644 --- a/pkg/optimize/spanToSGRules.go +++ b/pkg/optimize/ipSpanToSGRules.go @@ -14,37 +14,6 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -// SG remote -func tcpudpSGSpanToSGRules(span map[ir.SGName]*interval.CanonicalSet, direction ir.Direction, isTCP bool) []ir.SGRule { - result := make([]ir.SGRule, 0) - for sgName, intervals := range span { - for _, dstPorts := range intervals.Intervals() { - p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) - result = append(result, ir.NewSGRule(direction, sgName, p, netset.GetCidrAll(), "")) - } - } - return result -} - -func icmpSGSpanToSGRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Direction) []ir.SGRule { - result := make([]ir.SGRule, 0) - for sgName, icmpSet := range span { - for _, icmp := range icmpSet.Partitions() { - p, _ := netp.NewICMP(icmp.TypeCode) - result = append(result, ir.NewSGRule(direction, sgName, p, netset.GetCidrAll(), "")) - } - } - return result -} - -func protocolAllSGSpanToSGRules(span []*ir.SGName, direction ir.Direction) []ir.SGRule { - result := make([]ir.SGRule, len(span)) - for i, sgName := range span { - result[i] = ir.NewSGRule(direction, sgName, netp.AnyProtocol{}, netset.GetCidrAll(), "") - } - return result -} - // IPAddrs remote func allSpanIPToSGRules(span *netset.IPBlock, direction ir.Direction) []ir.SGRule { result := make([]ir.SGRule, 0) diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index 52eebfce..97ad5c2d 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -36,14 +36,14 @@ type ( all []ir.SGRule } - sgRulesToSGSpans struct { + sgSpansToSGPerProtocol struct { tcp map[ir.SGName]*interval.CanonicalSet udp map[ir.SGName]*interval.CanonicalSet icmp map[ir.SGName]*netset.ICMPSet all []*ir.SGName } - sgRulesToIPAddrsSpans struct { + sgSpansToIPPerProtocol struct { tcp []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] udp []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] icmp []ds.Pair[*netset.IPBlock, *netset.ICMPSet] @@ -111,6 +111,7 @@ func (s *SGOptimizer) Optimize() ir.OptimizeCollection { // reduceSGRules attempts to reduce the number of rules with different remote types separately func (s *SGOptimizer) reduceSGRules(rules []ir.SGRule, direction ir.Direction) []ir.SGRule { + // separate all rules to groups of (protocol X remote) ruleGroups := divideSGRules(rules) // rules with SG as a remote @@ -129,27 +130,8 @@ func (s *SGOptimizer) reduceSGRules(rules []ir.SGRule, direction ir.Direction) [ return append(optimizedRulesToSG, optimizedRulesToIPAddrs...) } -func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGRule { - // delete other protocols rules if all protocol rule exists - for _, sgName := range spans.all { - delete(spans.tcp, *sgName) - delete(spans.udp, *sgName) - delete(spans.icmp, *sgName) - } - - // merge tcp, udp and icmp rules into all protocol rule - for sgName, tcpPorts := range spans.tcp { - if udpPorts, ok := spans.udp[sgName]; ok { - if ic, ok := spans.icmp[sgName]; ok { - if ic.Equal(netset.AllICMPSet()) && allPorts(tcpPorts) && allPorts(udpPorts) { // all tcp&udp ports and all icmp types&codes - delete(spans.tcp, sgName) - delete(spans.udp, sgName) - delete(spans.icmp, sgName) - spans.all = append(spans.all, utils.Ptr(sgName)) - } - } - } - } +func reduceSGRulesToSG(spans *sgSpansToSGPerProtocol, direction ir.Direction) []ir.SGRule { + spans = compressSpansToSG(spans) // convert spans to SG rules tcpRules := tcpudpSGSpanToSGRules(spans.tcp, direction, true) @@ -161,7 +143,7 @@ func reduceSGRulesToSG(spans *sgRulesToSGSpans, direction ir.Direction) []ir.SGR return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) } -func reduceSGRulesToIPAddrs(spans *sgRulesToIPAddrsSpans, direction ir.Direction) []ir.SGRule { +func reduceSGRulesToIPAddrs(spans *sgSpansToIPPerProtocol, direction ir.Direction) []ir.SGRule { spans = compressToAllProtocolRule(spans) // spans to SG rules @@ -221,38 +203,6 @@ func divideSGRules(rules []ir.SGRule) *sgRuleGroups { return &sgRuleGroups{rulesToSG: rulesToSG, rulesToIPAddrs: rulesToIPAddrs} } -// observation: It pays to switch to all protocol rule when we have rules that cover all other protocols -// on exactly the same cidr (only one protocol can exceed). -func compressToAllProtocolRule(span *sgRulesToIPAddrsSpans) *sgRulesToIPAddrsSpans { - t := 0 - u := 0 - i := 0 - - for t != len(span.tcp) && u != len(span.udp) && i != len(span.icmp) { - if !allPorts(span.tcp[t].Right) { - t++ - continue - } - if !allPorts(span.udp[u].Right) { - u++ - continue - } - if !span.icmp[i].Right.Equal(netset.AllICMPSet()) { - i++ - continue - } - - if span.tcp[t].Left.Equal(span.udp[u].Left) && span.tcp[t].Left.Equal(span.icmp[i].Left) { - span.all = span.all.Union(span.tcp[t].Left.Copy()) - span.tcp = append(span.tcp[:t], span.tcp[t+1:]...) - span.udp = append(span.udp[:u], span.udp[u+1:]...) - span.icmp = append(span.icmp[:i], span.icmp[i+1:]...) - } - } - - return span -} - func (s *sgRulesPerProtocol) allRules() []ir.SGRule { return append(s.tcp, append(s.udp, append(s.icmp, s.all...)...)...) } diff --git a/pkg/optimize/sgRulesToSpan.go b/pkg/optimize/sgRulesToIPToSpan.go similarity index 64% rename from pkg/optimize/sgRulesToSpan.go rename to pkg/optimize/sgRulesToIPToSpan.go index a9779988..f0fd4541 100644 --- a/pkg/optimize/sgRulesToSpan.go +++ b/pkg/optimize/sgRulesToIPToSpan.go @@ -15,59 +15,16 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -// Rules with remote SG -func sgRulesToSGToSpans(rules *sgRulesPerProtocol) *sgRulesToSGSpans { - tcpSpan := tcpudpRulesToSGToPortsSpan(rules.tcp) - udpSpan := tcpudpRulesToSGToPortsSpan(rules.udp) - icmpSpan := icmpRulesToSGToSpan(rules.icmp) - allSpan := allProtocolRulesToSGToSpan(rules.all) - return &sgRulesToSGSpans{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} -} - -func tcpudpRulesToSGToPortsSpan(rules []ir.SGRule) map[ir.SGName]*interval.CanonicalSet { - result := make(map[ir.SGName]*interval.CanonicalSet) - for i := range rules { - p := rules[i].Protocol.(netp.TCPUDP) // already checked - remote := rules[i].Remote.(ir.SGName) // already checked - if result[remote] == nil { - result[remote] = interval.NewCanonicalSet() - } - result[remote].AddInterval(p.DstPorts()) - } - return result -} - -func icmpRulesToSGToSpan(rules []ir.SGRule) map[ir.SGName]*netset.ICMPSet { - result := make(map[ir.SGName]*netset.ICMPSet) - for i := range rules { - p := rules[i].Protocol.(netp.ICMP) // already checked - remote := rules[i].Remote.(ir.SGName) // already checked - if result[remote] == nil { - result[remote] = netset.EmptyICMPSet() - } - result[remote].Union(netset.NewICMPSet(p)) - } - return result -} - -func allProtocolRulesToSGToSpan(rules []ir.SGRule) []*ir.SGName { - result := make(map[ir.SGName]struct{}) - for i := range rules { - remote := rules[i].Remote.(ir.SGName) - result[remote] = struct{}{} - } - return utils.ToPtrSlice(utils.SortedMapKeys(result)) -} - -// Rules with IPAddrs remote -func sgRulesToIPAddrsToSpans(rules *sgRulesPerProtocol) *sgRulesToIPAddrsSpans { +// calculate all spans and set them in sgRulesPerProtocol struct +func sgRulesToIPAddrsToSpans(rules *sgRulesPerProtocol) *sgSpansToIPPerProtocol { tcpSpan := tcpudpRulesToIPAddrsToPortsSpan(rules.tcp) udpSpan := tcpudpRulesToIPAddrsToPortsSpan(rules.udp) icmpSpan := icmpRulesToIPAddrsToSpan(rules.icmp) allSpan := allProtocolRulesToIPAddrsToSpan(rules.all) - return &sgRulesToIPAddrsSpans{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} + return &sgSpansToIPPerProtocol{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} } +// all protocol rules to a span. The span will be splitted to disjoint CIDRs func allProtocolRulesToIPAddrsToSpan(rules []ir.SGRule) *netset.IPBlock { res := netset.NewIPBlock() for i := range rules { @@ -76,8 +33,8 @@ func allProtocolRulesToIPAddrsToSpan(rules []ir.SGRule) *netset.IPBlock { return res } -// converts []ir.SGRule (where all rules or either TCP/UDP but not both) to a span of (IPBlock X ports). -// all IPBlocks are disjoint. +// tcp/udp rules (separately) to a span of (IPBlock X protocol ports). +// all IPBlocks are disjoint func tcpudpRulesToIPAddrsToPortsSpan(rules []ir.SGRule) []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] { span := tcpudpMapSpan(rules) result := ds.NewProductLeft[*netset.IPBlock, *interval.CanonicalSet]() @@ -88,6 +45,8 @@ func tcpudpRulesToIPAddrsToPortsSpan(rules []ir.SGRule) []ds.Pair[*netset.IPBloc return sortPartitionsByIPAddrs(result.Partitions()) } +// icmp rules to a span of (IPBlock X icmp set). +// all IPBlocks are disjoint func icmpRulesToIPAddrsToSpan(rules []ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.ICMPSet] { span := icmpMapSpan((rules)) result := ds.NewProductLeft[*netset.IPBlock, *netset.ICMPSet]() @@ -98,7 +57,12 @@ func icmpRulesToIPAddrsToSpan(rules []ir.SGRule) []ds.Pair[*netset.IPBlock, *net return sortPartitionsByIPAddrs(result.Partitions()) } -// Help functions +/* ######################## */ +/* #### HELP FUNCTIONS #### */ +/* ######################## */ + +// tcp/udp rules to a span in a map format, where the key is the IPBlock and the value contains the protocol ports +// all ipblocks are disjoint func tcpudpMapSpan(rules []ir.SGRule) map[*netset.IPBlock]*interval.CanonicalSet { span := make(map[*netset.IPBlock]*interval.CanonicalSet, 0) // all keys are disjoint for i := range rules { @@ -109,6 +73,8 @@ func tcpudpMapSpan(rules []ir.SGRule) map[*netset.IPBlock]*interval.CanonicalSet return span } +// icmp rules to a span in a map format, where the key is the IPBlock and the value contains the icmp set +// all ipblocks are disjoint func icmpMapSpan(rules []ir.SGRule) map[*netset.IPBlock]*netset.ICMPSet { span := make(map[*netset.IPBlock]*netset.ICMPSet, 0) // all keys are disjoint for i := range rules { @@ -119,6 +85,9 @@ func icmpMapSpan(rules []ir.SGRule) map[*netset.IPBlock]*netset.ICMPSet { return span } +// updateSpan gets the current span, and a rule details (IPBlock and a protocol set) +// if the IPBlock is already in the map, the new protocol set will be unioned with the existing one +// otherwise the rule will be added in the `addRuleToSpan` function. func updateSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleSet T, ruleIP *netset.IPBlock) map[*netset.IPBlock]T { if protocolSet, ok := span[ruleIP]; ok { span[ruleIP] = protocolSet.Union(ruleSet) @@ -128,6 +97,11 @@ func updateSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleSet T, ruleIP *nets return utils.MergeSetMaps(span, newMap) } +// any IPblock that overlaps with the new ipblock: +// 1. will be deleted from the new map +// 2. will be splitted into two parts: the part overlapping with the new ipblock and the part that is not +// a. the overlapping part will enter the new map, where the existing set will be unioned with the new set +// b. the non overlapping part will enter the new map with the same value he had. func addRuleToSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleIP *netset.IPBlock, ruleSet T) (s, res map[*netset.IPBlock]T) { res = make(map[*netset.IPBlock]T, 0) for ipblock := range span { diff --git a/pkg/optimize/sgRulesToSGToSpan.go b/pkg/optimize/sgRulesToSGToSpan.go new file mode 100644 index 00000000..364f3d91 --- /dev/null +++ b/pkg/optimize/sgRulesToSGToSpan.go @@ -0,0 +1,62 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import ( + "github.com/np-guard/models/pkg/interval" + "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/utils" +) + +// calculate all spans and set them in sgRulesPerProtocol struct +func sgRulesToSGToSpans(rules *sgRulesPerProtocol) *sgSpansToSGPerProtocol { + tcpSpan := tcpudpRulesToSGToPortsSpan(rules.tcp) + udpSpan := tcpudpRulesToSGToPortsSpan(rules.udp) + icmpSpan := icmpRulesToSGToSpan(rules.icmp) + allSpan := allProtocolRulesToSGToSpan(rules.all) + return &sgSpansToSGPerProtocol{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} +} + +// tcp/udp rules to a span -- map where the key is the SG name and the value is the protocol ports +func tcpudpRulesToSGToPortsSpan(rules []ir.SGRule) map[ir.SGName]*interval.CanonicalSet { + result := make(map[ir.SGName]*interval.CanonicalSet) + for i := range rules { + p := rules[i].Protocol.(netp.TCPUDP) // already checked + remote := rules[i].Remote.(ir.SGName) // already checked + if result[remote] == nil { + result[remote] = interval.NewCanonicalSet() + } + result[remote].AddInterval(p.DstPorts()) + } + return result +} + +// icmp rules to a span -- map where the key is the SG name and the value is icmp set +func icmpRulesToSGToSpan(rules []ir.SGRule) map[ir.SGName]*netset.ICMPSet { + result := make(map[ir.SGName]*netset.ICMPSet) + for i := range rules { + p := rules[i].Protocol.(netp.ICMP) // already checked + remote := rules[i].Remote.(ir.SGName) // already checked + if result[remote] == nil { + result[remote] = netset.EmptyICMPSet() + } + result[remote].Union(netset.NewICMPSet(p)) + } + return result +} + +// all protocol rules to a span of SG names slice +func allProtocolRulesToSGToSpan(rules []ir.SGRule) []*ir.SGName { + result := make(map[ir.SGName]struct{}) + for i := range rules { + remote := rules[i].Remote.(ir.SGName) + result[remote] = struct{}{} + } + return utils.ToPtrSlice(utils.SortedMapKeys(result)) +} diff --git a/pkg/optimize/sgSpanToSGRules.go b/pkg/optimize/sgSpanToSGRules.go new file mode 100644 index 00000000..c60042fd --- /dev/null +++ b/pkg/optimize/sgSpanToSGRules.go @@ -0,0 +1,47 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import ( + "github.com/np-guard/models/pkg/interval" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +// span (SGName X ports set) to SG rules +func tcpudpSGSpanToSGRules(span map[ir.SGName]*interval.CanonicalSet, direction ir.Direction, isTCP bool) []ir.SGRule { + result := make([]ir.SGRule, 0) + for sgName, intervals := range span { + for _, dstPorts := range intervals.Intervals() { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) + result = append(result, ir.NewSGRule(direction, sgName, p, netset.GetCidrAll(), "")) + } + } + return result +} + +// span (SGName X icmp set) to SG rules +func icmpSGSpanToSGRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Direction) []ir.SGRule { + result := make([]ir.SGRule, 0) + for sgName, icmpSet := range span { + for _, icmp := range icmpSet.Partitions() { + p, _ := netp.NewICMP(icmp.TypeCode) + result = append(result, ir.NewSGRule(direction, sgName, p, netset.GetCidrAll(), "")) + } + } + return result +} + +// span (slice of SGs) to SG rules +func protocolAllSGSpanToSGRules(span []*ir.SGName, direction ir.Direction) []ir.SGRule { + result := make([]ir.SGRule, len(span)) + for i, sgName := range span { + result[i] = ir.NewSGRule(direction, sgName, netp.AnyProtocol{}, netset.GetCidrAll(), "") + } + return result +} diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 362ad854..293ee3bd 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -9,6 +9,7 @@ import ( "log" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) From 67f320be4cf149954fa3794883d93bf3fe6763e6 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 25 Sep 2024 13:35:03 +0300 Subject: [PATCH 044/131] merge --- .../acl_tg_multiple/nacl_single_expected.tf | 243 ------------------ test/data/acl_tg_multiple/single_test-vpc0.tf | 145 ----------- test/data/acl_tg_multiple/single_test-vpc1.tf | 49 ---- test/data/sg_single_conn/sg_expected.csv | 3 - 4 files changed, 440 deletions(-) delete mode 100644 test/data/acl_tg_multiple/nacl_single_expected.tf delete mode 100644 test/data/acl_tg_multiple/single_test-vpc0.tf delete mode 100644 test/data/acl_tg_multiple/single_test-vpc1.tf delete mode 100644 test/data/sg_single_conn/sg_expected.csv diff --git a/test/data/acl_tg_multiple/nacl_single_expected.tf b/test/data/acl_tg_multiple/nacl_single_expected.tf deleted file mode 100644 index 09a80278..00000000 --- a/test/data/acl_tg_multiple/nacl_single_expected.tf +++ /dev/null @@ -1,243 +0,0 @@ -# test-vpc0/singleACL [10.240.0.0/24] -resource "ibm_is_network_acl" "acl-test-vpc0--singleACL" { - name = "acl-test-vpc0--singleACL" - resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id - # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] - rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" - destination = "10.240.4.0/24" - } - # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] - rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" - destination = "10.240.0.0/24" - } - # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] - rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" - destination = "10.240.4.0/24" - } - # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] - rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" - destination = "10.240.0.0/24" - } - # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] - rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" - destination = "10.240.5.0/24" - udp { - port_min = 53 - port_max = 53 - } - } - # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] - rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" - destination = "10.240.5.0/24" - udp { - port_min = 53 - port_max = 53 - } - } - # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] - rules { - name = "rule6" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" - destination = "10.240.5.0/24" - udp { - port_min = 53 - port_max = 53 - } - } - # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] - rules { - name = "rule7" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" - destination = "10.240.5.0/24" - udp { - port_min = 53 - port_max = 53 - } - } - # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] - rules { - name = "rule8" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" - destination = "10.240.9.0/24" - icmp { - type = 0 - } - } - # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] - rules { - name = "rule9" - action = "allow" - direction = "inbound" - source = "10.240.9.0/24" - destination = "10.240.8.0/24" - icmp { - type = 8 - } - } - # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] - rules { - name = "rule10" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" - destination = "10.240.9.0/24" - icmp { - type = 0 - } - } - # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] - rules { - name = "rule11" - action = "allow" - direction = "outbound" - source = "10.240.9.0/24" - destination = "10.240.8.0/24" - icmp { - type = 8 - } - } - # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections - rules { - name = "rule12" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" - destination = "10.240.1.0/24" - } - # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections - rules { - name = "rule13" - action = "deny" - direction = "outbound" - source = "10.240.1.0/24" - destination = "0.0.0.0/0" - } -} - -# test-vpc1/singleACL [10.240.64.0/24] -resource "ibm_is_network_acl" "acl-test-vpc1--singleACL" { - name = "acl-test-vpc1--singleACL" - resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id - # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] - rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" - destination = "10.240.80.0/24" - icmp { - type = 0 - } - } - # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] - rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.80.0/24" - destination = "10.240.64.0/24" - icmp { - type = 8 - } - } - # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] - rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" - destination = "10.240.80.0/24" - icmp { - type = 0 - } - } - # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] - rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.80.0/24" - destination = "10.240.64.0/24" - icmp { - type = 8 - } - } -} - -# test-vpc2/singleACL [10.240.128.0/24] -resource "ibm_is_network_acl" "acl-test-vpc2--singleACL" { - name = "acl-test-vpc2--singleACL" - resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc2_id - # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections - rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" - destination = "10.240.128.0/24" - } - # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections - rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" - destination = "0.0.0.0/0" - } -} - -# test-vpc3/singleACL [10.240.192.0/24] -resource "ibm_is_network_acl" "acl-test-vpc3--singleACL" { - name = "acl-test-vpc3--singleACL" - resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc3_id - # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections - rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" - destination = "10.240.192.0/24" - } - # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections - rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.192.0/24" - destination = "0.0.0.0/0" - } -} diff --git a/test/data/acl_tg_multiple/single_test-vpc0.tf b/test/data/acl_tg_multiple/single_test-vpc0.tf deleted file mode 100644 index c9ea8d01..00000000 --- a/test/data/acl_tg_multiple/single_test-vpc0.tf +++ /dev/null @@ -1,145 +0,0 @@ -resource "ibm_is_network_acl" "acl-test-vpc0--singleACL" { - name = "acl-test-vpc0--singleACL" - resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id - # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] - rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" - destination = "10.240.4.0/24" - } - # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] - rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" - destination = "10.240.0.0/24" - } - # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] - rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" - destination = "10.240.4.0/24" - } - # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] - rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" - destination = "10.240.0.0/24" - } - # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] - rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" - destination = "10.240.5.0/24" - udp { - port_min = 53 - port_max = 53 - } - } - # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] - rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" - destination = "10.240.5.0/24" - udp { - port_min = 53 - port_max = 53 - } - } - # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] - rules { - name = "rule6" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" - destination = "10.240.5.0/24" - udp { - port_min = 53 - port_max = 53 - } - } - # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] - rules { - name = "rule7" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" - destination = "10.240.5.0/24" - udp { - port_min = 53 - port_max = 53 - } - } - # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] - rules { - name = "rule8" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" - destination = "10.240.9.0/24" - icmp { - type = 0 - } - } - # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] - rules { - name = "rule9" - action = "allow" - direction = "inbound" - source = "10.240.9.0/24" - destination = "10.240.8.0/24" - icmp { - type = 8 - } - } - # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] - rules { - name = "rule10" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" - destination = "10.240.9.0/24" - icmp { - type = 0 - } - } - # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] - rules { - name = "rule11" - action = "allow" - direction = "outbound" - source = "10.240.9.0/24" - destination = "10.240.8.0/24" - icmp { - type = 8 - } - } - # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections - rules { - name = "rule12" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" - destination = "10.240.1.0/24" - } - # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections - rules { - name = "rule13" - action = "deny" - direction = "outbound" - source = "10.240.1.0/24" - destination = "0.0.0.0/0" - } -} diff --git a/test/data/acl_tg_multiple/single_test-vpc1.tf b/test/data/acl_tg_multiple/single_test-vpc1.tf deleted file mode 100644 index c8303eee..00000000 --- a/test/data/acl_tg_multiple/single_test-vpc1.tf +++ /dev/null @@ -1,49 +0,0 @@ -resource "ibm_is_network_acl" "acl-test-vpc1--singleACL" { - name = "acl-test-vpc1--singleACL" - resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id - # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] - rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" - destination = "10.240.80.0/24" - icmp { - type = 0 - } - } - # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] - rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.80.0/24" - destination = "10.240.64.0/24" - icmp { - type = 8 - } - } - # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] - rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" - destination = "10.240.80.0/24" - icmp { - type = 0 - } - } - # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] - rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.80.0/24" - destination = "10.240.64.0/24" - icmp { - type = 8 - } - } -} diff --git a/test/data/sg_single_conn/sg_expected.csv b/test/data/sg_single_conn/sg_expected.csv deleted file mode 100644 index 08335ae3..00000000 --- a/test/data/sg_single_conn/sg_expected.csv +++ /dev/null @@ -1,3 +0,0 @@ -SG,Direction,Remote type,Remote,Protocol,Protocol params,Description -test-vpc/be,Inbound,Security group,test-vpc/fe,UDP,ports 53-53,Internal. required-connections[0]: (instance test-vpc/fe)->(instance test-vpc/be); allowed-protocols[0] -test-vpc/fe,Outbound,Security group,test-vpc/be,UDP,ports 53-53,Internal. required-connections[0]: (instance test-vpc/fe)->(instance test-vpc/be); allowed-protocols[0] From 6be5ee02f0971e871b014df71ca4cad819c29a12 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 25 Sep 2024 13:41:58 +0300 Subject: [PATCH 045/131] fixed --- pkg/io/confio/parse_sgs.go | 59 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index f97cdb6d..250a7e6e 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -30,21 +30,22 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { if err != nil { return nil, err } - if sg.Name != nil { - vpcName := *sg.VPC.Name - if result.SGs[vpcName] == nil { - result.SGs[vpcName] = make(map[ir.SGName]*ir.SG) - } - result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, OutboundRules: outbound} + if sg.Name == nil || sg.VPC == nil || sg.VPC.Name == nil { + continue } + vpcName := *sg.VPC.Name + if result.SGs[vpcName] == nil { + result.SGs[vpcName] = make(map[ir.SGName]*ir.SG) + } + result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, OutboundRules: outbound} } return result, nil } // parse security rules, splitted into ingress and egress rules -func translateSGRules(sg *vpcv1.SecurityGroup) (ingressRules, egressRules []ir.SGRule, err error) { - ingressRules = []ir.SGRule{} - egressRules = []ir.SGRule{} +func translateSGRules(sg *vpcv1.SecurityGroup) (ingressRules, egressRules []*ir.SGRule, err error) { + ingressRules = []*ir.SGRule{} + egressRules = []*ir.SGRule{} for index := range sg.Rules { rule, err := translateSGRule(sg, index) if err != nil { @@ -60,7 +61,7 @@ func translateSGRules(sg *vpcv1.SecurityGroup) (ingressRules, egressRules []ir.S } // translateSGRule translates a security group rule to ir.SGRule -func translateSGRule(sg *vpcv1.SecurityGroup, index int) (sgRule ir.SGRule, err error) { +func translateSGRule(sg *vpcv1.SecurityGroup, index int) (sgRule *ir.SGRule, err error) { switch r := sg.Rules[index].(type) { case *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll: return translateSGRuleProtocolAll(r) @@ -69,63 +70,63 @@ func translateSGRule(sg *vpcv1.SecurityGroup, index int) (sgRule ir.SGRule, err case *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp: return translateSGRuleProtocolIcmp(r) } - return ir.SGRule{}, fmt.Errorf("error parsing rule number %d in %s sg", index, *sg.Name) + return nil, fmt.Errorf("error parsing rule number %d in %s sg", index, *sg.Name) } -func translateSGRuleProtocolAll(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll) (sgRule ir.SGRule, err error) { +func translateSGRuleProtocolAll(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll) (sgRule *ir.SGRule, err error) { direction, err := translateDirection(*rule.Direction) if err != nil { - return ir.SGRule{}, err + return nil, err } remote, err := translateRemote(rule.Remote) if err != nil { - return ir.SGRule{}, err + return nil, err } local, err := translateLocal(rule.Local) if err != nil { - return ir.SGRule{}, err + return nil, err } - return ir.SGRule{Direction: direction, Remote: remote, Protocol: netp.AnyProtocol{}, Local: local}, nil + return &ir.SGRule{Direction: direction, Remote: remote, Protocol: netp.AnyProtocol{}, Local: local}, nil } -func translateSGRuleProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (sgRule ir.SGRule, err error) { +func translateSGRuleProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (sgRule *ir.SGRule, err error) { direction, err := translateDirection(*rule.Direction) if err != nil { - return ir.SGRule{}, err + return nil, err } remote, err := translateRemote(rule.Remote) if err != nil { - return ir.SGRule{}, err + return nil, err } local, err := translateLocal(rule.Local) if err != nil { - return ir.SGRule{}, err + return nil, err } protocol, err := translateProtocolTCPUDP(rule) if err != nil { - return ir.SGRule{}, err + return nil, err } - return ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil + return &ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil } -func translateSGRuleProtocolIcmp(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp) (sgRule ir.SGRule, err error) { +func translateSGRuleProtocolIcmp(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp) (sgRule *ir.SGRule, err error) { direction, err := translateDirection(*rule.Direction) if err != nil { - return ir.SGRule{}, err + return nil, err } remote, err := translateRemote(rule.Remote) if err != nil { - return ir.SGRule{}, err + return nil, err } local, err := translateLocal(rule.Local) if err != nil { - return ir.SGRule{}, err + return nil, err } protocol, err := netp.ICMPFromTypeAndCode64(rule.Type, rule.Code) if err != nil { - return ir.SGRule{}, err + return nil, err } - return ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil + return &ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil } func translateDirection(direction string) (ir.Direction, error) { @@ -169,7 +170,7 @@ func translateLocal(local vpcv1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, er return nil, fmt.Errorf("error parsing Local field") } -// temporary - first version of optimization requires that local value will be 0.0.0.0/32 +// temporary - first version of optimization requires local = 0.0.0.0/32 func verifyLocalValue(ipAddrs *netset.IPBlock) (*netset.IPBlock, error) { if !ipAddrs.Equal(netset.GetCidrAll()) { return nil, fmt.Errorf("only 0.0.0.0/32 CIDR block is supported for local values") From bf9438fd772d6468b9deda511414c38d1717a19b Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 25 Sep 2024 15:40:31 +0300 Subject: [PATCH 046/131] wip --- cmd/subcmds/optimizeOutput.go | 8 ++-- cmd/subcmds/synthOutput.go | 8 ++-- pkg/io/confio/acl.go | 2 +- pkg/io/confio/common.go | 2 +- pkg/io/confio/sg.go | 2 +- pkg/io/csvio/acl.go | 2 +- pkg/io/csvio/common.go | 2 +- pkg/io/csvio/sg.go | 2 +- pkg/io/mdio/acl.go | 2 +- pkg/io/mdio/common.go | 2 +- pkg/io/mdio/sg.go | 2 +- pkg/io/tfio/acl.go | 2 +- pkg/io/tfio/common.go | 2 +- pkg/io/tfio/sg.go | 70 +++++++++++++++-------------------- pkg/ir/acl.go | 16 ++------ pkg/ir/common.go | 19 +++------- pkg/ir/sg.go | 16 ++------ pkg/optimize/common.go | 2 +- pkg/optimize/sg.go | 2 +- pkg/synth/acl.go | 2 +- pkg/synth/common.go | 2 +- pkg/synth/sg.go | 2 +- 22 files changed, 67 insertions(+), 102 deletions(-) diff --git a/cmd/subcmds/optimizeOutput.go b/cmd/subcmds/optimizeOutput.go index 2b602f1c..eedf753e 100644 --- a/cmd/subcmds/optimizeOutput.go +++ b/cmd/subcmds/optimizeOutput.go @@ -14,7 +14,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func writeOptimizeOutput(args *inArgs, collection ir.OptimizeCollection, vpcNames []string) error { +func writeOptimizeOutput(args *inArgs, collection ir.Collection, vpcNames []string) error { if err := checkOutputFlags(args); err != nil { return err } @@ -29,19 +29,19 @@ func writeOptimizeOutput(args *inArgs, collection ir.OptimizeCollection, vpcName return writeToFile(args.outputFile, data) } -func writeOptimizeCollection(args *inArgs, collection ir.OptimizeCollection) (*bytes.Buffer, error) { +func writeOptimizeCollection(args *inArgs, collection ir.Collection) (*bytes.Buffer, error) { var data bytes.Buffer writer, err := pickOptimizeWriter(args, &data) if err != nil { return nil, err } - if err := collection.WriteOptimize(writer); err != nil { + if err := collection.Write(writer, ""); err != nil { return nil, err } return &data, nil } -func pickOptimizeWriter(args *inArgs, data *bytes.Buffer) (ir.OptimizeWriter, error) { +func pickOptimizeWriter(args *inArgs, data *bytes.Buffer) (ir.Writer, error) { w := bufio.NewWriter(data) switch args.outputFmt { case tfOutputFormat: diff --git a/cmd/subcmds/synthOutput.go b/cmd/subcmds/synthOutput.go index 12e0670b..ad70e1a8 100644 --- a/cmd/subcmds/synthOutput.go +++ b/cmd/subcmds/synthOutput.go @@ -21,7 +21,7 @@ import ( const defaultDirectoryPermission = 0o755 -func writeOutput(args *inArgs, collection ir.SynthCollection, vpcNames []ir.ID) error { +func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error { if err := checkOutputFlags(args); err != nil { return err } @@ -61,19 +61,19 @@ func writeOutput(args *inArgs, collection ir.SynthCollection, vpcNames []ir.ID) return nil } -func writeSynthCollection(args *inArgs, collection ir.SynthCollection, vpc string) (*bytes.Buffer, error) { +func writeSynthCollection(args *inArgs, collection ir.Collection, vpc string) (*bytes.Buffer, error) { var data bytes.Buffer writer, err := pickSynthWriter(args, &data) if err != nil { return nil, err } - if err := collection.WriteSynth(writer, vpc); err != nil { + if err := collection.Write(writer, vpc); err != nil { return nil, err } return &data, nil } -func pickSynthWriter(args *inArgs, data *bytes.Buffer) (ir.SynthWriter, error) { +func pickSynthWriter(args *inArgs, data *bytes.Buffer) (ir.Writer, error) { w := bufio.NewWriter(data) switch args.outputFmt { case tfOutputFormat: diff --git a/pkg/io/confio/acl.go b/pkg/io/confio/acl.go index b2aa75d8..74ad494c 100644 --- a/pkg/io/confio/acl.go +++ b/pkg/io/confio/acl.go @@ -209,7 +209,7 @@ func subnetRef(subnet *configModel.Subnet) *vpcv1.SubnetReference { } } -func (w *Writer) WriteSynthACL(collection *ir.ACLCollection, _ string) error { +func (w *Writer) WriteACL(collection *ir.ACLCollection, _ string) error { if err := updateACLList(w.model, collection); err != nil { return err } diff --git a/pkg/io/confio/common.go b/pkg/io/confio/common.go index 97aa4274..e3e86f61 100644 --- a/pkg/io/confio/common.go +++ b/pkg/io/confio/common.go @@ -12,7 +12,7 @@ import ( configModel "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" ) -// Writer implements ir.SynthWriter +// Writer implements ir.Writer type Writer struct { w *bufio.Writer model *configModel.ResourcesContainerModel diff --git a/pkg/io/confio/sg.go b/pkg/io/confio/sg.go index 02a30ed7..e4b74be7 100644 --- a/pkg/io/confio/sg.go +++ b/pkg/io/confio/sg.go @@ -258,7 +258,7 @@ func updateSG(model *configModel.ResourcesContainerModel, collection *ir.SGColle return errors.Join(err1, err2) } -func (w *Writer) WriteSynthSG(collection *ir.SGCollection, _ string) error { +func (w *Writer) WriteSG(collection *ir.SGCollection, _ string) error { if err := updateSG(w.model, collection); err != nil { return err } diff --git a/pkg/io/csvio/acl.go b/pkg/io/csvio/acl.go index 0da377ef..0c1f62f4 100644 --- a/pkg/io/csvio/acl.go +++ b/pkg/io/csvio/acl.go @@ -18,7 +18,7 @@ import ( ) // Write prints an entire collection of acls as a single CSV table. -func (w *Writer) WriteSynthACL(collection *ir.ACLCollection, vpc string) error { +func (w *Writer) WriteACL(collection *ir.ACLCollection, vpc string) error { if err := w.w.WriteAll(aclHeader()); err != nil { return err } diff --git a/pkg/io/csvio/common.go b/pkg/io/csvio/common.go index c61e180e..41cd664d 100644 --- a/pkg/io/csvio/common.go +++ b/pkg/io/csvio/common.go @@ -18,7 +18,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -// Writer implements ir.SynthWriter +// Writer implements ir.Writer type Writer struct { w *csv.Writer } diff --git a/pkg/io/csvio/sg.go b/pkg/io/csvio/sg.go index 67128c51..ed91a1ef 100644 --- a/pkg/io/csvio/sg.go +++ b/pkg/io/csvio/sg.go @@ -16,7 +16,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func (w *Writer) WriteSynthSG(collection *ir.SGCollection, vpc string) error { +func (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { if err := w.w.WriteAll(sgHeader()); err != nil { return err } diff --git a/pkg/io/mdio/acl.go b/pkg/io/mdio/acl.go index 0f895366..c75a54a1 100644 --- a/pkg/io/mdio/acl.go +++ b/pkg/io/mdio/acl.go @@ -18,7 +18,7 @@ import ( ) // Write prints an entire collection of acls as a single MD table. -func (w *Writer) WriteSynthACL(collection *ir.ACLCollection, vpc string) error { +func (w *Writer) WriteACL(collection *ir.ACLCollection, vpc string) error { if err := w.writeAll(aclHeader()); err != nil { return err } diff --git a/pkg/io/mdio/common.go b/pkg/io/mdio/common.go index fad3d774..abfb24a8 100644 --- a/pkg/io/mdio/common.go +++ b/pkg/io/mdio/common.go @@ -20,7 +20,7 @@ import ( const leftAlign = " :--- " -// Writer implements ir.SynthWriter +// Writer implements ir.Writer type Writer struct { w *bufio.Writer } diff --git a/pkg/io/mdio/sg.go b/pkg/io/mdio/sg.go index 5cf4308d..3277b3fa 100644 --- a/pkg/io/mdio/sg.go +++ b/pkg/io/mdio/sg.go @@ -16,7 +16,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func (w *Writer) WriteSynthSG(collection *ir.SGCollection, vpc string) error { +func (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { if err := w.writeAll(sgHeader()); err != nil { return err } diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index 95d77473..3575629a 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -18,7 +18,7 @@ import ( ) // WriteACL prints an entire collection of acls as a sequence of terraform resources. -func (w *Writer) WriteSynthACL(c *ir.ACLCollection, vpc string) error { +func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string) error { collection, err := aclCollection(c, vpc) if err != nil { return err diff --git a/pkg/io/tfio/common.go b/pkg/io/tfio/common.go index 6fd5c8f3..96611c65 100644 --- a/pkg/io/tfio/common.go +++ b/pkg/io/tfio/common.go @@ -20,7 +20,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -// Writer implements ir.SynthWriter and ir.OptimizeWriter +// Writer implements ir.Writer type Writer struct { w *bufio.Writer } diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 05f8e017..747be97d 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -17,17 +17,9 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func (w *Writer) WriteSynthSG(c *ir.SGCollection, vpc string) error { - return w.writeSGCollection(c, vpc, true) -} - -func (w *Writer) WriteOptimizeSG(c *ir.SGCollection) error { - return w.writeSGCollection(c, "", false) -} - -// writeSGCollection prints an entire collection of Security Groups as a sequence of terraform resources. -func (w *Writer) writeSGCollection(c *ir.SGCollection, vpc string, writeComments bool) error { - collection, err := sgCollection(c, vpc, writeComments) +// WriteSG prints an entire collection of Security Groups as a sequence of terraform resources. +func (w *Writer) WriteSG(c *ir.SGCollection, vpc string) error { + collection, err := sgCollection(c, vpc) if err != nil { return err } @@ -36,7 +28,8 @@ func (w *Writer) writeSGCollection(c *ir.SGCollection, vpc string, writeComments if err != nil { return err } - return w.w.Flush() + err = w.w.Flush() + return err } func value(x interface{}) (string, error) { @@ -67,24 +60,22 @@ func sgProtocol(t netp.Protocol) []tf.Block { return nil } -func sgRule(rule *ir.SGRule, sgName ir.SGName, i int, writeComment bool) (tf.Block, error) { +func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { ruleName := fmt.Sprintf("%s-%v", ir.ChangeScoping(sgName.String()), i) if err := verifyName(ruleName); err != nil { return tf.Block{}, err } - comment := "" - if writeComment { - comment = fmt.Sprintf("# %v", rule.Explanation) - } + group, err1 := value(sgName) remote, err2 := value(rule.Remote) if err := errors.Join(err1, err2); err != nil { return tf.Block{}, err } + return tf.Block{ Name: "resource", - Labels: []string{quote("ibm_is_security_group_rule"), quote(ruleName)}, - Comment: comment, + Labels: []string{quote("ibm_is_security_group_rule"), ir.ChangeScoping(quote(ruleName))}, + Comment: fmt.Sprintf("# %v", rule.Explanation), Arguments: []tf.Argument{ {Name: "group", Value: group}, {Name: "direction", Value: quote(direction(rule.Direction))}, @@ -112,27 +103,26 @@ func sg(sgName, comment string) (tf.Block, error) { }, nil } -func sgCollection(t *ir.SGCollection, vpc string, writeComments bool) (*tf.ConfigFile, error) { - resources := make([]tf.Block, 0) - // for _, sgName := range t.SortedSGNames(vpc) { - // comment := "\n" - // if writeComments { - // comment = fmt.Sprintf("\n### SG attached to %v", sgName) - // } - // sg, err := sg(sgName.String(), comment) - // if err != nil { - // return nil, err - // } - // resources = append(resources, sg) - // rules := sg.AllRules() - // for i, rule := range rules { - // rule, err := sgRule(rule, sgName, i) - // if err != nil { - // return nil, err - // } - // resources = append(resources, rule) - // } - // } +func sgCollection(t *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { + var resources []tf.Block //nolint:prealloc // nontrivial to calculate, and an unlikely performance bottleneck + for _, sgName := range t.SortedSGNames(vpc) { + comment := "" + vpcName := ir.VpcFromScopedResource(string(sgName)) + rules := t.SGs[vpcName][sgName].AllRules() + comment = fmt.Sprintf("\n### SG attached to %v", sgName) + sg, err := sg(sgName.String(), comment) + if err != nil { + return nil, err + } + resources = append(resources, sg) + for i, rule := range rules { + rule, err := sgRule(rule, sgName, i) + if err != nil { + return nil, err + } + resources = append(resources, rule) + } + } return &tf.ConfigFile{ Resources: resources, }, nil diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index 81c621be..b8e23d6e 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -38,12 +38,8 @@ type ( ACLs map[ID]map[string]*ACL } - SynthACLWriter interface { - WriteSynthACL(aclColl *ACLCollection, vpc string) error - } - - OptimizeACLWriter interface { - WriteOptimizeACL(aclColl *ACLCollection) error + ACLWriter interface { + WriteACL(aclColl *ACLCollection, vpc string) error } ) @@ -133,12 +129,8 @@ func (c *ACLCollection) VpcNames() []string { return utils.SortedMapKeys(c.ACLs) } -func (c *ACLCollection) WriteSynth(w SynthWriter, vpc string) error { - return w.WriteSynthACL(c, vpc) -} - -func (c *ACLCollection) WriteOptimize(w OptimizeWriter) error { - return w.WriteOptimizeACL(c) +func (c *ACLCollection) Write(w Writer, vpc string) error { + return w.WriteACL(c, vpc) } func (c *ACLCollection) SortedACLSubnets(vpc string) []string { diff --git a/pkg/ir/common.go b/pkg/ir/common.go index 5f9fddd8..b747840f 100644 --- a/pkg/ir/common.go +++ b/pkg/ir/common.go @@ -8,22 +8,13 @@ package ir type ( Direction string - SynthCollection interface { - WriteSynth(writer SynthWriter, vpc string) error + Collection interface { + Write(writer Writer, vpc string) error } - OptimizeCollection interface { - WriteOptimize(writer OptimizeWriter) error - } - - SynthWriter interface { - SynthACLWriter - SynthSGWriter - } - - OptimizeWriter interface { - OptimizeACLWriter - OptimizeSGWriter + Writer interface { + ACLWriter + SGWriter } ) diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 4ad83116..d394e36c 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -54,12 +54,8 @@ type ( SGs map[ID]map[SGName]*SG } - SynthSGWriter interface { - WriteSynthSG(sgColl *SGCollection, vpc string) error - } - - OptimizeSGWriter interface { - WriteOptimizeSG(sgColl *SGCollection) error + SGWriter interface { + WriteSG(sgColl *SGCollection, vpc string) error } ) @@ -122,12 +118,8 @@ func (c *SGCollection) VpcNames() []string { return utils.SortedMapKeys(c.SGs) } -func (c *SGCollection) WriteSynth(w SynthWriter, vpc string) error { - return w.WriteSynthSG(c, vpc) -} - -func (c *SGCollection) WriteOptimize(w OptimizeWriter) error { - return w.WriteOptimizeSG(c) +func (c *SGCollection) Write(w Writer, vpc string) error { + return w.WriteSG(c, vpc) } func (c *SGCollection) SortedSGNames(vpc ID) []SGName { diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index 96ed3b9d..b9ee7306 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -12,7 +12,7 @@ type Optimizer interface { ParseCollection(filename string) error // optimize number of SG/nACL rules - Optimize() (ir.OptimizeCollection, error) + Optimize() (ir.Collection, error) // returns a slice of all vpc names. used to generate locals file VpcNames() []string diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index 16828db5..d039544d 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -29,7 +29,7 @@ func (s *SGOptimizer) ParseCollection(filename string) error { return nil } -func (s *SGOptimizer) Optimize() (ir.OptimizeCollection, error) { +func (s *SGOptimizer) Optimize() (ir.Collection, error) { return s.sgCollection, nil } diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index 8807a865..2b3dff12 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -27,7 +27,7 @@ func NewACLSynthesizer(s *ir.Spec, single bool) Synthesizer { return &ACLSynthesizer{spec: s, singleACL: single, result: ir.NewACLCollection()} } -func (a *ACLSynthesizer) Synth() (ir.SynthCollection, error) { +func (a *ACLSynthesizer) Synth() (ir.Collection, error) { return a.makeACL() } diff --git a/pkg/synth/common.go b/pkg/synth/common.go index d29100ca..e6e516f3 100644 --- a/pkg/synth/common.go +++ b/pkg/synth/common.go @@ -15,7 +15,7 @@ import ( type ( Synthesizer interface { - Synth() (ir.SynthCollection, error) + Synth() (ir.Collection, error) } namedAddrs struct { diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index e9947d23..70c2433a 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -25,7 +25,7 @@ func NewSGSynthesizer(s *ir.Spec, _ bool) Synthesizer { return &SGSynthesizer{spec: s, result: ir.NewSGCollection()} } -func (s *SGSynthesizer) Synth() (ir.SynthCollection, error) { +func (s *SGSynthesizer) Synth() (ir.Collection, error) { return s.makeSG() } From e3d4668fa06a388f953dbe692ce23d5fdcb4ba12 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 25 Sep 2024 15:58:35 +0300 Subject: [PATCH 047/131] wip --- pkg/io/tfio/acl.go | 4 ---- pkg/ir/acl.go | 7 +++---- pkg/ir/sg.go | 7 +++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index 3575629a..b7f3df42 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -32,10 +32,6 @@ func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string) error { return err } -func (w *Writer) WriteOptimizeACL(c *ir.ACLCollection) error { - return fmt.Errorf("OptimizeACL is not supported yet") -} - func aclProtocol(t netp.Protocol) []tf.Block { switch p := t.(type) { case netp.TCPUDP: diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index b8e23d6e..e2f60cf6 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -29,7 +29,6 @@ type ( ACL struct { Subnet string - VpcName string Internal []ACLRule External []ACLRule } @@ -108,8 +107,8 @@ func NewACLCollection() *ACLCollection { return &ACLCollection{ACLs: map[ID]map[string]*ACL{}} } -func NewACL(subnet, vpcName string) *ACL { - return &ACL{Subnet: subnet, VpcName: vpcName, Internal: []ACLRule{}, External: []ACLRule{}} +func NewACL(subnet string) *ACL { + return &ACL{Subnet: subnet, Internal: []ACLRule{}, External: []ACLRule{}} } func (c *ACLCollection) LookupOrCreate(subnet string) *ACL { @@ -117,7 +116,7 @@ func (c *ACLCollection) LookupOrCreate(subnet string) *ACL { if acl, ok := c.ACLs[vpcName][subnet]; ok { return acl } - newACL := NewACL(subnet, vpcName) + newACL := NewACL(subnet) if c.ACLs[vpcName] == nil { c.ACLs[vpcName] = make(map[string]*ACL) } diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index d394e36c..2317a4ec 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -44,7 +44,6 @@ type ( SG struct { SGName SGName - VpcName string InboundRules []*SGRule OutboundRules []*SGRule Attached []ID @@ -80,8 +79,8 @@ func (r *SGRule) mustSupersede(other *SGRule) bool { return res } -func NewSG(vpcName string, sgName SGName) *SG { - return &SG{SGName: sgName, VpcName: vpcName, InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Attached: []ID{}} +func NewSG(sgName SGName) *SG { + return &SG{SGName: sgName, InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Attached: []ID{}} } func NewSGCollection() *SGCollection { @@ -93,7 +92,7 @@ func (c *SGCollection) LookupOrCreate(name SGName) *SG { if sg, ok := c.SGs[vpcName][name]; ok { return sg } - newSG := NewSG(vpcName, name) + newSG := NewSG(name) if c.SGs[vpcName] == nil { c.SGs[vpcName] = make(map[SGName]*SG) } From ebb4b3b48278eda39866976f0d3166177ed663c8 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 25 Sep 2024 16:22:05 +0300 Subject: [PATCH 048/131] wip --- pkg/io/confio/parse_sgs.go | 2 +- pkg/io/tfio/acl.go | 8 +++++++- pkg/io/tfio/sg.go | 21 ++++++++++++++++++++- pkg/ir/acl.go | 7 ++++--- pkg/ir/sg.go | 7 ++++--- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index 250a7e6e..1fff790b 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -37,7 +37,7 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { if result.SGs[vpcName] == nil { result.SGs[vpcName] = make(map[ir.SGName]*ir.SG) } - result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, OutboundRules: outbound} + result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{VpcName: vpcName, InboundRules: inbound, OutboundRules: outbound} } return result, nil } diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index b7f3df42..401aef06 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -64,8 +64,14 @@ func aclRule(rule *ir.ACLRule, name string) (tf.Block, error) { {Name: "source", Value: quote(rule.Source.String())}, {Name: "destination", Value: quote(rule.Destination.String())}, } + + comment := "" + if rule.Explanation != "" { + comment = fmt.Sprintf("# %v", rule.Explanation) + } + return tf.Block{Name: "rules", - Comment: fmt.Sprintf("# %v", rule.Explanation), + Comment: comment, Arguments: arguments, Blocks: aclProtocol(rule.Protocol), }, nil diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 747be97d..c4dadcb7 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -72,10 +72,15 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { return tf.Block{}, err } + comment := "" + if rule.Explanation != "" { + comment = fmt.Sprintf("# %v", rule.Explanation) + } + return tf.Block{ Name: "resource", Labels: []string{quote("ibm_is_security_group_rule"), ir.ChangeScoping(quote(ruleName))}, - Comment: fmt.Sprintf("# %v", rule.Explanation), + Comment: comment, Arguments: []tf.Argument{ {Name: "group", Value: group}, {Name: "direction", Value: quote(direction(rule.Direction))}, @@ -105,6 +110,20 @@ func sg(sgName, comment string) (tf.Block, error) { func sgCollection(t *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { var resources []tf.Block //nolint:prealloc // nontrivial to calculate, and an unlikely performance bottleneck + + for _, vpcName := range t.VpcNames() { + if vpc != vpcName && vpc != "" { + continue + } + for _, sgName := range t.SortedSGNames(vpcName) { + rules := t.SGs[vpcName][sgName].AllRules() + comment := fmt.Sprintf("\n### SG attached to %s", sgName) + } + if vpc == "" { + break + } + } + for _, sgName := range t.SortedSGNames(vpc) { comment := "" vpcName := ir.VpcFromScopedResource(string(sgName)) diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index e2f60cf6..b8e23d6e 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -29,6 +29,7 @@ type ( ACL struct { Subnet string + VpcName string Internal []ACLRule External []ACLRule } @@ -107,8 +108,8 @@ func NewACLCollection() *ACLCollection { return &ACLCollection{ACLs: map[ID]map[string]*ACL{}} } -func NewACL(subnet string) *ACL { - return &ACL{Subnet: subnet, Internal: []ACLRule{}, External: []ACLRule{}} +func NewACL(subnet, vpcName string) *ACL { + return &ACL{Subnet: subnet, VpcName: vpcName, Internal: []ACLRule{}, External: []ACLRule{}} } func (c *ACLCollection) LookupOrCreate(subnet string) *ACL { @@ -116,7 +117,7 @@ func (c *ACLCollection) LookupOrCreate(subnet string) *ACL { if acl, ok := c.ACLs[vpcName][subnet]; ok { return acl } - newACL := NewACL(subnet) + newACL := NewACL(subnet, vpcName) if c.ACLs[vpcName] == nil { c.ACLs[vpcName] = make(map[string]*ACL) } diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 2317a4ec..1245fcae 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -44,6 +44,7 @@ type ( SG struct { SGName SGName + VpcName string InboundRules []*SGRule OutboundRules []*SGRule Attached []ID @@ -79,8 +80,8 @@ func (r *SGRule) mustSupersede(other *SGRule) bool { return res } -func NewSG(sgName SGName) *SG { - return &SG{SGName: sgName, InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Attached: []ID{}} +func NewSG(sgName SGName, vpcName string) *SG { + return &SG{SGName: sgName, VpcName: vpcName, InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Attached: []ID{}} } func NewSGCollection() *SGCollection { @@ -92,7 +93,7 @@ func (c *SGCollection) LookupOrCreate(name SGName) *SG { if sg, ok := c.SGs[vpcName][name]; ok { return sg } - newSG := NewSG(name) + newSG := NewSG(name, vpcName) if c.SGs[vpcName] == nil { c.SGs[vpcName] = make(map[SGName]*SG) } From f34b9b7fd411ccdad95349ff39bc5039be9e5af1 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 25 Sep 2024 17:06:48 +0300 Subject: [PATCH 049/131] fixed --- pkg/io/tfio/sg.go | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index c4dadcb7..88389dc0 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -90,18 +90,21 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { }, nil } -func sg(sgName, comment string) (tf.Block, error) { - vpcName := ir.VpcFromScopedResource(sgName) - sgName = ir.ChangeScoping(sgName) - if err := verifyName(sgName); err != nil { +func sg(sgName, vpcName string) (tf.Block, error) { + tfSGName := ir.ChangeScoping(sgName) + comment := fmt.Sprintf("\n### SG attached to %s", sgName) + if sgName == tfSGName { // its optimization + comment = "" + } + if err := verifyName(tfSGName); err != nil { return tf.Block{}, err } return tf.Block{ Name: "resource", //nolint:revive // obvious false positive - Labels: []string{quote("ibm_is_security_group"), ir.ChangeScoping(quote(sgName))}, + Labels: []string{quote("ibm_is_security_group"), quote(tfSGName)}, Comment: comment, Arguments: []tf.Argument{ - {Name: "name", Value: quote("sg-" + sgName)}, + {Name: "name", Value: quote("sg-" + tfSGName)}, {Name: "resource_group", Value: "local.sg_synth_resource_group_id"}, {Name: "vpc", Value: fmt.Sprintf("local.sg_synth_%s_id", vpcName)}, }, @@ -109,7 +112,7 @@ func sg(sgName, comment string) (tf.Block, error) { } func sgCollection(t *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { - var resources []tf.Block //nolint:prealloc // nontrivial to calculate, and an unlikely performance bottleneck + var resources []tf.Block for _, vpcName := range t.VpcNames() { if vpc != vpcName && vpc != "" { @@ -117,29 +120,18 @@ func sgCollection(t *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { } for _, sgName := range t.SortedSGNames(vpcName) { rules := t.SGs[vpcName][sgName].AllRules() - comment := fmt.Sprintf("\n### SG attached to %s", sgName) - } - if vpc == "" { - break - } - } - - for _, sgName := range t.SortedSGNames(vpc) { - comment := "" - vpcName := ir.VpcFromScopedResource(string(sgName)) - rules := t.SGs[vpcName][sgName].AllRules() - comment = fmt.Sprintf("\n### SG attached to %v", sgName) - sg, err := sg(sgName.String(), comment) - if err != nil { - return nil, err - } - resources = append(resources, sg) - for i, rule := range rules { - rule, err := sgRule(rule, sgName, i) + sg, err := sg(sgName.String(), vpcName) if err != nil { return nil, err } - resources = append(resources, rule) + resources = append(resources, sg) + for i, rule := range rules { + rule, err := sgRule(rule, sgName, i) + if err != nil { + return nil, err + } + resources = append(resources, rule) + } } } return &tf.ConfigFile{ From ca64cee72f46f0ddf99d6d265265b9e729fb43ab Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 30 Sep 2024 11:01:02 +0300 Subject: [PATCH 050/131] avoid code dup --- cmd/subcmds/optimize.go | 2 +- cmd/subcmds/optimizeOutput.go | 52 ------------------- cmd/subcmds/optimizeSG.go | 3 ++ cmd/subcmds/{synthOutput.go => output.go} | 56 +++++++++++++++----- cmd/subcmds/outputCommon.go | 63 ----------------------- cmd/subcmds/outputFormat.go | 6 +-- cmd/subcmds/synth.go | 2 +- cmd/subcmds/synthACL.go | 3 ++ cmd/subcmds/synthSG.go | 3 ++ cmd/subcmds/verifyFlags.go | 24 +++++++++ 10 files changed, 80 insertions(+), 134 deletions(-) delete mode 100644 cmd/subcmds/optimizeOutput.go rename cmd/subcmds/{synthOutput.go => output.go} (57%) delete mode 100644 cmd/subcmds/outputCommon.go create mode 100644 cmd/subcmds/verifyFlags.go diff --git a/cmd/subcmds/optimize.go b/cmd/subcmds/optimize.go index c3ea273c..483d3705 100644 --- a/cmd/subcmds/optimize.go +++ b/cmd/subcmds/optimize.go @@ -41,5 +41,5 @@ func optimization(cmd *cobra.Command, args *inArgs, newOptimizer optimize.Optimi if err != nil { return err } - return writeOptimizeOutput(args, collection, newOptimizer.VpcNames()) + return writeOutput(args, collection, newOptimizer.VpcNames(), false) } diff --git a/cmd/subcmds/optimizeOutput.go b/cmd/subcmds/optimizeOutput.go deleted file mode 100644 index eedf753e..00000000 --- a/cmd/subcmds/optimizeOutput.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package subcmds - -import ( - "bufio" - "bytes" - "fmt" - - "github.com/np-guard/vpc-network-config-synthesis/pkg/io/tfio" - "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" -) - -func writeOptimizeOutput(args *inArgs, collection ir.Collection, vpcNames []string) error { - if err := checkOutputFlags(args); err != nil { - return err - } - _, isACLCollection := collection.(*ir.ACLCollection) - if err := writeLocals(args, vpcNames, isACLCollection); err != nil { - return err - } - data, err := writeOptimizeCollection(args, collection) - if err != nil { - return err - } - return writeToFile(args.outputFile, data) -} - -func writeOptimizeCollection(args *inArgs, collection ir.Collection) (*bytes.Buffer, error) { - var data bytes.Buffer - writer, err := pickOptimizeWriter(args, &data) - if err != nil { - return nil, err - } - if err := collection.Write(writer, ""); err != nil { - return nil, err - } - return &data, nil -} - -func pickOptimizeWriter(args *inArgs, data *bytes.Buffer) (ir.Writer, error) { - w := bufio.NewWriter(data) - switch args.outputFmt { - case tfOutputFormat: - return tfio.NewWriter(w), nil - default: - return nil, fmt.Errorf("bad output format: %q", args.outputFmt) - } -} diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go index 6a07c367..7311dd55 100644 --- a/cmd/subcmds/optimizeSG.go +++ b/cmd/subcmds/optimizeSG.go @@ -18,6 +18,9 @@ func NewOptimizeSGCommand(args *inArgs) *cobra.Command { Long: `OptimizeSG attempts to reduce the number of security group rules in a SG without changing the semantic.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { + if err := validateFlags(args); err != nil { + return err + } return optimization(cmd, args, optimize.NewSGOptimizer(args.firewallName)) }, } diff --git a/cmd/subcmds/synthOutput.go b/cmd/subcmds/output.go similarity index 57% rename from cmd/subcmds/synthOutput.go rename to cmd/subcmds/output.go index ad70e1a8..9def6e87 100644 --- a/cmd/subcmds/synthOutput.go +++ b/cmd/subcmds/output.go @@ -10,21 +10,19 @@ import ( "bytes" "fmt" "os" + "path/filepath" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/confio" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/csvio" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/mdio" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/tfio" - "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) +const defaultFilePermission = 0o644 const defaultDirectoryPermission = 0o755 -func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error { - if err := checkOutputFlags(args); err != nil { - return err - } +func writeOutput(args *inArgs, collection ir.Collection, vpcNames []string, isSynth bool) error { if args.outputDir != "" { // create the directory if needed if err := os.MkdirAll(args.outputDir, defaultDirectoryPermission); err != nil { return err @@ -38,7 +36,7 @@ func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error var data *bytes.Buffer var err error if args.outputDir == "" { - if data, err = writeSynthCollection(args, collection, ""); err != nil { + if data, err = writeCollection(args, collection, "", isSynth); err != nil { return err } return writeToFile(args.outputFile, data) @@ -51,7 +49,7 @@ func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error if args.prefix != "" { args.outputFile = args.outputDir + "/" + args.prefix + "_" + suffix } - if data, err = writeSynthCollection(args, collection, vpc); err != nil { + if data, err = writeCollection(args, collection, vpc, isSynth); err != nil { return err } if err := writeToFile(args.outputFile, data); err != nil { @@ -61,9 +59,9 @@ func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error return nil } -func writeSynthCollection(args *inArgs, collection ir.Collection, vpc string) (*bytes.Buffer, error) { +func writeCollection(args *inArgs, collection ir.Collection, vpc string, isSynth bool) (*bytes.Buffer, error) { var data bytes.Buffer - writer, err := pickSynthWriter(args, &data) + writer, err := pickWriter(args, &data, isSynth) if err != nil { return nil, err } @@ -73,7 +71,7 @@ func writeSynthCollection(args *inArgs, collection ir.Collection, vpc string) (* return &data, nil } -func pickSynthWriter(args *inArgs, data *bytes.Buffer) (ir.Writer, error) { +func pickWriter(args *inArgs, data *bytes.Buffer, isSynth bool) (ir.Writer, error) { w := bufio.NewWriter(data) switch args.outputFmt { case tfOutputFormat: @@ -82,9 +80,39 @@ func pickSynthWriter(args *inArgs, data *bytes.Buffer) (ir.Writer, error) { return csvio.NewWriter(w), nil case mdOutputFormat: return mdio.NewWriter(w), nil - case apiOutputFormat: - return confio.NewWriter(w, args.configFile) - default: - return nil, fmt.Errorf("bad output format: %q", args.outputFmt) + case jsonOutputFormat: + if isSynth { + return confio.NewWriter(w, args.configFile) + } + } + return nil, fmt.Errorf("bad output format: %q", args.outputFmt) +} + +func writeToFile(outputFile string, data *bytes.Buffer) error { + if outputFile == "" { + fmt.Println(data.String()) + return nil + } + return os.WriteFile(outputFile, data.Bytes(), defaultFilePermission) +} + +func writeLocals(args *inArgs, vpcNames []ir.ID, isACL bool) error { + if !args.locals { + return nil + } + + var data *bytes.Buffer + var err error + if data, err = tfio.WriteLocals(vpcNames, isACL); err != nil { + return err + } + + outputFile := "" + suffix := "/locals.tf" + if args.outputDir != "" { + outputFile = args.outputDir + suffix + } else if args.outputFile != "" { + outputFile = filepath.Dir(args.outputFile) + suffix } + return writeToFile(outputFile, data) } diff --git a/cmd/subcmds/outputCommon.go b/cmd/subcmds/outputCommon.go deleted file mode 100644 index aa399315..00000000 --- a/cmd/subcmds/outputCommon.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package subcmds - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - - "github.com/np-guard/vpc-network-config-synthesis/pkg/io/tfio" - "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" -) - -const defaultFilePermission = 0o644 - -func checkOutputFlags(args *inArgs) error { - if args.outputDir != "" && args.outputFile != "" { - return fmt.Errorf("only one of -d and -o can be supplied") - } - if err := updateOutputFormat(args); err != nil { - return err - } - if args.outputDir != "" && args.outputFmt == apiOutputFormat { - return fmt.Errorf("-d cannot be used with format json") - } - return nil -} - -func writeToFile(outputFile string, data *bytes.Buffer) error { - if outputFile == "" { - fmt.Println(data.String()) - return nil - } - return os.WriteFile(outputFile, data.Bytes(), defaultFilePermission) -} - -func writeLocals(args *inArgs, vpcNames []ir.ID, isACL bool) error { - if !args.locals { - return nil - } - if args.outputFmt != tfOutputFormat { - return fmt.Errorf("--locals flag requires setting the output format to tf") - } - - var data *bytes.Buffer - var err error - if data, err = tfio.WriteLocals(vpcNames, isACL); err != nil { - return err - } - - outputFile := "" - suffix := "/locals.tf" - if args.outputDir != "" { - outputFile = args.outputDir + suffix - } else if args.outputFile != "" { - outputFile = filepath.Dir(args.outputFile) + suffix - } - return writeToFile(outputFile, data) -} diff --git a/cmd/subcmds/outputFormat.go b/cmd/subcmds/outputFormat.go index 51a36c60..f435c43a 100644 --- a/cmd/subcmds/outputFormat.go +++ b/cmd/subcmds/outputFormat.go @@ -14,11 +14,11 @@ const ( tfOutputFormat = "tf" csvOutputFormat = "csv" mdOutputFormat = "md" - apiOutputFormat = "json" + jsonOutputFormat = "json" defaultOutputFormat = csvOutputFormat ) -var outputFormats = []string{tfOutputFormat, csvOutputFormat, mdOutputFormat, apiOutputFormat} +var outputFormats = []string{tfOutputFormat, csvOutputFormat, mdOutputFormat, jsonOutputFormat} func updateOutputFormat(args *inArgs) error { var err error @@ -40,7 +40,7 @@ func inferFormatUsingFilename(filename string) (string, error) { case strings.HasSuffix(filename, ".md"): return mdOutputFormat, nil case strings.HasSuffix(filename, ".json"): - return apiOutputFormat, nil + return jsonOutputFormat, nil default: return "", fmt.Errorf("bad output format") } diff --git a/cmd/subcmds/synth.go b/cmd/subcmds/synth.go index fab5ee4b..91b8250b 100644 --- a/cmd/subcmds/synth.go +++ b/cmd/subcmds/synth.go @@ -48,5 +48,5 @@ func synthesis(cmd *cobra.Command, args *inArgs, newSynthesizer func(*ir.Spec, b if err != nil { return err } - return writeOutput(args, collection, utils.MapKeys(spec.Defs.ConfigDefs.VPCs)) + return writeOutput(args, collection, utils.MapKeys(spec.Defs.ConfigDefs.VPCs), true) } diff --git a/cmd/subcmds/synthACL.go b/cmd/subcmds/synthACL.go index 4aee4040..96c6aea3 100644 --- a/cmd/subcmds/synthACL.go +++ b/cmd/subcmds/synthACL.go @@ -19,6 +19,9 @@ func NewSynthACLCommand(args *inArgs) *cobra.Command { Endpoints in the required-connectivity specification may be subnets, subnet segments, CIDR segments and externals.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { + if err := validateFlags(args); err != nil { + return err + } return synthesis(cmd, args, synth.NewACLSynthesizer, args.singleacl) }, } diff --git a/cmd/subcmds/synthSG.go b/cmd/subcmds/synthSG.go index 88bb4a56..215324ca 100644 --- a/cmd/subcmds/synthSG.go +++ b/cmd/subcmds/synthSG.go @@ -19,6 +19,9 @@ func NewSynthSGCommand(args *inArgs) *cobra.Command { Endpoints in the required-connectivity specification may be Instances (VSIs), Network Interfaces, VPEs and externals.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { + if err := validateFlags(args); err != nil { + return err + } return synthesis(cmd, args, synth.NewSGSynthesizer, false) }, } diff --git a/cmd/subcmds/verifyFlags.go b/cmd/subcmds/verifyFlags.go new file mode 100644 index 00000000..b794732a --- /dev/null +++ b/cmd/subcmds/verifyFlags.go @@ -0,0 +1,24 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package subcmds + +import "fmt" + +func validateFlags(args *inArgs) error { + if args.outputDir != "" && args.outputFile != "" { + return fmt.Errorf("only one of -d and -o can be supplied") + } + if err := updateOutputFormat(args); err != nil { + return err + } + if args.outputDir != "" && args.outputFmt == jsonOutputFormat { + return fmt.Errorf("-d cannot be used with format json") + } + if args.locals && args.outputFmt != tfOutputFormat { + return fmt.Errorf("--locals flag requires setting the output format to tf") + } + return nil +} From 49f4a474856d97a26d8e292c90b1ab56a0aa483c Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 30 Sep 2024 11:05:10 +0300 Subject: [PATCH 051/131] fixed --- cmd/subcmds/optimize.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmd/subcmds/optimize.go b/cmd/subcmds/optimize.go index 483d3705..c346e15b 100644 --- a/cmd/subcmds/optimize.go +++ b/cmd/subcmds/optimize.go @@ -23,9 +23,6 @@ func NewOptimizeCommand(args *inArgs) *cobra.Command { // flags cmd.PersistentFlags().StringVarP(&args.firewallName, firewallNameFlag, "n", "", "which vpcFirewall to optimize") - // flags settings - _ = cmd.MarkPersistentFlagRequired(firewallNameFlag) // temporary - // sub cmds cmd.AddCommand(NewOptimizeSGCommand(args)) From 766f737583eb1974e907e66c9401e9a91666fb77 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 30 Sep 2024 11:14:52 +0300 Subject: [PATCH 052/131] fix output fmts --- pkg/io/csvio/sg.go | 18 +++++++++++------- pkg/io/mdio/sg.go | 18 +++++++++++------- pkg/io/tfio/sg.go | 8 ++++---- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/pkg/io/csvio/sg.go b/pkg/io/csvio/sg.go index ed91a1ef..35c74f8b 100644 --- a/pkg/io/csvio/sg.go +++ b/pkg/io/csvio/sg.go @@ -20,14 +20,18 @@ func (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { if err := w.w.WriteAll(sgHeader()); err != nil { return err } - for _, sgName := range collection.SortedSGNames(vpc) { - vpcName := ir.VpcFromScopedResource(string(sgName)) - sgTable, err := makeSGTable(collection.SGs[vpcName][sgName], sgName) - if err != nil { - return err + for _, vpcName := range collection.VpcNames() { + if vpc != vpcName && vpc != "" { + continue } - if err := w.w.WriteAll(sgTable); err != nil { - return err + for _, sgName := range collection.SortedSGNames(vpcName) { + sgTable, err := makeSGTable(collection.SGs[vpcName][sgName], sgName) + if err != nil { + return err + } + if err := w.w.WriteAll(sgTable); err != nil { + return err + } } } return nil diff --git a/pkg/io/mdio/sg.go b/pkg/io/mdio/sg.go index 3277b3fa..0fcbf734 100644 --- a/pkg/io/mdio/sg.go +++ b/pkg/io/mdio/sg.go @@ -20,14 +20,18 @@ func (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { if err := w.writeAll(sgHeader()); err != nil { return err } - for _, sgName := range collection.SortedSGNames(vpc) { - vpcName := ir.VpcFromScopedResource(string(sgName)) - sgTable, err := makeSGTable(collection.SGs[vpcName][sgName], sgName) - if err != nil { - return err + for _, vpcName := range collection.VpcNames() { + if vpc != vpcName && vpc != "" { + continue } - if err := w.writeAll(sgTable); err != nil { - return err + for _, sgName := range collection.SortedSGNames(vpcName) { + sgTable, err := makeSGTable(collection.SGs[vpcName][sgName], sgName) + if err != nil { + return err + } + if err := w.writeAll(sgTable); err != nil { + return err + } } } return nil diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 88389dc0..793c5c7a 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -111,15 +111,15 @@ func sg(sgName, vpcName string) (tf.Block, error) { }, nil } -func sgCollection(t *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { +func sgCollection(collection *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { var resources []tf.Block - for _, vpcName := range t.VpcNames() { + for _, vpcName := range collection.VpcNames() { if vpc != vpcName && vpc != "" { continue } - for _, sgName := range t.SortedSGNames(vpcName) { - rules := t.SGs[vpcName][sgName].AllRules() + for _, sgName := range collection.SortedSGNames(vpcName) { + rules := collection.SGs[vpcName][sgName].AllRules() sg, err := sg(sgName.String(), vpcName) if err != nil { return nil, err From e6bb1b3c5df15bc26291e4b56c91c7dea3848c43 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 30 Sep 2024 11:44:54 +0300 Subject: [PATCH 053/131] tests template --- .../{synth_test_list.go => main_test_list.go} | 7 +++++- test/tests_defs.go | 24 +++++++++++-------- 2 files changed, 20 insertions(+), 11 deletions(-) rename test/{synth_test_list.go => main_test_list.go} (96%) diff --git a/test/synth_test_list.go b/test/main_test_list.go similarity index 96% rename from test/synth_test_list.go rename to test/main_test_list.go index d8e37147..57e61c77 100644 --- a/test/synth_test_list.go +++ b/test/main_test_list.go @@ -37,7 +37,7 @@ const ( ) func allMainTests() []testCase { - return append(synthACLTestsList(), synthSGTestsList()...) + return append(synthACLTestsList(), append(synthSGTestsList(), optimizeSGTestsLists()...)...) } //nolint:funlen //all acl synthesis tests @@ -310,3 +310,8 @@ func synthSGTestsList() []testCase { }, } } + +// Note: spec files in data folder are used to create the config object files (acl_testing4 config) +func optimizeSGTestsLists() []testCase { + return []testCase{} +} diff --git a/test/tests_defs.go b/test/tests_defs.go index 08668069..e5a32ebd 100644 --- a/test/tests_defs.go +++ b/test/tests_defs.go @@ -14,16 +14,17 @@ type testCase struct { } type command struct { - cmd string - subcmd string - singleacl bool - config string - spec string - outputFile string - outputDir string - prefix string - format string - locals bool + cmd string + subcmd string + singleacl bool + config string + spec string + outputFile string + outputDir string + prefix string + format string + locals bool + firewallName string } const ( @@ -72,6 +73,9 @@ func (c *command) Args(dataFolder, resultsFolder string) []string { if c.locals { res = append(res, "-l") } + if c.firewallName != "" { + res = append(res, "-n", c.firewallName) + } return res } From 34410edc6a2e4b8407d306a20ebc1eaae97ae969 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 30 Sep 2024 13:32:47 +0300 Subject: [PATCH 054/131] tests data --- .../optimize_sg_icmp_codes/config_object.json | 2169 ++++++++++++++ .../optimize_sg_icmp_codes/conn_spec.json | 143 + test/data/optimize_sg_icmp_codes/details.txt | 14 + .../optimize_sg_icmp_types/config_object.json | 2493 +++++++++++++++++ .../optimize_sg_icmp_types/conn_spec.json | 359 +++ test/data/optimize_sg_icmp_types/details.txt | 28 + .../config_object.json | 2214 +++++++++++++++ .../conn_spec.json | 169 ++ .../optimize_sg_protocols_to_all/details.txt | 16 + .../optimize_sg_redundant/config_object.json | 2023 +++++++++++++ .../data/optimize_sg_redundant/conn_spec.json | 48 + test/data/optimize_sg_redundant/details.txt | 10 + test/data/optimize_sg_t/config_object.json | 2009 +++++++++++++ test/data/optimize_sg_t/conn_spec.json | 60 + test/data/optimize_sg_t/details.txt | 8 + .../data/optimize_sg_t_all/config_object.json | 2007 +++++++++++++ test/data/optimize_sg_t_all/conn_spec.json | 53 + test/data/optimize_sg_t_all/details.txt | 8 + test/main_test_list.go | 89 +- test/tests_defs.go | 7 +- 20 files changed, 13922 insertions(+), 5 deletions(-) create mode 100644 test/data/optimize_sg_icmp_codes/config_object.json create mode 100644 test/data/optimize_sg_icmp_codes/conn_spec.json create mode 100644 test/data/optimize_sg_icmp_codes/details.txt create mode 100644 test/data/optimize_sg_icmp_types/config_object.json create mode 100644 test/data/optimize_sg_icmp_types/conn_spec.json create mode 100644 test/data/optimize_sg_icmp_types/details.txt create mode 100644 test/data/optimize_sg_protocols_to_all/config_object.json create mode 100644 test/data/optimize_sg_protocols_to_all/conn_spec.json create mode 100644 test/data/optimize_sg_protocols_to_all/details.txt create mode 100644 test/data/optimize_sg_redundant/config_object.json create mode 100644 test/data/optimize_sg_redundant/conn_spec.json create mode 100644 test/data/optimize_sg_redundant/details.txt create mode 100644 test/data/optimize_sg_t/config_object.json create mode 100644 test/data/optimize_sg_t/conn_spec.json create mode 100644 test/data/optimize_sg_t/details.txt create mode 100644 test/data/optimize_sg_t_all/config_object.json create mode 100644 test/data/optimize_sg_t_all/conn_spec.json create mode 100644 test/data/optimize_sg_t_all/details.txt diff --git a/test/data/optimize_sg_icmp_codes/config_object.json b/test/data/optimize_sg_icmp_codes/config_object.json new file mode 100644 index 00000000..d059fc05 --- /dev/null +++ b/test/data/optimize_sg_icmp_codes/config_object.json @@ -0,0 +1,2169 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.22.217.112" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.12.160.153" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.16.253.223" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail" + }, + "default_routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "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": "test-vpc1", + "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-09-09T09:09:50.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": true, + "name": "filling-tasty-bacterium-parlor", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.64.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:20", + "id": "id:21", + "is_default": true, + "name": "relearn-ragweed-goon-feisty", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.128.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:22", + "id": "id:23", + "is_default": true, + "name": "unruffled-penknife-snowshoe-ninetieth", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:51.000Z", + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.20.0/24", + "name": "subnet2", + "network_acl": { + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.20.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:33", + "id": "id:34", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:35", + "id": "id:36", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:37", + "id": "id:38", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:39", + "id": "id:40", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.4", + "auto_delete": true, + "created_at": "2024-09-09T09:11:08.000Z", + "href": "href:41", + "id": "id:42", + "lifecycle_state": "stable", + "name": "startle-percent-embellish-squeegee", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.20.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:45", + "id": "id:46", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.10.0/24", + "name": "subnet1", + "network_acl": { + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.10.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:53", + "id": "id:54", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:55", + "id": "id:56", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:57", + "id": "id:58", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:59", + "id": "id:60", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:52.000Z", + "href": "href:61", + "id": "id:62", + "lifecycle_state": "stable", + "name": "tableware-sprawl-shrivel-popper", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.10.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:65", + "id": "id:66", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-09-09T09:10:18.000Z", + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.30.0/24", + "name": "subnet3", + "network_acl": { + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.30.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:73", + "id": "id:74", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:75", + "id": "id:76", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:77", + "id": "id:78", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:79", + "id": "id:80", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:81", + "id": "id:82", + "lifecycle_state": "stable", + "name": "disallow-oxidant-etching-selection", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.5", + "auto_delete": true, + "created_at": "2024-09-09T09:10:36.000Z", + "href": "href:85", + "id": "id:86", + "lifecycle_state": "stable", + "name": "reheat-joyride-little-overprice", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:89", + "id": "id:90", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + } + ], + "public_gateways": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:30", + "floating_ip": { + "address": "52.118.147.142", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1" + }, + "href": "href:31", + "id": "id:32", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "floating_ips": [ + { + "address": "52.116.129.168", + "created_at": "2024-09-09T09:11:31.000Z", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + }, + { + "address": "52.118.147.142", + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway", + "crn": "crn:30" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": "2024-09-09T09:10:15.000Z", + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:99", + "id": "id:100", + "name": "acl2-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:97", + "id": "id:98", + "ip_version": "ipv4", + "name": "acl2-out-1", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:101", + "id": "id:102", + "name": "acl2-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:99", + "id": "id:100", + "ip_version": "ipv4", + "name": "acl2-out-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:103", + "id": "id:104", + "name": "acl2-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:101", + "id": "id:102", + "ip_version": "ipv4", + "name": "acl2-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:103", + "id": "id:104", + "ip_version": "ipv4", + "name": "acl2-in-2", + "source": "10.240.10.0/24", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:107", + "id": "id:108", + "name": "acl1-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "172.217.22.46/32", + "direction": "outbound", + "href": "href:105", + "id": "id:106", + "ip_version": "ipv4", + "name": "acl1-out-1", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:109", + "id": "id:110", + "name": "acl1-out-3" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "outbound", + "href": "href:107", + "id": "id:108", + "ip_version": "ipv4", + "name": "acl1-out-2", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:111", + "id": "id:112", + "name": "acl1-out-4" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:109", + "id": "id:110", + "ip_version": "ipv4", + "name": "acl1-out-3", + "source": "10.240.10.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:113", + "id": "id:114", + "name": "acl1-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:111", + "id": "id:112", + "ip_version": "ipv4", + "name": "acl1-out-4", + "source": "10.240.10.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:115", + "id": "id:116", + "name": "acl1-in-2" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:113", + "id": "id:114", + "ip_version": "ipv4", + "name": "acl1-in-1", + "source": "172.217.22.46/32", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:117", + "id": "id:118", + "name": "acl1-in-3" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:115", + "id": "id:116", + "ip_version": "ipv4", + "name": "acl1-in-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:119", + "id": "id:120", + "name": "acl1-in-4" + }, + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:117", + "id": "id:118", + "ip_version": "ipv4", + "name": "acl1-in-3", + "source": "10.240.30.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:119", + "id": "id:120", + "ip_version": "ipv4", + "name": "acl1-in-4", + "source": "10.240.30.0/24", + "destination_port_max": 443, + "destination_port_min": 443, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + } + ], + "subnets": [ + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:123", + "id": "id:124", + "name": "acl3-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:121", + "id": "id:122", + "ip_version": "ipv4", + "name": "acl3-out-1", + "source": "10.240.30.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:125", + "id": "id:126", + "name": "acl3-in-1" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:123", + "id": "id:124", + "ip_version": "ipv4", + "name": "acl3-out-2", + "source": "10.240.30.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:127", + "id": "id:128", + "name": "acl3-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:125", + "id": "id:126", + "ip_version": "ipv4", + "name": "acl3-in-1", + "source": "10.240.10.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-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:127", + "id": "id:128", + "ip_version": "ipv4", + "name": "acl3-in-2", + "source": "10.240.10.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + } + ], + "subnets": [ + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:131", + "id": "id:132", + "name": "allow-outbound" + }, + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:129", + "id": "id:130", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:131", + "id": "id:132", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:133", + "href": "href:134", + "id": "id:135", + "name": "sg1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:136", + "id": "id:137", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "href:138", + "id": "id:139", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:140", + "id": "id:141", + "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:142", + "id": "id:143", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:6", + "href": "fake:href:6", + "id": "fake:id:6", + "name": "test-vpc1--vsi2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "fake:href:1", + "id": "fake:id:1", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "code": 0, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "inbound", + "href": "fake:href:3", + "id": "fake:id:3", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "code": 1, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "inbound", + "href": "fake:href:4", + "id": "fake:id:4", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "code": 2, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "inbound", + "href": "fake:href:5", + "id": "fake:id:5", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "code": 3, + "protocol": "icmp", + "type": 5 + } + ], + "targets": [ + { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "fake:href:7", + "id": "fake:id:7", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "code": 0, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "outbound", + "href": "fake:href:8", + "id": "fake:id:8", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "code": 1, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "outbound", + "href": "fake:href:9", + "id": "fake:id:9", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "code": 2, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "outbound", + "href": "fake:href:10", + "id": "fake:id:10", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "code": 3, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "outbound", + "href": "fake:href:11", + "id": "fake:id:11", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:6", + "href": "fake:href:6", + "id": "fake:id:6", + "name": "test-vpc1--vsi2" + }, + "code": 0, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "outbound", + "href": "fake:href:12", + "id": "fake:id:12", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:6", + "href": "fake:href:6", + "id": "fake:id:6", + "name": "test-vpc1--vsi2" + }, + "code": 1, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "outbound", + "href": "fake:href:13", + "id": "fake:id:13", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:6", + "href": "fake:href:6", + "id": "fake:id:6", + "name": "test-vpc1--vsi2" + }, + "code": 2, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "outbound", + "href": "fake:href:14", + "id": "fake:id:14", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:6", + "href": "fake:href:6", + "id": "fake:id:6", + "name": "test-vpc1--vsi2" + }, + "code": 3, + "protocol": "icmp", + "type": 5 + } + ], + "targets": [ + { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:15", + "href": "fake:href:15", + "id": "fake:id:15", + "name": "test-vpc1--vsi3b", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:16", + "href": "fake:href:16", + "id": "fake:id:16", + "name": "test-vpc1--vsi3a", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [], + "instances": [ + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:11:07.000Z", + "crn": "crn:144", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:145", + "id": "id:146", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi2", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:11:07.000Z", + "floating_ips": [], + "href": "href:43", + "id": "id:44", + "name": "ni2", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:6", + "href": "fake:href:6", + "id": "fake:id:6", + "name": "test-vpc1--vsi2" + } + ], + "status": "available", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:52.000Z", + "crn": "crn:157", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:158", + "id": "id:159", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:52.000Z", + "floating_ips": [ + { + "address": "52.116.129.168", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip" + } + ], + "href": "href:63", + "id": "id:64", + "name": "ni1", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:166", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:167", + "id": "id:168", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3b", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:15", + "href": "fake:href:15", + "id": "fake:id:15", + "name": "test-vpc1--vsi3b" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:34.000Z", + "crn": "crn:175", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:176", + "id": "id:177", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3a", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:16", + "href": "fake:href:16", + "id": "fake:id:16", + "name": "test-vpc1--vsi3a" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + } + ], + "virtual_nis": null, + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-09-09T09:09:51.000Z", + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "fiscally-fresh-uncanny-ceramics", + "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": "subnet2", + "resource_type": "subnet" + }, + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "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_sg_icmp_codes/conn_spec.json b/test/data/optimize_sg_icmp_codes/conn_spec.json new file mode 100644 index 00000000..83342736 --- /dev/null +++ b/test/data/optimize_sg_icmp_codes/conn_spec.json @@ -0,0 +1,143 @@ +{ + "externals": { + "e1": "0.0.0.0/31" + }, + "required-connections": [ + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 5, + "code": 0 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 5, + "code": 1 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 5, + "code": 2 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 5, + "code": 3 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 5, + "code": 0 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 5, + "code": 1 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 5, + "code": 2 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 5, + "code": 3 + } + ] + } + ] +} diff --git a/test/data/optimize_sg_icmp_codes/details.txt b/test/data/optimize_sg_icmp_codes/details.txt new file mode 100644 index 00000000..ac439dbe --- /dev/null +++ b/test/data/optimize_sg_icmp_codes/details.txt @@ -0,0 +1,14 @@ +vsi1 --> 0.0.0.0/31 (icmp type:5 code:0) +vsi1 --> 0.0.0.0/31 (icmp type:5 code:1) +vsi1 --> 0.0.0.0/31 (icmp type:5 code:2) +vsi1 --> 0.0.0.0/31 (icmp type:5 code:3) + +vsi1 --> vsi2 (icmp type:5 code:0) +vsi1 --> vsi2 (icmp type:5 code:1) +vsi1 --> vsi2 (icmp type:5 code:2) +vsi1 --> vsi2 (icmp type:5 code:3) + +==================================== + +vsi1 --> 0.0.0.0/31 (icmp type:5) +vsi1 --> vsi2 (icmp type:5) \ No newline at end of file diff --git a/test/data/optimize_sg_icmp_types/config_object.json b/test/data/optimize_sg_icmp_types/config_object.json new file mode 100644 index 00000000..0511af0e --- /dev/null +++ b/test/data/optimize_sg_icmp_types/config_object.json @@ -0,0 +1,2493 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.22.217.112" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.12.160.153" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.16.253.223" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail" + }, + "default_routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "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": "test-vpc1", + "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-09-09T09:09:50.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": true, + "name": "filling-tasty-bacterium-parlor", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.64.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:20", + "id": "id:21", + "is_default": true, + "name": "relearn-ragweed-goon-feisty", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.128.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:22", + "id": "id:23", + "is_default": true, + "name": "unruffled-penknife-snowshoe-ninetieth", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:51.000Z", + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.20.0/24", + "name": "subnet2", + "network_acl": { + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.20.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:33", + "id": "id:34", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:35", + "id": "id:36", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:37", + "id": "id:38", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:39", + "id": "id:40", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.4", + "auto_delete": true, + "created_at": "2024-09-09T09:11:08.000Z", + "href": "href:41", + "id": "id:42", + "lifecycle_state": "stable", + "name": "startle-percent-embellish-squeegee", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.20.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:45", + "id": "id:46", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.10.0/24", + "name": "subnet1", + "network_acl": { + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.10.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:53", + "id": "id:54", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:55", + "id": "id:56", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:57", + "id": "id:58", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:59", + "id": "id:60", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:52.000Z", + "href": "href:61", + "id": "id:62", + "lifecycle_state": "stable", + "name": "tableware-sprawl-shrivel-popper", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.10.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:65", + "id": "id:66", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-09-09T09:10:18.000Z", + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.30.0/24", + "name": "subnet3", + "network_acl": { + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.30.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:73", + "id": "id:74", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:75", + "id": "id:76", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:77", + "id": "id:78", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:79", + "id": "id:80", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:81", + "id": "id:82", + "lifecycle_state": "stable", + "name": "disallow-oxidant-etching-selection", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.5", + "auto_delete": true, + "created_at": "2024-09-09T09:10:36.000Z", + "href": "href:85", + "id": "id:86", + "lifecycle_state": "stable", + "name": "reheat-joyride-little-overprice", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:89", + "id": "id:90", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + } + ], + "public_gateways": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:30", + "floating_ip": { + "address": "52.118.147.142", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1" + }, + "href": "href:31", + "id": "id:32", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "floating_ips": [ + { + "address": "52.116.129.168", + "created_at": "2024-09-09T09:11:31.000Z", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + }, + { + "address": "52.118.147.142", + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway", + "crn": "crn:30" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": "2024-09-09T09:10:15.000Z", + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:99", + "id": "id:100", + "name": "acl2-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:97", + "id": "id:98", + "ip_version": "ipv4", + "name": "acl2-out-1", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:101", + "id": "id:102", + "name": "acl2-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:99", + "id": "id:100", + "ip_version": "ipv4", + "name": "acl2-out-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:103", + "id": "id:104", + "name": "acl2-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:101", + "id": "id:102", + "ip_version": "ipv4", + "name": "acl2-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:103", + "id": "id:104", + "ip_version": "ipv4", + "name": "acl2-in-2", + "source": "10.240.10.0/24", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:107", + "id": "id:108", + "name": "acl1-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "172.217.22.46/32", + "direction": "outbound", + "href": "href:105", + "id": "id:106", + "ip_version": "ipv4", + "name": "acl1-out-1", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:109", + "id": "id:110", + "name": "acl1-out-3" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "outbound", + "href": "href:107", + "id": "id:108", + "ip_version": "ipv4", + "name": "acl1-out-2", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:111", + "id": "id:112", + "name": "acl1-out-4" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:109", + "id": "id:110", + "ip_version": "ipv4", + "name": "acl1-out-3", + "source": "10.240.10.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:113", + "id": "id:114", + "name": "acl1-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:111", + "id": "id:112", + "ip_version": "ipv4", + "name": "acl1-out-4", + "source": "10.240.10.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:115", + "id": "id:116", + "name": "acl1-in-2" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:113", + "id": "id:114", + "ip_version": "ipv4", + "name": "acl1-in-1", + "source": "172.217.22.46/32", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:117", + "id": "id:118", + "name": "acl1-in-3" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:115", + "id": "id:116", + "ip_version": "ipv4", + "name": "acl1-in-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:119", + "id": "id:120", + "name": "acl1-in-4" + }, + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:117", + "id": "id:118", + "ip_version": "ipv4", + "name": "acl1-in-3", + "source": "10.240.30.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:119", + "id": "id:120", + "ip_version": "ipv4", + "name": "acl1-in-4", + "source": "10.240.30.0/24", + "destination_port_max": 443, + "destination_port_min": 443, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + } + ], + "subnets": [ + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:123", + "id": "id:124", + "name": "acl3-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:121", + "id": "id:122", + "ip_version": "ipv4", + "name": "acl3-out-1", + "source": "10.240.30.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:125", + "id": "id:126", + "name": "acl3-in-1" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:123", + "id": "id:124", + "ip_version": "ipv4", + "name": "acl3-out-2", + "source": "10.240.30.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:127", + "id": "id:128", + "name": "acl3-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:125", + "id": "id:126", + "ip_version": "ipv4", + "name": "acl3-in-1", + "source": "10.240.10.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-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:127", + "id": "id:128", + "ip_version": "ipv4", + "name": "acl3-in-2", + "source": "10.240.10.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + } + ], + "subnets": [ + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:131", + "id": "id:132", + "name": "allow-outbound" + }, + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:129", + "id": "id:130", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:131", + "id": "id:132", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:133", + "href": "href:134", + "id": "id:135", + "name": "sg1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:136", + "id": "id:137", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "href:138", + "id": "id:139", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:140", + "id": "id:141", + "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:142", + "id": "id:143", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "fake:href:1", + "id": "fake:id:1", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 0 + }, + { + "direction": "inbound", + "href": "fake:href:3", + "id": "fake:id:3", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 3 + }, + { + "direction": "inbound", + "href": "fake:href:4", + "id": "fake:id:4", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 4 + }, + { + "direction": "inbound", + "href": "fake:href:5", + "id": "fake:id:5", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "inbound", + "href": "fake:href:6", + "id": "fake:id:6", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 8 + }, + { + "direction": "inbound", + "href": "fake:href:7", + "id": "fake:id:7", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 11 + }, + { + "direction": "inbound", + "href": "fake:href:8", + "id": "fake:id:8", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 12 + }, + { + "direction": "inbound", + "href": "fake:href:9", + "id": "fake:id:9", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 13 + }, + { + "direction": "inbound", + "href": "fake:href:10", + "id": "fake:id:10", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 14 + }, + { + "direction": "inbound", + "href": "fake:href:11", + "id": "fake:id:11", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 15 + }, + { + "direction": "inbound", + "href": "fake:href:12", + "id": "fake:id:12", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp", + "type": 16 + } + ], + "targets": [ + { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "fake:href:14", + "id": "fake:id:14", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 0 + }, + { + "direction": "outbound", + "href": "fake:href:15", + "id": "fake:id:15", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 3 + }, + { + "direction": "outbound", + "href": "fake:href:16", + "id": "fake:id:16", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 4 + }, + { + "direction": "outbound", + "href": "fake:href:17", + "id": "fake:id:17", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "outbound", + "href": "fake:href:18", + "id": "fake:id:18", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 8 + }, + { + "direction": "outbound", + "href": "fake:href:19", + "id": "fake:id:19", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 11 + }, + { + "direction": "outbound", + "href": "fake:href:20", + "id": "fake:id:20", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 12 + }, + { + "direction": "outbound", + "href": "fake:href:21", + "id": "fake:id:21", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 13 + }, + { + "direction": "outbound", + "href": "fake:href:22", + "id": "fake:id:22", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 14 + }, + { + "direction": "outbound", + "href": "fake:href:23", + "id": "fake:id:23", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 15 + }, + { + "direction": "outbound", + "href": "fake:href:24", + "id": "fake:id:24", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp", + "type": 16 + }, + { + "direction": "outbound", + "href": "fake:href:25", + "id": "fake:id:25", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 0 + }, + { + "direction": "outbound", + "href": "fake:href:26", + "id": "fake:id:26", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 3 + }, + { + "direction": "outbound", + "href": "fake:href:27", + "id": "fake:id:27", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 4 + }, + { + "direction": "outbound", + "href": "fake:href:28", + "id": "fake:id:28", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 5 + }, + { + "direction": "outbound", + "href": "fake:href:29", + "id": "fake:id:29", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 8 + }, + { + "direction": "outbound", + "href": "fake:href:30", + "id": "fake:id:30", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 11 + }, + { + "direction": "outbound", + "href": "fake:href:31", + "id": "fake:id:31", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 12 + }, + { + "direction": "outbound", + "href": "fake:href:32", + "id": "fake:id:32", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 13 + }, + { + "direction": "outbound", + "href": "fake:href:33", + "id": "fake:id:33", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 14 + }, + { + "direction": "outbound", + "href": "fake:href:34", + "id": "fake:id:34", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 15 + }, + { + "direction": "outbound", + "href": "fake:href:35", + "id": "fake:id:35", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp", + "type": 16 + } + ], + "targets": [ + { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:36", + "href": "fake:href:36", + "id": "fake:id:36", + "name": "test-vpc1--vsi3b", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:37", + "href": "fake:href:37", + "id": "fake:id:37", + "name": "test-vpc1--vsi3a", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [], + "instances": [ + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:11:07.000Z", + "crn": "crn:144", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:145", + "id": "id:146", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi2", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:11:07.000Z", + "floating_ips": [], + "href": "href:43", + "id": "id:44", + "name": "ni2", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:13", + "href": "fake:href:13", + "id": "fake:id:13", + "name": "test-vpc1--vsi2" + } + ], + "status": "available", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:52.000Z", + "crn": "crn:157", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:158", + "id": "id:159", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:52.000Z", + "floating_ips": [ + { + "address": "52.116.129.168", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip" + } + ], + "href": "href:63", + "id": "id:64", + "name": "ni1", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:166", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:167", + "id": "id:168", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3b", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:36", + "href": "fake:href:36", + "id": "fake:id:36", + "name": "test-vpc1--vsi3b" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:34.000Z", + "crn": "crn:175", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:176", + "id": "id:177", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3a", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:37", + "href": "fake:href:37", + "id": "fake:id:37", + "name": "test-vpc1--vsi3a" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + } + ], + "virtual_nis": null, + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-09-09T09:09:51.000Z", + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "fiscally-fresh-uncanny-ceramics", + "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": "subnet2", + "resource_type": "subnet" + }, + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "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_sg_icmp_types/conn_spec.json b/test/data/optimize_sg_icmp_types/conn_spec.json new file mode 100644 index 00000000..f9c8648c --- /dev/null +++ b/test/data/optimize_sg_icmp_types/conn_spec.json @@ -0,0 +1,359 @@ +{ + "externals": { + "e1": "0.0.0.0/31" + }, + "required-connections": [ + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 0 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 3 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 4 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 5 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 8 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 11 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 12 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 13 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 14 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 15 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 16 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 0 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 3 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 4 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 5 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 8 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 11 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 12 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 13 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 14 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 15 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP", + "type": 16 + } + ] + } + ] +} diff --git a/test/data/optimize_sg_icmp_types/details.txt b/test/data/optimize_sg_icmp_types/details.txt new file mode 100644 index 00000000..c13db0ec --- /dev/null +++ b/test/data/optimize_sg_icmp_types/details.txt @@ -0,0 +1,28 @@ +vsi1 --> 0.0.0.0/31 (icmp type:0) +vsi1 --> 0.0.0.0/31 (icmp type:3) +vsi1 --> 0.0.0.0/31 (icmp type:4) +vsi1 --> 0.0.0.0/31 (icmp type:5) +vsi1 --> 0.0.0.0/31 (icmp type:8) +vsi1 --> 0.0.0.0/31 (icmp type:11) +vsi1 --> 0.0.0.0/31 (icmp type:12) +vsi1 --> 0.0.0.0/31 (icmp type:13) +vsi1 --> 0.0.0.0/31 (icmp type:14) +vsi1 --> 0.0.0.0/31 (icmp type:15) +vsi1 --> 0.0.0.0/31 (icmp type:16) + +vsi1 --> vsi2 (icmp type:0) +vsi1 --> vsi2 (icmp type:3) +vsi1 --> vsi2 (icmp type:4) +vsi1 --> vsi2 (icmp type:5) +vsi1 --> vsi2 (icmp type:8) +vsi1 --> vsi2 (icmp type:11) +vsi1 --> vsi2 (icmp type:12) +vsi1 --> vsi2 (icmp type:13) +vsi1 --> vsi2 (icmp type:14) +vsi1 --> vsi2 (icmp type:15) +vsi1 --> vsi2 (icmp type:16) + +==================================== + +vsi1 --> 0.0.0.0/31 (icmp) +vsi1 --> vsi2 (icmp) \ No newline at end of file diff --git a/test/data/optimize_sg_protocols_to_all/config_object.json b/test/data/optimize_sg_protocols_to_all/config_object.json new file mode 100644 index 00000000..23a99429 --- /dev/null +++ b/test/data/optimize_sg_protocols_to_all/config_object.json @@ -0,0 +1,2214 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.22.217.112" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.12.160.153" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.16.253.223" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail" + }, + "default_routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "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": "test-vpc1", + "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-09-09T09:09:50.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": true, + "name": "filling-tasty-bacterium-parlor", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.64.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:20", + "id": "id:21", + "is_default": true, + "name": "relearn-ragweed-goon-feisty", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.128.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:22", + "id": "id:23", + "is_default": true, + "name": "unruffled-penknife-snowshoe-ninetieth", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:51.000Z", + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.20.0/24", + "name": "subnet2", + "network_acl": { + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.20.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:33", + "id": "id:34", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:35", + "id": "id:36", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:37", + "id": "id:38", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:39", + "id": "id:40", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.4", + "auto_delete": true, + "created_at": "2024-09-09T09:11:08.000Z", + "href": "href:41", + "id": "id:42", + "lifecycle_state": "stable", + "name": "startle-percent-embellish-squeegee", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.20.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:45", + "id": "id:46", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.10.0/24", + "name": "subnet1", + "network_acl": { + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.10.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:53", + "id": "id:54", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:55", + "id": "id:56", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:57", + "id": "id:58", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:59", + "id": "id:60", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:52.000Z", + "href": "href:61", + "id": "id:62", + "lifecycle_state": "stable", + "name": "tableware-sprawl-shrivel-popper", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.10.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:65", + "id": "id:66", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-09-09T09:10:18.000Z", + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.30.0/24", + "name": "subnet3", + "network_acl": { + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.30.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:73", + "id": "id:74", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:75", + "id": "id:76", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:77", + "id": "id:78", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:79", + "id": "id:80", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:81", + "id": "id:82", + "lifecycle_state": "stable", + "name": "disallow-oxidant-etching-selection", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.5", + "auto_delete": true, + "created_at": "2024-09-09T09:10:36.000Z", + "href": "href:85", + "id": "id:86", + "lifecycle_state": "stable", + "name": "reheat-joyride-little-overprice", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:89", + "id": "id:90", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + } + ], + "public_gateways": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:30", + "floating_ip": { + "address": "52.118.147.142", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1" + }, + "href": "href:31", + "id": "id:32", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "floating_ips": [ + { + "address": "52.116.129.168", + "created_at": "2024-09-09T09:11:31.000Z", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + }, + { + "address": "52.118.147.142", + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway", + "crn": "crn:30" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": "2024-09-09T09:10:15.000Z", + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:99", + "id": "id:100", + "name": "acl2-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:97", + "id": "id:98", + "ip_version": "ipv4", + "name": "acl2-out-1", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:101", + "id": "id:102", + "name": "acl2-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:99", + "id": "id:100", + "ip_version": "ipv4", + "name": "acl2-out-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:103", + "id": "id:104", + "name": "acl2-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:101", + "id": "id:102", + "ip_version": "ipv4", + "name": "acl2-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:103", + "id": "id:104", + "ip_version": "ipv4", + "name": "acl2-in-2", + "source": "10.240.10.0/24", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:107", + "id": "id:108", + "name": "acl1-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "172.217.22.46/32", + "direction": "outbound", + "href": "href:105", + "id": "id:106", + "ip_version": "ipv4", + "name": "acl1-out-1", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:109", + "id": "id:110", + "name": "acl1-out-3" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "outbound", + "href": "href:107", + "id": "id:108", + "ip_version": "ipv4", + "name": "acl1-out-2", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:111", + "id": "id:112", + "name": "acl1-out-4" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:109", + "id": "id:110", + "ip_version": "ipv4", + "name": "acl1-out-3", + "source": "10.240.10.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:113", + "id": "id:114", + "name": "acl1-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:111", + "id": "id:112", + "ip_version": "ipv4", + "name": "acl1-out-4", + "source": "10.240.10.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:115", + "id": "id:116", + "name": "acl1-in-2" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:113", + "id": "id:114", + "ip_version": "ipv4", + "name": "acl1-in-1", + "source": "172.217.22.46/32", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:117", + "id": "id:118", + "name": "acl1-in-3" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:115", + "id": "id:116", + "ip_version": "ipv4", + "name": "acl1-in-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:119", + "id": "id:120", + "name": "acl1-in-4" + }, + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:117", + "id": "id:118", + "ip_version": "ipv4", + "name": "acl1-in-3", + "source": "10.240.30.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:119", + "id": "id:120", + "ip_version": "ipv4", + "name": "acl1-in-4", + "source": "10.240.30.0/24", + "destination_port_max": 443, + "destination_port_min": 443, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + } + ], + "subnets": [ + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:123", + "id": "id:124", + "name": "acl3-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:121", + "id": "id:122", + "ip_version": "ipv4", + "name": "acl3-out-1", + "source": "10.240.30.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:125", + "id": "id:126", + "name": "acl3-in-1" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:123", + "id": "id:124", + "ip_version": "ipv4", + "name": "acl3-out-2", + "source": "10.240.30.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:127", + "id": "id:128", + "name": "acl3-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:125", + "id": "id:126", + "ip_version": "ipv4", + "name": "acl3-in-1", + "source": "10.240.10.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-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:127", + "id": "id:128", + "ip_version": "ipv4", + "name": "acl3-in-2", + "source": "10.240.10.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + } + ], + "subnets": [ + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:131", + "id": "id:132", + "name": "allow-outbound" + }, + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:129", + "id": "id:130", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:131", + "id": "id:132", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:133", + "href": "href:134", + "id": "id:135", + "name": "sg1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:136", + "id": "id:137", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "href:138", + "id": "id:139", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:140", + "id": "id:141", + "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:142", + "id": "id:143", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "fake:href:1", + "id": "fake:id:1", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "icmp" + }, + { + "direction": "inbound", + "href": "fake:href:3", + "id": "fake:id:3", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "inbound", + "href": "fake:href:4", + "id": "fake:id:4", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "port_max": 100, + "port_min": 1, + "protocol": "udp" + }, + { + "direction": "inbound", + "href": "fake:href:5", + "id": "fake:id:5", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "port_max": 150, + "port_min": 50, + "protocol": "udp" + }, + { + "direction": "inbound", + "href": "fake:href:6", + "id": "fake:id:6", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "port_max": 65535, + "port_min": 151, + "protocol": "udp" + } + ], + "targets": [ + { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "fake:href:8", + "id": "fake:id:8", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "icmp" + }, + { + "direction": "outbound", + "href": "fake:href:9", + "id": "fake:id:9", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "outbound", + "href": "fake:href:10", + "id": "fake:id:10", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "port_max": 100, + "port_min": 1, + "protocol": "udp" + }, + { + "direction": "outbound", + "href": "fake:href:11", + "id": "fake:id:11", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "port_max": 150, + "port_min": 50, + "protocol": "udp" + }, + { + "direction": "outbound", + "href": "fake:href:12", + "id": "fake:id:12", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "port_max": 65535, + "port_min": 151, + "protocol": "udp" + }, + { + "direction": "outbound", + "href": "fake:href:13", + "id": "fake:id:13", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi2" + }, + "protocol": "icmp" + }, + { + "direction": "outbound", + "href": "fake:href:14", + "id": "fake:id:14", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi2" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "outbound", + "href": "fake:href:15", + "id": "fake:id:15", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi2" + }, + "port_max": 100, + "port_min": 1, + "protocol": "udp" + }, + { + "direction": "outbound", + "href": "fake:href:16", + "id": "fake:id:16", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi2" + }, + "port_max": 150, + "port_min": 50, + "protocol": "udp" + }, + { + "direction": "outbound", + "href": "fake:href:17", + "id": "fake:id:17", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi2" + }, + "port_max": 65535, + "port_min": 151, + "protocol": "udp" + } + ], + "targets": [ + { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:18", + "href": "fake:href:18", + "id": "fake:id:18", + "name": "test-vpc1--vsi3b", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:19", + "href": "fake:href:19", + "id": "fake:id:19", + "name": "test-vpc1--vsi3a", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [], + "instances": [ + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:11:07.000Z", + "crn": "crn:144", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:145", + "id": "id:146", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi2", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:11:07.000Z", + "floating_ips": [], + "href": "href:43", + "id": "id:44", + "name": "ni2", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi2" + } + ], + "status": "available", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:52.000Z", + "crn": "crn:157", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:158", + "id": "id:159", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:52.000Z", + "floating_ips": [ + { + "address": "52.116.129.168", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip" + } + ], + "href": "href:63", + "id": "id:64", + "name": "ni1", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:166", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:167", + "id": "id:168", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3b", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:18", + "href": "fake:href:18", + "id": "fake:id:18", + "name": "test-vpc1--vsi3b" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:34.000Z", + "crn": "crn:175", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:176", + "id": "id:177", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3a", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:19", + "href": "fake:href:19", + "id": "fake:id:19", + "name": "test-vpc1--vsi3a" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + } + ], + "virtual_nis": null, + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-09-09T09:09:51.000Z", + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "fiscally-fresh-uncanny-ceramics", + "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": "subnet2", + "resource_type": "subnet" + }, + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "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_sg_protocols_to_all/conn_spec.json b/test/data/optimize_sg_protocols_to_all/conn_spec.json new file mode 100644 index 00000000..32a127fb --- /dev/null +++ b/test/data/optimize_sg_protocols_to_all/conn_spec.json @@ -0,0 +1,169 @@ +{ + "externals": { + "e1": "0.0.0.0/31" + }, + "required-connections": [ + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "ICMP" + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "TCP" + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "UDP", + "min_destination_port": 1, + "max_destination_port": 100 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "UDP", + "min_destination_port": 50, + "max_destination_port": 150 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "UDP", + "min_destination_port": 151, + "max_destination_port": 65535 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "ICMP" + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "TCP" + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "UDP", + "min_destination_port": 1, + "max_destination_port": 100 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "UDP", + "min_destination_port": 50, + "max_destination_port": 150 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "UDP", + "min_destination_port": 151, + "max_destination_port": 65535 + } + ] + } + ] +} diff --git a/test/data/optimize_sg_protocols_to_all/details.txt b/test/data/optimize_sg_protocols_to_all/details.txt new file mode 100644 index 00000000..ca29dc0f --- /dev/null +++ b/test/data/optimize_sg_protocols_to_all/details.txt @@ -0,0 +1,16 @@ +vsi1 --> 0.0.0.0/31 (icmp) +vsi1 --> 0.0.0.0/31 (tcp) +vsi1 --> 0.0.0.0/31 (udp ports 1-100) +vsi1 --> 0.0.0.0/31 (udp ports 50-150) +vsi1 --> 0.0.0.0/31 (udp ports 151-65535) + +vsi1 --> vsi2 (icmp) +vsi1 --> vsi2 (tcp) +vsi1 --> vsi2 (udp ports 1-100) +vsi1 --> vsi2 (udp ports 50-150) +vsi1 --> vsi2 (udp ports 151-65535) + +==================================== + +vsi1 --> 0.0.0.0/31 (all protocol) +vsi1 --> vsi2 (all protocol) \ No newline at end of file diff --git a/test/data/optimize_sg_redundant/config_object.json b/test/data/optimize_sg_redundant/config_object.json new file mode 100644 index 00000000..e9dd5c87 --- /dev/null +++ b/test/data/optimize_sg_redundant/config_object.json @@ -0,0 +1,2023 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.22.217.112" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.12.160.153" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.16.253.223" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail" + }, + "default_routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "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": "test-vpc1", + "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-09-09T09:09:50.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": true, + "name": "filling-tasty-bacterium-parlor", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.64.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:20", + "id": "id:21", + "is_default": true, + "name": "relearn-ragweed-goon-feisty", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.128.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:22", + "id": "id:23", + "is_default": true, + "name": "unruffled-penknife-snowshoe-ninetieth", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:51.000Z", + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.20.0/24", + "name": "subnet2", + "network_acl": { + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.20.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:33", + "id": "id:34", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:35", + "id": "id:36", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:37", + "id": "id:38", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:39", + "id": "id:40", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.4", + "auto_delete": true, + "created_at": "2024-09-09T09:11:08.000Z", + "href": "href:41", + "id": "id:42", + "lifecycle_state": "stable", + "name": "startle-percent-embellish-squeegee", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.20.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:45", + "id": "id:46", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.10.0/24", + "name": "subnet1", + "network_acl": { + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.10.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:53", + "id": "id:54", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:55", + "id": "id:56", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:57", + "id": "id:58", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:59", + "id": "id:60", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:52.000Z", + "href": "href:61", + "id": "id:62", + "lifecycle_state": "stable", + "name": "tableware-sprawl-shrivel-popper", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.10.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:65", + "id": "id:66", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-09-09T09:10:18.000Z", + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.30.0/24", + "name": "subnet3", + "network_acl": { + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.30.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:73", + "id": "id:74", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:75", + "id": "id:76", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:77", + "id": "id:78", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:79", + "id": "id:80", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:81", + "id": "id:82", + "lifecycle_state": "stable", + "name": "disallow-oxidant-etching-selection", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.5", + "auto_delete": true, + "created_at": "2024-09-09T09:10:36.000Z", + "href": "href:85", + "id": "id:86", + "lifecycle_state": "stable", + "name": "reheat-joyride-little-overprice", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:89", + "id": "id:90", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + } + ], + "public_gateways": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:30", + "floating_ip": { + "address": "52.118.147.142", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1" + }, + "href": "href:31", + "id": "id:32", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "floating_ips": [ + { + "address": "52.116.129.168", + "created_at": "2024-09-09T09:11:31.000Z", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + }, + { + "address": "52.118.147.142", + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway", + "crn": "crn:30" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": "2024-09-09T09:10:15.000Z", + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:99", + "id": "id:100", + "name": "acl2-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:97", + "id": "id:98", + "ip_version": "ipv4", + "name": "acl2-out-1", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:101", + "id": "id:102", + "name": "acl2-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:99", + "id": "id:100", + "ip_version": "ipv4", + "name": "acl2-out-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:103", + "id": "id:104", + "name": "acl2-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:101", + "id": "id:102", + "ip_version": "ipv4", + "name": "acl2-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:103", + "id": "id:104", + "ip_version": "ipv4", + "name": "acl2-in-2", + "source": "10.240.10.0/24", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:107", + "id": "id:108", + "name": "acl1-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "172.217.22.46/32", + "direction": "outbound", + "href": "href:105", + "id": "id:106", + "ip_version": "ipv4", + "name": "acl1-out-1", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:109", + "id": "id:110", + "name": "acl1-out-3" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "outbound", + "href": "href:107", + "id": "id:108", + "ip_version": "ipv4", + "name": "acl1-out-2", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:111", + "id": "id:112", + "name": "acl1-out-4" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:109", + "id": "id:110", + "ip_version": "ipv4", + "name": "acl1-out-3", + "source": "10.240.10.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:113", + "id": "id:114", + "name": "acl1-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:111", + "id": "id:112", + "ip_version": "ipv4", + "name": "acl1-out-4", + "source": "10.240.10.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:115", + "id": "id:116", + "name": "acl1-in-2" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:113", + "id": "id:114", + "ip_version": "ipv4", + "name": "acl1-in-1", + "source": "172.217.22.46/32", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:117", + "id": "id:118", + "name": "acl1-in-3" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:115", + "id": "id:116", + "ip_version": "ipv4", + "name": "acl1-in-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:119", + "id": "id:120", + "name": "acl1-in-4" + }, + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:117", + "id": "id:118", + "ip_version": "ipv4", + "name": "acl1-in-3", + "source": "10.240.30.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:119", + "id": "id:120", + "ip_version": "ipv4", + "name": "acl1-in-4", + "source": "10.240.30.0/24", + "destination_port_max": 443, + "destination_port_min": 443, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + } + ], + "subnets": [ + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:123", + "id": "id:124", + "name": "acl3-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:121", + "id": "id:122", + "ip_version": "ipv4", + "name": "acl3-out-1", + "source": "10.240.30.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:125", + "id": "id:126", + "name": "acl3-in-1" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:123", + "id": "id:124", + "ip_version": "ipv4", + "name": "acl3-out-2", + "source": "10.240.30.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:127", + "id": "id:128", + "name": "acl3-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:125", + "id": "id:126", + "ip_version": "ipv4", + "name": "acl3-in-1", + "source": "10.240.10.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-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:127", + "id": "id:128", + "ip_version": "ipv4", + "name": "acl3-in-2", + "source": "10.240.10.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + } + ], + "subnets": [ + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:131", + "id": "id:132", + "name": "allow-outbound" + }, + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:129", + "id": "id:130", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:131", + "id": "id:132", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:133", + "href": "href:134", + "id": "id:135", + "name": "sg1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:136", + "id": "id:137", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "href:138", + "id": "id:139", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:140", + "id": "id:141", + "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:142", + "id": "id:143", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:3", + "href": "fake:href:3", + "id": "fake:id:3", + "name": "test-vpc1--vsi2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "fake:href:1", + "id": "fake:id:1", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "all" + } + ], + "targets": [ + { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "fake:href:4", + "id": "fake:id:4", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/30" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "fake:href:5", + "id": "fake:id:5", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "fake:href:6", + "id": "fake:id:6", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:3", + "href": "fake:href:3", + "id": "fake:id:3", + "name": "test-vpc1--vsi2" + }, + "protocol": "all" + } + ], + "targets": [ + { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi3b", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:8", + "href": "fake:href:8", + "id": "fake:id:8", + "name": "test-vpc1--vsi3a", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [], + "instances": [ + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:11:07.000Z", + "crn": "crn:144", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:145", + "id": "id:146", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi2", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:11:07.000Z", + "floating_ips": [], + "href": "href:43", + "id": "id:44", + "name": "ni2", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:3", + "href": "fake:href:3", + "id": "fake:id:3", + "name": "test-vpc1--vsi2" + } + ], + "status": "available", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:52.000Z", + "crn": "crn:157", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:158", + "id": "id:159", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:52.000Z", + "floating_ips": [ + { + "address": "52.116.129.168", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip" + } + ], + "href": "href:63", + "id": "id:64", + "name": "ni1", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:166", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:167", + "id": "id:168", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3b", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi3b" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:34.000Z", + "crn": "crn:175", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:176", + "id": "id:177", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3a", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:8", + "href": "fake:href:8", + "id": "fake:id:8", + "name": "test-vpc1--vsi3a" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + } + ], + "virtual_nis": null, + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-09-09T09:09:51.000Z", + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "fiscally-fresh-uncanny-ceramics", + "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": "subnet2", + "resource_type": "subnet" + }, + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "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_sg_redundant/conn_spec.json b/test/data/optimize_sg_redundant/conn_spec.json new file mode 100644 index 00000000..ef2331cd --- /dev/null +++ b/test/data/optimize_sg_redundant/conn_spec.json @@ -0,0 +1,48 @@ +{ + "externals": { + "e1": "0.0.0.0/30", + "e2": "0.0.0.0/31" + }, + "required-connections": [ + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + } + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e2", + "type": "external" + } + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + } + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + } + } + ] +} diff --git a/test/data/optimize_sg_redundant/details.txt b/test/data/optimize_sg_redundant/details.txt new file mode 100644 index 00000000..70573b2d --- /dev/null +++ b/test/data/optimize_sg_redundant/details.txt @@ -0,0 +1,10 @@ +vsi1 --> 0.0.0.0/30 (protocol all) +vsi1 --> 0.0.0.0/31 (protocol all) + +vsi1 --> vsi2 (protocol all) +vsi1 --> vsi2 (protocol all) + +==================================== + +vsi1 --> 0.0.0.0/30 (all protocol) +vsi1 --> vsi2 (all protocol) \ No newline at end of file diff --git a/test/data/optimize_sg_t/config_object.json b/test/data/optimize_sg_t/config_object.json new file mode 100644 index 00000000..347bd139 --- /dev/null +++ b/test/data/optimize_sg_t/config_object.json @@ -0,0 +1,2009 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.22.217.112" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.12.160.153" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.16.253.223" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail" + }, + "default_routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "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": "test-vpc1", + "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-09-09T09:09:50.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": true, + "name": "filling-tasty-bacterium-parlor", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.64.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:20", + "id": "id:21", + "is_default": true, + "name": "relearn-ragweed-goon-feisty", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.128.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:22", + "id": "id:23", + "is_default": true, + "name": "unruffled-penknife-snowshoe-ninetieth", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:51.000Z", + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.20.0/24", + "name": "subnet2", + "network_acl": { + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.20.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:33", + "id": "id:34", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:35", + "id": "id:36", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:37", + "id": "id:38", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:39", + "id": "id:40", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.4", + "auto_delete": true, + "created_at": "2024-09-09T09:11:08.000Z", + "href": "href:41", + "id": "id:42", + "lifecycle_state": "stable", + "name": "startle-percent-embellish-squeegee", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.20.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:45", + "id": "id:46", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.10.0/24", + "name": "subnet1", + "network_acl": { + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.10.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:53", + "id": "id:54", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:55", + "id": "id:56", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:57", + "id": "id:58", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:59", + "id": "id:60", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:52.000Z", + "href": "href:61", + "id": "id:62", + "lifecycle_state": "stable", + "name": "tableware-sprawl-shrivel-popper", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.10.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:65", + "id": "id:66", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-09-09T09:10:18.000Z", + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.30.0/24", + "name": "subnet3", + "network_acl": { + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.30.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:73", + "id": "id:74", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:75", + "id": "id:76", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:77", + "id": "id:78", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:79", + "id": "id:80", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:81", + "id": "id:82", + "lifecycle_state": "stable", + "name": "disallow-oxidant-etching-selection", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.5", + "auto_delete": true, + "created_at": "2024-09-09T09:10:36.000Z", + "href": "href:85", + "id": "id:86", + "lifecycle_state": "stable", + "name": "reheat-joyride-little-overprice", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:89", + "id": "id:90", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + } + ], + "public_gateways": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:30", + "floating_ip": { + "address": "52.118.147.142", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1" + }, + "href": "href:31", + "id": "id:32", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "floating_ips": [ + { + "address": "52.116.129.168", + "created_at": "2024-09-09T09:11:31.000Z", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + }, + { + "address": "52.118.147.142", + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway", + "crn": "crn:30" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": "2024-09-09T09:10:15.000Z", + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:99", + "id": "id:100", + "name": "acl2-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:97", + "id": "id:98", + "ip_version": "ipv4", + "name": "acl2-out-1", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:101", + "id": "id:102", + "name": "acl2-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:99", + "id": "id:100", + "ip_version": "ipv4", + "name": "acl2-out-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:103", + "id": "id:104", + "name": "acl2-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:101", + "id": "id:102", + "ip_version": "ipv4", + "name": "acl2-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:103", + "id": "id:104", + "ip_version": "ipv4", + "name": "acl2-in-2", + "source": "10.240.10.0/24", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:107", + "id": "id:108", + "name": "acl1-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "172.217.22.46/32", + "direction": "outbound", + "href": "href:105", + "id": "id:106", + "ip_version": "ipv4", + "name": "acl1-out-1", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:109", + "id": "id:110", + "name": "acl1-out-3" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "outbound", + "href": "href:107", + "id": "id:108", + "ip_version": "ipv4", + "name": "acl1-out-2", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:111", + "id": "id:112", + "name": "acl1-out-4" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:109", + "id": "id:110", + "ip_version": "ipv4", + "name": "acl1-out-3", + "source": "10.240.10.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:113", + "id": "id:114", + "name": "acl1-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:111", + "id": "id:112", + "ip_version": "ipv4", + "name": "acl1-out-4", + "source": "10.240.10.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:115", + "id": "id:116", + "name": "acl1-in-2" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:113", + "id": "id:114", + "ip_version": "ipv4", + "name": "acl1-in-1", + "source": "172.217.22.46/32", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:117", + "id": "id:118", + "name": "acl1-in-3" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:115", + "id": "id:116", + "ip_version": "ipv4", + "name": "acl1-in-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:119", + "id": "id:120", + "name": "acl1-in-4" + }, + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:117", + "id": "id:118", + "ip_version": "ipv4", + "name": "acl1-in-3", + "source": "10.240.30.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:119", + "id": "id:120", + "ip_version": "ipv4", + "name": "acl1-in-4", + "source": "10.240.30.0/24", + "destination_port_max": 443, + "destination_port_min": 443, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + } + ], + "subnets": [ + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:123", + "id": "id:124", + "name": "acl3-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:121", + "id": "id:122", + "ip_version": "ipv4", + "name": "acl3-out-1", + "source": "10.240.30.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:125", + "id": "id:126", + "name": "acl3-in-1" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:123", + "id": "id:124", + "ip_version": "ipv4", + "name": "acl3-out-2", + "source": "10.240.30.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:127", + "id": "id:128", + "name": "acl3-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:125", + "id": "id:126", + "ip_version": "ipv4", + "name": "acl3-in-1", + "source": "10.240.10.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-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:127", + "id": "id:128", + "ip_version": "ipv4", + "name": "acl3-in-2", + "source": "10.240.10.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + } + ], + "subnets": [ + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:131", + "id": "id:132", + "name": "allow-outbound" + }, + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:129", + "id": "id:130", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:131", + "id": "id:132", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:133", + "href": "href:134", + "id": "id:135", + "name": "sg1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:136", + "id": "id:137", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "href:138", + "id": "id:139", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:140", + "id": "id:141", + "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:142", + "id": "id:143", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:1", + "href": "fake:href:1", + "id": "fake:id:1", + "name": "test-vpc1--vsi2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:5", + "href": "fake:href:5", + "id": "fake:id:5", + "name": "test-vpc1--vsi1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "fake:href:2", + "id": "fake:id:2", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "port_max": 10, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "outbound", + "href": "fake:href:3", + "id": "fake:id:3", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.2/31" + }, + "port_max": 20, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "outbound", + "href": "fake:href:4", + "id": "fake:id:4", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.4/30" + }, + "port_max": 10, + "port_min": 1, + "protocol": "tcp" + } + ], + "targets": [ + { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:6", + "href": "fake:href:6", + "id": "fake:id:6", + "name": "test-vpc1--vsi3b", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi3a", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [], + "instances": [ + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:11:07.000Z", + "crn": "crn:144", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:145", + "id": "id:146", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi2", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:11:07.000Z", + "floating_ips": [], + "href": "href:43", + "id": "id:44", + "name": "ni2", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:1", + "href": "fake:href:1", + "id": "fake:id:1", + "name": "test-vpc1--vsi2" + } + ], + "status": "available", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:52.000Z", + "crn": "crn:157", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:158", + "id": "id:159", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:52.000Z", + "floating_ips": [ + { + "address": "52.116.129.168", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip" + } + ], + "href": "href:63", + "id": "id:64", + "name": "ni1", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:5", + "href": "fake:href:5", + "id": "fake:id:5", + "name": "test-vpc1--vsi1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:166", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:167", + "id": "id:168", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3b", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:6", + "href": "fake:href:6", + "id": "fake:id:6", + "name": "test-vpc1--vsi3b" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:34.000Z", + "crn": "crn:175", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:176", + "id": "id:177", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3a", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi3a" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + } + ], + "virtual_nis": null, + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-09-09T09:09:51.000Z", + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "fiscally-fresh-uncanny-ceramics", + "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": "subnet2", + "resource_type": "subnet" + }, + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "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_sg_t/conn_spec.json b/test/data/optimize_sg_t/conn_spec.json new file mode 100644 index 00000000..469de1d7 --- /dev/null +++ b/test/data/optimize_sg_t/conn_spec.json @@ -0,0 +1,60 @@ +{ + "externals": { + "e1": "0.0.0.0/31", + "e2": "0.0.0.2/31", + "e3": "0.0.0.4/30" + }, + "required-connections": [ + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "TCP", + "min_destination_port": 1, + "max_destination_port": 10 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e2", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "TCP", + "min_destination_port": 1, + "max_destination_port": 20 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e3", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "TCP", + "min_destination_port": 1, + "max_destination_port": 10 + } + ] + } + ] +} diff --git a/test/data/optimize_sg_t/details.txt b/test/data/optimize_sg_t/details.txt new file mode 100644 index 00000000..f0569c96 --- /dev/null +++ b/test/data/optimize_sg_t/details.txt @@ -0,0 +1,8 @@ +vsi1 --> 0.0.0.0/31 (tcp ports 1-10) +vsi1 --> 0.0.0.2/31 (tcp ports 1-20) +vsi1 --> 0.0.0.4/30 (tcp ports 1-10) + +==================================== + +vsi1 --> 0.0.0.0/29 (tcp ports 1-10) +vsi1 --> 0.0.0.2/31 (tcp ports 1-20) \ No newline at end of file diff --git a/test/data/optimize_sg_t_all/config_object.json b/test/data/optimize_sg_t_all/config_object.json new file mode 100644 index 00000000..45eaa62d --- /dev/null +++ b/test/data/optimize_sg_t_all/config_object.json @@ -0,0 +1,2007 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.22.217.112" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.12.160.153" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.16.253.223" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail" + }, + "default_routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "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": "test-vpc1", + "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-09-09T09:09:50.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": true, + "name": "filling-tasty-bacterium-parlor", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.64.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:20", + "id": "id:21", + "is_default": true, + "name": "relearn-ragweed-goon-feisty", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.128.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:22", + "id": "id:23", + "is_default": true, + "name": "unruffled-penknife-snowshoe-ninetieth", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:51.000Z", + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.20.0/24", + "name": "subnet2", + "network_acl": { + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.20.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:33", + "id": "id:34", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:35", + "id": "id:36", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:37", + "id": "id:38", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:39", + "id": "id:40", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.4", + "auto_delete": true, + "created_at": "2024-09-09T09:11:08.000Z", + "href": "href:41", + "id": "id:42", + "lifecycle_state": "stable", + "name": "startle-percent-embellish-squeegee", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.20.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:45", + "id": "id:46", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.10.0/24", + "name": "subnet1", + "network_acl": { + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.10.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:53", + "id": "id:54", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:55", + "id": "id:56", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:57", + "id": "id:58", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:59", + "id": "id:60", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:52.000Z", + "href": "href:61", + "id": "id:62", + "lifecycle_state": "stable", + "name": "tableware-sprawl-shrivel-popper", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.10.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:65", + "id": "id:66", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-09-09T09:10:18.000Z", + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.30.0/24", + "name": "subnet3", + "network_acl": { + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.30.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:73", + "id": "id:74", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:75", + "id": "id:76", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:77", + "id": "id:78", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:79", + "id": "id:80", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:81", + "id": "id:82", + "lifecycle_state": "stable", + "name": "disallow-oxidant-etching-selection", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.5", + "auto_delete": true, + "created_at": "2024-09-09T09:10:36.000Z", + "href": "href:85", + "id": "id:86", + "lifecycle_state": "stable", + "name": "reheat-joyride-little-overprice", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:89", + "id": "id:90", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + } + ], + "public_gateways": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:30", + "floating_ip": { + "address": "52.118.147.142", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1" + }, + "href": "href:31", + "id": "id:32", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "floating_ips": [ + { + "address": "52.116.129.168", + "created_at": "2024-09-09T09:11:31.000Z", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + }, + { + "address": "52.118.147.142", + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway", + "crn": "crn:30" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": "2024-09-09T09:10:15.000Z", + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:99", + "id": "id:100", + "name": "acl2-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:97", + "id": "id:98", + "ip_version": "ipv4", + "name": "acl2-out-1", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:101", + "id": "id:102", + "name": "acl2-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:99", + "id": "id:100", + "ip_version": "ipv4", + "name": "acl2-out-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:103", + "id": "id:104", + "name": "acl2-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:101", + "id": "id:102", + "ip_version": "ipv4", + "name": "acl2-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:103", + "id": "id:104", + "ip_version": "ipv4", + "name": "acl2-in-2", + "source": "10.240.10.0/24", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:107", + "id": "id:108", + "name": "acl1-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "172.217.22.46/32", + "direction": "outbound", + "href": "href:105", + "id": "id:106", + "ip_version": "ipv4", + "name": "acl1-out-1", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:109", + "id": "id:110", + "name": "acl1-out-3" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "outbound", + "href": "href:107", + "id": "id:108", + "ip_version": "ipv4", + "name": "acl1-out-2", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:111", + "id": "id:112", + "name": "acl1-out-4" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:109", + "id": "id:110", + "ip_version": "ipv4", + "name": "acl1-out-3", + "source": "10.240.10.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:113", + "id": "id:114", + "name": "acl1-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:111", + "id": "id:112", + "ip_version": "ipv4", + "name": "acl1-out-4", + "source": "10.240.10.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:115", + "id": "id:116", + "name": "acl1-in-2" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:113", + "id": "id:114", + "ip_version": "ipv4", + "name": "acl1-in-1", + "source": "172.217.22.46/32", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:117", + "id": "id:118", + "name": "acl1-in-3" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:115", + "id": "id:116", + "ip_version": "ipv4", + "name": "acl1-in-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:119", + "id": "id:120", + "name": "acl1-in-4" + }, + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:117", + "id": "id:118", + "ip_version": "ipv4", + "name": "acl1-in-3", + "source": "10.240.30.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:119", + "id": "id:120", + "ip_version": "ipv4", + "name": "acl1-in-4", + "source": "10.240.30.0/24", + "destination_port_max": 443, + "destination_port_min": 443, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + } + ], + "subnets": [ + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:123", + "id": "id:124", + "name": "acl3-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:121", + "id": "id:122", + "ip_version": "ipv4", + "name": "acl3-out-1", + "source": "10.240.30.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:125", + "id": "id:126", + "name": "acl3-in-1" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:123", + "id": "id:124", + "ip_version": "ipv4", + "name": "acl3-out-2", + "source": "10.240.30.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:127", + "id": "id:128", + "name": "acl3-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:125", + "id": "id:126", + "ip_version": "ipv4", + "name": "acl3-in-1", + "source": "10.240.10.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-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:127", + "id": "id:128", + "ip_version": "ipv4", + "name": "acl3-in-2", + "source": "10.240.10.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + } + ], + "subnets": [ + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:131", + "id": "id:132", + "name": "allow-outbound" + }, + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:129", + "id": "id:130", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:131", + "id": "id:132", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:133", + "href": "href:134", + "id": "id:135", + "name": "sg1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:136", + "id": "id:137", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "href:138", + "id": "id:139", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:140", + "id": "id:141", + "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:142", + "id": "id:143", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:1", + "href": "fake:href:1", + "id": "fake:id:1", + "name": "test-vpc1--vsi2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:5", + "href": "fake:href:5", + "id": "fake:id:5", + "name": "test-vpc1--vsi1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "fake:href:2", + "id": "fake:id:2", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "port_max": 10, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "outbound", + "href": "fake:href:3", + "id": "fake:id:3", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.2/31" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "fake:href:4", + "id": "fake:id:4", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.4/30" + }, + "port_max": 10, + "port_min": 1, + "protocol": "tcp" + } + ], + "targets": [ + { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:6", + "href": "fake:href:6", + "id": "fake:id:6", + "name": "test-vpc1--vsi3b", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi3a", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [], + "instances": [ + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:11:07.000Z", + "crn": "crn:144", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:145", + "id": "id:146", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi2", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:11:07.000Z", + "floating_ips": [], + "href": "href:43", + "id": "id:44", + "name": "ni2", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:1", + "href": "fake:href:1", + "id": "fake:id:1", + "name": "test-vpc1--vsi2" + } + ], + "status": "available", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:52.000Z", + "crn": "crn:157", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:158", + "id": "id:159", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:52.000Z", + "floating_ips": [ + { + "address": "52.116.129.168", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip" + } + ], + "href": "href:63", + "id": "id:64", + "name": "ni1", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:5", + "href": "fake:href:5", + "id": "fake:id:5", + "name": "test-vpc1--vsi1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:166", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:167", + "id": "id:168", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3b", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:6", + "href": "fake:href:6", + "id": "fake:id:6", + "name": "test-vpc1--vsi3b" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:34.000Z", + "crn": "crn:175", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:176", + "id": "id:177", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3a", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi3a" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + } + ], + "virtual_nis": null, + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-09-09T09:09:51.000Z", + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "fiscally-fresh-uncanny-ceramics", + "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": "subnet2", + "resource_type": "subnet" + }, + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "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_sg_t_all/conn_spec.json b/test/data/optimize_sg_t_all/conn_spec.json new file mode 100644 index 00000000..e4b6b3a9 --- /dev/null +++ b/test/data/optimize_sg_t_all/conn_spec.json @@ -0,0 +1,53 @@ +{ + "externals": { + "e1": "0.0.0.0/31", + "e2": "0.0.0.2/31", + "e3": "0.0.0.4/30" + }, + "required-connections": [ + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e1", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "TCP", + "min_destination_port": 1, + "max_destination_port": 10 + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e2", + "type": "external" + } + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e3", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "TCP", + "min_destination_port": 1, + "max_destination_port": 10 + } + ] + } + ] +} diff --git a/test/data/optimize_sg_t_all/details.txt b/test/data/optimize_sg_t_all/details.txt new file mode 100644 index 00000000..0de517d7 --- /dev/null +++ b/test/data/optimize_sg_t_all/details.txt @@ -0,0 +1,8 @@ +vsi1 --> 0.0.0.0/31 (tcp ports 1-10) +vsi1 --> 0.0.0.2/31 (all protocols) +vsi1 --> 0.0.0.4/30 (tcp ports 1-10) + +==================================== + +vsi1 --> 0.0.0.0/29 (tcp ports 1-10) +vsi1 --> 0.0.0.2/31 (all protocols) \ No newline at end of file diff --git a/test/main_test_list.go b/test/main_test_list.go index 57e61c77..e0af4153 100644 --- a/test/main_test_list.go +++ b/test/main_test_list.go @@ -24,6 +24,8 @@ const ( aclTgMultipleConfig = "%s/acl_tg_multiple/config_object.json" aclTgMultipleSpec = "%s/acl_tg_multiple/conn_spec.json" + optimizeSGProtocolsToAllConfig = "%s/optimize_sg_protocols_to_all/config_object.json" + sgProtocolsConfig = "%s/sg_protocols/config_object.json" sgProtocolsSpec = "%s/sg_protocols/conn_spec.json" @@ -34,6 +36,7 @@ const ( sgTgMultipleSpec = "%s/sg_tg_multiple/conn_spec.json" tfOutputFmt = "tf" + vsi1 = "vsi1" ) func allMainTests() []testCase { @@ -311,7 +314,89 @@ func synthSGTestsList() []testCase { } } -// Note: spec files in data folder are used to create the config object files (acl_testing4 config) +// Note1: spec files in data folder are used to create the config object files (acl_testing4 config) +// Note2: each data folder has a details.txt file with the test explanation func optimizeSGTestsLists() []testCase { - return []testCase{} + return []testCase{ + { + testName: "optimize_sg_icmp_codes", + args: &command{ + cmd: optimize, + subcmd: sg, + config: "%s/optimize_sg_icmp_codes/config_object.json", + outputFile: "%s/optimize_sg_icmp_codes/sg_expected.tf", + firewallName: vsi1, + }, + }, + { + testName: "optimize_sg_icmp_types", + args: &command{ + cmd: optimize, + subcmd: sg, + config: "%s/optimize_sg_icmp_types/config_object.json", + outputFile: "%s/optimize_sg_icmp_types/sg_expected.tf", + firewallName: vsi1, + }, + }, + { + testName: "optimize_sg_protocols_to_all_tf", + args: &command{ + cmd: optimize, + subcmd: sg, + config: optimizeSGProtocolsToAllConfig, + outputFile: "%s/optimize_sg_protocols_to_all_tf/sg_expected.tf", + firewallName: vsi1, + }, + }, + { + testName: "optimize_sg_protocols_to_all_csv", + args: &command{ + cmd: optimize, + subcmd: sg, + config: optimizeSGProtocolsToAllConfig, + outputFile: "%s/optimize_sg_protocols_to_all_csv/sg_expected.csv", + firewallName: vsi1, + }, + }, + { + testName: "optimize_sg_protocols_to_all_md", + args: &command{ + cmd: optimize, + subcmd: sg, + config: optimizeSGProtocolsToAllConfig, + outputFile: "%s/optimize_sg_protocols_to_all_md/sg_expected.md", + firewallName: vsi1, + }, + }, + { + testName: "optimize_sg_redundant", + args: &command{ + cmd: optimize, + subcmd: sg, + config: "%s/optimize_sg_redundant/config_object.json", + outputFile: "%s/optimize_sg_redundant/sg_expected.tf", + firewallName: vsi1, + }, + }, + { + testName: "optimize_sg_t", + args: &command{ + cmd: optimize, + subcmd: sg, + config: "%s/optimize_sg_t/config_object.json", + outputFile: "%s/optimize_sg_t/sg_expected.tf", + firewallName: vsi1, + }, + }, + { + testName: "optimize_sg_t_all", + args: &command{ + cmd: optimize, + subcmd: sg, + config: "%s/optimize_sg_t_all/config_object.json", + outputFile: "%s/optimize_sg_t_all/sg_expected.tf", + firewallName: vsi1, + }, + }, + } } diff --git a/test/tests_defs.go b/test/tests_defs.go index e5a32ebd..8baea0f4 100644 --- a/test/tests_defs.go +++ b/test/tests_defs.go @@ -35,9 +35,10 @@ const ( defaultDirectoryPermission = 0o755 - synth string = "synth" - acl string = "acl" - sg string = "sg" + synth string = "synth" + optimize string = "optimize" + acl string = "acl" + sg string = "sg" ) func (c *command) Args(dataFolder, resultsFolder string) []string { From 28a55eceefc8fef35eb2483434cd659d7e1aea85 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 30 Sep 2024 16:22:38 +0300 Subject: [PATCH 055/131] wip --- pkg/io/tfio/acl.go | 4 +- pkg/io/tfio/sg.go | 4 +- pkg/optimize/compressRules.go | 9 +- pkg/optimize/sg.go | 76 ++++++---- pkg/optimize/sgRulesToIPToSpan.go | 4 + pkg/optimize/sgRulesToSGToSpan.go | 10 +- pkg/optimize/sgSpanToSGRules.go | 2 +- pkg/utils/utils.go | 8 -- .../optimize_sg_icmp_codes/sg_expected.tf | 68 +++++++++ .../optimize_sg_icmp_types/sg_expected.tf | 67 +++++++++ .../sg_expected.csv | 7 + .../sg_expected.md | 8 ++ .../sg_expected.tf | 78 ++++++++++ .../optimize_sg_redundant/sg_expected.tf | 55 +++++++ test/expected/optimize_sg_t/sg_expected.tf | 76 ++++++++++ .../expected/optimize_sg_t_all/sg_expected.tf | 68 +++++++++ test/main_test.go | 136 +++++++++--------- test/main_test_list.go | 56 ++++---- test/update_test.go | 40 +++--- 19 files changed, 606 insertions(+), 170 deletions(-) create mode 100644 test/expected/optimize_sg_icmp_codes/sg_expected.tf create mode 100644 test/expected/optimize_sg_icmp_types/sg_expected.tf create mode 100644 test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv create mode 100644 test/expected/optimize_sg_protocols_to_all_md/sg_expected.md create mode 100644 test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf create mode 100644 test/expected/optimize_sg_redundant/sg_expected.tf create mode 100644 test/expected/optimize_sg_t/sg_expected.tf create mode 100644 test/expected/optimize_sg_t_all/sg_expected.tf diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index 7f641d3b..d71b8d56 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -65,7 +65,7 @@ func aclRule(rule *ir.ACLRule, name string) (tf.Block, error) { {Name: "destination", Value: quote(rule.Destination.String())}, } - comment := "" + comment := "\n" if rule.Explanation != "" { comment = fmt.Sprintf("# %v", rule.Explanation) } @@ -109,7 +109,7 @@ func aclCollection(t *ir.ACLCollection, vpc string) (*tf.ConfigFile, error) { var acls = make([]tf.Block, len(sortedACLs)) i := 0 for _, subnet := range sortedACLs { - comment := "" + comment := "\n" vpcName := ir.VpcFromScopedResource(subnet) acl := t.ACLs[vpcName][subnet] if len(sortedACLs) > 1 { // not a single nacl diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 793c5c7a..dafcaa6d 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -93,8 +93,8 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { func sg(sgName, vpcName string) (tf.Block, error) { tfSGName := ir.ChangeScoping(sgName) comment := fmt.Sprintf("\n### SG attached to %s", sgName) - if sgName == tfSGName { // its optimization - comment = "" + if sgName == tfSGName { // optimization mode + comment = "\n" } if err := verifyName(tfSGName); err != nil { return tf.Block{}, err diff --git a/pkg/optimize/compressRules.go b/pkg/optimize/compressRules.go index 67757fc8..6f9bb4d8 100644 --- a/pkg/optimize/compressRules.go +++ b/pkg/optimize/compressRules.go @@ -7,7 +7,6 @@ package optimize import ( "github.com/np-guard/models/pkg/netset" - "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) func compressSpansToSG(spans *sgSpansToSGPerProtocol) *sgSpansToSGPerProtocol { @@ -18,9 +17,9 @@ func compressSpansToSG(spans *sgSpansToSGPerProtocol) *sgSpansToSGPerProtocol { // delete other protocols rules if all protocol rule exists func deleteOtherProtocolIfAllProtocolExists(spans *sgSpansToSGPerProtocol) *sgSpansToSGPerProtocol { for _, sgName := range spans.all { - delete(spans.tcp, *sgName) - delete(spans.udp, *sgName) - delete(spans.icmp, *sgName) + delete(spans.tcp, sgName) + delete(spans.udp, sgName) + delete(spans.icmp, sgName) } return spans } @@ -34,7 +33,7 @@ func compressThreeProtocolsToAllProtocol(spans *sgSpansToSGPerProtocol) *sgSpans delete(spans.tcp, sgName) delete(spans.udp, sgName) delete(spans.icmp, sgName) - spans.all = append(spans.all, utils.Ptr(sgName)) + spans.all = append(spans.all, sgName) } } } diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index 35092850..fc39861e 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -6,6 +6,7 @@ SPDX-License-Identifier: Apache-2.0 package optimize import ( + "fmt" "log" "github.com/np-guard/models/pkg/ds" @@ -40,7 +41,7 @@ type ( tcp map[ir.SGName]*interval.CanonicalSet udp map[ir.SGName]*interval.CanonicalSet icmp map[ir.SGName]*netset.ICMPSet - all []*ir.SGName + all []ir.SGName } sgSpansToIPPerProtocol struct { @@ -71,42 +72,57 @@ func (s *SGOptimizer) VpcNames() []string { } // Optimize attempts to reduce the number of SG rules -// the algorithm attempts to reduce both inbound and outbound rules separately -// A message is printed to the log at the end of the algorithm +// if -n was supplied, it will attempt to reduce the number of rules only in it +// otherwise, it will attempt to reduce the number of rules in all SGs func (s *SGOptimizer) Optimize() (ir.Collection, error) { - for vpcName := range s.sgCollection.SGs { - var sg *ir.SG - var ok bool - if sg, ok = s.sgCollection.SGs[vpcName][s.sgName]; !ok { - continue + if s.sgName != "" { + for _, vpcName := range utils.SortedMapKeys(s.sgCollection.SGs) { + if _, ok := s.sgCollection.SGs[vpcName][s.sgName]; ok { + s.OptimizeSG(vpcName, s.sgName) + return s.sgCollection, nil + } } - reducedRules := 0 + return nil, fmt.Errorf("could no find %s sg", s.sgName) + } - // reduce inbound rules first - newInboundRules := s.reduceSGRules(sg.InboundRules, ir.Inbound) - if len(sg.InboundRules) > len(newInboundRules) { - reducedRules += len(sg.InboundRules) - len(newInboundRules) - s.sgCollection.SGs[vpcName][s.sgName].InboundRules = newInboundRules + for _, vpcName := range utils.SortedMapKeys(s.sgCollection.SGs) { + for _, sgName := range utils.SortedMapKeys(s.sgCollection.SGs[vpcName]) { + s.OptimizeSG(vpcName, sgName) } + } + return s.sgCollection, nil +} - // reduce outbound rules second - newOutboundRules := s.reduceSGRules(sg.OutboundRules, ir.Outbound) - if len(sg.OutboundRules) > len(newOutboundRules) { - reducedRules += len(sg.OutboundRules) - len(newOutboundRules) - s.sgCollection.SGs[vpcName][s.sgName].OutboundRules = newOutboundRules - } +// Optimize attempts to reduce the number of SG rules +// the algorithm attempts to reduce both inbound and outbound rules separately +// A message is printed to the log at the end of the algorithm +func (s *SGOptimizer) OptimizeSG(vpcName string, sgName ir.SGName) { + sg := s.sgCollection.SGs[vpcName][sgName] + reducedRules := 0 + + // reduce inbound rules first + newInboundRules := s.reduceSGRules(sg.InboundRules, ir.Inbound) + if len(sg.InboundRules) > len(newInboundRules) { + reducedRules += len(sg.InboundRules) - len(newInboundRules) + s.sgCollection.SGs[vpcName][sgName].InboundRules = newInboundRules + } - // print a message to the log - switch { - case reducedRules == 0: - log.Printf("no rules were reduced in sg %s", string(s.sgName)) - case reducedRules == 1: - log.Printf("1 rule was reduced in sg %s", string(s.sgName)) - default: - log.Printf("%d rules were reduced in sg %s", reducedRules, string(s.sgName)) - } + // reduce outbound rules second + newOutboundRules := s.reduceSGRules(sg.OutboundRules, ir.Outbound) + if len(sg.OutboundRules) > len(newOutboundRules) { + reducedRules += len(sg.OutboundRules) - len(newOutboundRules) + s.sgCollection.SGs[vpcName][sgName].OutboundRules = newOutboundRules + } + + // print a message to the log + switch { + case reducedRules == 0: + log.Printf("no rules were reduced in sg %s\n", string(sgName)) + case reducedRules == 1: + log.Printf("1 rule was reduced in sg %s\n", string(sgName)) + default: + log.Printf("%d rules were reduced in sg %s\n", reducedRules, string(sgName)) } - return s.sgCollection, nil } // reduceSGRules attempts to reduce the number of rules with different remote types separately diff --git a/pkg/optimize/sgRulesToIPToSpan.go b/pkg/optimize/sgRulesToIPToSpan.go index ed8611fa..af994076 100644 --- a/pkg/optimize/sgRulesToIPToSpan.go +++ b/pkg/optimize/sgRulesToIPToSpan.go @@ -104,10 +104,13 @@ func updateSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleSet T, ruleIP *nets // b. the non overlapping part will enter the new map with the same value he had. func addRuleToSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleIP *netset.IPBlock, ruleSet T) (s, res map[*netset.IPBlock]T) { res = make(map[*netset.IPBlock]T, 0) + uncovered := ruleIP.Copy() for ipblock := range span { if !ipblock.Overlap(ruleIP) { continue } + uncovered = uncovered.Subtract(ipblock) + overlappingIPs := ruleIP.Subtract(ipblock) for _, ip := range overlappingIPs.Split() { res[ip] = span[ipblock].Copy().Union(ruleSet) @@ -118,5 +121,6 @@ func addRuleToSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleIP *netset.IPBlo } delete(span, ipblock) } + res[uncovered] = ruleSet.Copy() return span, res } diff --git a/pkg/optimize/sgRulesToSGToSpan.go b/pkg/optimize/sgRulesToSGToSpan.go index 7e780a81..d71c6df8 100644 --- a/pkg/optimize/sgRulesToSGToSpan.go +++ b/pkg/optimize/sgRulesToSGToSpan.go @@ -6,6 +6,8 @@ SPDX-License-Identifier: Apache-2.0 package optimize import ( + "fmt" + "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" @@ -46,17 +48,19 @@ func icmpRulesToSGToSpan(rules []*ir.SGRule) map[ir.SGName]*netset.ICMPSet { if result[remote] == nil { result[remote] = netset.EmptyICMPSet() } - result[remote].Union(netset.NewICMPSet(p)) + result[remote] = result[remote].Union(netset.NewICMPSet(p)) + + fmt.Println("i=", i, ": num partitions=", len(result[remote].Partitions())) } return result } // all protocol rules to a span of SG names slice -func allProtocolRulesToSGToSpan(rules []*ir.SGRule) []*ir.SGName { +func allProtocolRulesToSGToSpan(rules []*ir.SGRule) []ir.SGName { result := make(map[ir.SGName]struct{}) for i := range rules { remote := rules[i].Remote.(ir.SGName) result[remote] = struct{}{} } - return utils.ToPtrSlice(utils.SortedMapKeys(result)) + return utils.SortedMapKeys(result) } diff --git a/pkg/optimize/sgSpanToSGRules.go b/pkg/optimize/sgSpanToSGRules.go index 0eb66ab1..b3cc640d 100644 --- a/pkg/optimize/sgSpanToSGRules.go +++ b/pkg/optimize/sgSpanToSGRules.go @@ -38,7 +38,7 @@ func icmpSGSpanToSGRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Direct } // span (slice of SGs) to SG rules -func protocolAllSGSpanToSGRules(span []*ir.SGName, direction ir.Direction) []*ir.SGRule { +func protocolAllSGSpanToSGRules(span []ir.SGName, direction ir.Direction) []*ir.SGRule { result := make([]*ir.SGRule, len(span)) for i, sgName := range span { result[i] = ir.NewSGRule(direction, sgName, netp.AnyProtocol{}, netset.GetCidrAll(), "") diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index c867fc55..e3923aa5 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -50,14 +50,6 @@ func Int64PointerToIntPointer(v *int64) *int { return Ptr(int(*v)) } -func ToPtrSlice[T any](s []T) []*T { - res := make([]*T, len(s)) - for i := range s { - res[i] = Ptr(s[i]) - } - return res -} - // m1 does not have any key of m2 func MergeSetMaps[T comparable, K ds.Set[K]](m1, m2 map[T]K) map[T]K { for key, val := range m2 { diff --git a/test/expected/optimize_sg_icmp_codes/sg_expected.tf b/test/expected/optimize_sg_icmp_codes/sg_expected.tf new file mode 100644 index 00000000..41db042e --- /dev/null +++ b/test/expected/optimize_sg_icmp_codes/sg_expected.tf @@ -0,0 +1,68 @@ +resource "ibm_is_security_group" "sg1" { + name = "sg-sg1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi1" { + name = "sg-test-vpc1--vsi1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc1--vsi2.id + icmp { + type = 5 + } +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.0/31" + icmp { + } +} + + +resource "ibm_is_security_group" "test-vpc1--vsi2" { + name = "sg-test-vpc1--vsi2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi2-0" { + group = ibm_is_security_group.test-vpc1--vsi2.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc1--vsi1.id + icmp { + type = 5 + } +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3a" { + name = "sg-test-vpc1--vsi3a" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3b" { + name = "sg-test-vpc1--vsi3b" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { + name = "sg-wombat-hesitate-scorn-subprime" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-0" { + group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id + direction = "inbound" + remote = ibm_is_security_group.wombat-hesitate-scorn-subprime.id +} diff --git a/test/expected/optimize_sg_icmp_types/sg_expected.tf b/test/expected/optimize_sg_icmp_types/sg_expected.tf new file mode 100644 index 00000000..2795bc56 --- /dev/null +++ b/test/expected/optimize_sg_icmp_types/sg_expected.tf @@ -0,0 +1,67 @@ +resource "ibm_is_security_group" "sg1" { + name = "sg-sg1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi1" { + name = "sg-test-vpc1--vsi1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc1--vsi2.id + icmp { + } +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.0/31" + icmp { + type = 0 + } +} + + +resource "ibm_is_security_group" "test-vpc1--vsi2" { + name = "sg-test-vpc1--vsi2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi2-0" { + group = ibm_is_security_group.test-vpc1--vsi2.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc1--vsi1.id + icmp { + } +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3a" { + name = "sg-test-vpc1--vsi3a" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3b" { + name = "sg-test-vpc1--vsi3b" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { + name = "sg-wombat-hesitate-scorn-subprime" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-0" { + group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id + direction = "inbound" + remote = ibm_is_security_group.wombat-hesitate-scorn-subprime.id +} diff --git a/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv b/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv new file mode 100644 index 00000000..773f874b --- /dev/null +++ b/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv @@ -0,0 +1,7 @@ +SG,Direction,Remote type,Remote,Protocol,Protocol params,Description +test-vpc1--vsi1,Outbound,Security group,test-vpc1--vsi2,ALL,, +test-vpc1--vsi1,Outbound,CIDR block,0.0.0.0/31,TCP,ports 1-1, +test-vpc1--vsi1,Outbound,CIDR block,0.0.0.0/31,UDP,ports 1-1, +test-vpc1--vsi1,Outbound,CIDR block,0.0.0.0/31,ICMP,"Type: Any, Code: Any", +test-vpc1--vsi2,Inbound,Security group,test-vpc1--vsi1,ALL,, +wombat-hesitate-scorn-subprime,Inbound,Security group,wombat-hesitate-scorn-subprime,ALL,, diff --git a/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md b/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md new file mode 100644 index 00000000..4fdc42e0 --- /dev/null +++ b/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md @@ -0,0 +1,8 @@ + | SG | Direction | Remote type | Remote | Protocol | Protocol params | Description | + | :--- | :--- | :--- | :--- | :--- | :--- | :--- | + | test-vpc1--vsi1 | Outbound | Security group | test-vpc1--vsi2 | ALL | | | + | test-vpc1--vsi1 | Outbound | CIDR block | 0.0.0.0/31 | TCP | ports 1-1 | | + | test-vpc1--vsi1 | Outbound | CIDR block | 0.0.0.0/31 | UDP | ports 1-1 | | + | test-vpc1--vsi1 | Outbound | CIDR block | 0.0.0.0/31 | ICMP | Type: Any, Code: Any | | + | test-vpc1--vsi2 | Inbound | Security group | test-vpc1--vsi1 | ALL | | | + | wombat-hesitate-scorn-subprime | Inbound | Security group | wombat-hesitate-scorn-subprime | ALL | | | diff --git a/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf b/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf new file mode 100644 index 00000000..d8324ff5 --- /dev/null +++ b/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf @@ -0,0 +1,78 @@ +resource "ibm_is_security_group" "sg1" { + name = "sg-sg1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi1" { + name = "sg-test-vpc1--vsi1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc1--vsi2.id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.0/31" + tcp { + port_max = 1 + } +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-2" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.0/31" + udp { + port_max = 1 + } +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-3" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.0/31" + icmp { + } +} + + +resource "ibm_is_security_group" "test-vpc1--vsi2" { + name = "sg-test-vpc1--vsi2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi2-0" { + group = ibm_is_security_group.test-vpc1--vsi2.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc1--vsi1.id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3a" { + name = "sg-test-vpc1--vsi3a" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3b" { + name = "sg-test-vpc1--vsi3b" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { + name = "sg-wombat-hesitate-scorn-subprime" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-0" { + group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id + direction = "inbound" + remote = ibm_is_security_group.wombat-hesitate-scorn-subprime.id +} diff --git a/test/expected/optimize_sg_redundant/sg_expected.tf b/test/expected/optimize_sg_redundant/sg_expected.tf new file mode 100644 index 00000000..15bd1e64 --- /dev/null +++ b/test/expected/optimize_sg_redundant/sg_expected.tf @@ -0,0 +1,55 @@ +resource "ibm_is_security_group" "sg1" { + name = "sg-sg1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi1" { + name = "sg-test-vpc1--vsi1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc1--vsi2.id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi2" { + name = "sg-test-vpc1--vsi2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi2-0" { + group = ibm_is_security_group.test-vpc1--vsi2.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc1--vsi1.id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3a" { + name = "sg-test-vpc1--vsi3a" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3b" { + name = "sg-test-vpc1--vsi3b" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { + name = "sg-wombat-hesitate-scorn-subprime" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-0" { + group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id + direction = "inbound" + remote = ibm_is_security_group.wombat-hesitate-scorn-subprime.id +} diff --git a/test/expected/optimize_sg_t/sg_expected.tf b/test/expected/optimize_sg_t/sg_expected.tf new file mode 100644 index 00000000..32fd2e3b --- /dev/null +++ b/test/expected/optimize_sg_t/sg_expected.tf @@ -0,0 +1,76 @@ +resource "ibm_is_security_group" "sg1" { + name = "sg-sg1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "sg1-0" { + group = ibm_is_security_group.sg1.id + direction = "inbound" + remote = "0.0.0.0/0" +} +resource "ibm_is_security_group_rule" "sg1-1" { + group = ibm_is_security_group.sg1.id + direction = "outbound" + remote = "0.0.0.0/0" +} + + +resource "ibm_is_security_group" "test-vpc1--vsi1" { + name = "sg-test-vpc1--vsi1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.0/30" + tcp { + port_max = 1 + } +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.2/31" + tcp { + port_max = 1 + } +} + + +resource "ibm_is_security_group" "test-vpc1--vsi2" { + name = "sg-test-vpc1--vsi2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3a" { + name = "sg-test-vpc1--vsi3a" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3b" { + name = "sg-test-vpc1--vsi3b" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { + name = "sg-wombat-hesitate-scorn-subprime" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-0" { + group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id + direction = "inbound" + remote = ibm_is_security_group.wombat-hesitate-scorn-subprime.id +} +resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-1" { + group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id + direction = "outbound" + remote = "0.0.0.0/0" +} diff --git a/test/expected/optimize_sg_t_all/sg_expected.tf b/test/expected/optimize_sg_t_all/sg_expected.tf new file mode 100644 index 00000000..f932cb58 --- /dev/null +++ b/test/expected/optimize_sg_t_all/sg_expected.tf @@ -0,0 +1,68 @@ +resource "ibm_is_security_group" "sg1" { + name = "sg-sg1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "sg1-0" { + group = ibm_is_security_group.sg1.id + direction = "inbound" + remote = "0.0.0.0/0" +} +resource "ibm_is_security_group_rule" "sg1-1" { + group = ibm_is_security_group.sg1.id + direction = "outbound" + remote = "0.0.0.0/0" +} + + +resource "ibm_is_security_group" "test-vpc1--vsi1" { + name = "sg-test-vpc1--vsi1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.0/29" + tcp { + port_max = 1 + } +} + + +resource "ibm_is_security_group" "test-vpc1--vsi2" { + name = "sg-test-vpc1--vsi2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3a" { + name = "sg-test-vpc1--vsi3a" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "test-vpc1--vsi3b" { + name = "sg-test-vpc1--vsi3b" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + + +resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { + name = "sg-wombat-hesitate-scorn-subprime" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-0" { + group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id + direction = "inbound" + remote = ibm_is_security_group.wombat-hesitate-scorn-subprime.id +} +resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-1" { + group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id + direction = "outbound" + remote = "0.0.0.0/0" +} diff --git a/test/main_test.go b/test/main_test.go index aabe832d..998995de 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -5,84 +5,84 @@ SPDX-License-Identifier: Apache-2.0 package test -import ( - "os" - "path/filepath" - "regexp" - "strings" - "testing" +// import ( +// "os" +// "path/filepath" +// "regexp" +// "strings" +// "testing" - "github.com/np-guard/vpc-network-config-synthesis/cmd/subcmds" -) +// "github.com/np-guard/vpc-network-config-synthesis/cmd/subcmds" +// ) -func TestMain(t *testing.T) { - for _, tt := range allMainTests() { - t.Run(tt.testName, func(t *testing.T) { - // create a sub folder - if err := os.MkdirAll(filepath.Join(resultsFolder, tt.testName), defaultDirectoryPermission); err != nil { - t.Fatalf("Bad test %s; error creating folder for results: %v", tt.testName, err) - } +// func TestMain(t *testing.T) { +// for _, tt := range allMainTests() { +// t.Run(tt.testName, func(t *testing.T) { +// // create a sub folder +// if err := os.MkdirAll(filepath.Join(resultsFolder, tt.testName), defaultDirectoryPermission); err != nil { +// t.Fatalf("Bad test %s; error creating folder for results: %v", tt.testName, err) +// } - // run command - if err := subcmds.Main(tt.args.Args(dataFolder, resultsFolder)); err != nil { - t.Fatalf("Bad test %s; unexpected err: %v", tt.testName, err) - } +// // run command +// if err := subcmds.Main(tt.args.Args(dataFolder, resultsFolder)); err != nil { +// t.Fatalf("Bad test %s; unexpected err: %v", tt.testName, err) +// } - // compare results - compareTestResults(t, tt.testName) - }) - } - removeGeneratedFiles() -} +// // compare results +// compareTestResults(t, tt.testName) +// }) +// } +// removeGeneratedFiles() +// } -func compareTestResults(t *testing.T, testName string) { - expectedSubDirPath := filepath.Join(expectedFolder, testName) - expectedDirFiles := readDir(t, expectedSubDirPath) - expectedFileNames := strings.Join(expectedDirFiles, ", ") +// func compareTestResults(t *testing.T, testName string) { +// expectedSubDirPath := filepath.Join(expectedFolder, testName) +// expectedDirFiles := readDir(t, expectedSubDirPath) +// expectedFileNames := strings.Join(expectedDirFiles, ", ") - resultsSubDirPath := filepath.Join(resultsFolder, testName) - resultsDirFiles := readDir(t, resultsSubDirPath) - resultsFileNames := strings.Join(resultsDirFiles, ", ") +// resultsSubDirPath := filepath.Join(resultsFolder, testName) +// resultsDirFiles := readDir(t, resultsSubDirPath) +// resultsFileNames := strings.Join(resultsDirFiles, ", ") - if len(expectedDirFiles) != len(resultsDirFiles) { - t.Fatalf("Bad test: %s; incorrect number of files created.\nexpected: %s\ngot: %s", testName, expectedFileNames, resultsFileNames) - } +// if len(expectedDirFiles) != len(resultsDirFiles) { +// t.Fatalf("Bad test: %s; incorrect number of files created.\nexpected: %s\ngot: %s", testName, expectedFileNames, resultsFileNames) +// } - for _, file := range expectedDirFiles { - if readFile(t, filepath.Join(expectedSubDirPath, file), testName) != readFile(t, filepath.Join(resultsSubDirPath, file), testName) { - t.Fatalf("Bad test %s; The %s file is different than expected", testName, file) - } - } -} +// for _, file := range expectedDirFiles { +// if readFile(t, filepath.Join(expectedSubDirPath, file), testName) != readFile(t, filepath.Join(resultsSubDirPath, file), testName) { +// t.Fatalf("Bad test %s; The %s file is different than expected", testName, file) +// } +// } +// } -func readDir(t *testing.T, dirName string) []string { - entries, err := os.ReadDir(dirName) - if err != nil { - t.Fatalf("Bad test %s; error reading folder: %s", dirName, err) - } +// func readDir(t *testing.T, dirName string) []string { +// entries, err := os.ReadDir(dirName) +// if err != nil { +// t.Fatalf("Bad test %s; error reading folder: %s", dirName, err) +// } - result := make([]string, len(entries)) - for i := range entries { - result[i] = entries[i].Name() - } - return result -} +// result := make([]string, len(entries)) +// for i := range entries { +// result[i] = entries[i].Name() +// } +// return result +// } -func readFile(t *testing.T, file, testName string) string { - buf, err := os.ReadFile(file) - if err != nil { - t.Fatalf("Bad test: %s; error reading file %s: %v", testName, file, err) - } - return shrinkWhitespace(string(buf)) -} +// func readFile(t *testing.T, file, testName string) string { +// buf, err := os.ReadFile(file) +// if err != nil { +// t.Fatalf("Bad test: %s; error reading file %s: %v", testName, file, err) +// } +// return shrinkWhitespace(string(buf)) +// } -func shrinkWhitespace(s string) string { - return regexp.MustCompile(`[ \t]+`).ReplaceAllString(s, " ") -} +// func shrinkWhitespace(s string) string { +// return regexp.MustCompile(`[ \t]+`).ReplaceAllString(s, " ") +// } -func removeGeneratedFiles() { - err := os.RemoveAll(resultsFolder) - if err != nil { - panic(err) - } -} +// func removeGeneratedFiles() { +// err := os.RemoveAll(resultsFolder) +// if err != nil { +// panic(err) +// } +// } diff --git a/test/main_test_list.go b/test/main_test_list.go index e0af4153..a2f0982c 100644 --- a/test/main_test_list.go +++ b/test/main_test_list.go @@ -36,7 +36,7 @@ const ( sgTgMultipleSpec = "%s/sg_tg_multiple/conn_spec.json" tfOutputFmt = "tf" - vsi1 = "vsi1" + vsi1 = "test-vpc1--vsi1" ) func allMainTests() []testCase { @@ -321,61 +321,55 @@ func optimizeSGTestsLists() []testCase { { testName: "optimize_sg_icmp_codes", args: &command{ - cmd: optimize, - subcmd: sg, - config: "%s/optimize_sg_icmp_codes/config_object.json", - outputFile: "%s/optimize_sg_icmp_codes/sg_expected.tf", - firewallName: vsi1, + cmd: optimize, + subcmd: sg, + config: "%s/optimize_sg_icmp_codes/config_object.json", + outputFile: "%s/optimize_sg_icmp_codes/sg_expected.tf", }, }, { testName: "optimize_sg_icmp_types", args: &command{ - cmd: optimize, - subcmd: sg, - config: "%s/optimize_sg_icmp_types/config_object.json", - outputFile: "%s/optimize_sg_icmp_types/sg_expected.tf", - firewallName: vsi1, + cmd: optimize, + subcmd: sg, + config: "%s/optimize_sg_icmp_types/config_object.json", + outputFile: "%s/optimize_sg_icmp_types/sg_expected.tf", }, }, { testName: "optimize_sg_protocols_to_all_tf", args: &command{ - cmd: optimize, - subcmd: sg, - config: optimizeSGProtocolsToAllConfig, - outputFile: "%s/optimize_sg_protocols_to_all_tf/sg_expected.tf", - firewallName: vsi1, + cmd: optimize, + subcmd: sg, + config: optimizeSGProtocolsToAllConfig, + outputFile: "%s/optimize_sg_protocols_to_all_tf/sg_expected.tf", }, }, { testName: "optimize_sg_protocols_to_all_csv", args: &command{ - cmd: optimize, - subcmd: sg, - config: optimizeSGProtocolsToAllConfig, - outputFile: "%s/optimize_sg_protocols_to_all_csv/sg_expected.csv", - firewallName: vsi1, + cmd: optimize, + subcmd: sg, + config: optimizeSGProtocolsToAllConfig, + outputFile: "%s/optimize_sg_protocols_to_all_csv/sg_expected.csv", }, }, { testName: "optimize_sg_protocols_to_all_md", args: &command{ - cmd: optimize, - subcmd: sg, - config: optimizeSGProtocolsToAllConfig, - outputFile: "%s/optimize_sg_protocols_to_all_md/sg_expected.md", - firewallName: vsi1, + cmd: optimize, + subcmd: sg, + config: optimizeSGProtocolsToAllConfig, + outputFile: "%s/optimize_sg_protocols_to_all_md/sg_expected.md", }, }, { testName: "optimize_sg_redundant", args: &command{ - cmd: optimize, - subcmd: sg, - config: "%s/optimize_sg_redundant/config_object.json", - outputFile: "%s/optimize_sg_redundant/sg_expected.tf", - firewallName: vsi1, + cmd: optimize, + subcmd: sg, + config: "%s/optimize_sg_redundant/config_object.json", + outputFile: "%s/optimize_sg_redundant/sg_expected.tf", }, }, { diff --git a/test/update_test.go b/test/update_test.go index 209921cf..7687fabe 100644 --- a/test/update_test.go +++ b/test/update_test.go @@ -5,26 +5,26 @@ SPDX-License-Identifier: Apache-2.0 package test -// import ( -// "os" -// "path/filepath" -// "testing" +import ( + "os" + "path/filepath" + "testing" -// "github.com/np-guard/vpc-network-config-synthesis/cmd/subcmds" -// ) + "github.com/np-guard/vpc-network-config-synthesis/cmd/subcmds" +) -// func TestUpdate(t *testing.T) { -// for _, tt := range allMainTests() { -// t.Run(tt.testName, func(t *testing.T) { -// // create a sub folder -// if err := os.MkdirAll(filepath.Join(expectedFolder, tt.testName), defaultDirectoryPermission); err != nil { -// t.Errorf("Bad test %s: %s", tt.testName, err) -// } +func TestUpdate(t *testing.T) { + for _, tt := range allMainTests() { + t.Run(tt.testName, func(t *testing.T) { + // create a sub folder + if err := os.MkdirAll(filepath.Join(expectedFolder, tt.testName), defaultDirectoryPermission); err != nil { + t.Errorf("Bad test %s: %s", tt.testName, err) + } -// err := subcmds.Main(tt.args.Args(dataFolder, expectedFolder)) -// if err != nil { -// t.Errorf("Bad test %s: %s", tt.testName, err) -// } -// }) -// } -// } + err := subcmds.Main(tt.args.Args(dataFolder, expectedFolder)) + if err != nil { + t.Errorf("Bad test %s: %s", tt.testName, err) + } + }) + } +} From 4919d003da77eb6511bde04412a60fad5afd55a3 Mon Sep 17 00:00:00 2001 From: Yair Slobodin <154875779+YairSlobodin1@users.noreply.github.com> Date: Tue, 1 Oct 2024 09:52:05 +0300 Subject: [PATCH 056/131] Read sgs (#192) --- pkg/io/confio/parse_sgs.go | 178 ++++++++++++++++++++++++++++++++++++- pkg/ir/sg.go | 2 + pkg/utils/utils.go | 16 ++++ 3 files changed, 194 insertions(+), 2 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index b7892297..91853903 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -5,8 +5,182 @@ SPDX-License-Identifier: Apache-2.0 package confio -import "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +import ( + "fmt" + "log" + "github.com/IBM/vpc-go-sdk/vpcv1" + + "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/utils" +) + +// ReadSG translates SGs from a config_object file to map[ir.SGName]*SG func ReadSGs(filename string) (*ir.SGCollection, error) { - return nil, nil + config, err := readModel(filename) + if err != nil { + return nil, err + } + + result := ir.NewSGCollection() + for i, sg := range config.SecurityGroupList { + inbound, outbound, err := translateSGRules(&sg.SecurityGroup) + if err != nil { + return nil, err + } + if sg.Name == nil || sg.VPC == nil || sg.VPC.Name == nil { + log.Printf("Warning: missing SG/VPC name in sg at index %d\n", i) + continue + } + vpcName := *sg.VPC.Name + if result.SGs[vpcName] == nil { + result.SGs[vpcName] = make(map[ir.SGName]*ir.SG) + } + result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, OutboundRules: outbound} + } + return result, nil +} + +// parse security rules, splitted into ingress and egress rules +func translateSGRules(sg *vpcv1.SecurityGroup) (ingressRules, egressRules []*ir.SGRule, err error) { + for index := range sg.Rules { + rule, err := translateSGRule(sg, index) + if err != nil { + return nil, nil, err + } + if rule.Direction == ir.Inbound { + ingressRules = append(ingressRules, rule) + } else { + egressRules = append(egressRules, rule) + } + } + return ingressRules, egressRules, nil +} + +// translateSGRule translates a security group rule to ir.SGRule +func translateSGRule(sg *vpcv1.SecurityGroup, index int) (sgRule *ir.SGRule, err error) { + switch r := sg.Rules[index].(type) { + case *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll: + return translateSGRuleProtocolAll(r) + case *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp: + return translateSGRuleProtocolTCPUDP(r) + case *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp: + return translateSGRuleProtocolIcmp(r) + } + return nil, fmt.Errorf("error parsing rule number %d in sg %s in VPC %s", index, *sg.Name, *sg.VPC.Name) +} + +func translateSGRuleProtocolAll(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll) (sgRule *ir.SGRule, err error) { + direction, err := translateDirection(*rule.Direction) + if err != nil { + return nil, err + } + remote, err := translateRemote(rule.Remote) + if err != nil { + return nil, err + } + local, err := translateLocal(rule.Local) + if err != nil { + return nil, err + } + return &ir.SGRule{Direction: direction, Remote: remote, Protocol: netp.AnyProtocol{}, Local: local}, nil +} + +func translateSGRuleProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (sgRule *ir.SGRule, err error) { + direction, err := translateDirection(*rule.Direction) + if err != nil { + return nil, err + } + remote, err := translateRemote(rule.Remote) + if err != nil { + return nil, err + } + local, err := translateLocal(rule.Local) + if err != nil { + return nil, err + } + protocol, err := translateProtocolTCPUDP(rule) + if err != nil { + return nil, err + } + return &ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil +} + +func translateSGRuleProtocolIcmp(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp) (sgRule *ir.SGRule, err error) { + direction, err := translateDirection(*rule.Direction) + if err != nil { + return nil, err + } + remote, err := translateRemote(rule.Remote) + if err != nil { + return nil, err + } + local, err := translateLocal(rule.Local) + if err != nil { + return nil, err + } + protocol, err := netp.ICMPFromTypeAndCode64(rule.Type, rule.Code) + if err != nil { + return nil, err + } + return &ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil +} + +func translateDirection(direction string) (ir.Direction, error) { + if direction == "inbound" { + return ir.Inbound, nil + } else if direction == "outbound" { + return ir.Outbound, nil + } + return ir.Inbound, fmt.Errorf("SG rule direction must be either inbound or outbound") +} + +func translateRemote(remote vpcv1.SecurityGroupRuleRemoteIntf) (ir.RemoteType, error) { + if r, ok := remote.(*vpcv1.SecurityGroupRuleRemote); ok { + switch { + case r.CIDRBlock != nil: + return netset.IPBlockFromCidr(*r.CIDRBlock) + case r.Address != nil: + return netset.IPBlockFromIPAddress(*r.Address) + case r.Name != nil: + return ir.SGName(*r.Name), nil + } + } + return nil, fmt.Errorf("unexpected SG rule remote") +} + +func translateLocal(local vpcv1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, error) { + var err error + var ipAddrs *netset.IPBlock + if l, ok := local.(*vpcv1.SecurityGroupRuleLocal); ok { + if l.CIDRBlock != nil { + ipAddrs, err = netset.IPBlockFromCidr(*l.CIDRBlock) + } + if l.Address != nil { + ipAddrs, err = netset.IPBlockFromIPAddress(*l.CIDRBlock) + } + if err != nil { + return nil, err + } + return verifyLocalValue(ipAddrs) + } + return nil, fmt.Errorf("error parsing Local field") +} + +// temporary - first version of optimization requires local = 0.0.0.0/32 +func verifyLocalValue(ipAddrs *netset.IPBlock) (*netset.IPBlock, error) { + if !ipAddrs.Equal(netset.GetCidrAll()) { + return nil, fmt.Errorf("only 0.0.0.0/32 CIDR block is supported for local values") + } + return ipAddrs, nil +} + +func translateProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (netp.Protocol, error) { + isTCP := *rule.Protocol == vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudpProtocolTCPConst + minDstPort := utils.GetProperty(rule.PortMin, netp.MinPort) + maxDstPort := utils.GetProperty(rule.PortMax, netp.MaxPort) + return netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(minDstPort), int(maxDstPort)) } diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 0011b011..e90538d5 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -10,6 +10,7 @@ import ( "reflect" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) @@ -40,6 +41,7 @@ type SGRule struct { Direction Direction Remote RemoteType Protocol netp.Protocol + Local *netset.IPBlock Explanation string } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index acf9e3d2..ede1bb67 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -31,3 +31,19 @@ func SortedAllInnerMapsKeys[T, K cmp.Ordered, V any](m map[K]map[T]V) []T { slices.Sort(keys) return keys } + +// GetProperty returns pointer p if it is valid, else it returns the provided default value +// used to get min/max port or icmp type +func GetProperty(p *int64, defaultP int64) int64 { + if p == nil { + return defaultP + } + return *p +} + +func Int64PointerToIntPointer(v *int64) *int { + if v == nil { + return nil + } + return Ptr(int(*v)) +} From 2de0e771a168ecfe5ca8fcdaffd7e7307b84b732 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 1 Oct 2024 19:17:22 +0300 Subject: [PATCH 057/131] wip --- pkg/optimize/compressRules.go | 2 +- pkg/optimize/sg.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/optimize/compressRules.go b/pkg/optimize/compressRules.go index 6f9bb4d8..687ed963 100644 --- a/pkg/optimize/compressRules.go +++ b/pkg/optimize/compressRules.go @@ -43,7 +43,7 @@ func compressThreeProtocolsToAllProtocol(spans *sgSpansToSGPerProtocol) *sgSpans // observation: It pays to switch to all protocol rule when we have rules that cover all other protocols // on exactly the same cidr (only one protocol can exceed). -func compressToAllProtocolRule(span *sgSpansToIPPerProtocol) *sgSpansToIPPerProtocol { +func compressSpansToIP(span *sgSpansToIPPerProtocol) *sgSpansToIPPerProtocol { t := 0 u := 0 i := 0 diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index fc39861e..b30df27f 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -160,7 +160,7 @@ func reduceSGRulesToSG(spans *sgSpansToSGPerProtocol, direction ir.Direction) [] } func reduceSGRulesToIPAddrs(spans *sgSpansToIPPerProtocol, direction ir.Direction) []*ir.SGRule { - spans = compressToAllProtocolRule(spans) + spans = compressSpansToIP(spans) // spans to SG rules tcpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, true) From 02cae44c748a332434c595ad4e89d1032f7fd581 Mon Sep 17 00:00:00 2001 From: Yair Slobodin <154875779+YairSlobodin1@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:43:53 +0300 Subject: [PATCH 058/131] Optimize output and flags (#193) --- cmd/subcmds/optimize.go | 24 +++++++++++- cmd/subcmds/optimizeOutput.go | 14 ------- cmd/subcmds/optimizeSG.go | 23 +++--------- cmd/subcmds/output.go | 57 +++++++++++++---------------- cmd/subcmds/outputFormat.go | 6 +-- cmd/subcmds/root.go | 46 +++++++++++++---------- cmd/subcmds/synth.go | 11 +++++- cmd/subcmds/unmarshal.go | 7 ++++ cmd/subcmds/validateFlags.go | 24 ++++++++++++ pkg/io/confio/parse_acls.go | 12 ++++++ pkg/io/csvio/sg.go | 18 +++++---- pkg/io/mdio/sg.go | 18 +++++---- pkg/io/tfio/acl.go | 8 +++- pkg/io/tfio/sg.go | 53 ++++++++++++++++----------- pkg/ir/acl.go | 69 +++++++++++++++++++---------------- pkg/ir/common.go | 23 +++++++----- pkg/ir/sg.go | 63 ++++++++++++++++++-------------- pkg/optimize/common.go | 13 +++++++ pkg/optimize/sg.go | 18 ++++++++- pkg/synth/common.go | 1 + 20 files changed, 311 insertions(+), 197 deletions(-) delete mode 100644 cmd/subcmds/optimizeOutput.go create mode 100644 cmd/subcmds/validateFlags.go create mode 100644 pkg/io/confio/parse_acls.go create mode 100644 pkg/optimize/common.go diff --git a/cmd/subcmds/optimize.go b/cmd/subcmds/optimize.go index 877662a9..353a86eb 100644 --- a/cmd/subcmds/optimize.go +++ b/cmd/subcmds/optimize.go @@ -5,7 +5,14 @@ SPDX-License-Identifier: Apache-2.0 package subcmds -import "github.com/spf13/cobra" +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" +) func NewOptimizeCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ @@ -14,7 +21,22 @@ func NewOptimizeCommand(args *inArgs) *cobra.Command { Long: `optimization of existing SG (nACLS are not supported yet)`, } + // sub cmds cmd.AddCommand(NewOptimizeSGCommand(args)) return cmd } + +func optimization(cmd *cobra.Command, args *inArgs, newOptimizer func(ir.Collection, string) optimize.Optimizer, isSG bool) error { + cmd.SilenceUsage = true // if we got this far, flags are syntactically correct, so no need to print usage + collection, err := parseCollection(args, isSG) + if err != nil { + return fmt.Errorf("could not parse config file %v: %w", args.configFile, err) + } + optimizer := newOptimizer(collection, args.firewallName) + optimizedCollection, err := optimizer.Optimize() + if err != nil { + return err + } + return writeOutput(args, optimizedCollection, collection.VpcNames(), false) +} diff --git a/cmd/subcmds/optimizeOutput.go b/cmd/subcmds/optimizeOutput.go deleted file mode 100644 index af92e337..00000000 --- a/cmd/subcmds/optimizeOutput.go +++ /dev/null @@ -1,14 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package subcmds - -import ( - "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" -) - -func writeOptimizeOutput(_ *inArgs, _ ir.Collection) error { - return nil -} diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go index 57ee6c32..7b5fe908 100644 --- a/cmd/subcmds/optimizeSG.go +++ b/cmd/subcmds/optimizeSG.go @@ -6,14 +6,13 @@ SPDX-License-Identifier: Apache-2.0 package subcmds import ( - "fmt" - "github.com/spf13/cobra" - "github.com/np-guard/vpc-network-config-synthesis/pkg/io/confio" "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" ) +const sgNameFlag = "sg-name" + func NewOptimizeSGCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "sg", @@ -21,24 +20,12 @@ func NewOptimizeSGCommand(args *inArgs) *cobra.Command { Long: `OptimizeSG attempts to reduce the number of security group rules in a SG without changing the semantic.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { - return optimization(cmd, args) + return optimization(cmd, args, optimize.NewSGOptimizer, true) }, } - cmd.Flags().StringVarP(&args.sgName, sgNameFlag, "s", "", "which SG to optimize") - _ = cmd.MarkFlagRequired(sgNameFlag) // Todo: delete this line. if sgName flag is not supplied - optimize all SGs + // flags + cmd.PersistentFlags().StringVarP(&args.firewallName, sgNameFlag, "n", "", "which security group to optimize") return cmd } - -func optimization(cmd *cobra.Command, args *inArgs) error { - cmd.SilenceUsage = true // if we got this far, flags are syntactically correct, so no need to print usage - sgs, err := confio.ReadSGs(args.configFile) - if err != nil { - return fmt.Errorf("could not parse config file %v: %w", args.configFile, err) - } - if optimize.ReduceSGRules(sgs, args.sgName) != nil { - return err - } - return writeOptimizeOutput(args, sgs) -} diff --git a/cmd/subcmds/output.go b/cmd/subcmds/output.go index aa817b7e..b3f71013 100644 --- a/cmd/subcmds/output.go +++ b/cmd/subcmds/output.go @@ -16,33 +16,27 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/io/csvio" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/mdio" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/tfio" - "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) const defaultFilePermission = 0o644 const defaultDirectoryPermission = 0o755 -func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error { - if err := updateOutputFormat(args); err != nil { - return err - } - if args.outputDir != "" && args.outputFmt == apiOutputFormat { - return fmt.Errorf("-d cannot be used with format json") - } +func writeOutput(args *inArgs, collection ir.Collection, vpcNames []string, isSynth bool) error { if args.outputDir != "" { // create the directory if needed if err := os.MkdirAll(args.outputDir, defaultDirectoryPermission); err != nil { return err } } - if err := writeLocals(args, collection, vpcNames); err != nil { + + if err := writeLocals(args, vpcNames, collection); err != nil { return err } var data *bytes.Buffer var err error if args.outputDir == "" { - if data, err = writeCollection(args, collection, ""); err != nil { + if data, err = writeCollection(args, collection, "", isSynth); err != nil { return err } return writeToFile(args.outputFile, data) @@ -55,7 +49,7 @@ func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error if args.prefix != "" { args.outputFile = args.outputDir + "/" + args.prefix + "_" + suffix } - if data, err = writeCollection(args, collection, vpc); err != nil { + if data, err = writeCollection(args, collection, vpc, isSynth); err != nil { return err } if err := writeToFile(args.outputFile, data); err != nil { @@ -65,9 +59,9 @@ func writeOutput(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error return nil } -func writeCollection(args *inArgs, collection ir.Collection, vpc string) (*bytes.Buffer, error) { +func writeCollection(args *inArgs, collection ir.Collection, vpc string, isSynth bool) (*bytes.Buffer, error) { var data bytes.Buffer - writer, err := pickWriter(args, &data) + writer, err := pickWriter(args, &data, isSynth) if err != nil { return nil, err } @@ -77,15 +71,7 @@ func writeCollection(args *inArgs, collection ir.Collection, vpc string) (*bytes return &data, nil } -func writeToFile(outputFile string, data *bytes.Buffer) error { - if outputFile == "" { - fmt.Println(data.String()) - return nil - } - return os.WriteFile(outputFile, data.Bytes(), defaultFilePermission) -} - -func pickWriter(args *inArgs, data *bytes.Buffer) (ir.Writer, error) { +func pickWriter(args *inArgs, data *bytes.Buffer, isSynth bool) (ir.Writer, error) { w := bufio.NewWriter(data) switch args.outputFmt { case tfOutputFormat: @@ -94,24 +80,31 @@ func pickWriter(args *inArgs, data *bytes.Buffer) (ir.Writer, error) { return csvio.NewWriter(w), nil case mdOutputFormat: return mdio.NewWriter(w), nil - case apiOutputFormat: - return confio.NewWriter(w, args.configFile) - default: - return nil, fmt.Errorf("bad output format: %q", args.outputFmt) + case jsonOutputFormat: + if isSynth { + return confio.NewWriter(w, args.configFile) + } } + return nil, fmt.Errorf("bad output format: %q", args.outputFmt) } -func writeLocals(args *inArgs, collection ir.Collection, vpcNames []ir.ID) error { - if !args.locals { +func writeToFile(outputFile string, data *bytes.Buffer) error { + if outputFile == "" { + fmt.Println(data.String()) return nil } - if args.outputFmt != tfOutputFormat { - return fmt.Errorf("--locals flag requires setting the output format to tf") - } + return os.WriteFile(outputFile, data.Bytes(), defaultFilePermission) +} - _, isACLCollection := collection.(*ir.ACLCollection) +func writeLocals(args *inArgs, vpcNames []ir.ID, collection ir.Collection) error { + if !args.locals { + return nil + } var data *bytes.Buffer var err error + + _, isACLCollection := collection.(*ir.ACLCollection) + if data, err = tfio.WriteLocals(vpcNames, isACLCollection); err != nil { return err } diff --git a/cmd/subcmds/outputFormat.go b/cmd/subcmds/outputFormat.go index 51a36c60..f435c43a 100644 --- a/cmd/subcmds/outputFormat.go +++ b/cmd/subcmds/outputFormat.go @@ -14,11 +14,11 @@ const ( tfOutputFormat = "tf" csvOutputFormat = "csv" mdOutputFormat = "md" - apiOutputFormat = "json" + jsonOutputFormat = "json" defaultOutputFormat = csvOutputFormat ) -var outputFormats = []string{tfOutputFormat, csvOutputFormat, mdOutputFormat, apiOutputFormat} +var outputFormats = []string{tfOutputFormat, csvOutputFormat, mdOutputFormat, jsonOutputFormat} func updateOutputFormat(args *inArgs) error { var err error @@ -40,7 +40,7 @@ func inferFormatUsingFilename(filename string) (string, error) { case strings.HasSuffix(filename, ".md"): return mdOutputFormat, nil case strings.HasSuffix(filename, ".json"): - return apiOutputFormat, nil + return jsonOutputFormat, nil default: return "", fmt.Errorf("bad output format") } diff --git a/cmd/subcmds/root.go b/cmd/subcmds/root.go index 1f47e591..98ff7973 100644 --- a/cmd/subcmds/root.go +++ b/cmd/subcmds/root.go @@ -14,56 +14,62 @@ import ( const ( configFlag = "config" - specFlag = "spec" outputFmtFlag = "format" outputFileFlag = "output-file" outputDirFlag = "output-dir" prefixFlag = "prefix" - sgNameFlag = "sg-name" singleACLFlag = "single" localsFlag = "locals" ) type inArgs struct { - configFile string - specFile string - outputFmt string - outputFile string - outputDir string - prefix string - sgName string - singleacl bool - locals bool + configFile string + specFile string + outputFmt string + outputFile string + outputDir string + prefix string + firewallName string + singleacl bool + locals bool } func NewRootCommand() *cobra.Command { args := &inArgs{} + // allow PersistentPreRunE + cobra.EnableTraverseRunHooks = true + rootCmd := &cobra.Command{ Use: "vpcgen", - Short: "Tool for automatic synthesis of VPC network configurations", - Long: `Tool for automatic synthesis of VPC network configurations, namely Network ACLs and Security Groups.`, + Short: "A tool for synthesizing and optimizing VPC network configurations", + Long: `A tool for synthesizing and optimizing VPC network configurations, namely Network ACLs and Security Groups.`, + PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { + return validateFlags(args) + }, } + // flags rootCmd.PersistentFlags().StringVarP(&args.configFile, configFlag, "c", "", "JSON file containing a configuration object of existing resources") rootCmd.PersistentFlags().StringVarP(&args.outputFmt, outputFmtFlag, "f", "", "Output format; "+mustBeOneOf(outputFormats)) rootCmd.PersistentFlags().StringVarP(&args.outputFile, outputFileFlag, "o", "", "Write all generated resources to the specified file.") - rootCmd.PersistentFlags().StringVarP(&args.outputDir, outputDirFlag, "d", "", - "Write generated resources to files in the specified directory, one file per VPC.") - rootCmd.PersistentFlags().StringVarP(&args.prefix, prefixFlag, "p", "", "The prefix of the files that will be created.") rootCmd.PersistentFlags().BoolVarP(&args.locals, localsFlag, "l", false, "whether to generate a locals.tf file (only possible when the output format is tf)") - rootCmd.PersistentFlags().SortFlags = false + // flags set for all commands + rootCmd.PersistentFlags().SortFlags = false _ = rootCmd.MarkPersistentFlagRequired(configFlag) - rootCmd.MarkFlagsMutuallyExclusive(outputFileFlag, outputDirFlag) + // sub cmds rootCmd.AddCommand(NewSynthCommand(args)) rootCmd.AddCommand(NewOptimizeCommand(args)) - rootCmd.CompletionOptions.HiddenDefaultCmd = true - rootCmd.SetHelpCommand(&cobra.Command{Hidden: true}) // disable help command. should use --help flag instead + // prevent Cobra from creating a default 'completion' command + rootCmd.CompletionOptions.DisableDefaultCmd = true + + // disable help command. should use --help flag instead + rootCmd.SetHelpCommand(&cobra.Command{Hidden: true}) return rootCmd } diff --git a/cmd/subcmds/synth.go b/cmd/subcmds/synth.go index ef0f81d4..83eb348a 100644 --- a/cmd/subcmds/synth.go +++ b/cmd/subcmds/synth.go @@ -13,6 +13,8 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) +const specFlag = "spec" + func NewSynthCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "synth", @@ -21,9 +23,16 @@ func NewSynthCommand(args *inArgs) *cobra.Command { --config and --spec parameters must be supplied.`, } + // flags cmd.PersistentFlags().StringVarP(&args.specFile, specFlag, "s", "", "JSON file containing spec file") + cmd.PersistentFlags().StringVarP(&args.outputDir, outputDirFlag, "d", "", + "Write generated resources to files in the specified directory, one file per VPC.") + cmd.PersistentFlags().StringVarP(&args.prefix, prefixFlag, "p", "", "The prefix of the files that will be created.") + + // flags settings _ = cmd.MarkPersistentFlagRequired(specFlag) + // sub cmds cmd.AddCommand(NewSynthACLCommand(args)) cmd.AddCommand(NewSynthSGCommand(args)) @@ -41,5 +50,5 @@ func synthesis(cmd *cobra.Command, args *inArgs, newSynthesizer func(*ir.Spec, b if err != nil { return err } - return writeOutput(args, collection, utils.MapKeys(spec.Defs.ConfigDefs.VPCs)) + return writeOutput(args, collection, utils.MapKeys(spec.Defs.ConfigDefs.VPCs), true) } diff --git a/cmd/subcmds/unmarshal.go b/cmd/subcmds/unmarshal.go index 5fa7c720..fcb1f76e 100644 --- a/cmd/subcmds/unmarshal.go +++ b/cmd/subcmds/unmarshal.go @@ -26,3 +26,10 @@ func unmarshal(args *inArgs) (*ir.Spec, error) { return model, nil } + +func parseCollection(args *inArgs, isSG bool) (ir.Collection, error) { + if isSG { + return confio.ReadSGs(args.configFile) + } + return confio.ReadACLs(args.configFile) +} diff --git a/cmd/subcmds/validateFlags.go b/cmd/subcmds/validateFlags.go new file mode 100644 index 00000000..be56f6fd --- /dev/null +++ b/cmd/subcmds/validateFlags.go @@ -0,0 +1,24 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package subcmds + +import "fmt" + +func validateFlags(args *inArgs) error { + if args.outputDir != "" && args.outputFile != "" { + return fmt.Errorf("specifying both -d and -o is not allowed") + } + if err := updateOutputFormat(args); err != nil { + return err + } + if args.outputDir != "" && args.outputFmt == jsonOutputFormat { + return fmt.Errorf("-d cannot be used with format json") + } + if args.locals && args.outputFmt != tfOutputFormat { + return fmt.Errorf("--locals flag requires setting the output format to tf") + } + return nil +} diff --git a/pkg/io/confio/parse_acls.go b/pkg/io/confio/parse_acls.go new file mode 100644 index 00000000..13481978 --- /dev/null +++ b/pkg/io/confio/parse_acls.go @@ -0,0 +1,12 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package confio + +import "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + +func ReadACLs(_ string) (*ir.ACLCollection, error) { + return nil, nil +} diff --git a/pkg/io/csvio/sg.go b/pkg/io/csvio/sg.go index ed91a1ef..35c74f8b 100644 --- a/pkg/io/csvio/sg.go +++ b/pkg/io/csvio/sg.go @@ -20,14 +20,18 @@ func (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { if err := w.w.WriteAll(sgHeader()); err != nil { return err } - for _, sgName := range collection.SortedSGNames(vpc) { - vpcName := ir.VpcFromScopedResource(string(sgName)) - sgTable, err := makeSGTable(collection.SGs[vpcName][sgName], sgName) - if err != nil { - return err + for _, vpcName := range collection.VpcNames() { + if vpc != vpcName && vpc != "" { + continue } - if err := w.w.WriteAll(sgTable); err != nil { - return err + for _, sgName := range collection.SortedSGNames(vpcName) { + sgTable, err := makeSGTable(collection.SGs[vpcName][sgName], sgName) + if err != nil { + return err + } + if err := w.w.WriteAll(sgTable); err != nil { + return err + } } } return nil diff --git a/pkg/io/mdio/sg.go b/pkg/io/mdio/sg.go index 3277b3fa..0fcbf734 100644 --- a/pkg/io/mdio/sg.go +++ b/pkg/io/mdio/sg.go @@ -20,14 +20,18 @@ func (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { if err := w.writeAll(sgHeader()); err != nil { return err } - for _, sgName := range collection.SortedSGNames(vpc) { - vpcName := ir.VpcFromScopedResource(string(sgName)) - sgTable, err := makeSGTable(collection.SGs[vpcName][sgName], sgName) - if err != nil { - return err + for _, vpcName := range collection.VpcNames() { + if vpc != vpcName && vpc != "" { + continue } - if err := w.writeAll(sgTable); err != nil { - return err + for _, sgName := range collection.SortedSGNames(vpcName) { + sgTable, err := makeSGTable(collection.SGs[vpcName][sgName], sgName) + if err != nil { + return err + } + if err := w.writeAll(sgTable); err != nil { + return err + } } } return nil diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index b0dd23e8..7f641d3b 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -64,8 +64,14 @@ func aclRule(rule *ir.ACLRule, name string) (tf.Block, error) { {Name: "source", Value: quote(rule.Source.String())}, {Name: "destination", Value: quote(rule.Destination.String())}, } + + comment := "" + if rule.Explanation != "" { + comment = fmt.Sprintf("# %v", rule.Explanation) + } + return tf.Block{Name: "rules", - Comment: fmt.Sprintf("# %v", rule.Explanation), + Comment: comment, Arguments: arguments, Blocks: aclProtocol(rule.Protocol), }, nil diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 747be97d..793c5c7a 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -72,10 +72,15 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { return tf.Block{}, err } + comment := "" + if rule.Explanation != "" { + comment = fmt.Sprintf("# %v", rule.Explanation) + } + return tf.Block{ Name: "resource", Labels: []string{quote("ibm_is_security_group_rule"), ir.ChangeScoping(quote(ruleName))}, - Comment: fmt.Sprintf("# %v", rule.Explanation), + Comment: comment, Arguments: []tf.Argument{ {Name: "group", Value: group}, {Name: "direction", Value: quote(direction(rule.Direction))}, @@ -85,42 +90,48 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { }, nil } -func sg(sgName, comment string) (tf.Block, error) { - vpcName := ir.VpcFromScopedResource(sgName) - sgName = ir.ChangeScoping(sgName) - if err := verifyName(sgName); err != nil { +func sg(sgName, vpcName string) (tf.Block, error) { + tfSGName := ir.ChangeScoping(sgName) + comment := fmt.Sprintf("\n### SG attached to %s", sgName) + if sgName == tfSGName { // its optimization + comment = "" + } + if err := verifyName(tfSGName); err != nil { return tf.Block{}, err } return tf.Block{ Name: "resource", //nolint:revive // obvious false positive - Labels: []string{quote("ibm_is_security_group"), ir.ChangeScoping(quote(sgName))}, + Labels: []string{quote("ibm_is_security_group"), quote(tfSGName)}, Comment: comment, Arguments: []tf.Argument{ - {Name: "name", Value: quote("sg-" + sgName)}, + {Name: "name", Value: quote("sg-" + tfSGName)}, {Name: "resource_group", Value: "local.sg_synth_resource_group_id"}, {Name: "vpc", Value: fmt.Sprintf("local.sg_synth_%s_id", vpcName)}, }, }, nil } -func sgCollection(t *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { - var resources []tf.Block //nolint:prealloc // nontrivial to calculate, and an unlikely performance bottleneck - for _, sgName := range t.SortedSGNames(vpc) { - comment := "" - vpcName := ir.VpcFromScopedResource(string(sgName)) - rules := t.SGs[vpcName][sgName].AllRules() - comment = fmt.Sprintf("\n### SG attached to %v", sgName) - sg, err := sg(sgName.String(), comment) - if err != nil { - return nil, err +func sgCollection(collection *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { + var resources []tf.Block + + for _, vpcName := range collection.VpcNames() { + if vpc != vpcName && vpc != "" { + continue } - resources = append(resources, sg) - for i, rule := range rules { - rule, err := sgRule(rule, sgName, i) + for _, sgName := range collection.SortedSGNames(vpcName) { + rules := collection.SGs[vpcName][sgName].AllRules() + sg, err := sg(sgName.String(), vpcName) if err != nil { return nil, err } - resources = append(resources, rule) + resources = append(resources, sg) + for i, rule := range rules { + rule, err := sgRule(rule, sgName, i) + if err != nil { + return nil, err + } + resources = append(resources, rule) + } } } return &tf.ConfigFile{ diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index b1de36c3..e13b91bb 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -15,36 +15,38 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -type Action string +type ( + Action string + + ACLRule struct { + Action Action + Direction Direction + Source *netset.IPBlock + Destination *netset.IPBlock + Protocol netp.Protocol + Explanation string + } + + ACL struct { + Subnet string + Internal []*ACLRule + External []*ACLRule + } + + ACLCollection struct { + ACLs map[ID]map[string]*ACL + } + + ACLWriter interface { + WriteACL(aclColl *ACLCollection, vpc string) error + } +) const ( Allow Action = "allow" Deny Action = "deny" ) -type ACLRule struct { - Action Action - Direction Direction - Source *netset.IPBlock - Destination *netset.IPBlock - Protocol netp.Protocol - Explanation string -} - -type ACL struct { - Subnet string - Internal []*ACLRule - External []*ACLRule -} - -type ACLCollection struct { - ACLs map[ID]map[string]*ACL -} - -type ACLWriter interface { - WriteACL(aclColl *ACLCollection, vpc string) error -} - func (r *ACLRule) isRedundant(rules []*ACLRule) bool { for _, rule := range rules { if rule.mustSupersede(r) { @@ -105,24 +107,27 @@ func NewACLCollection() *ACLCollection { return &ACLCollection{ACLs: map[ID]map[string]*ACL{}} } -func NewACL() *ACL { - return &ACL{Internal: []*ACLRule{}, External: []*ACLRule{}} +func NewACL(subnet string) *ACL { + return &ACL{Subnet: subnet, Internal: []*ACLRule{}, External: []*ACLRule{}} } -func (c *ACLCollection) LookupOrCreate(name string) *ACL { - vpcName := VpcFromScopedResource(name) - if acl, ok := c.ACLs[vpcName][name]; ok { +func (c *ACLCollection) LookupOrCreate(subnet string) *ACL { + vpcName := VpcFromScopedResource(subnet) + if acl, ok := c.ACLs[vpcName][subnet]; ok { return acl } - newACL := NewACL() - newACL.Subnet = name + newACL := NewACL(subnet) if c.ACLs[vpcName] == nil { c.ACLs[vpcName] = make(map[string]*ACL) } - c.ACLs[vpcName][name] = newACL + c.ACLs[vpcName][subnet] = newACL return newACL } +func (c *ACLCollection) VpcNames() []string { + return utils.SortedMapKeys(c.ACLs) +} + func (c *ACLCollection) Write(w Writer, vpc string) error { return w.WriteACL(c, vpc) } diff --git a/pkg/ir/common.go b/pkg/ir/common.go index e10b1265..a89aeae8 100644 --- a/pkg/ir/common.go +++ b/pkg/ir/common.go @@ -5,18 +5,21 @@ SPDX-License-Identifier: Apache-2.0 package ir -type Direction string +type ( + Direction string + + Collection interface { + Write(writer Writer, vpc string) error + VpcNames() []string + } + + Writer interface { + ACLWriter + SGWriter + } +) const ( Outbound Direction = "outbound" Inbound Direction = "inbound" ) - -type Writer interface { - ACLWriter - SGWriter -} - -type Collection interface { - Write(writer Writer, vpc string) error -} diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index e90538d5..2317a4ec 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -26,37 +26,40 @@ const ( SGResourceFileShareMountTarget SGResource = "fsmt" ) -type SGName string +type ( + SGName string -func (s SGName) String() string { - return string(s) -} + RemoteType interface { + fmt.Stringer + // *netset.IPBlock | SGName + } -type RemoteType interface { - fmt.Stringer - // *netset.IPBlock | SGName -} + SGRule struct { + Direction Direction + Remote RemoteType + Protocol netp.Protocol + Local *netset.IPBlock + Explanation string + } -type SGRule struct { - Direction Direction - Remote RemoteType - Protocol netp.Protocol - Local *netset.IPBlock - Explanation string -} + SG struct { + SGName SGName + InboundRules []*SGRule + OutboundRules []*SGRule + Attached []ID + } -type SG struct { - InboundRules []*SGRule - OutboundRules []*SGRule - Attached []ID -} + SGCollection struct { + SGs map[ID]map[SGName]*SG + } -type SGCollection struct { - SGs map[ID]map[SGName]*SG -} + SGWriter interface { + WriteSG(sgColl *SGCollection, vpc string) error + } +) -type SGWriter interface { - WriteSG(sgColl *SGCollection, vpc string) error +func (s SGName) String() string { + return string(s) } func (r *SGRule) isRedundant(rules []*SGRule) bool { @@ -76,8 +79,8 @@ func (r *SGRule) mustSupersede(other *SGRule) bool { return res } -func NewSG() *SG { - return &SG{InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Attached: []ID{}} +func NewSG(sgName SGName) *SG { + return &SG{SGName: sgName, InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Attached: []ID{}} } func NewSGCollection() *SGCollection { @@ -89,7 +92,7 @@ func (c *SGCollection) LookupOrCreate(name SGName) *SG { if sg, ok := c.SGs[vpcName][name]; ok { return sg } - newSG := NewSG() + newSG := NewSG(name) if c.SGs[vpcName] == nil { c.SGs[vpcName] = make(map[SGName]*SG) } @@ -110,6 +113,10 @@ func (a *SG) AllRules() []*SGRule { return append(a.InboundRules, a.OutboundRules...) } +func (c *SGCollection) VpcNames() []string { + return utils.SortedMapKeys(c.SGs) +} + func (c *SGCollection) Write(w Writer, vpc string) error { return w.WriteSG(c, vpc) } diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go new file mode 100644 index 00000000..010c2239 --- /dev/null +++ b/pkg/optimize/common.go @@ -0,0 +1,13 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + +type Optimizer interface { + // attempts to reduce number of SG/nACL rules + Optimize() (ir.Collection, error) +} diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg.go index f3301962..3288d2a7 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg.go @@ -9,6 +9,20 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func ReduceSGRules(_ *ir.SGCollection, _ string) error { - return nil +type SGOptimizer struct { + sgCollection *ir.SGCollection + sgName ir.SGName + sgVPC *string +} + +func NewSGOptimizer(collection ir.Collection, sgName string) Optimizer { + components := ir.ScopingComponents(sgName) + if len(components) == 1 { + return &SGOptimizer{sgCollection: collection.(*ir.SGCollection), sgName: ir.SGName(sgName), sgVPC: nil} + } + return &SGOptimizer{sgCollection: collection.(*ir.SGCollection), sgName: ir.SGName(components[1]), sgVPC: &components[0]} +} + +func (s *SGOptimizer) Optimize() (ir.Collection, error) { + return s.sgCollection, nil } diff --git a/pkg/synth/common.go b/pkg/synth/common.go index e6e516f3..a9b7b51f 100644 --- a/pkg/synth/common.go +++ b/pkg/synth/common.go @@ -15,6 +15,7 @@ import ( type ( Synthesizer interface { + // generates SGs/nACLs Synth() (ir.Collection, error) } From 11effb77d7433383b3a61fc607607cb7f1436552 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 7 Oct 2024 13:15:45 +0300 Subject: [PATCH 059/131] fix merging --- cmd/subcmds/synthACL.go | 3 --- cmd/subcmds/synthSG.go | 3 --- pkg/ir/acl.go | 4 ++-- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/cmd/subcmds/synthACL.go b/cmd/subcmds/synthACL.go index 96c6aea3..4aee4040 100644 --- a/cmd/subcmds/synthACL.go +++ b/cmd/subcmds/synthACL.go @@ -19,9 +19,6 @@ func NewSynthACLCommand(args *inArgs) *cobra.Command { Endpoints in the required-connectivity specification may be subnets, subnet segments, CIDR segments and externals.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { - if err := validateFlags(args); err != nil { - return err - } return synthesis(cmd, args, synth.NewACLSynthesizer, args.singleacl) }, } diff --git a/cmd/subcmds/synthSG.go b/cmd/subcmds/synthSG.go index 215324ca..88bb4a56 100644 --- a/cmd/subcmds/synthSG.go +++ b/cmd/subcmds/synthSG.go @@ -19,9 +19,6 @@ func NewSynthSGCommand(args *inArgs) *cobra.Command { Endpoints in the required-connectivity specification may be Instances (VSIs), Network Interfaces, VPEs and externals.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { - if err := validateFlags(args); err != nil { - return err - } return synthesis(cmd, args, synth.NewSGSynthesizer, false) }, } diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index ace507ab..e13b91bb 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -48,8 +48,8 @@ const ( ) func (r *ACLRule) isRedundant(rules []*ACLRule) bool { - for i := range rules { - if rules[i].mustSupersede(r) { + for _, rule := range rules { + if rule.mustSupersede(r) { return true } } From 2bb071974414ceb97148f52b7122eaaecb47873b Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 8 Oct 2024 18:35:42 +0300 Subject: [PATCH 060/131] models new version, cubes, wip --- cmd/subcmds/optimizeSG.go | 4 +- go.mod | 2 +- go.sum | 4 +- pkg/io/confio/parse_sgs.go | 2 +- pkg/optimize/common.go | 56 +- pkg/optimize/compressRules.go | 74 - pkg/optimize/ip.go | 81 - pkg/optimize/ipSpanToSGRules.go | 147 - pkg/optimize/sg/ipCubesToRules.go | 152 + pkg/optimize/sg/optimizeSG_test.go | 57 + pkg/optimize/sg/reduceCubes.go | 118 + pkg/optimize/sg/rulesToCubes.go | 106 + pkg/optimize/{ => sg}/sg.go | 108 +- .../sgCubesToRules.go} | 24 +- pkg/optimize/sgRulesToIPToSpan.go | 126 - pkg/optimize/sgRulesToSGToSpan.go | 66 - .../optimize_sg_icmp_codes/config_object.json | 2169 -------------- .../optimize_sg_icmp_codes/conn_spec.json | 143 - test/data/optimize_sg_icmp_codes/details.txt | 14 - .../optimize_sg_icmp_types/config_object.json | 2493 ----------------- .../optimize_sg_icmp_types/conn_spec.json | 359 --- test/data/optimize_sg_icmp_types/details.txt | 28 - .../optimize_sg_icmp_codes/sg_expected.tf | 70 - .../optimize_sg_icmp_types/sg_expected.tf | 67 - test/main_test_list.go | 18 - 25 files changed, 554 insertions(+), 5934 deletions(-) delete mode 100644 pkg/optimize/compressRules.go delete mode 100644 pkg/optimize/ip.go delete mode 100644 pkg/optimize/ipSpanToSGRules.go create mode 100644 pkg/optimize/sg/ipCubesToRules.go create mode 100644 pkg/optimize/sg/optimizeSG_test.go create mode 100644 pkg/optimize/sg/reduceCubes.go create mode 100644 pkg/optimize/sg/rulesToCubes.go rename pkg/optimize/{ => sg}/sg.go (59%) rename pkg/optimize/{sgSpanToSGRules.go => sg/sgCubesToRules.go} (52%) delete mode 100644 pkg/optimize/sgRulesToIPToSpan.go delete mode 100644 pkg/optimize/sgRulesToSGToSpan.go delete mode 100644 test/data/optimize_sg_icmp_codes/config_object.json delete mode 100644 test/data/optimize_sg_icmp_codes/conn_spec.json delete mode 100644 test/data/optimize_sg_icmp_codes/details.txt delete mode 100644 test/data/optimize_sg_icmp_types/config_object.json delete mode 100644 test/data/optimize_sg_icmp_types/conn_spec.json delete mode 100644 test/data/optimize_sg_icmp_types/details.txt delete mode 100644 test/expected/optimize_sg_icmp_codes/sg_expected.tf delete mode 100644 test/expected/optimize_sg_icmp_types/sg_expected.tf diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go index 7b5fe908..9606234b 100644 --- a/cmd/subcmds/optimizeSG.go +++ b/cmd/subcmds/optimizeSG.go @@ -8,7 +8,7 @@ package subcmds import ( "github.com/spf13/cobra" - "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" + sgoptimizer "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize/sg" ) const sgNameFlag = "sg-name" @@ -20,7 +20,7 @@ func NewOptimizeSGCommand(args *inArgs) *cobra.Command { Long: `OptimizeSG attempts to reduce the number of security group rules in a SG without changing the semantic.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { - return optimization(cmd, args, optimize.NewSGOptimizer, true) + return optimization(cmd, args, sgoptimizer.NewSGOptimizer, true) }, } diff --git a/go.mod b/go.mod index 2a404e56..78ec72e8 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.0 require ( github.com/IBM/vpc-go-sdk v0.60.0 github.com/np-guard/cloud-resource-collector v0.15.0 - github.com/np-guard/models v0.5.0 + github.com/np-guard/models v0.5.1-0.20241008132809-1e27bae86fe4 github.com/spf13/cobra v1.8.1 ) diff --git a/go.sum b/go.sum index e4aac127..a83a5162 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.15.0 h1:jkmxql6D1uBr/qmSOsBzUgeDxlUXSCe7dBKfqfK+QZ4= github.com/np-guard/cloud-resource-collector v0.15.0/go.mod h1:klCHnNnuuVcCtGQHA7R1a8fqnvfMCk/5Jdld6V7sN2A= -github.com/np-guard/models v0.5.0 h1:P37gCg3RD23hZHymFWtthrF+mGIwyHJkWy0wIWIzokQ= -github.com/np-guard/models v0.5.0/go.mod h1:29M8utxinyUpYaDuIuOyCcMBf7EsMWZcIrRWCjFm0Bw= +github.com/np-guard/models v0.5.1-0.20241008132809-1e27bae86fe4 h1:wsf8U4t74ouuhLqdvxrf247pcjCPlrDhEggpUeskiHo= +github.com/np-guard/models v0.5.1-0.20241008132809-1e27bae86fe4/go.mod h1:29M8utxinyUpYaDuIuOyCcMBf7EsMWZcIrRWCjFm0Bw= 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= diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index 91853903..e1528913 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -122,7 +122,7 @@ func translateSGRuleProtocolIcmp(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleP if err != nil { return nil, err } - protocol, err := netp.ICMPFromTypeAndCode64(rule.Type, rule.Code) + protocol, err := netp.ICMPFromTypeAndCode64WithoutRFCValidation(rule.Type, rule.Code) if err != nil { return nil, err } diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index e802dbdd..d4ba3e45 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -9,7 +9,6 @@ import ( "sort" "github.com/np-guard/models/pkg/ds" - "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" @@ -22,12 +21,59 @@ type Optimizer interface { } // each IPBlock is a single CIDR. The CIDRs are disjoint. -func sortPartitionsByIPAddrs[T any](p []ds.Pair[*netset.IPBlock, T]) []ds.Pair[*netset.IPBlock, T] { - cmp := func(i, j int) bool { return p[i].Left.FirstIPAddress() < p[j].Left.FirstIPAddress() } +func SortPartitionsByIPAddrs[T any](p []ds.Pair[*netset.IPBlock, T]) []ds.Pair[*netset.IPBlock, T] { + cmp := func(i, j int) bool { + if p[i].Left.FirstIPAddress() == p[j].Left.FirstIPAddress() { + return p[i].Left.LastIPAddress() < p[j].Left.LastIPAddress() + } + return p[i].Left.FirstIPAddress() < p[j].Left.FirstIPAddress() + } sort.Slice(p, cmp) return p } -func allPorts(ports *interval.CanonicalSet) bool { - return ports.Equal(netp.AllPorts().ToSet()) +func LessIPBlock(this, other *netset.IPBlock) bool { + if this.FirstIPAddress() == this.FirstIPAddress() { + return this.LastIPAddress() < other.LastIPAddress() + } + return this.FirstIPAddress() < other.FirstIPAddress() +} + +func IcmpsetPartitions(icmpset *netset.ICMPSet) []netp.ICMP { + result := make([]netp.ICMP, 0) + if icmpset.IsAll() { + icmp, _ := netp.ICMPFromTypeAndCode64WithoutRFCValidation(nil, nil) + return []netp.ICMP{icmp} + } + + for _, cube := range icmpset.Partitions() { + for _, typeInterval := range cube.Left.Intervals() { + for _, icmpType := range typeInterval.Elements() { + if cube.Right.Equal(netset.AllICMPCodes()) { + icmp, _ := netp.ICMPFromTypeAndCode64WithoutRFCValidation(&icmpType, nil) + result = append(result, icmp) + continue + } + for _, codeInterval := range cube.Right.Intervals() { + for _, icmpCode := range codeInterval.Elements() { + icmp, _ := netp.ICMPFromTypeAndCode64WithoutRFCValidation(&icmpType, &icmpCode) + result = append(result, icmp) + } + } + } + } + } + return result +} + +func IcmpRuleToIcmpSet(icmp netp.ICMP) *netset.ICMPSet { + if icmp.TypeCode == nil { + return netset.AllICMPSet() + } + icmpType := int64(icmp.TypeCode.Type) + if icmp.TypeCode.Code == nil { + return netset.NewICMPSet(icmpType, icmpType, int64(netp.MinICMPCode), int64(netp.MaxICMPCode)) + } + icmpCode := int64(*icmp.TypeCode.Code) + return netset.NewICMPSet(icmpType, icmpType, icmpCode, icmpCode) } diff --git a/pkg/optimize/compressRules.go b/pkg/optimize/compressRules.go deleted file mode 100644 index 687ed963..00000000 --- a/pkg/optimize/compressRules.go +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package optimize - -import ( - "github.com/np-guard/models/pkg/netset" -) - -func compressSpansToSG(spans *sgSpansToSGPerProtocol) *sgSpansToSGPerProtocol { - spans = deleteOtherProtocolIfAllProtocolExists(spans) - return compressThreeProtocolsToAllProtocol(spans) -} - -// delete other protocols rules if all protocol rule exists -func deleteOtherProtocolIfAllProtocolExists(spans *sgSpansToSGPerProtocol) *sgSpansToSGPerProtocol { - for _, sgName := range spans.all { - delete(spans.tcp, sgName) - delete(spans.udp, sgName) - delete(spans.icmp, sgName) - } - return spans -} - -// merge tcp, udp and icmp rules into all protocol rule -func compressThreeProtocolsToAllProtocol(spans *sgSpansToSGPerProtocol) *sgSpansToSGPerProtocol { - for sgName, tcpPorts := range spans.tcp { - if udpPorts, ok := spans.udp[sgName]; ok { - if ic, ok := spans.icmp[sgName]; ok { - if ic.Equal(netset.AllICMPSet()) && allPorts(tcpPorts) && allPorts(udpPorts) { // all tcp&udp ports and all icmp types&codes - delete(spans.tcp, sgName) - delete(spans.udp, sgName) - delete(spans.icmp, sgName) - spans.all = append(spans.all, sgName) - } - } - } - } - return spans -} - -// observation: It pays to switch to all protocol rule when we have rules that cover all other protocols -// on exactly the same cidr (only one protocol can exceed). -func compressSpansToIP(span *sgSpansToIPPerProtocol) *sgSpansToIPPerProtocol { - t := 0 - u := 0 - i := 0 - - for t != len(span.tcp) && u != len(span.udp) && i != len(span.icmp) { - if !allPorts(span.tcp[t].Right) { - t++ - continue - } - if !allPorts(span.udp[u].Right) { - u++ - continue - } - if !span.icmp[i].Right.Equal(netset.AllICMPSet()) { - i++ - continue - } - - if span.tcp[t].Left.Equal(span.udp[u].Left) && span.tcp[t].Left.Equal(span.icmp[i].Left) { - span.all = span.all.Union(span.tcp[t].Left.Copy()) - span.tcp = append(span.tcp[:t], span.tcp[t+1:]...) - span.udp = append(span.udp[:u], span.udp[u+1:]...) - span.icmp = append(span.icmp[:i], span.icmp[i+1:]...) - } - } - - return span -} diff --git a/pkg/optimize/ip.go b/pkg/optimize/ip.go deleted file mode 100644 index c1a844af..00000000 --- a/pkg/optimize/ip.go +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package optimize - -import ( - "log" - "strings" - - "github.com/np-guard/models/pkg/netset" -) - -// temporary file, should be implemented in models repo -const commaSeparator = ", " - -// given a and b single disjoint cidrs, a 0 { - prevIPBlock := span[i-1].Left - currIPBlock := span[i].Left - if !touching(prevIPBlock, currIPBlock) { // the cidrs are not touching - hole := IPBlockFromRange(NextIP(prevIPBlock), BeforeIP(currIPBlock)) - if !hole.IsSubset(allSpan) { // there in no all rule covering the hole - for _, r := range rules { - p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.End())) - for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) - } - } - rules = []ds.Pair[*netset.IPBlock, *interval.Interval]{} - } - } - } - - activePorts := interval.NewCanonicalSet() - for _, r := range rules { - if !r.Right.ToSet().IsSubset(span[i].Right) { // create rules - p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.End())) - for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) - } - } else { - activePorts.AddInterval(*r.Right) - } - } - - // new rules - for _, ports := range span[i].Right.Intervals() { - if !ports.ToSet().IsSubset(activePorts) { // it is not contained in other rules - r := ds.Pair[*netset.IPBlock, *interval.Interval]{Left: FirstIPAddress(span[i].Left), Right: &ports} - rules = append(rules, r) - } - } - } - - // create the rest of the rules - for _, r := range rules { - p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.Start())) - for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[len(span)-1].Left))) { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) - } - } - - return result -} - -// problem: where should I end the rule? -// func createTcpudpRules(rules []ds.Pair[*netset.IPBlock, *interval.Interval], span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], -// direction ir.Direction, isTCP bool) (res []ir.SGRule) { -// res = make([]ir.SGRule, 0) -// for _, r := range rules { -// p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.Start())) -// for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[len(span)-1].Left))) { -// res = append(res, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) -// } -// } -// return res -// } - -func icmpSpanToSGRules(span []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allSpan *netset.IPBlock, direction ir.Direction) []*ir.SGRule { - rules := []ds.Pair[*netset.IPBlock, *netp.ICMP]{} - result := make([]*ir.SGRule, 0) - - for i := range span { - if i > 0 { - prevIPBlock := span[i-1].Left - currIPBlock := span[i].Left - if !touching(prevIPBlock, currIPBlock) { // the cidrs are not touching - hole := IPBlockFromRange(NextIP(prevIPBlock), BeforeIP(currIPBlock)) - if !hole.IsSubset(allSpan) { // there in no all rule covering the hole - for _, r := range rules { - p, _ := netp.NewICMP(r.Right.TypeCode) - for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) - } - } - rules = []ds.Pair[*netset.IPBlock, *netp.ICMP]{} - } - } - } - - activeICMP := netset.EmptyICMPSet() - for _, r := range rules { - ruleIcmpSet := netset.NewICMPSet(*r.Right) - if !ruleIcmpSet.IsSubset(span[i].Right) { // create rules - p, _ := netp.NewICMP(r.Right.TypeCode) - for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[i-1].Left))) { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) - } - } else { - activeICMP.Union(ruleIcmpSet) - } - } - - // new rules - for _, p := range span[i].Right.Partitions() { - if !netset.NewICMPSet(p).IsSubset(activeICMP) { - r := ds.Pair[*netset.IPBlock, *netp.ICMP]{Left: FirstIPAddress(span[i].Left), Right: &p} - rules = append(rules, r) - } - } - } - - // create the rest of the rules - for _, r := range rules { - p, _ := netp.NewICMP(r.Right.TypeCode) - for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[len(span)-1].Left))) { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) - } - } - - return result -} diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go new file mode 100644 index 00000000..e38acb9d --- /dev/null +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -0,0 +1,152 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package sgoptimizer + +import ( + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/interval" + "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 allProtocolIPCubesIPToRules(cubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { + result := make([]*ir.SGRule, 0) + for _, cidr := range cubes.SplitToCidrs() { + result = append(result, ir.NewSGRule(direction, cidr, netp.AnyProtocol{}, netset.GetCidrAll(), "")) + } + return result +} + +func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], allProtocolCubes *netset.IPBlock, + direction ir.Direction, isTCP bool) []*ir.SGRule { + activeRules := make(map[*netset.IPBlock]*interval.Interval) // start ip and ports + result := make([]*ir.SGRule, 0) + + for i := range cubes { + if i > 0 && !continuation(cubes[i-1], cubes[i], allProtocolCubes) { + for ipb, ports := range activeRules { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(ports.Start()), int(ports.End())) + ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[i-1].Left.LastIPAddressObject()) + for _, cidr := range ipRange.SplitToCidrs() { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + delete(activeRules, ipb) + } + } + + // rules whose ports are not in the current cube will not remain active + activePorts := interval.NewCanonicalSet() + for ipb, ports := range activeRules { + if !ports.ToSet().IsSubset(cubes[i].Right) { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(ports.Start()), int(ports.End())) + ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[i-1].Left.LastIPAddressObject()) + for _, cidr := range ipRange.SplitToCidrs() { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } else { + activePorts.AddInterval(*ports) + } + } + + // if the cube contains ports that are not contained in active rules, new rules will be created + for _, ports := range cubes[i].Right.Intervals() { + if !ports.ToSet().IsSubset(activePorts) { + activeRules[cubes[i].Left.FirstIPAddressObject()] = &ports + } + } + } + + // create the rest of the rules + for ipb, ports := range activeRules { + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(ports.Start()), int(ports.End())) + ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[len(cubes)-1].Left.LastIPAddressObject()) + for _, cidr := range ipRange.SplitToCidrs() { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } + + return result +} + +// problem: where should I end the rule? +// func createTcpudpRules(rules []ds.Pair[*netset.IPBlock, *interval.Interval], span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], +// direction ir.Direction, isTCP bool) (res []ir.SGRule) { +// res = make([]ir.SGRule, 0) +// for _, r := range rules { +// p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.Start())) +// for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[len(span)-1].Left))) { +// res = append(res, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) +// } +// } +// return res +// } + +func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allProtocolCubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { + activeRules := make(map[*netset.IPBlock]*netp.ICMP) + result := make([]*ir.SGRule, 0) + + for i := range cubes { + if i > 0 && !continuation(cubes[i-1], cubes[i], allProtocolCubes) { + for ipb, icmp := range activeRules { + p, _ := netp.NewICMP(icmp.TypeCode) + ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[i-1].Left.LastIPAddressObject()) + for _, cidr := range ipRange.SplitToCidrs() { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + delete(activeRules, ipb) + } + } + + // rules whose icmp value is not in the current cube will not remain active + activeICMP := netset.EmptyICMPSet() + for ipb, icmp := range activeRules { + ruleIcmpSet := optimize.IcmpRuleToIcmpSet(*icmp) + if !ruleIcmpSet.IsSubset(cubes[i].Right) { // create rules + p, _ := netp.NewICMPWithoutRFCValidation(icmp.TypeCode) + ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[i-1].Left.LastIPAddressObject()) + for _, cidr := range ipRange.SplitToCidrs() { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } else { + activeICMP.Union(ruleIcmpSet) + } + } + + // new rules + for _, p := range optimize.IcmpsetPartitions(cubes[i].Right) { + if !optimize.IcmpRuleToIcmpSet(p).IsSubset(activeICMP) { + activeRules[cubes[i].Left.FirstIPAddressObject()] = &p + } + } + } + + // create the rest of the rules + for ipb, icmp := range activeRules { + p, _ := netp.NewICMP(icmp.TypeCode) + ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[len(cubes)-1].Left.LastIPAddressObject()) + for _, cidr := range ipRange.SplitToCidrs() { + result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + } + } + + return result +} + +func continuation[T ds.Set[T]](prevPair, currPair ds.Pair[*netset.IPBlock, T], allProtocolCubes *netset.IPBlock) bool { + prevIPBlock := prevPair.Left + currIPBlock := currPair.Left + touching, _ := prevIPBlock.TouchingIPRanges(currIPBlock) + if touching { + return true + } + startH, _ := prevIPBlock.NextIP() + endH, _ := currIPBlock.PreviousIP() + hole, _ := netset.IPBlockFromIPRange(startH, endH) + return hole.IsSubset(allProtocolCubes) +} diff --git a/pkg/optimize/sg/optimizeSG_test.go b/pkg/optimize/sg/optimizeSG_test.go new file mode 100644 index 00000000..544fa53f --- /dev/null +++ b/pkg/optimize/sg/optimizeSG_test.go @@ -0,0 +1,57 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package sgoptimizer_test + +import ( + "log" + "testing" + + "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 TestOps(t *testing.T) { + sgRules := make([]*ir.SGRule, 0) + p1, _ := netp.NewTCPUDP(true, 1, 100, 1, 10) + p2, _ := netp.NewTCPUDP(true, 1, 100, 1, 20) + + ipb1, _ := netset.IPBlockFromCidrOrAddress("0.0.0.0") + ipb2, _ := netset.IPBlockFromCidrOrAddress("0.0.0.0/31") + + sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb1, p1, netset.GetCidrAll(), "")) + sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb2, p2, netset.GetCidrAll(), "")) + + res := tcpudpRulesToIPCubes(sgRules) + for i, pair := range res { + log.Println("pair ", i, ": ipblock: ", pair.Left.String(), ", ports: ", pair.Right.String()) + } + + sgRules = []*ir.SGRule{} + sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb2, p1, netset.GetCidrAll(), "")) + sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb1, p2, netset.GetCidrAll(), "")) + + res = tcpudpRulesToIPCubes(sgRules) + for i, pair := range res { + log.Println("pair ", i, ": ipblock: ", pair.Left.String(), ", ports: ", pair.Right.String()) + } + + t.Log("Hi") +} + +func tcpudpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.PortSet] { + cubes := ds.NewProductLeft[*netset.IPBlock, *netset.PortSet]() + for _, rule := range rules { + ipb := rule.Remote.(*netset.IPBlock) // already checked + portsSet := rule.Protocol.(netp.TCPUDP) // already checked + r := ds.CartesianPairLeft(ipb, portsSet.DstPorts().ToSet()) + cubes = cubes.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.PortSet]) + } + return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) +} diff --git a/pkg/optimize/sg/reduceCubes.go b/pkg/optimize/sg/reduceCubes.go new file mode 100644 index 00000000..3489ed49 --- /dev/null +++ b/pkg/optimize/sg/reduceCubes.go @@ -0,0 +1,118 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package sgoptimizer + +import ( + "slices" + + "github.com/np-guard/models/pkg/netset" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" +) + +func reduceSGCubes(spans *sgCubesPerProtocol) *sgCubesPerProtocol { + spans = deleteOtherProtocolIfAllProtocolExists(spans) + return compressThreeProtocolsToAllProtocol(spans) +} + +// delete other protocols rules if all protocol rule exists +func deleteOtherProtocolIfAllProtocolExists(spans *sgCubesPerProtocol) *sgCubesPerProtocol { + for _, sgName := range spans.all { + delete(spans.tcp, sgName) + delete(spans.udp, sgName) + delete(spans.icmp, sgName) + } + return spans +} + +// merge tcp, udp and icmp rules into all protocol rule +func compressThreeProtocolsToAllProtocol(spans *sgCubesPerProtocol) *sgCubesPerProtocol { + for sgName, tcpPorts := range spans.tcp { + if udpPorts, ok := spans.udp[sgName]; ok { + if ic, ok := spans.icmp[sgName]; ok { + if ic.IsAll() && tcpPorts.Equal(netset.AllPorts()) && udpPorts.Equal(netset.AllPorts()) { + delete(spans.tcp, sgName) + delete(spans.udp, sgName) + delete(spans.icmp, sgName) + spans.all = append(spans.all, sgName) + } + } + } + } + return spans +} + +// observation: It pays to switch to all protocol rule when we have rules that cover all other protocols +// on exactly the same cidr (only one protocol can exceed). +func reduceIPCubes(cubes *ipCubesPerProtocol) *ipCubesPerProtocol { + tcpPtr := 0 + udpPtr := 0 + icmpPtr := 0 + + var changed bool + for tcpPtr < len(cubes.tcp) && udpPtr < len(cubes.udp) && icmpPtr < len(cubes.icmp) { + if !cubes.tcp[tcpPtr].Right.Equal(netset.AllPorts()) { + tcpPtr++ + continue + } + if !cubes.udp[udpPtr].Right.Equal(netset.AllPorts()) { + udpPtr++ + continue + } + if !cubes.icmp[icmpPtr].Right.IsAll() { + icmpPtr++ + continue + } + + cubes, changed = reduce(cubes, tcpPtr, udpPtr, icmpPtr) + if changed { + continue + } + + tcpIP := cubes.tcp[tcpPtr].Left + udpIP := cubes.udp[udpPtr].Left + icmpIP := cubes.icmp[icmpPtr].Left + + if udpIP.IsSubset(tcpIP) && icmpIP.IsSubset(tcpIP) { + if optimize.LessIPBlock(udpIP, icmpIP) { + udpPtr++ + } else { + icmpPtr++ + } + continue + } + + } + return cubes +} + +func reduce(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) (*ipCubesPerProtocol, bool) { + tcpIP := cubes.tcp[tcpPtr].Left + udpIP := cubes.udp[udpPtr].Left + icmpIP := cubes.icmp[icmpPtr].Left + + if udpIP.IsSubset(tcpIP) && udpIP.Equal(icmpIP) { + cubes.all = cubes.all.Union(udpIP) + slices.Delete(cubes.udp, udpPtr, udpPtr+1) + slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) + if tcpIP.Equal(udpIP) { + slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) + } + // continue + } + + if tcpIP.IsSubset(udpIP) && tcpIP.Equal(icmpIP) { + cubes.all = cubes.all.Union(udpIP) + slices.Delete(cubes.udp, udpPtr, udpPtr+1) + slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) + if tcpIP.Equal(udpIP) { + slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) + } + // continue + } + + return cubes, false +} diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go new file mode 100644 index 00000000..84e28bd1 --- /dev/null +++ b/pkg/optimize/sg/rulesToCubes.go @@ -0,0 +1,106 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package sgoptimizer + +import ( + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/interval" + "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" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" +) + +// calculate all cubes +func rulesToIPCubes(rules *rulesPerProtocol) *ipCubesPerProtocol { + tcpCubes := tcpudpRulesToIPCubes(rules.tcp) + udpCubes := tcpudpRulesToIPCubes(rules.udp) + icmpCubes := icmpRulesToIPCubes(rules.icmp) + allCubes := allProtocolRulesToIPCubes(rules.all) + return &ipCubesPerProtocol{tcp: tcpCubes, udp: udpCubes, icmp: icmpCubes, all: allCubes} +} + +func rulesToSGCubes(rules *rulesPerProtocol) *sgCubesPerProtocol { + tcpSpan := tcpudpRulesToSGToPortsSpan(rules.tcp) + udpSpan := tcpudpRulesToSGToPortsSpan(rules.udp) + icmpSpan := icmpRulesToSGToSpan(rules.icmp) + allSpan := allProtocolRulesToSGToSpan(rules.all) + return &sgCubesPerProtocol{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} +} + +// all protocol rules to cubes +func allProtocolRulesToIPCubes(rules []*ir.SGRule) *netset.IPBlock { + res := netset.NewIPBlock() + for i := range rules { + res.Union(rules[i].Remote.(*netset.IPBlock)) + } + return res +} + +func allProtocolRulesToSGToSpan(rules []*ir.SGRule) []ir.SGName { + result := make(map[ir.SGName]struct{}) + for i := range rules { + remote := rules[i].Remote.(ir.SGName) + result[remote] = struct{}{} + } + return utils.SortedMapKeys(result) +} + +// tcp/udp rules (separately) to cubes (IPBlock X portset). +func tcpudpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.PortSet] { + cubes := ds.NewProductLeft[*netset.IPBlock, *netset.PortSet]() + for _, rule := range rules { + ipb := rule.Remote.(*netset.IPBlock) // already checked + p := rule.Protocol.(netp.TCPUDP) // already checked + r := ds.CartesianPairLeft(ipb, p.DstPorts().ToSet()) + cubes = cubes.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.PortSet]) + } + return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) +} + +// tcp/udp rules to cubes -- map where the key is the SG name and the value is the protocol ports +func tcpudpRulesToSGToPortsSpan(rules []*ir.SGRule) map[ir.SGName]*netset.PortSet { + result := make(map[ir.SGName]*netset.PortSet) + for _, rule := range rules { + p := rule.Protocol.(netp.TCPUDP) // already checked + remote := rule.Remote.(ir.SGName) // already checked + if result[remote] == nil { + result[remote] = interval.NewCanonicalSet() + } + result[remote].AddInterval(p.DstPorts()) + } + return result +} + +// icmp rules to cubes (IPBlock X icmp set). +func icmpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.ICMPSet] { + cubes := ds.NewProductLeft[*netset.IPBlock, *netset.ICMPSet]() + for _, rule := range rules { + ipb := rule.Remote.(*netset.IPBlock) // already checked + p := rule.Protocol.(netp.ICMP) // already checked + icmpSet := optimize.IcmpRuleToIcmpSet(p) + r := ds.CartesianPairLeft(ipb, icmpSet) + cubes = cubes.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.ICMPSet]) + } + return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) +} + +// icmp rules to cubes -- map where the key is the SG name and the value is icmpset +func icmpRulesToSGToSpan(rules []*ir.SGRule) map[ir.SGName]*netset.ICMPSet { + result := make(map[ir.SGName]*netset.ICMPSet) + for _, rule := range rules { + p := rule.Protocol.(netp.ICMP) // already checked + remote := rule.Remote.(ir.SGName) // already checked + if result[remote] == nil { + result[remote] = netset.EmptyICMPSet() + } + icmpSet := optimize.IcmpRuleToIcmpSet(p) + result[remote] = result[remote].Union(icmpSet) + } + return result +} diff --git a/pkg/optimize/sg.go b/pkg/optimize/sg/sg.go similarity index 59% rename from pkg/optimize/sg.go rename to pkg/optimize/sg/sg.go index 10529236..7ddbafd3 100644 --- a/pkg/optimize/sg.go +++ b/pkg/optimize/sg/sg.go @@ -3,76 +3,71 @@ Copyright 2023- IBM Inc. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package optimize +package sgoptimizer import ( "fmt" "log" "github.com/np-guard/models/pkg/ds" - "github.com/np-guard/models/pkg/interval" "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" "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) type ( - SGOptimizer struct { + sgOptimizer struct { sgCollection *ir.SGCollection sgName ir.SGName sgVPC *string } - sgRuleGroups struct { - rulesToSG *sgRulesPerProtocol - rulesToIPAddrs *sgRulesPerProtocol + ruleGroups struct { + sgRemoteRules *rulesPerProtocol + ipRemoteRules *rulesPerProtocol } - sgRulesPerProtocol struct { + rulesPerProtocol struct { tcp []*ir.SGRule udp []*ir.SGRule icmp []*ir.SGRule all []*ir.SGRule } - sgSpansToSGPerProtocol struct { - tcp map[ir.SGName]*interval.CanonicalSet - udp map[ir.SGName]*interval.CanonicalSet + sgCubesPerProtocol struct { + tcp map[ir.SGName]*netset.PortSet + udp map[ir.SGName]*netset.PortSet icmp map[ir.SGName]*netset.ICMPSet all []ir.SGName } - sgSpansToIPPerProtocol struct { - tcp []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] - udp []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] + ipCubesPerProtocol struct { + tcp []ds.Pair[*netset.IPBlock, *netset.PortSet] + udp []ds.Pair[*netset.IPBlock, *netset.PortSet] icmp []ds.Pair[*netset.IPBlock, *netset.ICMPSet] all *netset.IPBlock } ) -func NewSGOptimizer(collection ir.Collection, sgName string) Optimizer { +func NewSGOptimizer(collection ir.Collection, sgName string) optimize.Optimizer { components := ir.ScopingComponents(sgName) if len(components) == 1 { - return &SGOptimizer{sgCollection: collection.(*ir.SGCollection), sgName: ir.SGName(sgName), sgVPC: nil} + return &sgOptimizer{sgCollection: collection.(*ir.SGCollection), sgName: ir.SGName(sgName), sgVPC: nil} } - return &SGOptimizer{sgCollection: collection.(*ir.SGCollection), sgName: ir.SGName(components[1]), sgVPC: &components[0]} -} - -// returns a sorted slice of the vpc names -func (s *SGOptimizer) VpcNames() []string { - return utils.SortedMapKeys(s.sgCollection.SGs) + return &sgOptimizer{sgCollection: collection.(*ir.SGCollection), sgName: ir.SGName(components[1]), sgVPC: &components[0]} } // Optimize attempts to reduce the number of SG rules -// if -n was supplied, it will attempt to reduce the number of rules only in it +// if -n was supplied, it will attempt to reduce the number of rules only in the requested SG // otherwise, it will attempt to reduce the number of rules in all SGs -func (s *SGOptimizer) Optimize() (ir.Collection, error) { +func (s *sgOptimizer) Optimize() (ir.Collection, error) { if s.sgName != "" { for _, vpcName := range utils.SortedMapKeys(s.sgCollection.SGs) { if _, ok := s.sgCollection.SGs[vpcName][s.sgName]; ok { - s.OptimizeSG(vpcName, s.sgName) + s.optimizeSG(vpcName, s.sgName) return s.sgCollection, nil } } @@ -81,28 +76,28 @@ func (s *SGOptimizer) Optimize() (ir.Collection, error) { for _, vpcName := range utils.SortedMapKeys(s.sgCollection.SGs) { for _, sgName := range utils.SortedMapKeys(s.sgCollection.SGs[vpcName]) { - s.OptimizeSG(vpcName, sgName) + s.optimizeSG(vpcName, sgName) } } return s.sgCollection, nil } -// Optimize attempts to reduce the number of SG rules +// optimizeSG attempts to reduce the number of SG rules // the algorithm attempts to reduce both inbound and outbound rules separately // A message is printed to the log at the end of the algorithm -func (s *SGOptimizer) OptimizeSG(vpcName string, sgName ir.SGName) { +func (s *sgOptimizer) optimizeSG(vpcName string, sgName ir.SGName) { sg := s.sgCollection.SGs[vpcName][sgName] reducedRules := 0 // reduce inbound rules first - newInboundRules := s.reduceSGRules(sg.InboundRules, ir.Inbound) + newInboundRules := s.reduceRules(sg.InboundRules, ir.Inbound) if len(sg.InboundRules) > len(newInboundRules) { reducedRules += len(sg.InboundRules) - len(newInboundRules) s.sgCollection.SGs[vpcName][sgName].InboundRules = newInboundRules } // reduce outbound rules second - newOutboundRules := s.reduceSGRules(sg.OutboundRules, ir.Outbound) + newOutboundRules := s.reduceRules(sg.OutboundRules, ir.Outbound) if len(sg.OutboundRules) > len(newOutboundRules) { reducedRules += len(sg.OutboundRules) - len(newOutboundRules) s.sgCollection.SGs[vpcName][sgName].OutboundRules = newOutboundRules @@ -120,57 +115,58 @@ func (s *SGOptimizer) OptimizeSG(vpcName string, sgName ir.SGName) { } // reduceSGRules attempts to reduce the number of rules with different remote types separately -func (s *SGOptimizer) reduceSGRules(rules []*ir.SGRule, direction ir.Direction) []*ir.SGRule { +func (s *sgOptimizer) reduceRules(rules []*ir.SGRule, direction ir.Direction) []*ir.SGRule { // separate all rules to groups of (protocol X remote) ruleGroups := divideSGRules(rules) // rules with SG as a remote - optimizedRulesToSG := reduceSGRulesToSG(sgRulesToSGToSpans(ruleGroups.rulesToSG), direction) - if len(ruleGroups.rulesToSG.allRules()) < len(optimizedRulesToSG) { - optimizedRulesToSG = ruleGroups.rulesToSG.allRules() + optimizedRulesToSG := reduceRulesSGRemote(rulesToSGCubes(ruleGroups.sgRemoteRules), direction) + originlRulesToSG := ruleGroups.sgRemoteRules.allRules() + if len(originlRulesToSG) < len(optimizedRulesToSG) { // failed to reduce number of rules + optimizedRulesToSG = originlRulesToSG } // rules with IPBlock as a remote - optimizedRulesToIPAddrs := reduceSGRulesToIPAddrs(sgRulesToIPAddrsToSpans(ruleGroups.rulesToIPAddrs), direction) - if len(ruleGroups.rulesToIPAddrs.allRules()) < len(optimizedRulesToSG) { - optimizedRulesToIPAddrs = ruleGroups.rulesToIPAddrs.allRules() + optimizedRulesToIPAddrs := reduceRulesIPRemote(rulesToIPCubes(ruleGroups.ipRemoteRules), direction) + originalRulesToIPAddrs := ruleGroups.ipRemoteRules.allRules() + if len(originalRulesToIPAddrs) < len(optimizedRulesToSG) { // failed to reduce number of rules + optimizedRulesToIPAddrs = originalRulesToIPAddrs } - // append both slices together return append(optimizedRulesToSG, optimizedRulesToIPAddrs...) } -func reduceSGRulesToSG(spans *sgSpansToSGPerProtocol, direction ir.Direction) []*ir.SGRule { - spans = compressSpansToSG(spans) +func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*ir.SGRule { + cubes = reduceSGCubes(cubes) - // convert spans to SG rules - tcpRules := tcpudpSGSpanToSGRules(spans.tcp, direction, true) - udpRules := tcpudpSGSpanToSGRules(spans.udp, direction, false) - icmpRules := icmpSGSpanToSGRules(spans.icmp, direction) - allRules := protocolAllSGSpanToSGRules(spans.all, direction) + // cubes to SG rules + tcpRules := tcpudpSGCubesToRules(cubes.tcp, direction, true) + udpRules := tcpudpSGCubesToRules(cubes.udp, direction, false) + icmpRules := icmpSGCubesToRules(cubes.icmp, direction) + allRules := protocolAllCubesToRules(cubes.all, direction) // return all rules return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) } -func reduceSGRulesToIPAddrs(spans *sgSpansToIPPerProtocol, direction ir.Direction) []*ir.SGRule { - spans = compressSpansToIP(spans) +func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction) []*ir.SGRule { + cubes = reduceIPCubes(cubes) - // spans to SG rules - tcpRules := tcpudpIPSpanToSGRules(spans.tcp, spans.all, direction, true) - udpRules := tcpudpIPSpanToSGRules(spans.udp, spans.all, direction, false) - icmpRules := icmpSpanToSGRules(spans.icmp, spans.all, direction) - allRules := allSpanIPToSGRules(spans.all, direction) + // cubes to SG rules + tcpRules := tcpudpIPCubesToRules(cubes.tcp, cubes.all, direction, true) + udpRules := tcpudpIPCubesToRules(cubes.udp, cubes.all, direction, false) + icmpRules := icmpIPCubesToRules(cubes.icmp, cubes.all, direction) + allRules := allProtocolIPCubesIPToRules(cubes.all, direction) // return all rules return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) } // divide SGCollection to TCP/UDP/ICMP/ProtocolALL X SGRemote/IPAddrs rules -func divideSGRules(rules []*ir.SGRule) *sgRuleGroups { - rulesToSG := &sgRulesPerProtocol{tcp: make([]*ir.SGRule, 0), udp: make([]*ir.SGRule, 0), +func divideSGRules(rules []*ir.SGRule) *ruleGroups { + rulesToSG := &rulesPerProtocol{tcp: make([]*ir.SGRule, 0), udp: make([]*ir.SGRule, 0), icmp: make([]*ir.SGRule, 0), all: make([]*ir.SGRule, 0)} - rulesToIPAddrs := &sgRulesPerProtocol{tcp: make([]*ir.SGRule, 0), udp: make([]*ir.SGRule, 0), + rulesToIPAddrs := &rulesPerProtocol{tcp: make([]*ir.SGRule, 0), udp: make([]*ir.SGRule, 0), icmp: make([]*ir.SGRule, 0), all: make([]*ir.SGRule, 0)} for _, rule := range rules { @@ -210,9 +206,9 @@ func divideSGRules(rules []*ir.SGRule) *sgRuleGroups { } } } - return &sgRuleGroups{rulesToSG: rulesToSG, rulesToIPAddrs: rulesToIPAddrs} + return &ruleGroups{sgRemoteRules: rulesToSG, ipRemoteRules: rulesToIPAddrs} } -func (s *sgRulesPerProtocol) allRules() []*ir.SGRule { +func (s *rulesPerProtocol) allRules() []*ir.SGRule { return append(s.tcp, append(s.udp, append(s.icmp, s.all...)...)...) } diff --git a/pkg/optimize/sgSpanToSGRules.go b/pkg/optimize/sg/sgCubesToRules.go similarity index 52% rename from pkg/optimize/sgSpanToSGRules.go rename to pkg/optimize/sg/sgCubesToRules.go index b3cc640d..0eb4bd12 100644 --- a/pkg/optimize/sgSpanToSGRules.go +++ b/pkg/optimize/sg/sgCubesToRules.go @@ -3,7 +3,7 @@ Copyright 2023- IBM Inc. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package optimize +package sgoptimizer import ( "github.com/np-guard/models/pkg/interval" @@ -11,13 +11,14 @@ import ( "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" ) -// span (SGName X ports set) to SG rules -func tcpudpSGSpanToSGRules(span map[ir.SGName]*interval.CanonicalSet, direction ir.Direction, isTCP bool) []*ir.SGRule { +// cubes (SGName X ports set) to SG rules +func tcpudpSGCubesToRules(span map[ir.SGName]*interval.CanonicalSet, direction ir.Direction, isTCP bool) []*ir.SGRule { result := make([]*ir.SGRule, 0) - for sgName, intervals := range span { - for _, dstPorts := range intervals.Intervals() { + for sgName, portSet := range span { + for _, dstPorts := range portSet.Intervals() { p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) result = append(result, ir.NewSGRule(direction, sgName, p, netset.GetCidrAll(), "")) } @@ -25,20 +26,19 @@ func tcpudpSGSpanToSGRules(span map[ir.SGName]*interval.CanonicalSet, direction return result } -// span (SGName X icmp set) to SG rules -func icmpSGSpanToSGRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Direction) []*ir.SGRule { +// cubes (SGName X icmp set) to SG rules +func icmpSGCubesToRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Direction) []*ir.SGRule { result := make([]*ir.SGRule, 0) for sgName, icmpSet := range span { - for _, icmp := range icmpSet.Partitions() { - p, _ := netp.NewICMP(icmp.TypeCode) - result = append(result, ir.NewSGRule(direction, sgName, p, netset.GetCidrAll(), "")) + for _, icmp := range optimize.IcmpsetPartitions(icmpSet) { + result = append(result, ir.NewSGRule(direction, sgName, icmp, netset.GetCidrAll(), "")) } } return result } -// span (slice of SGs) to SG rules -func protocolAllSGSpanToSGRules(span []ir.SGName, direction ir.Direction) []*ir.SGRule { +// cubes (slice of SGs) to SG rules +func protocolAllCubesToRules(span []ir.SGName, direction ir.Direction) []*ir.SGRule { result := make([]*ir.SGRule, len(span)) for i, sgName := range span { result[i] = ir.NewSGRule(direction, sgName, netp.AnyProtocol{}, netset.GetCidrAll(), "") diff --git a/pkg/optimize/sgRulesToIPToSpan.go b/pkg/optimize/sgRulesToIPToSpan.go deleted file mode 100644 index af994076..00000000 --- a/pkg/optimize/sgRulesToIPToSpan.go +++ /dev/null @@ -1,126 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package optimize - -import ( - "github.com/np-guard/models/pkg/ds" - "github.com/np-guard/models/pkg/interval" - "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/utils" -) - -// calculate all spans and set them in sgRulesPerProtocol struct -func sgRulesToIPAddrsToSpans(rules *sgRulesPerProtocol) *sgSpansToIPPerProtocol { - tcpSpan := tcpudpRulesToIPAddrsToPortsSpan(rules.tcp) - udpSpan := tcpudpRulesToIPAddrsToPortsSpan(rules.udp) - icmpSpan := icmpRulesToIPAddrsToSpan(rules.icmp) - allSpan := allProtocolRulesToIPAddrsToSpan(rules.all) - return &sgSpansToIPPerProtocol{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} -} - -// all protocol rules to a span. The span will be splitted to disjoint CIDRs -func allProtocolRulesToIPAddrsToSpan(rules []*ir.SGRule) *netset.IPBlock { - res := netset.NewIPBlock() - for i := range rules { - res.Union(rules[i].Remote.(*netset.IPBlock)) - } - return res -} - -// tcp/udp rules (separately) to a span of (IPBlock X protocol ports). -// all IPBlocks are disjoint -func tcpudpRulesToIPAddrsToPortsSpan(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *interval.CanonicalSet] { - span := tcpudpMapSpan(rules) - result := ds.NewProductLeft[*netset.IPBlock, *interval.CanonicalSet]() - for ipblock, portsSet := range span { - r := ds.CartesianPairLeft(ipblock, portsSet) - result = result.Union(r).(*ds.ProductLeft[*netset.IPBlock, *interval.CanonicalSet]) - } - return sortPartitionsByIPAddrs(result.Partitions()) -} - -// icmp rules to a span of (IPBlock X icmp set). -// all IPBlocks are disjoint -func icmpRulesToIPAddrsToSpan(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.ICMPSet] { - span := icmpMapSpan((rules)) - result := ds.NewProductLeft[*netset.IPBlock, *netset.ICMPSet]() - for ipblock, icmpSet := range span { - r := ds.CartesianPairLeft(ipblock, icmpSet) - result = result.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.ICMPSet]) - } - return sortPartitionsByIPAddrs(result.Partitions()) -} - -/* ######################## */ -/* #### HELP FUNCTIONS #### */ -/* ######################## */ - -// tcp/udp rules to a span in a map format, where the key is the IPBlock and the value contains the protocol ports -// all ipblocks are disjoint -func tcpudpMapSpan(rules []*ir.SGRule) map[*netset.IPBlock]*interval.CanonicalSet { - span := make(map[*netset.IPBlock]*interval.CanonicalSet, 0) // all keys are disjoint - for i := range rules { - portsSet := rules[i].Protocol.(netp.TCPUDP).DstPorts().ToSet() // already checked - ruleIP := rules[i].Remote.(*netset.IPBlock) // already checked - span = updateSpan(span, portsSet, ruleIP) - } - return span -} - -// icmp rules to a span in a map format, where the key is the IPBlock and the value contains the icmp set -// all ipblocks are disjoint -func icmpMapSpan(rules []*ir.SGRule) map[*netset.IPBlock]*netset.ICMPSet { - span := make(map[*netset.IPBlock]*netset.ICMPSet, 0) // all keys are disjoint - for i := range rules { - icmpSet := netset.NewICMPSet(rules[i].Protocol.(netp.ICMP)) // already checked - ruleIP := rules[i].Remote.(*netset.IPBlock) // already checked - span = updateSpan(span, icmpSet, ruleIP) - } - return span -} - -// updateSpan gets the current span, and a rule details (IPBlock and a protocol set) -// if the IPBlock is already in the map, the new protocol set will be unioned with the existing one -// otherwise the rule will be added in the `addRuleToSpan` function. -func updateSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleSet T, ruleIP *netset.IPBlock) map[*netset.IPBlock]T { - if protocolSet, ok := span[ruleIP]; ok { - span[ruleIP] = protocolSet.Union(ruleSet) - return span - } - span, newMap := addRuleToSpan(span, ruleIP, ruleSet) - return utils.MergeSetMaps(span, newMap) -} - -// any IPblock that overlaps with the new ipblock: -// 1. will be deleted from the new map -// 2. will be splitted into two parts: the part overlapping with the new ipblock and the part that is not -// a. the overlapping part will enter the new map, where the existing set will be unioned with the new set -// b. the non overlapping part will enter the new map with the same value he had. -func addRuleToSpan[T ds.Set[T]](span map[*netset.IPBlock]T, ruleIP *netset.IPBlock, ruleSet T) (s, res map[*netset.IPBlock]T) { - res = make(map[*netset.IPBlock]T, 0) - uncovered := ruleIP.Copy() - for ipblock := range span { - if !ipblock.Overlap(ruleIP) { - continue - } - uncovered = uncovered.Subtract(ipblock) - - overlappingIPs := ruleIP.Subtract(ipblock) - for _, ip := range overlappingIPs.Split() { - res[ip] = span[ipblock].Copy().Union(ruleSet) - } - notOverlappingIPs := ipblock.Subtract(overlappingIPs) - for _, ip := range notOverlappingIPs.Split() { - res[ip] = span[ipblock].Copy() - } - delete(span, ipblock) - } - res[uncovered] = ruleSet.Copy() - return span, res -} diff --git a/pkg/optimize/sgRulesToSGToSpan.go b/pkg/optimize/sgRulesToSGToSpan.go deleted file mode 100644 index d71c6df8..00000000 --- a/pkg/optimize/sgRulesToSGToSpan.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package optimize - -import ( - "fmt" - - "github.com/np-guard/models/pkg/interval" - "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/utils" -) - -// calculate all spans and set them in sgRulesPerProtocol struct -func sgRulesToSGToSpans(rules *sgRulesPerProtocol) *sgSpansToSGPerProtocol { - tcpSpan := tcpudpRulesToSGToPortsSpan(rules.tcp) - udpSpan := tcpudpRulesToSGToPortsSpan(rules.udp) - icmpSpan := icmpRulesToSGToSpan(rules.icmp) - allSpan := allProtocolRulesToSGToSpan(rules.all) - return &sgSpansToSGPerProtocol{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} -} - -// tcp/udp rules to a span -- map where the key is the SG name and the value is the protocol ports -func tcpudpRulesToSGToPortsSpan(rules []*ir.SGRule) map[ir.SGName]*interval.CanonicalSet { - result := make(map[ir.SGName]*interval.CanonicalSet) - for i := range rules { - p := rules[i].Protocol.(netp.TCPUDP) // already checked - remote := rules[i].Remote.(ir.SGName) // already checked - if result[remote] == nil { - result[remote] = interval.NewCanonicalSet() - } - result[remote].AddInterval(p.DstPorts()) - } - return result -} - -// icmp rules to a span -- map where the key is the SG name and the value is icmp set -func icmpRulesToSGToSpan(rules []*ir.SGRule) map[ir.SGName]*netset.ICMPSet { - result := make(map[ir.SGName]*netset.ICMPSet) - for i := range rules { - p := rules[i].Protocol.(netp.ICMP) // already checked - remote := rules[i].Remote.(ir.SGName) // already checked - if result[remote] == nil { - result[remote] = netset.EmptyICMPSet() - } - result[remote] = result[remote].Union(netset.NewICMPSet(p)) - - fmt.Println("i=", i, ": num partitions=", len(result[remote].Partitions())) - } - return result -} - -// all protocol rules to a span of SG names slice -func allProtocolRulesToSGToSpan(rules []*ir.SGRule) []ir.SGName { - result := make(map[ir.SGName]struct{}) - for i := range rules { - remote := rules[i].Remote.(ir.SGName) - result[remote] = struct{}{} - } - return utils.SortedMapKeys(result) -} diff --git a/test/data/optimize_sg_icmp_codes/config_object.json b/test/data/optimize_sg_icmp_codes/config_object.json deleted file mode 100644 index d059fc05..00000000 --- a/test/data/optimize_sg_icmp_codes/config_object.json +++ /dev/null @@ -1,2169 +0,0 @@ -{ - "collector_version": "0.11.0", - "provider": "ibm", - "vpcs": [ - { - "classic_access": false, - "created_at": "2024-09-09T09:09:50.000Z", - "crn": "crn:1", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.217.112" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.12.160.153" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.16.253.223" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "capitol-siren-chirpy-doornail" - }, - "default_routing_table": { - "href": "href:11", - "id": "id:12", - "name": "fiscally-fresh-uncanny-ceramics", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "wombat-hesitate-scorn-subprime" - }, - "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": "test-vpc1", - "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-09-09T09:09:50.000Z", - "has_subnets": true, - "href": "href:18", - "id": "id:19", - "is_default": true, - "name": "filling-tasty-bacterium-parlor", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.64.0/18", - "created_at": "2024-09-09T09:09:50.000Z", - "has_subnets": false, - "href": "href:20", - "id": "id:21", - "is_default": true, - "name": "relearn-ragweed-goon-feisty", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "cidr": "10.240.128.0/18", - "created_at": "2024-09-09T09:09:50.000Z", - "has_subnets": false, - "href": "href:22", - "id": "id:23", - "is_default": true, - "name": "unruffled-penknife-snowshoe-ninetieth", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - } - ], - "subnets": [ - { - "available_ipv4_address_count": 250, - "created_at": "2024-09-09T09:10:51.000Z", - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.20.0/24", - "name": "subnet2", - "network_acl": { - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl2" - }, - "public_gateway": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "public-gw1", - "resource_type": "public_gateway" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "fiscally-fresh-uncanny-ceramics", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.20.0", - "auto_delete": false, - "created_at": "2024-09-09T09:10:51.000Z", - "href": "href:33", - "id": "id:34", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.20.1", - "auto_delete": false, - "created_at": "2024-09-09T09:10:51.000Z", - "href": "href:35", - "id": "id:36", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.20.2", - "auto_delete": false, - "created_at": "2024-09-09T09:10:51.000Z", - "href": "href:37", - "id": "id:38", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.20.3", - "auto_delete": false, - "created_at": "2024-09-09T09:10:51.000Z", - "href": "href:39", - "id": "id:40", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.20.4", - "auto_delete": true, - "created_at": "2024-09-09T09:11:08.000Z", - "href": "href:41", - "id": "id:42", - "lifecycle_state": "stable", - "name": "startle-percent-embellish-squeegee", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:43", - "id": "id:44", - "name": "ni2", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.20.255", - "auto_delete": false, - "created_at": "2024-09-09T09:10:51.000Z", - "href": "href:45", - "id": "id:46", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-09-09T09:10:35.000Z", - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.10.0/24", - "name": "subnet1", - "network_acl": { - "crn": "crn:50", - "href": "href:51", - "id": "id:52", - "name": "acl1" - }, - "public_gateway": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "public-gw1", - "resource_type": "public_gateway" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "fiscally-fresh-uncanny-ceramics", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.10.0", - "auto_delete": false, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:53", - "id": "id:54", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.10.1", - "auto_delete": false, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:55", - "id": "id:56", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.10.2", - "auto_delete": false, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:57", - "id": "id:58", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.10.3", - "auto_delete": false, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:59", - "id": "id:60", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.10.4", - "auto_delete": true, - "created_at": "2024-09-09T09:10:52.000Z", - "href": "href:61", - "id": "id:62", - "lifecycle_state": "stable", - "name": "tableware-sprawl-shrivel-popper", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:63", - "id": "id:64", - "name": "ni1", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.10.255", - "auto_delete": false, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:65", - "id": "id:66", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-09-09T09:10:18.000Z", - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.30.0/24", - "name": "subnet3", - "network_acl": { - "crn": "crn:70", - "href": "href:71", - "id": "id:72", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "fiscally-fresh-uncanny-ceramics", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.30.0", - "auto_delete": false, - "created_at": "2024-09-09T09:10:18.000Z", - "href": "href:73", - "id": "id:74", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.30.1", - "auto_delete": false, - "created_at": "2024-09-09T09:10:18.000Z", - "href": "href:75", - "id": "id:76", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.30.2", - "auto_delete": false, - "created_at": "2024-09-09T09:10:18.000Z", - "href": "href:77", - "id": "id:78", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.30.3", - "auto_delete": false, - "created_at": "2024-09-09T09:10:18.000Z", - "href": "href:79", - "id": "id:80", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.30.4", - "auto_delete": true, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:81", - "id": "id:82", - "lifecycle_state": "stable", - "name": "disallow-oxidant-etching-selection", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:83", - "id": "id:84", - "name": "ni3a", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.30.5", - "auto_delete": true, - "created_at": "2024-09-09T09:10:36.000Z", - "href": "href:85", - "id": "id:86", - "lifecycle_state": "stable", - "name": "reheat-joyride-little-overprice", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:87", - "id": "id:88", - "name": "ni3b", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.30.255", - "auto_delete": false, - "created_at": "2024-09-09T09:10:18.000Z", - "href": "href:89", - "id": "id:90", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - } - ], - "public_gateways": [ - { - "created_at": "2024-09-09T09:10:14.000Z", - "crn": "crn:30", - "floating_ip": { - "address": "52.118.147.142", - "crn": "crn:91", - "href": "href:92", - "id": "id:93", - "name": "public-gw1" - }, - "href": "href:31", - "id": "id:32", - "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": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - } - ], - "floating_ips": [ - { - "address": "52.116.129.168", - "created_at": "2024-09-09T09:11:31.000Z", - "crn": "crn:94", - "href": "href:95", - "id": "id:96", - "name": "vsi1-fip", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:63", - "id": "id:64", - "name": "ni1", - "primary_ip": { - "address": "10.240.10.4", - "href": "href:61", - "id": "id:62", - "name": "tableware-sprawl-shrivel-popper", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - }, - { - "address": "52.118.147.142", - "created_at": "2024-09-09T09:10:14.000Z", - "crn": "crn:91", - "href": "href:92", - "id": "id:93", - "name": "public-gw1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:31", - "id": "id:32", - "name": "public-gw1", - "resource_type": "public_gateway", - "crn": "crn:30" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - } - ], - "network_acls": [ - { - "created_at": "2024-09-09T09:10:15.000Z", - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:99", - "id": "id:100", - "name": "acl2-out-2" - }, - "created_at": "2024-09-09T09:10:15.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:97", - "id": "id:98", - "ip_version": "ipv4", - "name": "acl2-out-1", - "source": "10.240.20.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:101", - "id": "id:102", - "name": "acl2-in-1" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.10.0/24", - "direction": "outbound", - "href": "href:99", - "id": "id:100", - "ip_version": "ipv4", - "name": "acl2-out-2", - "source": "10.240.20.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:103", - "id": "id:104", - "name": "acl2-in-2" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.20.0/24", - "direction": "inbound", - "href": "href:101", - "id": "id:102", - "ip_version": "ipv4", - "name": "acl2-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-09-09T09:10:17.000Z", - "destination": "10.240.20.0/24", - "direction": "inbound", - "href": "href:103", - "id": "id:104", - "ip_version": "ipv4", - "name": "acl2-in-2", - "source": "10.240.10.0/24", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "name": "subnet2", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-09-09T09:10:14.000Z", - "crn": "crn:50", - "href": "href:51", - "id": "id:52", - "name": "acl1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:107", - "id": "id:108", - "name": "acl1-out-2" - }, - "created_at": "2024-09-09T09:10:15.000Z", - "destination": "172.217.22.46/32", - "direction": "outbound", - "href": "href:105", - "id": "id:106", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "10.240.10.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:109", - "id": "id:110", - "name": "acl1-out-3" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.20.0/24", - "direction": "outbound", - "href": "href:107", - "id": "id:108", - "ip_version": "ipv4", - "name": "acl1-out-2", - "source": "10.240.10.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:111", - "id": "id:112", - "name": "acl1-out-4" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.30.0/24", - "direction": "outbound", - "href": "href:109", - "id": "id:110", - "ip_version": "ipv4", - "name": "acl1-out-3", - "source": "10.240.10.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:113", - "id": "id:114", - "name": "acl1-in-1" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.30.0/24", - "direction": "outbound", - "href": "href:111", - "id": "id:112", - "ip_version": "ipv4", - "name": "acl1-out-4", - "source": "10.240.10.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:115", - "id": "id:116", - "name": "acl1-in-2" - }, - "created_at": "2024-09-09T09:10:17.000Z", - "destination": "10.240.10.0/24", - "direction": "inbound", - "href": "href:113", - "id": "id:114", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "172.217.22.46/32", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:117", - "id": "id:118", - "name": "acl1-in-3" - }, - "created_at": "2024-09-09T09:10:17.000Z", - "destination": "10.240.10.0/24", - "direction": "inbound", - "href": "href:115", - "id": "id:116", - "ip_version": "ipv4", - "name": "acl1-in-2", - "source": "10.240.20.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:119", - "id": "id:120", - "name": "acl1-in-4" - }, - "created_at": "2024-09-09T09:10:18.000Z", - "destination": "10.240.10.0/24", - "direction": "inbound", - "href": "href:117", - "id": "id:118", - "ip_version": "ipv4", - "name": "acl1-in-3", - "source": "10.240.30.0/24", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 443, - "source_port_min": 443 - }, - { - "action": "allow", - "created_at": "2024-09-09T09:10:18.000Z", - "destination": "10.240.10.0/24", - "direction": "inbound", - "href": "href:119", - "id": "id:120", - "ip_version": "ipv4", - "name": "acl1-in-4", - "source": "10.240.30.0/24", - "destination_port_max": 443, - "destination_port_min": 443, - "protocol": "tcp", - "source_port_max": 65535, - "source_port_min": 1 - } - ], - "subnets": [ - { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "subnet1", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-09-09T09:10:14.000Z", - "crn": "crn:70", - "href": "href:71", - "id": "id:72", - "name": "acl3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:123", - "id": "id:124", - "name": "acl3-out-2" - }, - "created_at": "2024-09-09T09:10:15.000Z", - "destination": "10.240.10.0/24", - "direction": "outbound", - "href": "href:121", - "id": "id:122", - "ip_version": "ipv4", - "name": "acl3-out-1", - "source": "10.240.30.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:125", - "id": "id:126", - "name": "acl3-in-1" - }, - "created_at": "2024-09-09T09:10:15.000Z", - "destination": "10.240.10.0/24", - "direction": "outbound", - "href": "href:123", - "id": "id:124", - "ip_version": "ipv4", - "name": "acl3-out-2", - "source": "10.240.30.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:127", - "id": "id:128", - "name": "acl3-in-2" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.30.0/24", - "direction": "inbound", - "href": "href:125", - "id": "id:126", - "ip_version": "ipv4", - "name": "acl3-in-1", - "source": "10.240.10.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-09-09T09:10:16.000Z", - "destination": "10.240.30.0/24", - "direction": "inbound", - "href": "href:127", - "id": "id:128", - "ip_version": "ipv4", - "name": "acl3-in-2", - "source": "10.240.10.0/24", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 443, - "source_port_min": 443 - } - ], - "subnets": [ - { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-09-09T09:09:50.000Z", - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "capitol-siren-chirpy-doornail", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:131", - "id": "id:132", - "name": "allow-outbound" - }, - "created_at": "2024-09-09T09:09:50.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:129", - "id": "id:130", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-09-09T09:09:50.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:131", - "id": "id:132", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "security_groups": [ - { - "created_at": "2024-09-09T09:10:14.000Z", - "crn": "crn:133", - "href": "href:134", - "id": "id:135", - "name": "sg1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:136", - "id": "id:137", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - }, - { - "direction": "outbound", - "href": "href:138", - "id": "id:139", - "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": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-09-09T09:09:50.000Z", - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "wombat-hesitate-scorn-subprime", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:140", - "id": "id:141", - "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:142", - "id": "id:143", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "wombat-hesitate-scorn-subprime" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": null, - "crn": "fake:crn:6", - "href": "fake:href:6", - "id": "fake:id:6", - "name": "test-vpc1--vsi2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "fake:href:1", - "id": "fake:id:1", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "code": 0, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "inbound", - "href": "fake:href:3", - "id": "fake:id:3", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "code": 1, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "inbound", - "href": "fake:href:4", - "id": "fake:id:4", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "code": 2, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "inbound", - "href": "fake:href:5", - "id": "fake:id:5", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "code": 3, - "protocol": "icmp", - "type": 5 - } - ], - "targets": [ - { - "href": "href:43", - "id": "id:44", - "name": "ni2", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": null, - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "fake:href:7", - "id": "fake:id:7", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "code": 0, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "outbound", - "href": "fake:href:8", - "id": "fake:id:8", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "code": 1, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "outbound", - "href": "fake:href:9", - "id": "fake:id:9", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "code": 2, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "outbound", - "href": "fake:href:10", - "id": "fake:id:10", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "code": 3, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "outbound", - "href": "fake:href:11", - "id": "fake:id:11", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:6", - "href": "fake:href:6", - "id": "fake:id:6", - "name": "test-vpc1--vsi2" - }, - "code": 0, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "outbound", - "href": "fake:href:12", - "id": "fake:id:12", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:6", - "href": "fake:href:6", - "id": "fake:id:6", - "name": "test-vpc1--vsi2" - }, - "code": 1, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "outbound", - "href": "fake:href:13", - "id": "fake:id:13", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:6", - "href": "fake:href:6", - "id": "fake:id:6", - "name": "test-vpc1--vsi2" - }, - "code": 2, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "outbound", - "href": "fake:href:14", - "id": "fake:id:14", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:6", - "href": "fake:href:6", - "id": "fake:id:6", - "name": "test-vpc1--vsi2" - }, - "code": 3, - "protocol": "icmp", - "type": 5 - } - ], - "targets": [ - { - "href": "href:63", - "id": "id:64", - "name": "ni1", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": null, - "crn": "fake:crn:15", - "href": "fake:href:15", - "id": "fake:id:15", - "name": "test-vpc1--vsi3b", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [], - "targets": [ - { - "href": "href:87", - "id": "id:88", - "name": "ni3b", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": null, - "crn": "fake:crn:16", - "href": "fake:href:16", - "id": "fake:id:16", - "name": "test-vpc1--vsi3a", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [], - "targets": [ - { - "href": "href:83", - "id": "id:84", - "name": "ni3a", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "endpoint_gateways": [], - "instances": [ - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:149" - }, - "href": "href:147", - "id": "id:148", - "name": "falsetto-snowstorm-bankbook-agreement", - "volume": { - "crn": "crn:150", - "href": "href:151", - "id": "id:152", - "name": "prawn-trusting-pasty-dental", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-09-09T09:11:07.000Z", - "crn": "crn:144", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:145", - "id": "id:146", - "image": { - "crn": "crn:153", - "href": "href:154", - "id": "id:155", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:43", - "id": "id:44", - "name": "ni2", - "primary_ip": { - "address": "10.240.20.4", - "href": "href:41", - "id": "id:42", - "name": "startle-percent-embellish-squeegee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:156", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:149" - }, - "href": "href:147", - "id": "id:148", - "name": "falsetto-snowstorm-bankbook-agreement", - "volume": { - "crn": "crn:150", - "href": "href:151", - "id": "id:152", - "name": "prawn-trusting-pasty-dental", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-09-09T09:11:07.000Z", - "floating_ips": [], - "href": "href:43", - "id": "id:44", - "name": "ni2", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.20.4", - "href": "href:41", - "id": "id:42", - "name": "startle-percent-embellish-squeegee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "fake:crn:6", - "href": "fake:href:6", - "id": "fake:id:6", - "name": "test-vpc1--vsi2" - } - ], - "status": "available", - "subnet": { - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:162" - }, - "href": "href:160", - "id": "id:161", - "name": "outskirts-oversized-roundish-ludicrous", - "volume": { - "crn": "crn:163", - "href": "href:164", - "id": "id:165", - "name": "family-tackling-foothold-train", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-09-09T09:10:52.000Z", - "crn": "crn:157", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:158", - "id": "id:159", - "image": { - "crn": "crn:153", - "href": "href:154", - "id": "id:155", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:63", - "id": "id:64", - "name": "ni1", - "primary_ip": { - "address": "10.240.10.4", - "href": "href:61", - "id": "id:62", - "name": "tableware-sprawl-shrivel-popper", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:156", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:162" - }, - "href": "href:160", - "id": "id:161", - "name": "outskirts-oversized-roundish-ludicrous", - "volume": { - "crn": "crn:163", - "href": "href:164", - "id": "id:165", - "name": "family-tackling-foothold-train", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-09-09T09:10:52.000Z", - "floating_ips": [ - { - "address": "52.116.129.168", - "crn": "crn:94", - "href": "href:95", - "id": "id:96", - "name": "vsi1-fip" - } - ], - "href": "href:63", - "id": "id:64", - "name": "ni1", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.10.4", - "href": "href:61", - "id": "id:62", - "name": "tableware-sprawl-shrivel-popper", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:171" - }, - "href": "href:169", - "id": "id:170", - "name": "camera-yam-headfirst-scabiosa", - "volume": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", - "name": "sprinkler-avenue-playset-dislodge", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-09-09T09:10:35.000Z", - "crn": "crn:166", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:167", - "id": "id:168", - "image": { - "crn": "crn:153", - "href": "href:154", - "id": "id:155", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi3b", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:87", - "id": "id:88", - "name": "ni3b", - "primary_ip": { - "address": "10.240.30.5", - "href": "href:85", - "id": "id:86", - "name": "reheat-joyride-little-overprice", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:156", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:171" - }, - "href": "href:169", - "id": "id:170", - "name": "camera-yam-headfirst-scabiosa", - "volume": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", - "name": "sprinkler-avenue-playset-dislodge", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-09-09T09:10:34.000Z", - "floating_ips": [], - "href": "href:87", - "id": "id:88", - "name": "ni3b", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.30.5", - "href": "href:85", - "id": "id:86", - "name": "reheat-joyride-little-overprice", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "fake:crn:15", - "href": "fake:href:15", - "id": "fake:id:15", - "name": "test-vpc1--vsi3b" - } - ], - "status": "available", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:180" - }, - "href": "href:178", - "id": "id:179", - "name": "cryptic-cork-saponify-lively", - "volume": { - "crn": "crn:181", - "href": "href:182", - "id": "id:183", - "name": "appraisal-mountains-itinerary-twine", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-09-09T09:10:34.000Z", - "crn": "crn:175", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:176", - "id": "id:177", - "image": { - "crn": "crn:153", - "href": "href:154", - "id": "id:155", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi3a", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:83", - "id": "id:84", - "name": "ni3a", - "primary_ip": { - "address": "10.240.30.4", - "href": "href:81", - "id": "id:82", - "name": "disallow-oxidant-etching-selection", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:156", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:180" - }, - "href": "href:178", - "id": "id:179", - "name": "cryptic-cork-saponify-lively", - "volume": { - "crn": "crn:181", - "href": "href:182", - "id": "id:183", - "name": "appraisal-mountains-itinerary-twine", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-09-09T09:10:34.000Z", - "floating_ips": [], - "href": "href:83", - "id": "id:84", - "name": "ni3a", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.30.4", - "href": "href:81", - "id": "id:82", - "name": "disallow-oxidant-etching-selection", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "fake:crn:16", - "href": "fake:href:16", - "id": "fake:id:16", - "name": "test-vpc1--vsi3a" - } - ], - "status": "available", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - } - ], - "virtual_nis": null, - "routing_tables": [ - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-09-09T09:09:51.000Z", - "href": "href:11", - "id": "id:12", - "is_default": true, - "lifecycle_state": "stable", - "name": "fiscally-fresh-uncanny-ceramics", - "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": "subnet2", - "resource_type": "subnet" - }, - { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "subnet1", - "resource_type": "subnet" - }, - { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "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_sg_icmp_codes/conn_spec.json b/test/data/optimize_sg_icmp_codes/conn_spec.json deleted file mode 100644 index 83342736..00000000 --- a/test/data/optimize_sg_icmp_codes/conn_spec.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "externals": { - "e1": "0.0.0.0/31" - }, - "required-connections": [ - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 5, - "code": 0 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 5, - "code": 1 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 5, - "code": 2 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 5, - "code": 3 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 5, - "code": 0 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 5, - "code": 1 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 5, - "code": 2 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 5, - "code": 3 - } - ] - } - ] -} diff --git a/test/data/optimize_sg_icmp_codes/details.txt b/test/data/optimize_sg_icmp_codes/details.txt deleted file mode 100644 index ac439dbe..00000000 --- a/test/data/optimize_sg_icmp_codes/details.txt +++ /dev/null @@ -1,14 +0,0 @@ -vsi1 --> 0.0.0.0/31 (icmp type:5 code:0) -vsi1 --> 0.0.0.0/31 (icmp type:5 code:1) -vsi1 --> 0.0.0.0/31 (icmp type:5 code:2) -vsi1 --> 0.0.0.0/31 (icmp type:5 code:3) - -vsi1 --> vsi2 (icmp type:5 code:0) -vsi1 --> vsi2 (icmp type:5 code:1) -vsi1 --> vsi2 (icmp type:5 code:2) -vsi1 --> vsi2 (icmp type:5 code:3) - -==================================== - -vsi1 --> 0.0.0.0/31 (icmp type:5) -vsi1 --> vsi2 (icmp type:5) \ No newline at end of file diff --git a/test/data/optimize_sg_icmp_types/config_object.json b/test/data/optimize_sg_icmp_types/config_object.json deleted file mode 100644 index 0511af0e..00000000 --- a/test/data/optimize_sg_icmp_types/config_object.json +++ /dev/null @@ -1,2493 +0,0 @@ -{ - "collector_version": "0.11.0", - "provider": "ibm", - "vpcs": [ - { - "classic_access": false, - "created_at": "2024-09-09T09:09:50.000Z", - "crn": "crn:1", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.217.112" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.12.160.153" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.16.253.223" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "capitol-siren-chirpy-doornail" - }, - "default_routing_table": { - "href": "href:11", - "id": "id:12", - "name": "fiscally-fresh-uncanny-ceramics", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "wombat-hesitate-scorn-subprime" - }, - "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": "test-vpc1", - "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-09-09T09:09:50.000Z", - "has_subnets": true, - "href": "href:18", - "id": "id:19", - "is_default": true, - "name": "filling-tasty-bacterium-parlor", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.64.0/18", - "created_at": "2024-09-09T09:09:50.000Z", - "has_subnets": false, - "href": "href:20", - "id": "id:21", - "is_default": true, - "name": "relearn-ragweed-goon-feisty", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "cidr": "10.240.128.0/18", - "created_at": "2024-09-09T09:09:50.000Z", - "has_subnets": false, - "href": "href:22", - "id": "id:23", - "is_default": true, - "name": "unruffled-penknife-snowshoe-ninetieth", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - } - ], - "subnets": [ - { - "available_ipv4_address_count": 250, - "created_at": "2024-09-09T09:10:51.000Z", - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.20.0/24", - "name": "subnet2", - "network_acl": { - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl2" - }, - "public_gateway": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "public-gw1", - "resource_type": "public_gateway" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "fiscally-fresh-uncanny-ceramics", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.20.0", - "auto_delete": false, - "created_at": "2024-09-09T09:10:51.000Z", - "href": "href:33", - "id": "id:34", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.20.1", - "auto_delete": false, - "created_at": "2024-09-09T09:10:51.000Z", - "href": "href:35", - "id": "id:36", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.20.2", - "auto_delete": false, - "created_at": "2024-09-09T09:10:51.000Z", - "href": "href:37", - "id": "id:38", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.20.3", - "auto_delete": false, - "created_at": "2024-09-09T09:10:51.000Z", - "href": "href:39", - "id": "id:40", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.20.4", - "auto_delete": true, - "created_at": "2024-09-09T09:11:08.000Z", - "href": "href:41", - "id": "id:42", - "lifecycle_state": "stable", - "name": "startle-percent-embellish-squeegee", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:43", - "id": "id:44", - "name": "ni2", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.20.255", - "auto_delete": false, - "created_at": "2024-09-09T09:10:51.000Z", - "href": "href:45", - "id": "id:46", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-09-09T09:10:35.000Z", - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.10.0/24", - "name": "subnet1", - "network_acl": { - "crn": "crn:50", - "href": "href:51", - "id": "id:52", - "name": "acl1" - }, - "public_gateway": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "public-gw1", - "resource_type": "public_gateway" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "fiscally-fresh-uncanny-ceramics", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.10.0", - "auto_delete": false, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:53", - "id": "id:54", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.10.1", - "auto_delete": false, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:55", - "id": "id:56", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.10.2", - "auto_delete": false, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:57", - "id": "id:58", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.10.3", - "auto_delete": false, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:59", - "id": "id:60", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.10.4", - "auto_delete": true, - "created_at": "2024-09-09T09:10:52.000Z", - "href": "href:61", - "id": "id:62", - "lifecycle_state": "stable", - "name": "tableware-sprawl-shrivel-popper", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:63", - "id": "id:64", - "name": "ni1", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.10.255", - "auto_delete": false, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:65", - "id": "id:66", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-09-09T09:10:18.000Z", - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.30.0/24", - "name": "subnet3", - "network_acl": { - "crn": "crn:70", - "href": "href:71", - "id": "id:72", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "fiscally-fresh-uncanny-ceramics", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.30.0", - "auto_delete": false, - "created_at": "2024-09-09T09:10:18.000Z", - "href": "href:73", - "id": "id:74", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.30.1", - "auto_delete": false, - "created_at": "2024-09-09T09:10:18.000Z", - "href": "href:75", - "id": "id:76", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.30.2", - "auto_delete": false, - "created_at": "2024-09-09T09:10:18.000Z", - "href": "href:77", - "id": "id:78", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.30.3", - "auto_delete": false, - "created_at": "2024-09-09T09:10:18.000Z", - "href": "href:79", - "id": "id:80", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.30.4", - "auto_delete": true, - "created_at": "2024-09-09T09:10:35.000Z", - "href": "href:81", - "id": "id:82", - "lifecycle_state": "stable", - "name": "disallow-oxidant-etching-selection", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:83", - "id": "id:84", - "name": "ni3a", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.30.5", - "auto_delete": true, - "created_at": "2024-09-09T09:10:36.000Z", - "href": "href:85", - "id": "id:86", - "lifecycle_state": "stable", - "name": "reheat-joyride-little-overprice", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:87", - "id": "id:88", - "name": "ni3b", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.30.255", - "auto_delete": false, - "created_at": "2024-09-09T09:10:18.000Z", - "href": "href:89", - "id": "id:90", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - } - ], - "public_gateways": [ - { - "created_at": "2024-09-09T09:10:14.000Z", - "crn": "crn:30", - "floating_ip": { - "address": "52.118.147.142", - "crn": "crn:91", - "href": "href:92", - "id": "id:93", - "name": "public-gw1" - }, - "href": "href:31", - "id": "id:32", - "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": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - } - ], - "floating_ips": [ - { - "address": "52.116.129.168", - "created_at": "2024-09-09T09:11:31.000Z", - "crn": "crn:94", - "href": "href:95", - "id": "id:96", - "name": "vsi1-fip", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:63", - "id": "id:64", - "name": "ni1", - "primary_ip": { - "address": "10.240.10.4", - "href": "href:61", - "id": "id:62", - "name": "tableware-sprawl-shrivel-popper", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - }, - { - "address": "52.118.147.142", - "created_at": "2024-09-09T09:10:14.000Z", - "crn": "crn:91", - "href": "href:92", - "id": "id:93", - "name": "public-gw1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:31", - "id": "id:32", - "name": "public-gw1", - "resource_type": "public_gateway", - "crn": "crn:30" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - } - ], - "network_acls": [ - { - "created_at": "2024-09-09T09:10:15.000Z", - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:99", - "id": "id:100", - "name": "acl2-out-2" - }, - "created_at": "2024-09-09T09:10:15.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:97", - "id": "id:98", - "ip_version": "ipv4", - "name": "acl2-out-1", - "source": "10.240.20.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:101", - "id": "id:102", - "name": "acl2-in-1" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.10.0/24", - "direction": "outbound", - "href": "href:99", - "id": "id:100", - "ip_version": "ipv4", - "name": "acl2-out-2", - "source": "10.240.20.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:103", - "id": "id:104", - "name": "acl2-in-2" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.20.0/24", - "direction": "inbound", - "href": "href:101", - "id": "id:102", - "ip_version": "ipv4", - "name": "acl2-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-09-09T09:10:17.000Z", - "destination": "10.240.20.0/24", - "direction": "inbound", - "href": "href:103", - "id": "id:104", - "ip_version": "ipv4", - "name": "acl2-in-2", - "source": "10.240.10.0/24", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "name": "subnet2", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-09-09T09:10:14.000Z", - "crn": "crn:50", - "href": "href:51", - "id": "id:52", - "name": "acl1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:107", - "id": "id:108", - "name": "acl1-out-2" - }, - "created_at": "2024-09-09T09:10:15.000Z", - "destination": "172.217.22.46/32", - "direction": "outbound", - "href": "href:105", - "id": "id:106", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "10.240.10.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:109", - "id": "id:110", - "name": "acl1-out-3" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.20.0/24", - "direction": "outbound", - "href": "href:107", - "id": "id:108", - "ip_version": "ipv4", - "name": "acl1-out-2", - "source": "10.240.10.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:111", - "id": "id:112", - "name": "acl1-out-4" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.30.0/24", - "direction": "outbound", - "href": "href:109", - "id": "id:110", - "ip_version": "ipv4", - "name": "acl1-out-3", - "source": "10.240.10.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:113", - "id": "id:114", - "name": "acl1-in-1" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.30.0/24", - "direction": "outbound", - "href": "href:111", - "id": "id:112", - "ip_version": "ipv4", - "name": "acl1-out-4", - "source": "10.240.10.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:115", - "id": "id:116", - "name": "acl1-in-2" - }, - "created_at": "2024-09-09T09:10:17.000Z", - "destination": "10.240.10.0/24", - "direction": "inbound", - "href": "href:113", - "id": "id:114", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "172.217.22.46/32", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:117", - "id": "id:118", - "name": "acl1-in-3" - }, - "created_at": "2024-09-09T09:10:17.000Z", - "destination": "10.240.10.0/24", - "direction": "inbound", - "href": "href:115", - "id": "id:116", - "ip_version": "ipv4", - "name": "acl1-in-2", - "source": "10.240.20.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:119", - "id": "id:120", - "name": "acl1-in-4" - }, - "created_at": "2024-09-09T09:10:18.000Z", - "destination": "10.240.10.0/24", - "direction": "inbound", - "href": "href:117", - "id": "id:118", - "ip_version": "ipv4", - "name": "acl1-in-3", - "source": "10.240.30.0/24", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 443, - "source_port_min": 443 - }, - { - "action": "allow", - "created_at": "2024-09-09T09:10:18.000Z", - "destination": "10.240.10.0/24", - "direction": "inbound", - "href": "href:119", - "id": "id:120", - "ip_version": "ipv4", - "name": "acl1-in-4", - "source": "10.240.30.0/24", - "destination_port_max": 443, - "destination_port_min": 443, - "protocol": "tcp", - "source_port_max": 65535, - "source_port_min": 1 - } - ], - "subnets": [ - { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "subnet1", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-09-09T09:10:14.000Z", - "crn": "crn:70", - "href": "href:71", - "id": "id:72", - "name": "acl3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:123", - "id": "id:124", - "name": "acl3-out-2" - }, - "created_at": "2024-09-09T09:10:15.000Z", - "destination": "10.240.10.0/24", - "direction": "outbound", - "href": "href:121", - "id": "id:122", - "ip_version": "ipv4", - "name": "acl3-out-1", - "source": "10.240.30.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:125", - "id": "id:126", - "name": "acl3-in-1" - }, - "created_at": "2024-09-09T09:10:15.000Z", - "destination": "10.240.10.0/24", - "direction": "outbound", - "href": "href:123", - "id": "id:124", - "ip_version": "ipv4", - "name": "acl3-out-2", - "source": "10.240.30.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:127", - "id": "id:128", - "name": "acl3-in-2" - }, - "created_at": "2024-09-09T09:10:16.000Z", - "destination": "10.240.30.0/24", - "direction": "inbound", - "href": "href:125", - "id": "id:126", - "ip_version": "ipv4", - "name": "acl3-in-1", - "source": "10.240.10.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-09-09T09:10:16.000Z", - "destination": "10.240.30.0/24", - "direction": "inbound", - "href": "href:127", - "id": "id:128", - "ip_version": "ipv4", - "name": "acl3-in-2", - "source": "10.240.10.0/24", - "destination_port_max": 65535, - "destination_port_min": 1, - "protocol": "tcp", - "source_port_max": 443, - "source_port_min": 443 - } - ], - "subnets": [ - { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-09-09T09:09:50.000Z", - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "capitol-siren-chirpy-doornail", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:131", - "id": "id:132", - "name": "allow-outbound" - }, - "created_at": "2024-09-09T09:09:50.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:129", - "id": "id:130", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-09-09T09:09:50.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:131", - "id": "id:132", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "security_groups": [ - { - "created_at": "2024-09-09T09:10:14.000Z", - "crn": "crn:133", - "href": "href:134", - "id": "id:135", - "name": "sg1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:136", - "id": "id:137", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - }, - { - "direction": "outbound", - "href": "href:138", - "id": "id:139", - "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": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-09-09T09:09:50.000Z", - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "wombat-hesitate-scorn-subprime", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:140", - "id": "id:141", - "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:142", - "id": "id:143", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "wombat-hesitate-scorn-subprime" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": null, - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "fake:href:1", - "id": "fake:id:1", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 0 - }, - { - "direction": "inbound", - "href": "fake:href:3", - "id": "fake:id:3", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 3 - }, - { - "direction": "inbound", - "href": "fake:href:4", - "id": "fake:id:4", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 4 - }, - { - "direction": "inbound", - "href": "fake:href:5", - "id": "fake:id:5", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "inbound", - "href": "fake:href:6", - "id": "fake:id:6", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 8 - }, - { - "direction": "inbound", - "href": "fake:href:7", - "id": "fake:id:7", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 11 - }, - { - "direction": "inbound", - "href": "fake:href:8", - "id": "fake:id:8", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 12 - }, - { - "direction": "inbound", - "href": "fake:href:9", - "id": "fake:id:9", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 13 - }, - { - "direction": "inbound", - "href": "fake:href:10", - "id": "fake:id:10", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 14 - }, - { - "direction": "inbound", - "href": "fake:href:11", - "id": "fake:id:11", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 15 - }, - { - "direction": "inbound", - "href": "fake:href:12", - "id": "fake:id:12", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - }, - "protocol": "icmp", - "type": 16 - } - ], - "targets": [ - { - "href": "href:43", - "id": "id:44", - "name": "ni2", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": null, - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "fake:href:14", - "id": "fake:id:14", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 0 - }, - { - "direction": "outbound", - "href": "fake:href:15", - "id": "fake:id:15", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 3 - }, - { - "direction": "outbound", - "href": "fake:href:16", - "id": "fake:id:16", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 4 - }, - { - "direction": "outbound", - "href": "fake:href:17", - "id": "fake:id:17", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "outbound", - "href": "fake:href:18", - "id": "fake:id:18", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 8 - }, - { - "direction": "outbound", - "href": "fake:href:19", - "id": "fake:id:19", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 11 - }, - { - "direction": "outbound", - "href": "fake:href:20", - "id": "fake:id:20", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 12 - }, - { - "direction": "outbound", - "href": "fake:href:21", - "id": "fake:id:21", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 13 - }, - { - "direction": "outbound", - "href": "fake:href:22", - "id": "fake:id:22", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 14 - }, - { - "direction": "outbound", - "href": "fake:href:23", - "id": "fake:id:23", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 15 - }, - { - "direction": "outbound", - "href": "fake:href:24", - "id": "fake:id:24", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/31" - }, - "protocol": "icmp", - "type": 16 - }, - { - "direction": "outbound", - "href": "fake:href:25", - "id": "fake:id:25", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 0 - }, - { - "direction": "outbound", - "href": "fake:href:26", - "id": "fake:id:26", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 3 - }, - { - "direction": "outbound", - "href": "fake:href:27", - "id": "fake:id:27", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 4 - }, - { - "direction": "outbound", - "href": "fake:href:28", - "id": "fake:id:28", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 5 - }, - { - "direction": "outbound", - "href": "fake:href:29", - "id": "fake:id:29", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 8 - }, - { - "direction": "outbound", - "href": "fake:href:30", - "id": "fake:id:30", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 11 - }, - { - "direction": "outbound", - "href": "fake:href:31", - "id": "fake:id:31", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 12 - }, - { - "direction": "outbound", - "href": "fake:href:32", - "id": "fake:id:32", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 13 - }, - { - "direction": "outbound", - "href": "fake:href:33", - "id": "fake:id:33", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 14 - }, - { - "direction": "outbound", - "href": "fake:href:34", - "id": "fake:id:34", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 15 - }, - { - "direction": "outbound", - "href": "fake:href:35", - "id": "fake:id:35", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - }, - "protocol": "icmp", - "type": 16 - } - ], - "targets": [ - { - "href": "href:63", - "id": "id:64", - "name": "ni1", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": null, - "crn": "fake:crn:36", - "href": "fake:href:36", - "id": "fake:id:36", - "name": "test-vpc1--vsi3b", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [], - "targets": [ - { - "href": "href:87", - "id": "id:88", - "name": "ni3b", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": null, - "crn": "fake:crn:37", - "href": "fake:href:37", - "id": "fake:id:37", - "name": "test-vpc1--vsi3a", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [], - "targets": [ - { - "href": "href:83", - "id": "id:84", - "name": "ni3a", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "endpoint_gateways": [], - "instances": [ - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:149" - }, - "href": "href:147", - "id": "id:148", - "name": "falsetto-snowstorm-bankbook-agreement", - "volume": { - "crn": "crn:150", - "href": "href:151", - "id": "id:152", - "name": "prawn-trusting-pasty-dental", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-09-09T09:11:07.000Z", - "crn": "crn:144", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:145", - "id": "id:146", - "image": { - "crn": "crn:153", - "href": "href:154", - "id": "id:155", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:43", - "id": "id:44", - "name": "ni2", - "primary_ip": { - "address": "10.240.20.4", - "href": "href:41", - "id": "id:42", - "name": "startle-percent-embellish-squeegee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:156", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:149" - }, - "href": "href:147", - "id": "id:148", - "name": "falsetto-snowstorm-bankbook-agreement", - "volume": { - "crn": "crn:150", - "href": "href:151", - "id": "id:152", - "name": "prawn-trusting-pasty-dental", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-09-09T09:11:07.000Z", - "floating_ips": [], - "href": "href:43", - "id": "id:44", - "name": "ni2", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.20.4", - "href": "href:41", - "id": "id:42", - "name": "startle-percent-embellish-squeegee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "fake:crn:13", - "href": "fake:href:13", - "id": "fake:id:13", - "name": "test-vpc1--vsi2" - } - ], - "status": "available", - "subnet": { - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:162" - }, - "href": "href:160", - "id": "id:161", - "name": "outskirts-oversized-roundish-ludicrous", - "volume": { - "crn": "crn:163", - "href": "href:164", - "id": "id:165", - "name": "family-tackling-foothold-train", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-09-09T09:10:52.000Z", - "crn": "crn:157", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:158", - "id": "id:159", - "image": { - "crn": "crn:153", - "href": "href:154", - "id": "id:155", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:63", - "id": "id:64", - "name": "ni1", - "primary_ip": { - "address": "10.240.10.4", - "href": "href:61", - "id": "id:62", - "name": "tableware-sprawl-shrivel-popper", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:156", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:162" - }, - "href": "href:160", - "id": "id:161", - "name": "outskirts-oversized-roundish-ludicrous", - "volume": { - "crn": "crn:163", - "href": "href:164", - "id": "id:165", - "name": "family-tackling-foothold-train", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-09-09T09:10:52.000Z", - "floating_ips": [ - { - "address": "52.116.129.168", - "crn": "crn:94", - "href": "href:95", - "id": "id:96", - "name": "vsi1-fip" - } - ], - "href": "href:63", - "id": "id:64", - "name": "ni1", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.10.4", - "href": "href:61", - "id": "id:62", - "name": "tableware-sprawl-shrivel-popper", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "fake:crn:2", - "href": "fake:href:2", - "id": "fake:id:2", - "name": "test-vpc1--vsi1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:171" - }, - "href": "href:169", - "id": "id:170", - "name": "camera-yam-headfirst-scabiosa", - "volume": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", - "name": "sprinkler-avenue-playset-dislodge", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-09-09T09:10:35.000Z", - "crn": "crn:166", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:167", - "id": "id:168", - "image": { - "crn": "crn:153", - "href": "href:154", - "id": "id:155", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi3b", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:87", - "id": "id:88", - "name": "ni3b", - "primary_ip": { - "address": "10.240.30.5", - "href": "href:85", - "id": "id:86", - "name": "reheat-joyride-little-overprice", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:156", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:171" - }, - "href": "href:169", - "id": "id:170", - "name": "camera-yam-headfirst-scabiosa", - "volume": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", - "name": "sprinkler-avenue-playset-dislodge", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-09-09T09:10:34.000Z", - "floating_ips": [], - "href": "href:87", - "id": "id:88", - "name": "ni3b", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.30.5", - "href": "href:85", - "id": "id:86", - "name": "reheat-joyride-little-overprice", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "fake:crn:36", - "href": "fake:href:36", - "id": "fake:id:36", - "name": "test-vpc1--vsi3b" - } - ], - "status": "available", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:180" - }, - "href": "href:178", - "id": "id:179", - "name": "cryptic-cork-saponify-lively", - "volume": { - "crn": "crn:181", - "href": "href:182", - "id": "id:183", - "name": "appraisal-mountains-itinerary-twine", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-09-09T09:10:34.000Z", - "crn": "crn:175", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:176", - "id": "id:177", - "image": { - "crn": "crn:153", - "href": "href:154", - "id": "id:155", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi3a", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:83", - "id": "id:84", - "name": "ni3a", - "primary_ip": { - "address": "10.240.30.4", - "href": "href:81", - "id": "id:82", - "name": "disallow-oxidant-etching-selection", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:156", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:180" - }, - "href": "href:178", - "id": "id:179", - "name": "cryptic-cork-saponify-lively", - "volume": { - "crn": "crn:181", - "href": "href:182", - "id": "id:183", - "name": "appraisal-mountains-itinerary-twine", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-09-09T09:10:34.000Z", - "floating_ips": [], - "href": "href:83", - "id": "id:84", - "name": "ni3a", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.30.4", - "href": "href:81", - "id": "id:82", - "name": "disallow-oxidant-etching-selection", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "fake:crn:37", - "href": "fake:href:37", - "id": "fake:id:37", - "name": "test-vpc1--vsi3a" - } - ], - "status": "available", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - } - ], - "virtual_nis": null, - "routing_tables": [ - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-09-09T09:09:51.000Z", - "href": "href:11", - "id": "id:12", - "is_default": true, - "lifecycle_state": "stable", - "name": "fiscally-fresh-uncanny-ceramics", - "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": "subnet2", - "resource_type": "subnet" - }, - { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "subnet1", - "resource_type": "subnet" - }, - { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "subnet3", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "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_sg_icmp_types/conn_spec.json b/test/data/optimize_sg_icmp_types/conn_spec.json deleted file mode 100644 index f9c8648c..00000000 --- a/test/data/optimize_sg_icmp_types/conn_spec.json +++ /dev/null @@ -1,359 +0,0 @@ -{ - "externals": { - "e1": "0.0.0.0/31" - }, - "required-connections": [ - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 0 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 3 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 4 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 5 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 8 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 11 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 12 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 13 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 14 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 15 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "e1", - "type": "external" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 16 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 0 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 3 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 4 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 5 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 8 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 11 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 12 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 13 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 14 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 15 - } - ] - }, - { - "src": { - "name": "vsi1", - "type": "instance" - }, - "dst": { - "name": "vsi2", - "type": "instance" - }, - "allowed-protocols": [ - { - "protocol": "ICMP", - "type": 16 - } - ] - } - ] -} diff --git a/test/data/optimize_sg_icmp_types/details.txt b/test/data/optimize_sg_icmp_types/details.txt deleted file mode 100644 index c13db0ec..00000000 --- a/test/data/optimize_sg_icmp_types/details.txt +++ /dev/null @@ -1,28 +0,0 @@ -vsi1 --> 0.0.0.0/31 (icmp type:0) -vsi1 --> 0.0.0.0/31 (icmp type:3) -vsi1 --> 0.0.0.0/31 (icmp type:4) -vsi1 --> 0.0.0.0/31 (icmp type:5) -vsi1 --> 0.0.0.0/31 (icmp type:8) -vsi1 --> 0.0.0.0/31 (icmp type:11) -vsi1 --> 0.0.0.0/31 (icmp type:12) -vsi1 --> 0.0.0.0/31 (icmp type:13) -vsi1 --> 0.0.0.0/31 (icmp type:14) -vsi1 --> 0.0.0.0/31 (icmp type:15) -vsi1 --> 0.0.0.0/31 (icmp type:16) - -vsi1 --> vsi2 (icmp type:0) -vsi1 --> vsi2 (icmp type:3) -vsi1 --> vsi2 (icmp type:4) -vsi1 --> vsi2 (icmp type:5) -vsi1 --> vsi2 (icmp type:8) -vsi1 --> vsi2 (icmp type:11) -vsi1 --> vsi2 (icmp type:12) -vsi1 --> vsi2 (icmp type:13) -vsi1 --> vsi2 (icmp type:14) -vsi1 --> vsi2 (icmp type:15) -vsi1 --> vsi2 (icmp type:16) - -==================================== - -vsi1 --> 0.0.0.0/31 (icmp) -vsi1 --> vsi2 (icmp) \ No newline at end of file diff --git a/test/expected/optimize_sg_icmp_codes/sg_expected.tf b/test/expected/optimize_sg_icmp_codes/sg_expected.tf deleted file mode 100644 index d1ca8c9d..00000000 --- a/test/expected/optimize_sg_icmp_codes/sg_expected.tf +++ /dev/null @@ -1,70 +0,0 @@ -resource "ibm_is_security_group" "sg1" { - name = "sg-sg1" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} - - -resource "ibm_is_security_group" "test-vpc1--vsi1" { - name = "sg-test-vpc1--vsi1" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} -resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { - group = ibm_is_security_group.test-vpc1--vsi1.id - direction = "outbound" - remote = ibm_is_security_group.test-vpc1--vsi2.id - icmp { - type = 5 - } -} -resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { - group = ibm_is_security_group.test-vpc1--vsi1.id - direction = "outbound" - remote = "0.0.0.0/31" - icmp { - type = 5 - code = 0 - } -} - - -resource "ibm_is_security_group" "test-vpc1--vsi2" { - name = "sg-test-vpc1--vsi2" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} -resource "ibm_is_security_group_rule" "test-vpc1--vsi2-0" { - group = ibm_is_security_group.test-vpc1--vsi2.id - direction = "inbound" - remote = ibm_is_security_group.test-vpc1--vsi1.id - icmp { - type = 5 - } -} - - -resource "ibm_is_security_group" "test-vpc1--vsi3a" { - name = "sg-test-vpc1--vsi3a" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} - - -resource "ibm_is_security_group" "test-vpc1--vsi3b" { - name = "sg-test-vpc1--vsi3b" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} - - -resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { - name = "sg-wombat-hesitate-scorn-subprime" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} -resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-0" { - group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id - direction = "inbound" - remote = ibm_is_security_group.wombat-hesitate-scorn-subprime.id -} diff --git a/test/expected/optimize_sg_icmp_types/sg_expected.tf b/test/expected/optimize_sg_icmp_types/sg_expected.tf deleted file mode 100644 index 2795bc56..00000000 --- a/test/expected/optimize_sg_icmp_types/sg_expected.tf +++ /dev/null @@ -1,67 +0,0 @@ -resource "ibm_is_security_group" "sg1" { - name = "sg-sg1" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} - - -resource "ibm_is_security_group" "test-vpc1--vsi1" { - name = "sg-test-vpc1--vsi1" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} -resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { - group = ibm_is_security_group.test-vpc1--vsi1.id - direction = "outbound" - remote = ibm_is_security_group.test-vpc1--vsi2.id - icmp { - } -} -resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { - group = ibm_is_security_group.test-vpc1--vsi1.id - direction = "outbound" - remote = "0.0.0.0/31" - icmp { - type = 0 - } -} - - -resource "ibm_is_security_group" "test-vpc1--vsi2" { - name = "sg-test-vpc1--vsi2" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} -resource "ibm_is_security_group_rule" "test-vpc1--vsi2-0" { - group = ibm_is_security_group.test-vpc1--vsi2.id - direction = "inbound" - remote = ibm_is_security_group.test-vpc1--vsi1.id - icmp { - } -} - - -resource "ibm_is_security_group" "test-vpc1--vsi3a" { - name = "sg-test-vpc1--vsi3a" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} - - -resource "ibm_is_security_group" "test-vpc1--vsi3b" { - name = "sg-test-vpc1--vsi3b" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} - - -resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { - name = "sg-wombat-hesitate-scorn-subprime" - resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id -} -resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-0" { - group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id - direction = "inbound" - remote = ibm_is_security_group.wombat-hesitate-scorn-subprime.id -} diff --git a/test/main_test_list.go b/test/main_test_list.go index a2f0982c..f9d63166 100644 --- a/test/main_test_list.go +++ b/test/main_test_list.go @@ -318,24 +318,6 @@ func synthSGTestsList() []testCase { // Note2: each data folder has a details.txt file with the test explanation func optimizeSGTestsLists() []testCase { return []testCase{ - { - testName: "optimize_sg_icmp_codes", - args: &command{ - cmd: optimize, - subcmd: sg, - config: "%s/optimize_sg_icmp_codes/config_object.json", - outputFile: "%s/optimize_sg_icmp_codes/sg_expected.tf", - }, - }, - { - testName: "optimize_sg_icmp_types", - args: &command{ - cmd: optimize, - subcmd: sg, - config: "%s/optimize_sg_icmp_types/config_object.json", - outputFile: "%s/optimize_sg_icmp_types/sg_expected.tf", - }, - }, { testName: "optimize_sg_protocols_to_all_tf", args: &command{ From fadb26bd5736c0a004269da54dfa3fda84d8e8b7 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 9 Oct 2024 08:43:11 +0300 Subject: [PATCH 061/131] portset --- pkg/optimize/sg/ipCubesToRules.go | 10 ++-- pkg/optimize/sg/rulesToCubes.go | 96 ++++++++++++++++--------------- pkg/optimize/sg/sg.go | 2 +- pkg/optimize/sg/sgCubesToRules.go | 7 +-- 4 files changed, 58 insertions(+), 57 deletions(-) diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go index e38acb9d..cf5c31b8 100644 --- a/pkg/optimize/sg/ipCubesToRules.go +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -23,13 +23,13 @@ func allProtocolIPCubesIPToRules(cubes *netset.IPBlock, direction ir.Direction) return result } -func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], allProtocolCubes *netset.IPBlock, +func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], allCubes *netset.IPBlock, direction ir.Direction, isTCP bool) []*ir.SGRule { activeRules := make(map[*netset.IPBlock]*interval.Interval) // start ip and ports result := make([]*ir.SGRule, 0) for i := range cubes { - if i > 0 && !continuation(cubes[i-1], cubes[i], allProtocolCubes) { + if i > 0 && !continuation(cubes[i-1], cubes[i], allCubes) { for ipb, ports := range activeRules { p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(ports.Start()), int(ports.End())) ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[i-1].Left.LastIPAddressObject()) @@ -75,7 +75,7 @@ func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *interval.CanonicalSe } // problem: where should I end the rule? -// func createTcpudpRules(rules []ds.Pair[*netset.IPBlock, *interval.Interval], span []ds.Pair[*netset.IPBlock, *interval.CanonicalSet], +// func createTcpudpRules(rules []ds.Pair[*netset.IPBlock, *interval.Interval], span []ds.Pair[*netset.IPBlock, *netset.PortSet], // direction ir.Direction, isTCP bool) (res []ir.SGRule) { // res = make([]ir.SGRule, 0) // for _, r := range rules { @@ -87,12 +87,12 @@ func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *interval.CanonicalSe // return res // } -func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allProtocolCubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { +func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { activeRules := make(map[*netset.IPBlock]*netp.ICMP) result := make([]*ir.SGRule, 0) for i := range cubes { - if i > 0 && !continuation(cubes[i-1], cubes[i], allProtocolCubes) { + if i > 0 && !continuation(cubes[i-1], cubes[i], allCubes) { for ipb, icmp := range activeRules { p, _ := netp.NewICMP(icmp.TypeCode) ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[i-1].Left.LastIPAddressObject()) diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go index 84e28bd1..deb07179 100644 --- a/pkg/optimize/sg/rulesToCubes.go +++ b/pkg/optimize/sg/rulesToCubes.go @@ -16,7 +16,55 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -// calculate all cubes +// SG remote +func rulesToSGCubes(rules *rulesPerProtocol) *sgCubesPerProtocol { + tcpSpan := tcpudpRulesSGCubes(rules.tcp) + udpSpan := tcpudpRulesSGCubes(rules.udp) + icmpSpan := icmpRulesSGCubes(rules.icmp) + allSpan := allProtocolRulesToSGCubes(rules.all) + return &sgCubesPerProtocol{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} +} + +// all protocol rules to cubes +func allProtocolRulesToSGCubes(rules []*ir.SGRule) []ir.SGName { + result := make(map[ir.SGName]struct{}) + for i := range rules { + remote := rules[i].Remote.(ir.SGName) // already checked + result[remote] = struct{}{} + } + return utils.SortedMapKeys(result) +} + +// tcp/udp rules to cubes -- map where the key is the SG name and the value is the protocol ports +func tcpudpRulesSGCubes(rules []*ir.SGRule) map[ir.SGName]*netset.PortSet { + result := make(map[ir.SGName]*netset.PortSet) + for _, rule := range rules { + p := rule.Protocol.(netp.TCPUDP) // already checked + remote := rule.Remote.(ir.SGName) // already checked + if result[remote] == nil { + result[remote] = interval.NewCanonicalSet() + } + result[remote].AddInterval(p.DstPorts()) + } + return result +} + +// icmp rules to cubes -- map where the key is the SG name and the value is icmpset +func icmpRulesSGCubes(rules []*ir.SGRule) map[ir.SGName]*netset.ICMPSet { + result := make(map[ir.SGName]*netset.ICMPSet) + for _, rule := range rules { + p := rule.Protocol.(netp.ICMP) // already checked + remote := rule.Remote.(ir.SGName) // already checked + if result[remote] == nil { + result[remote] = netset.EmptyICMPSet() + } + icmpSet := optimize.IcmpRuleToIcmpSet(p) + result[remote] = result[remote].Union(icmpSet) + } + return result +} + +// IP remote func rulesToIPCubes(rules *rulesPerProtocol) *ipCubesPerProtocol { tcpCubes := tcpudpRulesToIPCubes(rules.tcp) udpCubes := tcpudpRulesToIPCubes(rules.udp) @@ -25,14 +73,6 @@ func rulesToIPCubes(rules *rulesPerProtocol) *ipCubesPerProtocol { return &ipCubesPerProtocol{tcp: tcpCubes, udp: udpCubes, icmp: icmpCubes, all: allCubes} } -func rulesToSGCubes(rules *rulesPerProtocol) *sgCubesPerProtocol { - tcpSpan := tcpudpRulesToSGToPortsSpan(rules.tcp) - udpSpan := tcpudpRulesToSGToPortsSpan(rules.udp) - icmpSpan := icmpRulesToSGToSpan(rules.icmp) - allSpan := allProtocolRulesToSGToSpan(rules.all) - return &sgCubesPerProtocol{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} -} - // all protocol rules to cubes func allProtocolRulesToIPCubes(rules []*ir.SGRule) *netset.IPBlock { res := netset.NewIPBlock() @@ -42,15 +82,6 @@ func allProtocolRulesToIPCubes(rules []*ir.SGRule) *netset.IPBlock { return res } -func allProtocolRulesToSGToSpan(rules []*ir.SGRule) []ir.SGName { - result := make(map[ir.SGName]struct{}) - for i := range rules { - remote := rules[i].Remote.(ir.SGName) - result[remote] = struct{}{} - } - return utils.SortedMapKeys(result) -} - // tcp/udp rules (separately) to cubes (IPBlock X portset). func tcpudpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.PortSet] { cubes := ds.NewProductLeft[*netset.IPBlock, *netset.PortSet]() @@ -63,20 +94,6 @@ func tcpudpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) } -// tcp/udp rules to cubes -- map where the key is the SG name and the value is the protocol ports -func tcpudpRulesToSGToPortsSpan(rules []*ir.SGRule) map[ir.SGName]*netset.PortSet { - result := make(map[ir.SGName]*netset.PortSet) - for _, rule := range rules { - p := rule.Protocol.(netp.TCPUDP) // already checked - remote := rule.Remote.(ir.SGName) // already checked - if result[remote] == nil { - result[remote] = interval.NewCanonicalSet() - } - result[remote].AddInterval(p.DstPorts()) - } - return result -} - // icmp rules to cubes (IPBlock X icmp set). func icmpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.ICMPSet] { cubes := ds.NewProductLeft[*netset.IPBlock, *netset.ICMPSet]() @@ -89,18 +106,3 @@ func icmpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.I } return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) } - -// icmp rules to cubes -- map where the key is the SG name and the value is icmpset -func icmpRulesToSGToSpan(rules []*ir.SGRule) map[ir.SGName]*netset.ICMPSet { - result := make(map[ir.SGName]*netset.ICMPSet) - for _, rule := range rules { - p := rule.Protocol.(netp.ICMP) // already checked - remote := rule.Remote.(ir.SGName) // already checked - if result[remote] == nil { - result[remote] = netset.EmptyICMPSet() - } - icmpSet := optimize.IcmpRuleToIcmpSet(p) - result[remote] = result[remote].Union(icmpSet) - } - return result -} diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index 7ddbafd3..2427c265 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -116,7 +116,7 @@ func (s *sgOptimizer) optimizeSG(vpcName string, sgName ir.SGName) { // reduceSGRules attempts to reduce the number of rules with different remote types separately func (s *sgOptimizer) reduceRules(rules []*ir.SGRule, direction ir.Direction) []*ir.SGRule { - // separate all rules to groups of (protocol X remote) + // separate all rules to groups of protocol X remote ([tcp, udp, icmp, protocolAll] X [ip, sg]) ruleGroups := divideSGRules(rules) // rules with SG as a remote diff --git a/pkg/optimize/sg/sgCubesToRules.go b/pkg/optimize/sg/sgCubesToRules.go index 0eb4bd12..4ed229c7 100644 --- a/pkg/optimize/sg/sgCubesToRules.go +++ b/pkg/optimize/sg/sgCubesToRules.go @@ -6,7 +6,6 @@ SPDX-License-Identifier: Apache-2.0 package sgoptimizer import ( - "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" @@ -14,8 +13,8 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" ) -// cubes (SGName X ports set) to SG rules -func tcpudpSGCubesToRules(span map[ir.SGName]*interval.CanonicalSet, direction ir.Direction, isTCP bool) []*ir.SGRule { +// cubes (SGName X portSet) to SG rules +func tcpudpSGCubesToRules(span map[ir.SGName]*netset.PortSet, direction ir.Direction, isTCP bool) []*ir.SGRule { result := make([]*ir.SGRule, 0) for sgName, portSet := range span { for _, dstPorts := range portSet.Intervals() { @@ -26,7 +25,7 @@ func tcpudpSGCubesToRules(span map[ir.SGName]*interval.CanonicalSet, direction i return result } -// cubes (SGName X icmp set) to SG rules +// cubes (SGName X icmpset) to SG rules func icmpSGCubesToRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Direction) []*ir.SGRule { result := make([]*ir.SGRule, 0) for sgName, icmpSet := range span { From 3cdadc60ab8aa759600e6117abdcaef897df09bb Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 9 Oct 2024 13:46:10 +0300 Subject: [PATCH 062/131] convert ip cubes, generic ipCubeToRule --- pkg/optimize/common.go | 1 + pkg/optimize/sg/ipCubesToRules.go | 135 +++++++++++++---------------- pkg/optimize/sg/optimizeSG_test.go | 100 ++++++++++----------- pkg/optimize/sg/reduceCubes.go | 73 ++++++++++------ pkg/optimize/sg/rulesToCubes.go | 3 +- 5 files changed, 156 insertions(+), 156 deletions(-) diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index d4ba3e45..f28a4e62 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -32,6 +32,7 @@ func SortPartitionsByIPAddrs[T any](p []ds.Pair[*netset.IPBlock, T]) []ds.Pair[* return p } +// returns true if this 0 && !continuation(cubes[i-1], cubes[i], allCubes) { - for ipb, ports := range activeRules { - p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(ports.Start()), int(ports.End())) - ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[i-1].Left.LastIPAddressObject()) - for _, cidr := range ipRange.SplitToCidrs() { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) - } - delete(activeRules, ipb) - } + result = append(result, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)...) + activeRules = make(map[*netset.IPBlock]netp.Protocol) } - // rules whose ports are not in the current cube will not remain active + // if the proctol is not contained in the current cube, we will generate SG rules + // calculate active ports = active rules covers these ports activePorts := interval.NewCanonicalSet() - for ipb, ports := range activeRules { - if !ports.ToSet().IsSubset(cubes[i].Right) { - p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(ports.Start()), int(ports.End())) - ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[i-1].Left.LastIPAddressObject()) - for _, cidr := range ipRange.SplitToCidrs() { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + for ipb, protocol := range activeRules { + if tcpudp, ok := protocol.(netp.TCPUDP); ok { + if !tcpudp.DstPorts().ToSet().IsSubset(cubes[i].Right) { + result = append(result, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction)...) + } else { + activePorts.AddInterval(tcpudp.DstPorts()) } - } else { - activePorts.AddInterval(*ports) } } - // if the cube contains ports that are not contained in active rules, new rules will be created + // if the cube contains ports that are not contained in the active rules, new rules will be created for _, ports := range cubes[i].Right.Intervals() { if !ports.ToSet().IsSubset(activePorts) { - activeRules[cubes[i].Left.FirstIPAddressObject()] = &ports + p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(ports.Start()), int(ports.End())) + activeRules[cubes[i].Left.FirstIPAddressObject()] = p } } } - - // create the rest of the rules - for ipb, ports := range activeRules { - p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(ports.Start()), int(ports.End())) - ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[len(cubes)-1].Left.LastIPAddressObject()) - for _, cidr := range ipRange.SplitToCidrs() { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) - } - } - - return result + // generate all the existing rules + return append(result, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction)...) } -// problem: where should I end the rule? -// func createTcpudpRules(rules []ds.Pair[*netset.IPBlock, *interval.Interval], span []ds.Pair[*netset.IPBlock, *netset.PortSet], -// direction ir.Direction, isTCP bool) (res []ir.SGRule) { -// res = make([]ir.SGRule, 0) -// for _, r := range rules { -// p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(r.Right.Start()), int(r.Right.Start())) -// for _, cidr := range ToCidrs(IPBlockFromRange(r.Left, LastIPAddress(span[len(span)-1].Left))) { -// res = append(res, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) -// } -// } -// return res -// } - +// icmpIPCubesToRules converts cubes representing icmp protocol rules to SG rules func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { - activeRules := make(map[*netset.IPBlock]*netp.ICMP) + activeRules := make(map[*netset.IPBlock]netp.Protocol) // the key is the first IP result := make([]*ir.SGRule, 0) for i := range cubes { + // if it is not possible to continue the rule between the cubes, generate all the existing rules if i > 0 && !continuation(cubes[i-1], cubes[i], allCubes) { - for ipb, icmp := range activeRules { - p, _ := netp.NewICMP(icmp.TypeCode) - ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[i-1].Left.LastIPAddressObject()) - for _, cidr := range ipRange.SplitToCidrs() { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) - } - delete(activeRules, ipb) - } + result = append(result, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)...) + activeRules = make(map[*netset.IPBlock]netp.Protocol) } - // rules whose icmp value is not in the current cube will not remain active + // if the proctol is not contained in the current cube, we will generate SG rules + // calculate activeICMP = active rules covers these icmp values activeICMP := netset.EmptyICMPSet() - for ipb, icmp := range activeRules { - ruleIcmpSet := optimize.IcmpRuleToIcmpSet(*icmp) - if !ruleIcmpSet.IsSubset(cubes[i].Right) { // create rules - p, _ := netp.NewICMPWithoutRFCValidation(icmp.TypeCode) - ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[i-1].Left.LastIPAddressObject()) - for _, cidr := range ipRange.SplitToCidrs() { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) + for ipb, protocol := range activeRules { + if icmp, ok := protocol.(netp.ICMP); ok { + ruleIcmpSet := optimize.IcmpRuleToIcmpSet(icmp) + if !ruleIcmpSet.IsSubset(cubes[i].Right) { + result = append(result, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction)...) + } else { + activeICMP.Union(ruleIcmpSet) } - } else { - activeICMP.Union(ruleIcmpSet) } } - // new rules + // if the cube contains icmp values that are not contained in the active rules, new rules will be created for _, p := range optimize.IcmpsetPartitions(cubes[i].Right) { if !optimize.IcmpRuleToIcmpSet(p).IsSubset(activeICMP) { activeRules[cubes[i].Left.FirstIPAddressObject()] = &p @@ -126,18 +97,11 @@ func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCu } } - // create the rest of the rules - for ipb, icmp := range activeRules { - p, _ := netp.NewICMP(icmp.TypeCode) - ipRange, _ := netset.IPBlockFromIPRange(ipb, cubes[len(cubes)-1].Left.LastIPAddressObject()) - for _, cidr := range ipRange.SplitToCidrs() { - result = append(result, ir.NewSGRule(direction, cidr, p, netset.GetCidrAll(), "")) - } - } - - return result + // generate all the existing rules + return append(result, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction)...) } +// continuation returns true if the rules can be continued between the two cubes func continuation[T ds.Set[T]](prevPair, currPair ds.Pair[*netset.IPBlock, T], allProtocolCubes *netset.IPBlock) bool { prevIPBlock := prevPair.Left currIPBlock := currPair.Left @@ -150,3 +114,22 @@ func continuation[T ds.Set[T]](prevPair, currPair ds.Pair[*netset.IPBlock, T], a hole, _ := netset.IPBlockFromIPRange(startH, endH) return hole.IsSubset(allProtocolCubes) } + +// creates sgRules from SG active rules +func createActiveRules(activeRules map[*netset.IPBlock]netp.Protocol, endIP *netset.IPBlock, direction ir.Direction) []*ir.SGRule { + res := make([]*ir.SGRule, 0) + for ipb, protocol := range activeRules { + res = append(res, createNewRules(protocol, ipb, endIP, direction)...) + } + return res +} + +// 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) []*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, netset.GetCidrAll(), "")) + } + return res +} diff --git a/pkg/optimize/sg/optimizeSG_test.go b/pkg/optimize/sg/optimizeSG_test.go index 544fa53f..1bcd2c90 100644 --- a/pkg/optimize/sg/optimizeSG_test.go +++ b/pkg/optimize/sg/optimizeSG_test.go @@ -5,53 +5,53 @@ SPDX-License-Identifier: Apache-2.0 package sgoptimizer_test -import ( - "log" - "testing" - - "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 TestOps(t *testing.T) { - sgRules := make([]*ir.SGRule, 0) - p1, _ := netp.NewTCPUDP(true, 1, 100, 1, 10) - p2, _ := netp.NewTCPUDP(true, 1, 100, 1, 20) - - ipb1, _ := netset.IPBlockFromCidrOrAddress("0.0.0.0") - ipb2, _ := netset.IPBlockFromCidrOrAddress("0.0.0.0/31") - - sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb1, p1, netset.GetCidrAll(), "")) - sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb2, p2, netset.GetCidrAll(), "")) - - res := tcpudpRulesToIPCubes(sgRules) - for i, pair := range res { - log.Println("pair ", i, ": ipblock: ", pair.Left.String(), ", ports: ", pair.Right.String()) - } - - sgRules = []*ir.SGRule{} - sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb2, p1, netset.GetCidrAll(), "")) - sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb1, p2, netset.GetCidrAll(), "")) - - res = tcpudpRulesToIPCubes(sgRules) - for i, pair := range res { - log.Println("pair ", i, ": ipblock: ", pair.Left.String(), ", ports: ", pair.Right.String()) - } - - t.Log("Hi") -} - -func tcpudpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.PortSet] { - cubes := ds.NewProductLeft[*netset.IPBlock, *netset.PortSet]() - for _, rule := range rules { - ipb := rule.Remote.(*netset.IPBlock) // already checked - portsSet := rule.Protocol.(netp.TCPUDP) // already checked - r := ds.CartesianPairLeft(ipb, portsSet.DstPorts().ToSet()) - cubes = cubes.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.PortSet]) - } - return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) -} +// import ( +// "log" +// "testing" + +// "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 TestOps(t *testing.T) { +// sgRules := make([]*ir.SGRule, 0) +// p1, _ := netp.NewTCPUDP(true, 1, 100, 1, 10) +// p2, _ := netp.NewTCPUDP(true, 1, 100, 1, 20) + +// ipb1, _ := netset.IPBlockFromCidrOrAddress("0.0.0.0") +// ipb2, _ := netset.IPBlockFromCidrOrAddress("0.0.0.0/31") + +// sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb1, p1, netset.GetCidrAll(), "")) +// sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb2, p2, netset.GetCidrAll(), "")) + +// res := tcpudpRulesToIPCubes(sgRules) +// for i, pair := range res { +// log.Println("pair ", i, ": ipblock: ", pair.Left.String(), ", ports: ", pair.Right.String()) +// } + +// sgRules = []*ir.SGRule{} +// sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb2, p1, netset.GetCidrAll(), "")) +// sgRules = append(sgRules, ir.NewSGRule(ir.Outbound, ipb1, p2, netset.GetCidrAll(), "")) + +// res = tcpudpRulesToIPCubes(sgRules) +// for i, pair := range res { +// log.Println("pair ", i, ": ipblock: ", pair.Left.String(), ", ports: ", pair.Right.String()) +// } + +// t.Log("Hi") +// } + +// func tcpudpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.PortSet] { +// cubes := ds.NewProductLeft[*netset.IPBlock, *netset.PortSet]() +// for _, rule := range rules { +// ipb := rule.Remote.(*netset.IPBlock) // already checked +// portsSet := rule.Protocol.(netp.TCPUDP) // already checked +// r := ds.CartesianPairLeft(ipb, portsSet.DstPorts().ToSet()) +// cubes = cubes.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.PortSet]) +// } +// return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) +// } diff --git a/pkg/optimize/sg/reduceCubes.go b/pkg/optimize/sg/reduceCubes.go index 3489ed49..b597b894 100644 --- a/pkg/optimize/sg/reduceCubes.go +++ b/pkg/optimize/sg/reduceCubes.go @@ -47,6 +47,8 @@ func compressThreeProtocolsToAllProtocol(spans *sgCubesPerProtocol) *sgCubesPerP // observation: It pays to switch to all protocol rule when we have rules that cover all other protocols // on exactly the same cidr (only one protocol can exceed). +// +//nolint:gocyclo // multiple if statments func reduceIPCubes(cubes *ipCubesPerProtocol) *ipCubesPerProtocol { tcpPtr := 0 udpPtr := 0 @@ -67,7 +69,7 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) *ipCubesPerProtocol { continue } - cubes, changed = reduce(cubes, tcpPtr, udpPtr, icmpPtr) + cubes, changed = compressToAllCube(cubes, tcpPtr, udpPtr, icmpPtr) if changed { continue } @@ -76,43 +78,58 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) *ipCubesPerProtocol { udpIP := cubes.udp[udpPtr].Left icmpIP := cubes.icmp[icmpPtr].Left - if udpIP.IsSubset(tcpIP) && icmpIP.IsSubset(tcpIP) { - if optimize.LessIPBlock(udpIP, icmpIP) { - udpPtr++ - } else { - icmpPtr++ - } - continue - } + switch { + // one protocol ipb contains two other ipbs. advance the smaller ipb + case udpIP.IsSubset(tcpIP) && icmpIP.IsSubset(tcpIP) && optimize.LessIPBlock(udpIP, icmpIP): + udpPtr++ + case udpIP.IsSubset(tcpIP) && icmpIP.IsSubset(tcpIP) && optimize.LessIPBlock(icmpIP, udpIP): + icmpPtr++ + case tcpIP.IsSubset(udpIP) && icmpIP.IsSubset(udpIP) && optimize.LessIPBlock(tcpIP, icmpIP): + tcpPtr++ + case tcpIP.IsSubset(udpIP) && icmpIP.IsSubset(udpIP) && optimize.LessIPBlock(icmpIP, tcpIP): + icmpPtr++ + case tcpIP.IsSubset(icmpIP) && udpIP.IsSubset(icmpIP) && optimize.LessIPBlock(tcpIP, udpIP): + tcpPtr++ + case tcpIP.IsSubset(icmpIP) && udpIP.IsSubset(icmpIP) && optimize.LessIPBlock(udpIP, tcpIP): + udpPtr++ + // advance the smaller ipb + case optimize.LessIPBlock(tcpIP, udpIP) && optimize.LessIPBlock(tcpIP, icmpIP): + tcpPtr++ + case optimize.LessIPBlock(udpIP, tcpIP) && optimize.LessIPBlock(udpIP, icmpIP): + udpPtr++ + case optimize.LessIPBlock(icmpIP, tcpIP) && optimize.LessIPBlock(icmpIP, udpIP): + icmpPtr++ + } } return cubes } -func reduce(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) (*ipCubesPerProtocol, bool) { +// compress three protocol rules to all protocol rule (and maybe another protocol rule) +func compressToAllCube(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) (*ipCubesPerProtocol, bool) { tcpIP := cubes.tcp[tcpPtr].Left udpIP := cubes.udp[udpPtr].Left icmpIP := cubes.icmp[icmpPtr].Left - if udpIP.IsSubset(tcpIP) && udpIP.Equal(icmpIP) { + switch { + case udpIP.Equal(tcpIP) && udpIP.Equal(icmpIP): + cubes.tcp = slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) + fallthrough + case udpIP.IsSubset(tcpIP) && udpIP.Equal(icmpIP): + cubes.udp = slices.Delete(cubes.udp, udpPtr, udpPtr+1) + cubes.icmp = slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) cubes.all = cubes.all.Union(udpIP) - slices.Delete(cubes.udp, udpPtr, udpPtr+1) - slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) - if tcpIP.Equal(udpIP) { - slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) - } - // continue + return cubes, true + case tcpIP.IsSubset(udpIP) && tcpIP.Equal(icmpIP): + cubes.tcp = slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) + cubes.icmp = slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) + cubes.all = cubes.all.Union(tcpIP) + return cubes, true + case tcpIP.IsSubset(icmpIP) && tcpIP.Equal(udpIP): + cubes.tcp = slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) + cubes.udp = slices.Delete(cubes.udp, udpPtr, udpPtr+1) + cubes.all = cubes.all.Union(tcpIP) + return cubes, true } - - if tcpIP.IsSubset(udpIP) && tcpIP.Equal(icmpIP) { - cubes.all = cubes.all.Union(udpIP) - slices.Delete(cubes.udp, udpPtr, udpPtr+1) - slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) - if tcpIP.Equal(udpIP) { - slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) - } - // continue - } - return cubes, false } diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go index deb07179..589aad7e 100644 --- a/pkg/optimize/sg/rulesToCubes.go +++ b/pkg/optimize/sg/rulesToCubes.go @@ -100,8 +100,7 @@ func icmpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.I for _, rule := range rules { ipb := rule.Remote.(*netset.IPBlock) // already checked p := rule.Protocol.(netp.ICMP) // already checked - icmpSet := optimize.IcmpRuleToIcmpSet(p) - r := ds.CartesianPairLeft(ipb, icmpSet) + r := ds.CartesianPairLeft(ipb, optimize.IcmpRuleToIcmpSet(p)) cubes = cubes.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.ICMPSet]) } return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) From 69ca4125cb438aad649676a2a4b514fa54eca92b Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 9 Oct 2024 13:49:34 +0300 Subject: [PATCH 063/131] delete test --- pkg/optimize/common.go | 2 +- pkg/optimize/sg/optimizeSG_test.go | 57 -- .../acl_externals_tf/nacl_expected.tf | 348 +++++------ test/expected/acl_nif_tf/nacl_expected.tf | 216 +++---- .../acl_protocols_tf/nacl_expected.tf | 280 ++++----- .../expected/acl_segments_tf/nacl_expected.tf | 216 +++---- .../expected/acl_testing5_tf/nacl_expected.tf | 584 +++++++++--------- .../nacl_single_expected.tf | 420 ++++++------- .../acl_tg_multiple_tf/nacl_expected.tf | 200 +++--- .../acl_tg_multiple_tf_separate/test-vpc0.tf | 120 ++-- .../acl_tg_multiple_tf_separate/test-vpc1.tf | 40 +- .../acl_tg_multiple_tf_separate/test-vpc2.tf | 20 +- .../acl_tg_multiple_tf_separate/test-vpc3.tf | 20 +- test/expected/sg_protocols_tf/sg_expected.tf | 136 ++-- test/expected/sg_testing3_tf/sg_expected.tf | 68 +- .../sg_tg_multiple_tf_separate/test-vpc0.tf | 56 +- .../sg_tg_multiple_tf_separate/test-vpc1.tf | 16 +- .../sg_tg_multiple_tf_separate/test-vpc2.tf | 20 +- .../sg_tg_multiple_tf_separate/test-vpc3.tf | 4 +- 19 files changed, 1383 insertions(+), 1440 deletions(-) delete mode 100644 pkg/optimize/sg/optimizeSG_test.go diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index f28a4e62..9d62a104 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -34,7 +34,7 @@ func SortPartitionsByIPAddrs[T any](p []ds.Pair[*netset.IPBlock, T]) []ds.Pair[* // returns true if this(subnet test-vpc1/subnet1); allowed-protocols[0] rules { - name = "rule18" - action = "allow" - direction = "inbound" - source = "8.8.8.8" + name = "rule18" + action = "allow" + direction = "inbound" + source = "8.8.8.8" destination = "10.240.10.0/24" } # External. response to required-connections[0]: (external dns)->(subnet test-vpc1/subnet1); allowed-protocols[0] rules { - name = "rule19" - action = "allow" - direction = "outbound" - source = "10.240.10.0/24" + name = "rule19" + action = "allow" + direction = "outbound" + source = "10.240.10.0/24" destination = "8.8.8.8" } } # test-vpc1/subnet2 [10.240.20.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet2" { - name = "acl-test-vpc1--subnet2" + name = "acl-test-vpc1--subnet2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule0" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule0" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule1" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule1" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule2" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule2" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule3" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule3" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule4" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule4" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule5" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule5" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule6" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule6" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule7" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule7" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule8" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule8" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule9" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule9" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule10" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule10" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule11" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule11" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule12" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule12" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule13" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule13" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule14" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule14" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule15" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule15" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule16" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule16" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule17" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule17" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # External. required-connections[1]: (subnet test-vpc1/subnet2)->(external public internet); allowed-protocols[0] rules { - name = "rule18" - action = "allow" - direction = "outbound" - source = "10.240.20.0/24" + name = "rule18" + action = "allow" + direction = "outbound" + source = "10.240.20.0/24" destination = "0.0.0.0/0" } # External. response to required-connections[1]: (subnet test-vpc1/subnet2)->(external public internet); allowed-protocols[0] rules { - name = "rule19" - action = "allow" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule19" + action = "allow" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.20.0/24" } } # test-vpc1/subnet3 [10.240.30.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet3" { - name = "acl-test-vpc1--subnet3" + name = "acl-test-vpc1--subnet3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Deny all communication; subnet test-vpc1/subnet3[10.240.30.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.30.0/24" } # Deny all communication; subnet test-vpc1/subnet3[10.240.30.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.30.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.30.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_nif_tf/nacl_expected.tf b/test/expected/acl_nif_tf/nacl_expected.tf index 5d999aac..b3a073ba 100644 --- a/test/expected/acl_nif_tf/nacl_expected.tf +++ b/test/expected/acl_nif_tf/nacl_expected.tf @@ -1,14 +1,14 @@ # test-vpc0/subnet0 [10.240.0.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { - name = "acl-test-vpc0--subnet0" + name = "acl-test-vpc0--subnet0" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (subnet test-vpc0/subnet4)->(instance test-vpc0/vsi0-subnet0); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.0.0/24" icmp { type = 0 @@ -16,10 +16,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet4)->(instance test-vpc0/vsi0-subnet0); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.8.0/24" icmp { type = 8 @@ -29,25 +29,25 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { # test-vpc0/subnet1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { - name = "acl-test-vpc0--subnet1" + name = "acl-test-vpc0--subnet1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[1]: (nif test-vpc0/vsi0-subnet1/scale-clambake-endearing-abridged)->(subnet test-vpc0/subnet4); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.8.0/24" tcp { } } # Internal. response to required-connections[1]: (nif test-vpc0/vsi0-subnet1/scale-clambake-endearing-abridged)->(subnet test-vpc0/subnet4); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.1.0/24" tcp { } @@ -56,61 +56,61 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { # test-vpc0/subnet2 [10.240.4.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { - name = "acl-test-vpc0--subnet2" + name = "acl-test-vpc0--subnet2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Deny all communication; subnet test-vpc0/subnet2[10.240.4.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.4.0/24" } # Deny all communication; subnet test-vpc0/subnet2[10.240.4.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.4.0/24" destination = "0.0.0.0/0" } } # test-vpc0/subnet3 [10.240.5.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { - name = "acl-test-vpc0--subnet3" + name = "acl-test-vpc0--subnet3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Deny all communication; subnet test-vpc0/subnet3[10.240.5.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.5.0/24" } # Deny all communication; subnet test-vpc0/subnet3[10.240.5.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.5.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.5.0/24" destination = "0.0.0.0/0" } } # test-vpc0/subnet4 [10.240.8.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { - name = "acl-test-vpc0--subnet4" + name = "acl-test-vpc0--subnet4" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (subnet test-vpc0/subnet4)->(instance test-vpc0/vsi0-subnet0); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.0.0/24" icmp { type = 0 @@ -118,10 +118,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet4)->(instance test-vpc0/vsi0-subnet0); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.8.0/24" icmp { type = 8 @@ -129,20 +129,20 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { } # Internal. required-connections[1]: (nif test-vpc0/vsi0-subnet1/scale-clambake-endearing-abridged)->(subnet test-vpc0/subnet4); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.8.0/24" tcp { } } # Internal. response to required-connections[1]: (nif test-vpc0/vsi0-subnet1/scale-clambake-endearing-abridged)->(subnet test-vpc0/subnet4); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.1.0/24" tcp { } @@ -151,115 +151,115 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { # test-vpc0/subnet5 [10.240.9.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { - name = "acl-test-vpc0--subnet5" + name = "acl-test-vpc0--subnet5" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Deny all communication; subnet test-vpc0/subnet5[10.240.9.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.9.0/24" } # Deny all communication; subnet test-vpc0/subnet5[10.240.9.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.9.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.9.0/24" destination = "0.0.0.0/0" } } # test-vpc1/subnet10 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { - name = "acl-test-vpc1--subnet10" + name = "acl-test-vpc1--subnet10" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Deny all communication; subnet test-vpc1/subnet10[10.240.64.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.64.0/24" } # Deny all communication; subnet test-vpc1/subnet10[10.240.64.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.64.0/24" destination = "0.0.0.0/0" } } # test-vpc1/subnet11 [10.240.80.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { - name = "acl-test-vpc1--subnet11" + name = "acl-test-vpc1--subnet11" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Deny all communication; subnet test-vpc1/subnet11[10.240.80.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.80.0/24" } # Deny all communication; subnet test-vpc1/subnet11[10.240.80.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.80.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.80.0/24" destination = "0.0.0.0/0" } } # test-vpc2/subnet20 [10.240.128.0/24] resource "ibm_is_network_acl" "acl-test-vpc2--subnet20" { - name = "acl-test-vpc2--subnet20" + name = "acl-test-vpc2--subnet20" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc2_id + vpc = local.acl_synth_test-vpc2_id # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.128.0/24" } # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" destination = "0.0.0.0/0" } } # test-vpc3/subnet30 [10.240.192.0/24] resource "ibm_is_network_acl" "acl-test-vpc3--subnet30" { - name = "acl-test-vpc3--subnet30" + name = "acl-test-vpc3--subnet30" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc3_id + vpc = local.acl_synth_test-vpc3_id # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.192.0/24" } # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.192.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.192.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_protocols_tf/nacl_expected.tf b/test/expected/acl_protocols_tf/nacl_expected.tf index 89da29a6..444efeb6 100644 --- a/test/expected/acl_protocols_tf/nacl_expected.tf +++ b/test/expected/acl_protocols_tf/nacl_expected.tf @@ -1,107 +1,107 @@ # test-vpc0/subnet0 [10.240.0.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { - name = "acl-test-vpc0--subnet0" + name = "acl-test-vpc0--subnet0" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.0.0/24" tcp { } } # Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.1.0/24" icmp { } } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.0.0/24" icmp { } } # Internal. required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.9.0/24" } # Internal. response to required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.9.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.9.0/24" destination = "10.240.0.0/24" } } # test-vpc0/subnet1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { - name = "acl-test-vpc0--subnet1" + name = "acl-test-vpc0--subnet1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.0.0/24" tcp { } } # Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.1.0/24" icmp { } } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.0.0/24" icmp { } @@ -110,15 +110,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { # test-vpc0/subnet2 [10.240.4.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { - name = "acl-test-vpc0--subnet2" + name = "acl-test-vpc0--subnet2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" tcp { port_min = 8080 @@ -127,10 +127,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { } # Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.5.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.5.0/24" destination = "10.240.4.0/24" tcp { source_port_min = 8080 @@ -139,10 +139,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { } # Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" icmp { type = 3 @@ -153,15 +153,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { # test-vpc0/subnet3 [10.240.5.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { - name = "acl-test-vpc0--subnet3" + name = "acl-test-vpc0--subnet3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" tcp { port_min = 8080 @@ -170,10 +170,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { } # Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.5.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.5.0/24" destination = "10.240.4.0/24" tcp { source_port_min = 8080 @@ -182,10 +182,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { } # Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" icmp { type = 3 @@ -196,15 +196,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { # test-vpc0/subnet4 [10.240.8.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { - name = "acl-test-vpc0--subnet4" + name = "acl-test-vpc0--subnet4" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 15 @@ -212,10 +212,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.9.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.9.0/24" destination = "10.240.8.0/24" icmp { type = 16 @@ -223,10 +223,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { } # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" udp { } @@ -235,15 +235,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { # test-vpc0/subnet5 [10.240.9.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { - name = "acl-test-vpc0--subnet5" + name = "acl-test-vpc0--subnet5" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 15 @@ -251,10 +251,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.9.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.9.0/24" destination = "10.240.8.0/24" icmp { type = 16 @@ -262,43 +262,43 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { } # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" udp { } } # Internal. required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.9.0/24" } # Internal. response to required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.9.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.9.0/24" destination = "10.240.0.0/24" } } # test-vpc1/subnet10 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { - name = "acl-test-vpc1--subnet10" + name = "acl-test-vpc1--subnet10" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" udp { port_min = 53 @@ -309,15 +309,15 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { # test-vpc1/subnet11 [10.240.80.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { - name = "acl-test-vpc1--subnet11" + name = "acl-test-vpc1--subnet11" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" udp { port_min = 53 @@ -328,46 +328,46 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { # test-vpc2/subnet20 [10.240.128.0/24] resource "ibm_is_network_acl" "acl-test-vpc2--subnet20" { - name = "acl-test-vpc2--subnet20" + name = "acl-test-vpc2--subnet20" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc2_id + vpc = local.acl_synth_test-vpc2_id # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.128.0/24" } # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" destination = "0.0.0.0/0" } } # test-vpc3/subnet30 [10.240.192.0/24] resource "ibm_is_network_acl" "acl-test-vpc3--subnet30" { - name = "acl-test-vpc3--subnet30" + name = "acl-test-vpc3--subnet30" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc3_id + vpc = local.acl_synth_test-vpc3_id # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.192.0/24" } # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.192.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.192.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_segments_tf/nacl_expected.tf b/test/expected/acl_segments_tf/nacl_expected.tf index a781952b..7e615697 100644 --- a/test/expected/acl_segments_tf/nacl_expected.tf +++ b/test/expected/acl_segments_tf/nacl_expected.tf @@ -1,233 +1,233 @@ # testacl5-vpc/sub1-1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { - name = "acl-testacl5-vpc--sub1-1" + name = "acl-testacl5-vpc--sub1-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Deny all communication; subnet testacl5-vpc/sub1-1[10.240.1.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.1.0/24" } # Deny all communication; subnet testacl5-vpc/sub1-1[10.240.1.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.1.0/24" destination = "0.0.0.0/0" } } # testacl5-vpc/sub1-2 [10.240.2.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-2" { - name = "acl-testacl5-vpc--sub1-2" + name = "acl-testacl5-vpc--sub1-2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.2.0/23" } # Internal. response to required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.2.0/23" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.2.0/23" destination = "10.240.2.0/24" } # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.2.0/24" } # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.65.0/24" destination = "10.240.2.0/24" } } # testacl5-vpc/sub1-3 [10.240.3.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-3" { - name = "acl-testacl5-vpc--sub1-3" + name = "acl-testacl5-vpc--sub1-3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.2.0/23" } # Internal. response to required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.2.0/23" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.2.0/23" destination = "10.240.3.0/24" } # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.3.0/24" } # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.65.0/24" destination = "10.240.3.0/24" } } # testacl5-vpc/sub2-1 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { - name = "acl-testacl5-vpc--sub2-1" + name = "acl-testacl5-vpc--sub2-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.2.0/23" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.2.0/23" destination = "10.240.64.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.2.0/23" } # Internal. required-connections[2]: (segment subnetSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[2]: (segment subnetSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } } # testacl5-vpc/sub2-2 [10.240.65.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-2" { - name = "acl-testacl5-vpc--sub2-2" + name = "acl-testacl5-vpc--sub2-2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.2.0/23" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.2.0/23" destination = "10.240.65.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.65.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.65.0/24" destination = "10.240.2.0/23" } # Internal. required-connections[2]: (segment subnetSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[2]: (segment subnetSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.65.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } } # testacl5-vpc/sub3-1 [10.240.128.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { - name = "acl-testacl5-vpc--sub3-1" + name = "acl-testacl5-vpc--sub3-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Deny all communication; subnet testacl5-vpc/sub3-1[10.240.128.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.128.0/24" } # Deny all communication; subnet testacl5-vpc/sub3-1[10.240.128.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_testing5_tf/nacl_expected.tf b/test/expected/acl_testing5_tf/nacl_expected.tf index 69925897..1664f0e1 100644 --- a/test/expected/acl_testing5_tf/nacl_expected.tf +++ b/test/expected/acl_testing5_tf/nacl_expected.tf @@ -1,30 +1,30 @@ # testacl5-vpc/sub1-1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { - name = "acl-testacl5-vpc--sub1-1" + name = "acl-testacl5-vpc--sub1-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.1.0/24" } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -32,10 +32,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.1.0/24" icmp { type = 8 @@ -43,194 +43,194 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { } # Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. response to required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.2.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.2.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule6" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule6" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule7" - action = "allow" - direction = "inbound" - source = "10.240.3.0/24" + name = "rule7" + action = "allow" + direction = "inbound" + source = "10.240.3.0/24" destination = "10.240.1.0/24" tcp { } } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule8" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule8" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule9" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule9" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule10" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule10" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule11" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule11" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule12" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule12" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule13" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule13" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule14" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule14" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule15" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule15" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule16" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule16" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule17" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule17" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule18" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule18" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule19" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule19" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule20" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule20" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule21" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule21" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule22" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule22" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule23" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule23" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule24" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule24" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule25" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule25" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # External. required-connections[1]: (segment need-dns)->(external dns); allowed-protocols[0] rules { - name = "rule26" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule26" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "8.8.8.8" udp { port_min = 53 @@ -241,45 +241,45 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { # testacl5-vpc/sub1-2 [10.240.2.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-2" { - name = "acl-testacl5-vpc--sub1-2" + name = "acl-testacl5-vpc--sub1-2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. response to required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.3.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.3.0/24" destination = "10.240.2.0/24" tcp { } @@ -288,45 +288,45 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-2" { # testacl5-vpc/sub1-3 [10.240.3.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-3" { - name = "acl-testacl5-vpc--sub1-3" + name = "acl-testacl5-vpc--sub1-3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.2.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.2.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.2.0/24" tcp { } @@ -335,31 +335,31 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-3" { # testacl5-vpc/sub2-1 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { - name = "acl-testacl5-vpc--sub2-1" + name = "acl-testacl5-vpc--sub2-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.1.0/24" } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -367,10 +367,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -378,26 +378,26 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { } # Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } # Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule6" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule6" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" tcp { port_min = 443 @@ -406,10 +406,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { } # Internal. response to required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule7" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule7" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" tcp { source_port_min = 443 @@ -418,154 +418,154 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule8" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule8" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule9" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule9" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule10" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule10" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule11" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule11" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule12" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule12" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule13" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule13" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule14" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule14" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule15" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule15" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule16" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule16" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule17" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule17" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule18" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule18" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule19" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule19" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule20" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule20" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule21" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule21" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule22" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule22" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule23" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule23" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule24" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule24" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule25" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule25" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # External. required-connections[1]: (segment need-dns)->(external dns); allowed-protocols[0] rules { - name = "rule26" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule26" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "8.8.8.8" udp { port_min = 53 @@ -576,38 +576,38 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { # testacl5-vpc/sub2-2 [10.240.65.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-2" { - name = "acl-testacl5-vpc--sub2-2" + name = "acl-testacl5-vpc--sub2-2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.65.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } } # testacl5-vpc/sub3-1 [10.240.128.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { - name = "acl-testacl5-vpc--sub3-1" + name = "acl-testacl5-vpc--sub3-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -615,10 +615,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.1.0/24" icmp { type = 8 @@ -626,10 +626,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -637,10 +637,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -648,10 +648,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { } # Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" tcp { port_min = 443 @@ -660,10 +660,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { } # Internal. response to required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" tcp { source_port_min = 443 diff --git a/test/expected/acl_testing5_tf_single/nacl_single_expected.tf b/test/expected/acl_testing5_tf_single/nacl_single_expected.tf index 5e3a1e07..0aa3da5c 100644 --- a/test/expected/acl_testing5_tf_single/nacl_single_expected.tf +++ b/test/expected/acl_testing5_tf_single/nacl_single_expected.tf @@ -1,45 +1,45 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { - name = "acl-testacl5-vpc--singleACL" + name = "acl-testacl5-vpc--singleACL" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.1.0/24" } # Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.1.0/24" } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -47,10 +47,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.1.0/24" icmp { type = 8 @@ -58,10 +58,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule6" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule6" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -69,10 +69,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule7" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule7" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.1.0/24" icmp { type = 8 @@ -80,10 +80,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule8" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule8" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -91,10 +91,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule9" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule9" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -102,10 +102,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule10" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule10" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -113,10 +113,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule11" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule11" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -124,162 +124,162 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule12" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule12" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. response to required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule13" - action = "allow" - direction = "inbound" - source = "10.240.2.0/24" + name = "rule13" + action = "allow" + direction = "inbound" + source = "10.240.2.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule14" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule14" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. response to required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule15" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule15" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule16" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule16" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule17" - action = "allow" - direction = "inbound" - source = "10.240.3.0/24" + name = "rule17" + action = "allow" + direction = "inbound" + source = "10.240.3.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule18" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule18" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule19" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule19" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule20" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule20" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule21" - action = "allow" - direction = "inbound" - source = "10.240.3.0/24" + name = "rule21" + action = "allow" + direction = "inbound" + source = "10.240.3.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule22" - action = "allow" - direction = "inbound" - source = "10.240.2.0/24" + name = "rule22" + action = "allow" + direction = "inbound" + source = "10.240.2.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule23" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule23" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule24" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule24" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule25" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" + name = "rule25" + action = "allow" + direction = "inbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } # Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule26" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule26" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule27" - action = "allow" - direction = "outbound" - source = "10.240.65.0/24" + name = "rule27" + action = "allow" + direction = "outbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } # Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule28" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule28" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" tcp { port_min = 443 @@ -288,10 +288,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule29" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule29" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" tcp { source_port_min = 443 @@ -300,10 +300,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule30" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule30" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" tcp { port_min = 443 @@ -312,10 +312,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule31" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule31" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" tcp { source_port_min = 443 @@ -324,154 +324,154 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule32" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule32" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule33" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule33" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule34" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule34" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule35" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule35" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule36" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule36" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule37" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule37" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule38" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule38" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule39" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule39" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule40" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule40" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule41" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule41" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule42" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule42" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule43" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule43" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule44" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule44" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule45" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule45" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule46" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule46" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule47" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule47" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule48" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule48" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule49" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule49" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # External. required-connections[1]: (segment need-dns)->(external dns); allowed-protocols[0] rules { - name = "rule50" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule50" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "8.8.8.8" udp { port_min = 53 @@ -480,10 +480,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # External. required-connections[1]: (segment need-dns)->(external dns); allowed-protocols[0] rules { - name = "rule51" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule51" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "8.8.8.8" udp { port_min = 53 diff --git a/test/expected/acl_tg_multiple_tf/nacl_expected.tf b/test/expected/acl_tg_multiple_tf/nacl_expected.tf index da72d490..f140447f 100644 --- a/test/expected/acl_tg_multiple_tf/nacl_expected.tf +++ b/test/expected/acl_tg_multiple_tf/nacl_expected.tf @@ -1,30 +1,30 @@ # test-vpc0/subnet0 [10.240.0.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { - name = "acl-test-vpc0--subnet0" + name = "acl-test-vpc0--subnet0" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.4.0/24" } # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.0.0/24" } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -35,54 +35,54 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { # test-vpc0/subnet1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { - name = "acl-test-vpc0--subnet1" + name = "acl-test-vpc0--subnet1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.1.0/24" } # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.1.0/24" destination = "0.0.0.0/0" } } # test-vpc0/subnet2 [10.240.4.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { - name = "acl-test-vpc0--subnet2" + name = "acl-test-vpc0--subnet2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.4.0/24" } # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.0.0/24" } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -93,15 +93,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { # test-vpc0/subnet3 [10.240.5.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { - name = "acl-test-vpc0--subnet3" + name = "acl-test-vpc0--subnet3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -110,10 +110,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -124,15 +124,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { # test-vpc0/subnet4 [10.240.8.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { - name = "acl-test-vpc0--subnet4" + name = "acl-test-vpc0--subnet4" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 4 @@ -142,15 +142,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { # test-vpc0/subnet5 [10.240.9.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { - name = "acl-test-vpc0--subnet5" + name = "acl-test-vpc0--subnet5" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 4 @@ -160,15 +160,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { # test-vpc1/subnet10 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { - name = "acl-test-vpc1--subnet10" + name = "acl-test-vpc1--subnet10" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" icmp { type = 0 @@ -176,10 +176,10 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.80.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.80.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -189,15 +189,15 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { # test-vpc1/subnet11 [10.240.80.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { - name = "acl-test-vpc1--subnet11" + name = "acl-test-vpc1--subnet11" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" icmp { type = 0 @@ -205,10 +205,10 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.80.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.80.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -218,46 +218,46 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { # test-vpc2/subnet20 [10.240.128.0/24] resource "ibm_is_network_acl" "acl-test-vpc2--subnet20" { - name = "acl-test-vpc2--subnet20" + name = "acl-test-vpc2--subnet20" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc2_id + vpc = local.acl_synth_test-vpc2_id # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.128.0/24" } # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" destination = "0.0.0.0/0" } } # test-vpc3/subnet30 [10.240.192.0/24] resource "ibm_is_network_acl" "acl-test-vpc3--subnet30" { - name = "acl-test-vpc3--subnet30" + name = "acl-test-vpc3--subnet30" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc3_id + vpc = local.acl_synth_test-vpc3_id # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.192.0/24" } # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.192.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.192.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf b/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf index f4076710..7db93464 100644 --- a/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf +++ b/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf @@ -1,30 +1,30 @@ # test-vpc0/subnet0 [10.240.0.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { - name = "acl-test-vpc0--subnet0" + name = "acl-test-vpc0--subnet0" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.4.0/24" } # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.0.0/24" } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -35,54 +35,54 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { # test-vpc0/subnet1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { - name = "acl-test-vpc0--subnet1" + name = "acl-test-vpc0--subnet1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.1.0/24" } # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.1.0/24" destination = "0.0.0.0/0" } } # test-vpc0/subnet2 [10.240.4.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { - name = "acl-test-vpc0--subnet2" + name = "acl-test-vpc0--subnet2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.4.0/24" } # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.0.0/24" } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -93,15 +93,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { # test-vpc0/subnet3 [10.240.5.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { - name = "acl-test-vpc0--subnet3" + name = "acl-test-vpc0--subnet3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -110,10 +110,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -124,15 +124,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { # test-vpc0/subnet4 [10.240.8.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { - name = "acl-test-vpc0--subnet4" + name = "acl-test-vpc0--subnet4" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 4 @@ -142,15 +142,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { # test-vpc0/subnet5 [10.240.9.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { - name = "acl-test-vpc0--subnet5" + name = "acl-test-vpc0--subnet5" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 4 diff --git a/test/expected/acl_tg_multiple_tf_separate/test-vpc1.tf b/test/expected/acl_tg_multiple_tf_separate/test-vpc1.tf index 62ada153..78f27575 100644 --- a/test/expected/acl_tg_multiple_tf_separate/test-vpc1.tf +++ b/test/expected/acl_tg_multiple_tf_separate/test-vpc1.tf @@ -1,14 +1,14 @@ # test-vpc1/subnet10 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { - name = "acl-test-vpc1--subnet10" + name = "acl-test-vpc1--subnet10" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" icmp { type = 0 @@ -16,10 +16,10 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.80.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.80.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -29,15 +29,15 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { # test-vpc1/subnet11 [10.240.80.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { - name = "acl-test-vpc1--subnet11" + name = "acl-test-vpc1--subnet11" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" icmp { type = 0 @@ -45,10 +45,10 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.80.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.80.0/24" destination = "10.240.64.0/24" icmp { type = 8 diff --git a/test/expected/acl_tg_multiple_tf_separate/test-vpc2.tf b/test/expected/acl_tg_multiple_tf_separate/test-vpc2.tf index 26cda248..72b647d1 100644 --- a/test/expected/acl_tg_multiple_tf_separate/test-vpc2.tf +++ b/test/expected/acl_tg_multiple_tf_separate/test-vpc2.tf @@ -1,21 +1,21 @@ resource "ibm_is_network_acl" "acl-test-vpc2--subnet20" { - name = "acl-test-vpc2--subnet20" + name = "acl-test-vpc2--subnet20" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc2_id + vpc = local.acl_synth_test-vpc2_id # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.128.0/24" } # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_tg_multiple_tf_separate/test-vpc3.tf b/test/expected/acl_tg_multiple_tf_separate/test-vpc3.tf index bb8278a9..62ebac5b 100644 --- a/test/expected/acl_tg_multiple_tf_separate/test-vpc3.tf +++ b/test/expected/acl_tg_multiple_tf_separate/test-vpc3.tf @@ -1,21 +1,21 @@ resource "ibm_is_network_acl" "acl-test-vpc3--subnet30" { - name = "acl-test-vpc3--subnet30" + name = "acl-test-vpc3--subnet30" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc3_id + vpc = local.acl_synth_test-vpc3_id # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.192.0/24" } # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.192.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.192.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/sg_protocols_tf/sg_expected.tf b/test/expected/sg_protocols_tf/sg_expected.tf index f7519b05..1367a53c 100644 --- a/test/expected/sg_protocols_tf/sg_expected.tf +++ b/test/expected/sg_protocols_tf/sg_expected.tf @@ -1,68 +1,68 @@ ### SG attached to test-vpc0/vsi0-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { - name = "sg-test-vpc0--vsi0-subnet0" + name = "sg-test-vpc0--vsi0-subnet0" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi0-subnet1); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-0" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet1.id udp { } } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi0-subnet1); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-1" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet1.id icmp { } } ### SG attached to test-vpc0/vsi0-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { - name = "sg-test-vpc0--vsi0-subnet1" + name = "sg-test-vpc0--vsi0-subnet1" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi0-subnet1); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-0" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id udp { } } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi0-subnet1); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-1" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id icmp { } } ### SG attached to test-vpc0/vsi0-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { - name = "sg-test-vpc0--vsi0-subnet2" + name = "sg-test-vpc0--vsi0-subnet2" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[2]: (nif test-vpc0/vsi0-subnet2/graveyard-handmade-ransack-acquaint)->(nif test-vpc0/vsi0-subnet3/icky-balsamic-outgoing-leached); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet2-0" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet2.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet2.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet3.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet3.id tcp { } } # Internal. required-connections[2]: (nif test-vpc0/vsi0-subnet2/graveyard-handmade-ransack-acquaint)->(nif test-vpc0/vsi0-subnet3/icky-balsamic-outgoing-leached); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet2-1" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet2.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet2.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet3.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet3.id icmp { type = 11 code = 1 @@ -71,23 +71,23 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet2-1" { ### SG attached to test-vpc0/vsi0-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { - name = "sg-test-vpc0--vsi0-subnet3" + name = "sg-test-vpc0--vsi0-subnet3" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[2]: (nif test-vpc0/vsi0-subnet2/graveyard-handmade-ransack-acquaint)->(nif test-vpc0/vsi0-subnet3/icky-balsamic-outgoing-leached); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet3-0" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet3.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet3.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet2.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet2.id tcp { } } # Internal. required-connections[2]: (nif test-vpc0/vsi0-subnet2/graveyard-handmade-ransack-acquaint)->(nif test-vpc0/vsi0-subnet3/icky-balsamic-outgoing-leached); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet3-1" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet3.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet3.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet2.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet2.id icmp { type = 11 code = 1 @@ -96,29 +96,29 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet3-1" { ### SG attached to test-vpc0/vsi0-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { - name = "sg-test-vpc0--vsi0-subnet4" + name = "sg-test-vpc0--vsi0-subnet4" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi0-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { - name = "sg-test-vpc0--vsi0-subnet5" + name = "sg-test-vpc0--vsi0-subnet5" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { - name = "sg-test-vpc0--vsi1-subnet0" + name = "sg-test-vpc0--vsi1-subnet0" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-0" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id tcp { port_min = 8080 port_max = 8080 @@ -126,9 +126,9 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-0" { } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-1" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id udp { port_min = 53 port_max = 53 @@ -136,9 +136,9 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-1" { } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[2] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-2" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id icmp { type = 8 } @@ -146,15 +146,15 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-2" { ### SG attached to test-vpc0/vsi1-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { - name = "sg-test-vpc0--vsi1-subnet1" + name = "sg-test-vpc0--vsi1-subnet1" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-0" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id tcp { port_min = 8080 port_max = 8080 @@ -162,9 +162,9 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-0" { } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-1" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id udp { port_min = 53 port_max = 53 @@ -172,9 +172,9 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-1" { } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[2] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-2" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id icmp { type = 8 } @@ -182,84 +182,84 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-2" { ### SG attached to test-vpc0/vsi1-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { - name = "sg-test-vpc0--vsi1-subnet2" + name = "sg-test-vpc0--vsi1-subnet2" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { - name = "sg-test-vpc0--vsi1-subnet3" + name = "sg-test-vpc0--vsi1-subnet3" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { - name = "sg-test-vpc0--vsi1-subnet4" + name = "sg-test-vpc0--vsi1-subnet4" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { - name = "sg-test-vpc0--vsi1-subnet5" + name = "sg-test-vpc0--vsi1-subnet5" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc1/vsi0-subnet10 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { - name = "sg-test-vpc1--vsi0-subnet10" + name = "sg-test-vpc1--vsi0-subnet10" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id + vpc = local.sg_synth_test-vpc1_id } # External. required-connections[3]: (instance test-vpc1/vsi0-subnet10)->(external dns); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet10-0" { - group = ibm_is_security_group.test-vpc1--vsi0-subnet10.id + group = ibm_is_security_group.test-vpc1--vsi0-subnet10.id direction = "outbound" - remote = "8.8.8.8" + remote = "8.8.8.8" tcp { } } ### SG attached to test-vpc1/vsi0-subnet11 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { - name = "sg-test-vpc1--vsi0-subnet11" + name = "sg-test-vpc1--vsi0-subnet11" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id + vpc = local.sg_synth_test-vpc1_id } ### SG attached to test-vpc2/vsi0-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { - name = "sg-test-vpc2--vsi0-subnet20" + name = "sg-test-vpc2--vsi0-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } ### SG attached to test-vpc2/vsi1-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { - name = "sg-test-vpc2--vsi1-subnet20" + name = "sg-test-vpc2--vsi1-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } # External. required-connections[4]: (instance test-vpc2/vsi1-subnet20)->(external public internet); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc2--vsi1-subnet20-0" { - group = ibm_is_security_group.test-vpc2--vsi1-subnet20.id + group = ibm_is_security_group.test-vpc2--vsi1-subnet20.id direction = "outbound" - remote = "0.0.0.0/0" + remote = "0.0.0.0/0" } ### SG attached to test-vpc2/vsi2-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { - name = "sg-test-vpc2--vsi2-subnet20" + name = "sg-test-vpc2--vsi2-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } ### SG attached to test-vpc3/vsi0-subnet30 resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { - name = "sg-test-vpc3--vsi0-subnet30" + name = "sg-test-vpc3--vsi0-subnet30" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc3_id + vpc = local.sg_synth_test-vpc3_id } diff --git a/test/expected/sg_testing3_tf/sg_expected.tf b/test/expected/sg_testing3_tf/sg_expected.tf index 8bfb66a3..0da81523 100644 --- a/test/expected/sg_testing3_tf/sg_expected.tf +++ b/test/expected/sg_testing3_tf/sg_expected.tf @@ -1,48 +1,48 @@ ### SG attached to test-vpc/appdata-endpoint-gateway resource "ibm_is_security_group" "test-vpc--appdata-endpoint-gateway" { - name = "sg-test-vpc--appdata-endpoint-gateway" + name = "sg-test-vpc--appdata-endpoint-gateway" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } ### SG attached to test-vpc/be resource "ibm_is_security_group" "test-vpc--be" { - name = "sg-test-vpc--be" + name = "sg-test-vpc--be" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } # Internal. required-connections[2]: (instance test-vpc/fe)->(instance test-vpc/be); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--be-0" { - group = ibm_is_security_group.test-vpc--be.id + group = ibm_is_security_group.test-vpc--be.id direction = "inbound" - remote = ibm_is_security_group.test-vpc--fe.id + remote = ibm_is_security_group.test-vpc--fe.id tcp { } } # Internal. required-connections[3]: (instance test-vpc/be)->(instance test-vpc/opa); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--be-1" { - group = ibm_is_security_group.test-vpc--be.id + group = ibm_is_security_group.test-vpc--be.id direction = "outbound" - remote = ibm_is_security_group.test-vpc--opa.id + remote = ibm_is_security_group.test-vpc--opa.id } # Internal. required-connections[4]: (instance test-vpc/be)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--be-2" { - group = ibm_is_security_group.test-vpc--be.id + group = ibm_is_security_group.test-vpc--be.id direction = "outbound" - remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id + remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id } ### SG attached to test-vpc/fe resource "ibm_is_security_group" "test-vpc--fe" { - name = "sg-test-vpc--fe" + name = "sg-test-vpc--fe" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } # Internal. required-connections[1]: (instance test-vpc/proxy)->(instance test-vpc/fe); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--fe-0" { - group = ibm_is_security_group.test-vpc--fe.id + group = ibm_is_security_group.test-vpc--fe.id direction = "inbound" - remote = ibm_is_security_group.test-vpc--proxy.id + remote = ibm_is_security_group.test-vpc--proxy.id tcp { port_min = 9000 port_max = 9000 @@ -50,68 +50,68 @@ resource "ibm_is_security_group_rule" "test-vpc--fe-0" { } # Internal. required-connections[2]: (instance test-vpc/fe)->(instance test-vpc/be); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--fe-1" { - group = ibm_is_security_group.test-vpc--fe.id + group = ibm_is_security_group.test-vpc--fe.id direction = "outbound" - remote = ibm_is_security_group.test-vpc--be.id + remote = ibm_is_security_group.test-vpc--be.id tcp { } } ### SG attached to test-vpc/opa resource "ibm_is_security_group" "test-vpc--opa" { - name = "sg-test-vpc--opa" + name = "sg-test-vpc--opa" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } # Internal. required-connections[3]: (instance test-vpc/be)->(instance test-vpc/opa); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--opa-0" { - group = ibm_is_security_group.test-vpc--opa.id + group = ibm_is_security_group.test-vpc--opa.id direction = "inbound" - remote = ibm_is_security_group.test-vpc--be.id + remote = ibm_is_security_group.test-vpc--be.id } # Internal. required-connections[5]: (instance test-vpc/opa)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--opa-1" { - group = ibm_is_security_group.test-vpc--opa.id + group = ibm_is_security_group.test-vpc--opa.id direction = "outbound" - remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id + remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id } ### SG attached to test-vpc/policydb-endpoint-gateway resource "ibm_is_security_group" "test-vpc--policydb-endpoint-gateway" { - name = "sg-test-vpc--policydb-endpoint-gateway" + name = "sg-test-vpc--policydb-endpoint-gateway" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } # Internal. required-connections[4]: (instance test-vpc/be)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--policydb-endpoint-gateway-0" { - group = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id + group = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id direction = "inbound" - remote = ibm_is_security_group.test-vpc--be.id + remote = ibm_is_security_group.test-vpc--be.id } # Internal. required-connections[5]: (instance test-vpc/opa)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--policydb-endpoint-gateway-1" { - group = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id + group = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id direction = "inbound" - remote = ibm_is_security_group.test-vpc--opa.id + remote = ibm_is_security_group.test-vpc--opa.id } ### SG attached to test-vpc/proxy resource "ibm_is_security_group" "test-vpc--proxy" { - name = "sg-test-vpc--proxy" + name = "sg-test-vpc--proxy" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } # External. required-connections[0]: (external public internet)->(instance test-vpc/proxy); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--proxy-0" { - group = ibm_is_security_group.test-vpc--proxy.id + group = ibm_is_security_group.test-vpc--proxy.id direction = "inbound" - remote = "0.0.0.0/0" + remote = "0.0.0.0/0" } # Internal. required-connections[1]: (instance test-vpc/proxy)->(instance test-vpc/fe); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--proxy-1" { - group = ibm_is_security_group.test-vpc--proxy.id + group = ibm_is_security_group.test-vpc--proxy.id direction = "outbound" - remote = ibm_is_security_group.test-vpc--fe.id + remote = ibm_is_security_group.test-vpc--fe.id tcp { port_min = 9000 port_max = 9000 diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf index 8f4979ba..07de4293 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf @@ -1,95 +1,95 @@ ### SG attached to test-vpc0/vsi0-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { - name = "sg-test-vpc0--vsi0-subnet0" + name = "sg-test-vpc0--vsi0-subnet0" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi1-subnet4); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-0" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet4.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet4.id } ### SG attached to test-vpc0/vsi0-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { - name = "sg-test-vpc0--vsi0-subnet1" + name = "sg-test-vpc0--vsi0-subnet1" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi0-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { - name = "sg-test-vpc0--vsi0-subnet2" + name = "sg-test-vpc0--vsi0-subnet2" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi0-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { - name = "sg-test-vpc0--vsi0-subnet3" + name = "sg-test-vpc0--vsi0-subnet3" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi0-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { - name = "sg-test-vpc0--vsi0-subnet4" + name = "sg-test-vpc0--vsi0-subnet4" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi0-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { - name = "sg-test-vpc0--vsi0-subnet5" + name = "sg-test-vpc0--vsi0-subnet5" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { - name = "sg-test-vpc0--vsi1-subnet0" + name = "sg-test-vpc0--vsi1-subnet0" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { - name = "sg-test-vpc0--vsi1-subnet1" + name = "sg-test-vpc0--vsi1-subnet1" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { - name = "sg-test-vpc0--vsi1-subnet2" + name = "sg-test-vpc0--vsi1-subnet2" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { - name = "sg-test-vpc0--vsi1-subnet3" + name = "sg-test-vpc0--vsi1-subnet3" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { - name = "sg-test-vpc0--vsi1-subnet4" + name = "sg-test-vpc0--vsi1-subnet4" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi1-subnet4); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet4-0" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet4.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet4.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id } ### SG attached to test-vpc0/vsi1-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { - name = "sg-test-vpc0--vsi1-subnet5" + name = "sg-test-vpc0--vsi1-subnet5" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf index 06e11954..a4810cf4 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf @@ -1,29 +1,29 @@ ### SG attached to test-vpc1/vsi0-subnet10 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { - name = "sg-test-vpc1--vsi0-subnet10" + name = "sg-test-vpc1--vsi0-subnet10" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id + vpc = local.sg_synth_test-vpc1_id } # Internal. required-connections[2]: (instance test-vpc1/vsi0-subnet10)->(instance test-vpc1/vsi0-subnet11); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet10-0" { - group = ibm_is_security_group.test-vpc1--vsi0-subnet10.id + group = ibm_is_security_group.test-vpc1--vsi0-subnet10.id direction = "outbound" - remote = ibm_is_security_group.test-vpc1--vsi0-subnet11.id + remote = ibm_is_security_group.test-vpc1--vsi0-subnet11.id tcp { } } ### SG attached to test-vpc1/vsi0-subnet11 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { - name = "sg-test-vpc1--vsi0-subnet11" + name = "sg-test-vpc1--vsi0-subnet11" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id + vpc = local.sg_synth_test-vpc1_id } # Internal. required-connections[2]: (instance test-vpc1/vsi0-subnet10)->(instance test-vpc1/vsi0-subnet11); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet11-0" { - group = ibm_is_security_group.test-vpc1--vsi0-subnet11.id + group = ibm_is_security_group.test-vpc1--vsi0-subnet11.id direction = "inbound" - remote = ibm_is_security_group.test-vpc1--vsi0-subnet10.id + remote = ibm_is_security_group.test-vpc1--vsi0-subnet10.id tcp { } } diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf index bf96f422..a4e97bbb 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf @@ -1,14 +1,14 @@ ### SG attached to test-vpc2/vsi0-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { - name = "sg-test-vpc2--vsi0-subnet20" + name = "sg-test-vpc2--vsi0-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } # Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc2--vsi0-subnet20-0" { - group = ibm_is_security_group.test-vpc2--vsi0-subnet20.id + group = ibm_is_security_group.test-vpc2--vsi0-subnet20.id direction = "outbound" - remote = ibm_is_security_group.test-vpc2--vsi2-subnet20.id + remote = ibm_is_security_group.test-vpc2--vsi2-subnet20.id tcp { port_min = 53 port_max = 53 @@ -17,22 +17,22 @@ resource "ibm_is_security_group_rule" "test-vpc2--vsi0-subnet20-0" { ### SG attached to test-vpc2/vsi1-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { - name = "sg-test-vpc2--vsi1-subnet20" + name = "sg-test-vpc2--vsi1-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } ### SG attached to test-vpc2/vsi2-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { - name = "sg-test-vpc2--vsi2-subnet20" + name = "sg-test-vpc2--vsi2-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } # Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc2--vsi2-subnet20-0" { - group = ibm_is_security_group.test-vpc2--vsi2-subnet20.id + group = ibm_is_security_group.test-vpc2--vsi2-subnet20.id direction = "inbound" - remote = ibm_is_security_group.test-vpc2--vsi0-subnet20.id + remote = ibm_is_security_group.test-vpc2--vsi0-subnet20.id tcp { port_min = 53 port_max = 53 diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf index ef77175b..b01452c6 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf @@ -1,6 +1,6 @@ ### SG attached to test-vpc3/vsi0-subnet30 resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { - name = "sg-test-vpc3--vsi0-subnet30" + name = "sg-test-vpc3--vsi0-subnet30" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc3_id + vpc = local.sg_synth_test-vpc3_id } From c2512d9fa38cbde10a008b58455e448591accb56 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 9 Oct 2024 13:50:43 +0300 Subject: [PATCH 064/131] make fmt --- .../acl_externals_tf/nacl_expected.tf | 348 +++++------ test/expected/acl_nif_tf/nacl_expected.tf | 216 +++---- .../acl_protocols_tf/nacl_expected.tf | 280 ++++----- .../expected/acl_segments_tf/nacl_expected.tf | 216 +++---- .../expected/acl_testing5_tf/nacl_expected.tf | 584 +++++++++--------- .../nacl_single_expected.tf | 420 ++++++------- .../acl_tg_multiple_tf/nacl_expected.tf | 200 +++--- .../acl_tg_multiple_tf_separate/test-vpc0.tf | 120 ++-- .../acl_tg_multiple_tf_separate/test-vpc1.tf | 40 +- .../acl_tg_multiple_tf_separate/test-vpc2.tf | 20 +- .../acl_tg_multiple_tf_separate/test-vpc3.tf | 20 +- test/expected/sg_protocols_tf/sg_expected.tf | 136 ++-- test/expected/sg_testing3_tf/sg_expected.tf | 68 +- .../sg_tg_multiple_tf_separate/test-vpc0.tf | 56 +- .../sg_tg_multiple_tf_separate/test-vpc1.tf | 16 +- .../sg_tg_multiple_tf_separate/test-vpc2.tf | 20 +- .../sg_tg_multiple_tf_separate/test-vpc3.tf | 4 +- 17 files changed, 1382 insertions(+), 1382 deletions(-) diff --git a/test/expected/acl_externals_tf/nacl_expected.tf b/test/expected/acl_externals_tf/nacl_expected.tf index 5a9777d1..f5b01067 100644 --- a/test/expected/acl_externals_tf/nacl_expected.tf +++ b/test/expected/acl_externals_tf/nacl_expected.tf @@ -1,356 +1,356 @@ # test-vpc1/subnet1 [10.240.10.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet1" { - name = "acl-test-vpc1--subnet1" + name = "acl-test-vpc1--subnet1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule0" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule0" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule1" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule1" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule2" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule2" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule3" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule3" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule4" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule4" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule5" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule5" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule6" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule6" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule7" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule7" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule8" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule8" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule9" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule9" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule10" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule10" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule11" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule11" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule12" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule12" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule13" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule13" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule14" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule14" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule15" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule15" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule16" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule16" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule17" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule17" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # External. required-connections[0]: (external dns)->(subnet test-vpc1/subnet1); allowed-protocols[0] rules { - name = "rule18" - action = "allow" - direction = "inbound" - source = "8.8.8.8" + name = "rule18" + action = "allow" + direction = "inbound" + source = "8.8.8.8" destination = "10.240.10.0/24" } # External. response to required-connections[0]: (external dns)->(subnet test-vpc1/subnet1); allowed-protocols[0] rules { - name = "rule19" - action = "allow" - direction = "outbound" - source = "10.240.10.0/24" + name = "rule19" + action = "allow" + direction = "outbound" + source = "10.240.10.0/24" destination = "8.8.8.8" } } # test-vpc1/subnet2 [10.240.20.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet2" { - name = "acl-test-vpc1--subnet2" + name = "acl-test-vpc1--subnet2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule0" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule0" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule1" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule1" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule2" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule2" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule3" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule3" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule4" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule4" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule5" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule5" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule6" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule6" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule7" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule7" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule8" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule8" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule9" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule9" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule10" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule10" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule11" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule11" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule12" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule12" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule13" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule13" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule14" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule14" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule15" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule15" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule16" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule16" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule17" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule17" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # External. required-connections[1]: (subnet test-vpc1/subnet2)->(external public internet); allowed-protocols[0] rules { - name = "rule18" - action = "allow" - direction = "outbound" - source = "10.240.20.0/24" + name = "rule18" + action = "allow" + direction = "outbound" + source = "10.240.20.0/24" destination = "0.0.0.0/0" } # External. response to required-connections[1]: (subnet test-vpc1/subnet2)->(external public internet); allowed-protocols[0] rules { - name = "rule19" - action = "allow" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule19" + action = "allow" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.20.0/24" } } # test-vpc1/subnet3 [10.240.30.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet3" { - name = "acl-test-vpc1--subnet3" + name = "acl-test-vpc1--subnet3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Deny all communication; subnet test-vpc1/subnet3[10.240.30.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.30.0/24" } # Deny all communication; subnet test-vpc1/subnet3[10.240.30.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.30.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.30.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_nif_tf/nacl_expected.tf b/test/expected/acl_nif_tf/nacl_expected.tf index b3a073ba..5d999aac 100644 --- a/test/expected/acl_nif_tf/nacl_expected.tf +++ b/test/expected/acl_nif_tf/nacl_expected.tf @@ -1,14 +1,14 @@ # test-vpc0/subnet0 [10.240.0.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { - name = "acl-test-vpc0--subnet0" + name = "acl-test-vpc0--subnet0" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (subnet test-vpc0/subnet4)->(instance test-vpc0/vsi0-subnet0); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.0.0/24" icmp { type = 0 @@ -16,10 +16,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet4)->(instance test-vpc0/vsi0-subnet0); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.8.0/24" icmp { type = 8 @@ -29,25 +29,25 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { # test-vpc0/subnet1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { - name = "acl-test-vpc0--subnet1" + name = "acl-test-vpc0--subnet1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[1]: (nif test-vpc0/vsi0-subnet1/scale-clambake-endearing-abridged)->(subnet test-vpc0/subnet4); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.8.0/24" tcp { } } # Internal. response to required-connections[1]: (nif test-vpc0/vsi0-subnet1/scale-clambake-endearing-abridged)->(subnet test-vpc0/subnet4); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.1.0/24" tcp { } @@ -56,61 +56,61 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { # test-vpc0/subnet2 [10.240.4.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { - name = "acl-test-vpc0--subnet2" + name = "acl-test-vpc0--subnet2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Deny all communication; subnet test-vpc0/subnet2[10.240.4.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.4.0/24" } # Deny all communication; subnet test-vpc0/subnet2[10.240.4.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.4.0/24" destination = "0.0.0.0/0" } } # test-vpc0/subnet3 [10.240.5.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { - name = "acl-test-vpc0--subnet3" + name = "acl-test-vpc0--subnet3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Deny all communication; subnet test-vpc0/subnet3[10.240.5.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.5.0/24" } # Deny all communication; subnet test-vpc0/subnet3[10.240.5.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.5.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.5.0/24" destination = "0.0.0.0/0" } } # test-vpc0/subnet4 [10.240.8.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { - name = "acl-test-vpc0--subnet4" + name = "acl-test-vpc0--subnet4" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (subnet test-vpc0/subnet4)->(instance test-vpc0/vsi0-subnet0); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.0.0/24" icmp { type = 0 @@ -118,10 +118,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet4)->(instance test-vpc0/vsi0-subnet0); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.8.0/24" icmp { type = 8 @@ -129,20 +129,20 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { } # Internal. required-connections[1]: (nif test-vpc0/vsi0-subnet1/scale-clambake-endearing-abridged)->(subnet test-vpc0/subnet4); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.8.0/24" tcp { } } # Internal. response to required-connections[1]: (nif test-vpc0/vsi0-subnet1/scale-clambake-endearing-abridged)->(subnet test-vpc0/subnet4); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.1.0/24" tcp { } @@ -151,115 +151,115 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { # test-vpc0/subnet5 [10.240.9.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { - name = "acl-test-vpc0--subnet5" + name = "acl-test-vpc0--subnet5" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Deny all communication; subnet test-vpc0/subnet5[10.240.9.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.9.0/24" } # Deny all communication; subnet test-vpc0/subnet5[10.240.9.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.9.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.9.0/24" destination = "0.0.0.0/0" } } # test-vpc1/subnet10 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { - name = "acl-test-vpc1--subnet10" + name = "acl-test-vpc1--subnet10" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Deny all communication; subnet test-vpc1/subnet10[10.240.64.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.64.0/24" } # Deny all communication; subnet test-vpc1/subnet10[10.240.64.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.64.0/24" destination = "0.0.0.0/0" } } # test-vpc1/subnet11 [10.240.80.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { - name = "acl-test-vpc1--subnet11" + name = "acl-test-vpc1--subnet11" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Deny all communication; subnet test-vpc1/subnet11[10.240.80.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.80.0/24" } # Deny all communication; subnet test-vpc1/subnet11[10.240.80.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.80.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.80.0/24" destination = "0.0.0.0/0" } } # test-vpc2/subnet20 [10.240.128.0/24] resource "ibm_is_network_acl" "acl-test-vpc2--subnet20" { - name = "acl-test-vpc2--subnet20" + name = "acl-test-vpc2--subnet20" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc2_id + vpc = local.acl_synth_test-vpc2_id # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.128.0/24" } # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" destination = "0.0.0.0/0" } } # test-vpc3/subnet30 [10.240.192.0/24] resource "ibm_is_network_acl" "acl-test-vpc3--subnet30" { - name = "acl-test-vpc3--subnet30" + name = "acl-test-vpc3--subnet30" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc3_id + vpc = local.acl_synth_test-vpc3_id # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.192.0/24" } # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.192.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.192.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_protocols_tf/nacl_expected.tf b/test/expected/acl_protocols_tf/nacl_expected.tf index 444efeb6..89da29a6 100644 --- a/test/expected/acl_protocols_tf/nacl_expected.tf +++ b/test/expected/acl_protocols_tf/nacl_expected.tf @@ -1,107 +1,107 @@ # test-vpc0/subnet0 [10.240.0.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { - name = "acl-test-vpc0--subnet0" + name = "acl-test-vpc0--subnet0" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.0.0/24" tcp { } } # Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.1.0/24" icmp { } } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.0.0/24" icmp { } } # Internal. required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.9.0/24" } # Internal. response to required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.9.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.9.0/24" destination = "10.240.0.0/24" } } # test-vpc0/subnet1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { - name = "acl-test-vpc0--subnet1" + name = "acl-test-vpc0--subnet1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.0.0/24" tcp { } } # Internal. required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.1.0/24" icmp { } } # Internal. response to required-connections[0]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet1); allowed-protocols[1] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.0.0/24" icmp { } @@ -110,15 +110,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { # test-vpc0/subnet2 [10.240.4.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { - name = "acl-test-vpc0--subnet2" + name = "acl-test-vpc0--subnet2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" tcp { port_min = 8080 @@ -127,10 +127,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { } # Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.5.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.5.0/24" destination = "10.240.4.0/24" tcp { source_port_min = 8080 @@ -139,10 +139,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { } # Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" icmp { type = 3 @@ -153,15 +153,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { # test-vpc0/subnet3 [10.240.5.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { - name = "acl-test-vpc0--subnet3" + name = "acl-test-vpc0--subnet3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" tcp { port_min = 8080 @@ -170,10 +170,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { } # Internal. response to required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.5.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.5.0/24" destination = "10.240.4.0/24" tcp { source_port_min = 8080 @@ -182,10 +182,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { } # Internal. required-connections[1]: (subnet test-vpc0/subnet2)->(subnet test-vpc0/subnet3); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" icmp { type = 3 @@ -196,15 +196,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { # test-vpc0/subnet4 [10.240.8.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { - name = "acl-test-vpc0--subnet4" + name = "acl-test-vpc0--subnet4" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 15 @@ -212,10 +212,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.9.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.9.0/24" destination = "10.240.8.0/24" icmp { type = 16 @@ -223,10 +223,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { } # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" udp { } @@ -235,15 +235,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { # test-vpc0/subnet5 [10.240.9.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { - name = "acl-test-vpc0--subnet5" + name = "acl-test-vpc0--subnet5" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 15 @@ -251,10 +251,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { } # Internal. response to required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.9.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.9.0/24" destination = "10.240.8.0/24" icmp { type = 16 @@ -262,43 +262,43 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { } # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[1] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" udp { } } # Internal. required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.9.0/24" } # Internal. response to required-connections[4]: (subnet test-vpc0/subnet0)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.9.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.9.0/24" destination = "10.240.0.0/24" } } # test-vpc1/subnet10 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { - name = "acl-test-vpc1--subnet10" + name = "acl-test-vpc1--subnet10" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" udp { port_min = 53 @@ -309,15 +309,15 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { # test-vpc1/subnet11 [10.240.80.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { - name = "acl-test-vpc1--subnet11" + name = "acl-test-vpc1--subnet11" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" udp { port_min = 53 @@ -328,46 +328,46 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { # test-vpc2/subnet20 [10.240.128.0/24] resource "ibm_is_network_acl" "acl-test-vpc2--subnet20" { - name = "acl-test-vpc2--subnet20" + name = "acl-test-vpc2--subnet20" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc2_id + vpc = local.acl_synth_test-vpc2_id # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.128.0/24" } # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" destination = "0.0.0.0/0" } } # test-vpc3/subnet30 [10.240.192.0/24] resource "ibm_is_network_acl" "acl-test-vpc3--subnet30" { - name = "acl-test-vpc3--subnet30" + name = "acl-test-vpc3--subnet30" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc3_id + vpc = local.acl_synth_test-vpc3_id # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.192.0/24" } # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.192.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.192.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_segments_tf/nacl_expected.tf b/test/expected/acl_segments_tf/nacl_expected.tf index 7e615697..a781952b 100644 --- a/test/expected/acl_segments_tf/nacl_expected.tf +++ b/test/expected/acl_segments_tf/nacl_expected.tf @@ -1,233 +1,233 @@ # testacl5-vpc/sub1-1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { - name = "acl-testacl5-vpc--sub1-1" + name = "acl-testacl5-vpc--sub1-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Deny all communication; subnet testacl5-vpc/sub1-1[10.240.1.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.1.0/24" } # Deny all communication; subnet testacl5-vpc/sub1-1[10.240.1.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.1.0/24" destination = "0.0.0.0/0" } } # testacl5-vpc/sub1-2 [10.240.2.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-2" { - name = "acl-testacl5-vpc--sub1-2" + name = "acl-testacl5-vpc--sub1-2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.2.0/23" } # Internal. response to required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.2.0/23" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.2.0/23" destination = "10.240.2.0/24" } # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.2.0/24" } # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.65.0/24" destination = "10.240.2.0/24" } } # testacl5-vpc/sub1-3 [10.240.3.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-3" { - name = "acl-testacl5-vpc--sub1-3" + name = "acl-testacl5-vpc--sub1-3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.2.0/23" } # Internal. response to required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.2.0/23" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.2.0/23" destination = "10.240.3.0/24" } # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.3.0/24" } # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.65.0/24" destination = "10.240.3.0/24" } } # testacl5-vpc/sub2-1 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { - name = "acl-testacl5-vpc--sub2-1" + name = "acl-testacl5-vpc--sub2-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.2.0/23" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.2.0/23" destination = "10.240.64.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.2.0/23" } # Internal. required-connections[2]: (segment subnetSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[2]: (segment subnetSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } } # testacl5-vpc/sub2-2 [10.240.65.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-2" { - name = "acl-testacl5-vpc--sub2-2" + name = "acl-testacl5-vpc--sub2-2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.2.0/23" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.2.0/23" destination = "10.240.65.0/24" } # Internal. response to required-connections[1]: (segment cidrSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.65.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.65.0/24" destination = "10.240.2.0/23" } # Internal. required-connections[2]: (segment subnetSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[2]: (segment subnetSegment)->(segment subnetSegment); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.65.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } } # testacl5-vpc/sub3-1 [10.240.128.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { - name = "acl-testacl5-vpc--sub3-1" + name = "acl-testacl5-vpc--sub3-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Deny all communication; subnet testacl5-vpc/sub3-1[10.240.128.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.128.0/24" } # Deny all communication; subnet testacl5-vpc/sub3-1[10.240.128.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_testing5_tf/nacl_expected.tf b/test/expected/acl_testing5_tf/nacl_expected.tf index 1664f0e1..69925897 100644 --- a/test/expected/acl_testing5_tf/nacl_expected.tf +++ b/test/expected/acl_testing5_tf/nacl_expected.tf @@ -1,30 +1,30 @@ # testacl5-vpc/sub1-1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { - name = "acl-testacl5-vpc--sub1-1" + name = "acl-testacl5-vpc--sub1-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.1.0/24" } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -32,10 +32,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.1.0/24" icmp { type = 8 @@ -43,194 +43,194 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { } # Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. response to required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.2.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.2.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule6" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule6" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule7" - action = "allow" - direction = "inbound" - source = "10.240.3.0/24" + name = "rule7" + action = "allow" + direction = "inbound" + source = "10.240.3.0/24" destination = "10.240.1.0/24" tcp { } } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule8" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule8" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule9" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule9" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule10" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule10" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule11" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule11" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule12" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule12" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule13" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule13" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule14" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule14" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule15" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule15" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule16" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule16" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule17" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule17" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule18" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule18" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule19" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule19" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule20" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule20" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule21" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule21" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule22" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule22" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule23" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule23" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule24" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule24" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule25" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule25" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # External. required-connections[1]: (segment need-dns)->(external dns); allowed-protocols[0] rules { - name = "rule26" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule26" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "8.8.8.8" udp { port_min = 53 @@ -241,45 +241,45 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-1" { # testacl5-vpc/sub1-2 [10.240.2.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-2" { - name = "acl-testacl5-vpc--sub1-2" + name = "acl-testacl5-vpc--sub1-2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. response to required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.3.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.3.0/24" destination = "10.240.2.0/24" tcp { } @@ -288,45 +288,45 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-2" { # testacl5-vpc/sub1-3 [10.240.3.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-3" { - name = "acl-testacl5-vpc--sub1-3" + name = "acl-testacl5-vpc--sub1-3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.2.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.2.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.2.0/24" tcp { } @@ -335,31 +335,31 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub1-3" { # testacl5-vpc/sub2-1 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { - name = "acl-testacl5-vpc--sub2-1" + name = "acl-testacl5-vpc--sub2-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.1.0/24" } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -367,10 +367,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -378,26 +378,26 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { } # Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } # Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule6" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule6" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" tcp { port_min = 443 @@ -406,10 +406,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { } # Internal. response to required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule7" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule7" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" tcp { source_port_min = 443 @@ -418,154 +418,154 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule8" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule8" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule9" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule9" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule10" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule10" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule11" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule11" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule12" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule12" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule13" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule13" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule14" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule14" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule15" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule15" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule16" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule16" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule17" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule17" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule18" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule18" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule19" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule19" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule20" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule20" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule21" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule21" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule22" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule22" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule23" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule23" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule24" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule24" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule25" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule25" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # External. required-connections[1]: (segment need-dns)->(external dns); allowed-protocols[0] rules { - name = "rule26" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule26" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "8.8.8.8" udp { port_min = 53 @@ -576,38 +576,38 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { # testacl5-vpc/sub2-2 [10.240.65.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-2" { - name = "acl-testacl5-vpc--sub2-2" + name = "acl-testacl5-vpc--sub2-2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.65.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } } # testacl5-vpc/sub3-1 [10.240.128.0/24] resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { - name = "acl-testacl5-vpc--sub3-1" + name = "acl-testacl5-vpc--sub3-1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -615,10 +615,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.1.0/24" icmp { type = 8 @@ -626,10 +626,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -637,10 +637,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -648,10 +648,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { } # Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" tcp { port_min = 443 @@ -660,10 +660,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub3-1" { } # Internal. response to required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" tcp { source_port_min = 443 diff --git a/test/expected/acl_testing5_tf_single/nacl_single_expected.tf b/test/expected/acl_testing5_tf_single/nacl_single_expected.tf index 0aa3da5c..5e3a1e07 100644 --- a/test/expected/acl_testing5_tf_single/nacl_single_expected.tf +++ b/test/expected/acl_testing5_tf_single/nacl_single_expected.tf @@ -1,45 +1,45 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { - name = "acl-testacl5-vpc--singleACL" + name = "acl-testacl5-vpc--singleACL" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_testacl5-vpc_id + vpc = local.acl_synth_testacl5-vpc_id # Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.1.0/24" } # Internal. required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.64.0/24" } # Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { - name = "rule3" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.1.0/24" } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule4" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -47,10 +47,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule5" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.1.0/24" icmp { type = 8 @@ -58,10 +58,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule6" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule6" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -69,10 +69,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule7" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule7" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.1.0/24" icmp { type = 8 @@ -80,10 +80,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule8" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule8" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -91,10 +91,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule9" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule9" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -102,10 +102,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule10" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule10" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -113,10 +113,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { - name = "rule11" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule11" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -124,162 +124,162 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule12" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule12" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. response to required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule13" - action = "allow" - direction = "inbound" - source = "10.240.2.0/24" + name = "rule13" + action = "allow" + direction = "inbound" + source = "10.240.2.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule14" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule14" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. response to required-connections[3]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-2); allowed-protocols[0] rules { - name = "rule15" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule15" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule16" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule16" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule17" - action = "allow" - direction = "inbound" - source = "10.240.3.0/24" + name = "rule17" + action = "allow" + direction = "inbound" + source = "10.240.3.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule18" - action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + name = "rule18" + action = "allow" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[4]: (subnet testacl5-vpc/sub1-1)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule19" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule19" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.1.0/24" tcp { } } # Internal. required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule20" - action = "allow" - direction = "outbound" - source = "10.240.2.0/24" + name = "rule20" + action = "allow" + direction = "outbound" + source = "10.240.2.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule21" - action = "allow" - direction = "inbound" - source = "10.240.3.0/24" + name = "rule21" + action = "allow" + direction = "inbound" + source = "10.240.3.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule22" - action = "allow" - direction = "inbound" - source = "10.240.2.0/24" + name = "rule22" + action = "allow" + direction = "inbound" + source = "10.240.2.0/24" destination = "10.240.3.0/24" tcp { } } # Internal. response to required-connections[5]: (subnet testacl5-vpc/sub1-2)->(subnet testacl5-vpc/sub1-3); allowed-protocols[0] rules { - name = "rule23" - action = "allow" - direction = "outbound" - source = "10.240.3.0/24" + name = "rule23" + action = "allow" + direction = "outbound" + source = "10.240.3.0/24" destination = "10.240.2.0/24" tcp { } } # Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule24" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule24" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule25" - action = "allow" - direction = "inbound" - source = "10.240.65.0/24" + name = "rule25" + action = "allow" + direction = "inbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } # Internal. required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule26" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule26" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.65.0/24" } # Internal. response to required-connections[6]: (subnet testacl5-vpc/sub2-1)->(subnet testacl5-vpc/sub2-2); allowed-protocols[0] rules { - name = "rule27" - action = "allow" - direction = "outbound" - source = "10.240.65.0/24" + name = "rule27" + action = "allow" + direction = "outbound" + source = "10.240.65.0/24" destination = "10.240.64.0/24" } # Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule28" - action = "allow" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule28" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" tcp { port_min = 443 @@ -288,10 +288,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule29" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule29" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" tcp { source_port_min = 443 @@ -300,10 +300,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule30" - action = "allow" - direction = "inbound" - source = "10.240.128.0/24" + name = "rule30" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" destination = "10.240.64.0/24" tcp { port_min = 443 @@ -312,10 +312,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Internal. response to required-connections[7]: (subnet testacl5-vpc/sub3-1)->(subnet testacl5-vpc/sub2-1); allowed-protocols[0] rules { - name = "rule31" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule31" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" tcp { source_port_min = 443 @@ -324,154 +324,154 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule32" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule32" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,0 rules { - name = "rule33" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule33" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule34" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule34" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 0,1 rules { - name = "rule35" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule35" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule36" - action = "deny" - direction = "outbound" - source = "10.0.0.0/8" + name = "rule36" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 0,2 rules { - name = "rule37" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule37" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule38" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule38" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 1,0 rules { - name = "rule39" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule39" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule40" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule40" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,1 rules { - name = "rule41" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule41" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule42" - action = "deny" - direction = "outbound" - source = "172.16.0.0/12" + name = "rule42" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 1,2 rules { - name = "rule43" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule43" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule44" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule44" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "10.0.0.0/8" } # Deny other internal communication; see rfc1918#3; item 2,0 rules { - name = "rule45" - action = "deny" - direction = "inbound" - source = "10.0.0.0/8" + name = "rule45" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule46" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule46" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "172.16.0.0/12" } # Deny other internal communication; see rfc1918#3; item 2,1 rules { - name = "rule47" - action = "deny" - direction = "inbound" - source = "172.16.0.0/12" + name = "rule47" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule48" - action = "deny" - direction = "outbound" - source = "192.168.0.0/16" + name = "rule48" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # Deny other internal communication; see rfc1918#3; item 2,2 rules { - name = "rule49" - action = "deny" - direction = "inbound" - source = "192.168.0.0/16" + name = "rule49" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" destination = "192.168.0.0/16" } # External. required-connections[1]: (segment need-dns)->(external dns); allowed-protocols[0] rules { - name = "rule50" - action = "allow" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule50" + action = "allow" + direction = "outbound" + source = "10.240.1.0/24" destination = "8.8.8.8" udp { port_min = 53 @@ -480,10 +480,10 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { } # External. required-connections[1]: (segment need-dns)->(external dns); allowed-protocols[0] rules { - name = "rule51" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule51" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "8.8.8.8" udp { port_min = 53 diff --git a/test/expected/acl_tg_multiple_tf/nacl_expected.tf b/test/expected/acl_tg_multiple_tf/nacl_expected.tf index f140447f..da72d490 100644 --- a/test/expected/acl_tg_multiple_tf/nacl_expected.tf +++ b/test/expected/acl_tg_multiple_tf/nacl_expected.tf @@ -1,30 +1,30 @@ # test-vpc0/subnet0 [10.240.0.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { - name = "acl-test-vpc0--subnet0" + name = "acl-test-vpc0--subnet0" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.4.0/24" } # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.0.0/24" } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -35,54 +35,54 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { # test-vpc0/subnet1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { - name = "acl-test-vpc0--subnet1" + name = "acl-test-vpc0--subnet1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.1.0/24" } # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.1.0/24" destination = "0.0.0.0/0" } } # test-vpc0/subnet2 [10.240.4.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { - name = "acl-test-vpc0--subnet2" + name = "acl-test-vpc0--subnet2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.4.0/24" } # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.0.0/24" } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -93,15 +93,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { # test-vpc0/subnet3 [10.240.5.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { - name = "acl-test-vpc0--subnet3" + name = "acl-test-vpc0--subnet3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -110,10 +110,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -124,15 +124,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { # test-vpc0/subnet4 [10.240.8.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { - name = "acl-test-vpc0--subnet4" + name = "acl-test-vpc0--subnet4" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 4 @@ -142,15 +142,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { # test-vpc0/subnet5 [10.240.9.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { - name = "acl-test-vpc0--subnet5" + name = "acl-test-vpc0--subnet5" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 4 @@ -160,15 +160,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { # test-vpc1/subnet10 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { - name = "acl-test-vpc1--subnet10" + name = "acl-test-vpc1--subnet10" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" icmp { type = 0 @@ -176,10 +176,10 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.80.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.80.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -189,15 +189,15 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { # test-vpc1/subnet11 [10.240.80.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { - name = "acl-test-vpc1--subnet11" + name = "acl-test-vpc1--subnet11" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" icmp { type = 0 @@ -205,10 +205,10 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.80.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.80.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -218,46 +218,46 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { # test-vpc2/subnet20 [10.240.128.0/24] resource "ibm_is_network_acl" "acl-test-vpc2--subnet20" { - name = "acl-test-vpc2--subnet20" + name = "acl-test-vpc2--subnet20" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc2_id + vpc = local.acl_synth_test-vpc2_id # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.128.0/24" } # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" destination = "0.0.0.0/0" } } # test-vpc3/subnet30 [10.240.192.0/24] resource "ibm_is_network_acl" "acl-test-vpc3--subnet30" { - name = "acl-test-vpc3--subnet30" + name = "acl-test-vpc3--subnet30" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc3_id + vpc = local.acl_synth_test-vpc3_id # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.192.0/24" } # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.192.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.192.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf b/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf index 7db93464..f4076710 100644 --- a/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf +++ b/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf @@ -1,30 +1,30 @@ # test-vpc0/subnet0 [10.240.0.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { - name = "acl-test-vpc0--subnet0" + name = "acl-test-vpc0--subnet0" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.4.0/24" } # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.0.0/24" } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.0.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -35,54 +35,54 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { # test-vpc0/subnet1 [10.240.1.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { - name = "acl-test-vpc0--subnet1" + name = "acl-test-vpc0--subnet1" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.1.0/24" } # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.1.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.1.0/24" destination = "0.0.0.0/0" } } # test-vpc0/subnet2 [10.240.4.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { - name = "acl-test-vpc0--subnet2" + name = "acl-test-vpc0--subnet2" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.4.0/24" } # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.0.0/24" } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule2" - action = "allow" - direction = "outbound" - source = "10.240.4.0/24" + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -93,15 +93,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { # test-vpc0/subnet3 [10.240.5.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { - name = "acl-test-vpc0--subnet3" + name = "acl-test-vpc0--subnet3" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.0.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -110,10 +110,10 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.4.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" destination = "10.240.5.0/24" udp { port_min = 53 @@ -124,15 +124,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { # test-vpc0/subnet4 [10.240.8.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { - name = "acl-test-vpc0--subnet4" + name = "acl-test-vpc0--subnet4" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 4 @@ -142,15 +142,15 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { # test-vpc0/subnet5 [10.240.9.0/24] resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { - name = "acl-test-vpc0--subnet5" + name = "acl-test-vpc0--subnet5" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc0_id + vpc = local.acl_synth_test-vpc0_id # Internal. required-connections[2]: (subnet test-vpc0/subnet4)->(subnet test-vpc0/subnet5); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.8.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.8.0/24" destination = "10.240.9.0/24" icmp { type = 4 diff --git a/test/expected/acl_tg_multiple_tf_separate/test-vpc1.tf b/test/expected/acl_tg_multiple_tf_separate/test-vpc1.tf index 78f27575..62ada153 100644 --- a/test/expected/acl_tg_multiple_tf_separate/test-vpc1.tf +++ b/test/expected/acl_tg_multiple_tf_separate/test-vpc1.tf @@ -1,14 +1,14 @@ # test-vpc1/subnet10 [10.240.64.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { - name = "acl-test-vpc1--subnet10" + name = "acl-test-vpc1--subnet10" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" icmp { type = 0 @@ -16,10 +16,10 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "inbound" - source = "10.240.80.0/24" + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.80.0/24" destination = "10.240.64.0/24" icmp { type = 8 @@ -29,15 +29,15 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { # test-vpc1/subnet11 [10.240.80.0/24] resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { - name = "acl-test-vpc1--subnet11" + name = "acl-test-vpc1--subnet11" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc1_id + vpc = local.acl_synth_test-vpc1_id # Internal. required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule0" - action = "allow" - direction = "inbound" - source = "10.240.64.0/24" + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" destination = "10.240.80.0/24" icmp { type = 0 @@ -45,10 +45,10 @@ resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { } # Internal. response to required-connections[3]: (subnet test-vpc1/subnet10)->(subnet test-vpc1/subnet11); allowed-protocols[0] rules { - name = "rule1" - action = "allow" - direction = "outbound" - source = "10.240.80.0/24" + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.80.0/24" destination = "10.240.64.0/24" icmp { type = 8 diff --git a/test/expected/acl_tg_multiple_tf_separate/test-vpc2.tf b/test/expected/acl_tg_multiple_tf_separate/test-vpc2.tf index 72b647d1..26cda248 100644 --- a/test/expected/acl_tg_multiple_tf_separate/test-vpc2.tf +++ b/test/expected/acl_tg_multiple_tf_separate/test-vpc2.tf @@ -1,21 +1,21 @@ resource "ibm_is_network_acl" "acl-test-vpc2--subnet20" { - name = "acl-test-vpc2--subnet20" + name = "acl-test-vpc2--subnet20" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc2_id + vpc = local.acl_synth_test-vpc2_id # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.128.0/24" } # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.128.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/acl_tg_multiple_tf_separate/test-vpc3.tf b/test/expected/acl_tg_multiple_tf_separate/test-vpc3.tf index 62ebac5b..bb8278a9 100644 --- a/test/expected/acl_tg_multiple_tf_separate/test-vpc3.tf +++ b/test/expected/acl_tg_multiple_tf_separate/test-vpc3.tf @@ -1,21 +1,21 @@ resource "ibm_is_network_acl" "acl-test-vpc3--subnet30" { - name = "acl-test-vpc3--subnet30" + name = "acl-test-vpc3--subnet30" resource_group = local.acl_synth_resource_group_id - vpc = local.acl_synth_test-vpc3_id + vpc = local.acl_synth_test-vpc3_id # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule0" - action = "deny" - direction = "inbound" - source = "0.0.0.0/0" + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" destination = "10.240.192.0/24" } # Deny all communication; subnet test-vpc3/subnet30[10.240.192.0/24] does not have required connections rules { - name = "rule1" - action = "deny" - direction = "outbound" - source = "10.240.192.0/24" + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.192.0/24" destination = "0.0.0.0/0" } } diff --git a/test/expected/sg_protocols_tf/sg_expected.tf b/test/expected/sg_protocols_tf/sg_expected.tf index 1367a53c..f7519b05 100644 --- a/test/expected/sg_protocols_tf/sg_expected.tf +++ b/test/expected/sg_protocols_tf/sg_expected.tf @@ -1,68 +1,68 @@ ### SG attached to test-vpc0/vsi0-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { - name = "sg-test-vpc0--vsi0-subnet0" + name = "sg-test-vpc0--vsi0-subnet0" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi0-subnet1); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-0" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet1.id udp { } } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi0-subnet1); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-1" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet1.id icmp { } } ### SG attached to test-vpc0/vsi0-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { - name = "sg-test-vpc0--vsi0-subnet1" + name = "sg-test-vpc0--vsi0-subnet1" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi0-subnet1); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-0" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id udp { } } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi0-subnet1); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-1" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id icmp { } } ### SG attached to test-vpc0/vsi0-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { - name = "sg-test-vpc0--vsi0-subnet2" + name = "sg-test-vpc0--vsi0-subnet2" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[2]: (nif test-vpc0/vsi0-subnet2/graveyard-handmade-ransack-acquaint)->(nif test-vpc0/vsi0-subnet3/icky-balsamic-outgoing-leached); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet2-0" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet2.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet2.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet3.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet3.id tcp { } } # Internal. required-connections[2]: (nif test-vpc0/vsi0-subnet2/graveyard-handmade-ransack-acquaint)->(nif test-vpc0/vsi0-subnet3/icky-balsamic-outgoing-leached); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet2-1" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet2.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet2.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet3.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet3.id icmp { type = 11 code = 1 @@ -71,23 +71,23 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet2-1" { ### SG attached to test-vpc0/vsi0-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { - name = "sg-test-vpc0--vsi0-subnet3" + name = "sg-test-vpc0--vsi0-subnet3" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[2]: (nif test-vpc0/vsi0-subnet2/graveyard-handmade-ransack-acquaint)->(nif test-vpc0/vsi0-subnet3/icky-balsamic-outgoing-leached); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet3-0" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet3.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet3.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet2.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet2.id tcp { } } # Internal. required-connections[2]: (nif test-vpc0/vsi0-subnet2/graveyard-handmade-ransack-acquaint)->(nif test-vpc0/vsi0-subnet3/icky-balsamic-outgoing-leached); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet3-1" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet3.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet3.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet2.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet2.id icmp { type = 11 code = 1 @@ -96,29 +96,29 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet3-1" { ### SG attached to test-vpc0/vsi0-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { - name = "sg-test-vpc0--vsi0-subnet4" + name = "sg-test-vpc0--vsi0-subnet4" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi0-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { - name = "sg-test-vpc0--vsi0-subnet5" + name = "sg-test-vpc0--vsi0-subnet5" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { - name = "sg-test-vpc0--vsi1-subnet0" + name = "sg-test-vpc0--vsi1-subnet0" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-0" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id tcp { port_min = 8080 port_max = 8080 @@ -126,9 +126,9 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-0" { } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-1" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id udp { port_min = 53 port_max = 53 @@ -136,9 +136,9 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-1" { } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[2] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-2" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet1.id icmp { type = 8 } @@ -146,15 +146,15 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-2" { ### SG attached to test-vpc0/vsi1-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { - name = "sg-test-vpc0--vsi1-subnet1" + name = "sg-test-vpc0--vsi1-subnet1" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-0" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id tcp { port_min = 8080 port_max = 8080 @@ -162,9 +162,9 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-0" { } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[1] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-1" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id udp { port_min = 53 port_max = 53 @@ -172,9 +172,9 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-1" { } # Internal. required-connections[1]: (instance test-vpc0/vsi1-subnet0)->(instance test-vpc0/vsi1-subnet1); allowed-protocols[2] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-2" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet0.id icmp { type = 8 } @@ -182,84 +182,84 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-2" { ### SG attached to test-vpc0/vsi1-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { - name = "sg-test-vpc0--vsi1-subnet2" + name = "sg-test-vpc0--vsi1-subnet2" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { - name = "sg-test-vpc0--vsi1-subnet3" + name = "sg-test-vpc0--vsi1-subnet3" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { - name = "sg-test-vpc0--vsi1-subnet4" + name = "sg-test-vpc0--vsi1-subnet4" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { - name = "sg-test-vpc0--vsi1-subnet5" + name = "sg-test-vpc0--vsi1-subnet5" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc1/vsi0-subnet10 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { - name = "sg-test-vpc1--vsi0-subnet10" + name = "sg-test-vpc1--vsi0-subnet10" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id + vpc = local.sg_synth_test-vpc1_id } # External. required-connections[3]: (instance test-vpc1/vsi0-subnet10)->(external dns); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet10-0" { - group = ibm_is_security_group.test-vpc1--vsi0-subnet10.id + group = ibm_is_security_group.test-vpc1--vsi0-subnet10.id direction = "outbound" - remote = "8.8.8.8" + remote = "8.8.8.8" tcp { } } ### SG attached to test-vpc1/vsi0-subnet11 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { - name = "sg-test-vpc1--vsi0-subnet11" + name = "sg-test-vpc1--vsi0-subnet11" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id + vpc = local.sg_synth_test-vpc1_id } ### SG attached to test-vpc2/vsi0-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { - name = "sg-test-vpc2--vsi0-subnet20" + name = "sg-test-vpc2--vsi0-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } ### SG attached to test-vpc2/vsi1-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { - name = "sg-test-vpc2--vsi1-subnet20" + name = "sg-test-vpc2--vsi1-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } # External. required-connections[4]: (instance test-vpc2/vsi1-subnet20)->(external public internet); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc2--vsi1-subnet20-0" { - group = ibm_is_security_group.test-vpc2--vsi1-subnet20.id + group = ibm_is_security_group.test-vpc2--vsi1-subnet20.id direction = "outbound" - remote = "0.0.0.0/0" + remote = "0.0.0.0/0" } ### SG attached to test-vpc2/vsi2-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { - name = "sg-test-vpc2--vsi2-subnet20" + name = "sg-test-vpc2--vsi2-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } ### SG attached to test-vpc3/vsi0-subnet30 resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { - name = "sg-test-vpc3--vsi0-subnet30" + name = "sg-test-vpc3--vsi0-subnet30" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc3_id + vpc = local.sg_synth_test-vpc3_id } diff --git a/test/expected/sg_testing3_tf/sg_expected.tf b/test/expected/sg_testing3_tf/sg_expected.tf index 0da81523..8bfb66a3 100644 --- a/test/expected/sg_testing3_tf/sg_expected.tf +++ b/test/expected/sg_testing3_tf/sg_expected.tf @@ -1,48 +1,48 @@ ### SG attached to test-vpc/appdata-endpoint-gateway resource "ibm_is_security_group" "test-vpc--appdata-endpoint-gateway" { - name = "sg-test-vpc--appdata-endpoint-gateway" + name = "sg-test-vpc--appdata-endpoint-gateway" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } ### SG attached to test-vpc/be resource "ibm_is_security_group" "test-vpc--be" { - name = "sg-test-vpc--be" + name = "sg-test-vpc--be" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } # Internal. required-connections[2]: (instance test-vpc/fe)->(instance test-vpc/be); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--be-0" { - group = ibm_is_security_group.test-vpc--be.id + group = ibm_is_security_group.test-vpc--be.id direction = "inbound" - remote = ibm_is_security_group.test-vpc--fe.id + remote = ibm_is_security_group.test-vpc--fe.id tcp { } } # Internal. required-connections[3]: (instance test-vpc/be)->(instance test-vpc/opa); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--be-1" { - group = ibm_is_security_group.test-vpc--be.id + group = ibm_is_security_group.test-vpc--be.id direction = "outbound" - remote = ibm_is_security_group.test-vpc--opa.id + remote = ibm_is_security_group.test-vpc--opa.id } # Internal. required-connections[4]: (instance test-vpc/be)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--be-2" { - group = ibm_is_security_group.test-vpc--be.id + group = ibm_is_security_group.test-vpc--be.id direction = "outbound" - remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id + remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id } ### SG attached to test-vpc/fe resource "ibm_is_security_group" "test-vpc--fe" { - name = "sg-test-vpc--fe" + name = "sg-test-vpc--fe" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } # Internal. required-connections[1]: (instance test-vpc/proxy)->(instance test-vpc/fe); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--fe-0" { - group = ibm_is_security_group.test-vpc--fe.id + group = ibm_is_security_group.test-vpc--fe.id direction = "inbound" - remote = ibm_is_security_group.test-vpc--proxy.id + remote = ibm_is_security_group.test-vpc--proxy.id tcp { port_min = 9000 port_max = 9000 @@ -50,68 +50,68 @@ resource "ibm_is_security_group_rule" "test-vpc--fe-0" { } # Internal. required-connections[2]: (instance test-vpc/fe)->(instance test-vpc/be); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--fe-1" { - group = ibm_is_security_group.test-vpc--fe.id + group = ibm_is_security_group.test-vpc--fe.id direction = "outbound" - remote = ibm_is_security_group.test-vpc--be.id + remote = ibm_is_security_group.test-vpc--be.id tcp { } } ### SG attached to test-vpc/opa resource "ibm_is_security_group" "test-vpc--opa" { - name = "sg-test-vpc--opa" + name = "sg-test-vpc--opa" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } # Internal. required-connections[3]: (instance test-vpc/be)->(instance test-vpc/opa); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--opa-0" { - group = ibm_is_security_group.test-vpc--opa.id + group = ibm_is_security_group.test-vpc--opa.id direction = "inbound" - remote = ibm_is_security_group.test-vpc--be.id + remote = ibm_is_security_group.test-vpc--be.id } # Internal. required-connections[5]: (instance test-vpc/opa)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--opa-1" { - group = ibm_is_security_group.test-vpc--opa.id + group = ibm_is_security_group.test-vpc--opa.id direction = "outbound" - remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id + remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id } ### SG attached to test-vpc/policydb-endpoint-gateway resource "ibm_is_security_group" "test-vpc--policydb-endpoint-gateway" { - name = "sg-test-vpc--policydb-endpoint-gateway" + name = "sg-test-vpc--policydb-endpoint-gateway" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } # Internal. required-connections[4]: (instance test-vpc/be)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--policydb-endpoint-gateway-0" { - group = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id + group = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id direction = "inbound" - remote = ibm_is_security_group.test-vpc--be.id + remote = ibm_is_security_group.test-vpc--be.id } # Internal. required-connections[5]: (instance test-vpc/opa)->(vpe test-vpc/policydb-endpoint-gateway); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--policydb-endpoint-gateway-1" { - group = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id + group = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id direction = "inbound" - remote = ibm_is_security_group.test-vpc--opa.id + remote = ibm_is_security_group.test-vpc--opa.id } ### SG attached to test-vpc/proxy resource "ibm_is_security_group" "test-vpc--proxy" { - name = "sg-test-vpc--proxy" + name = "sg-test-vpc--proxy" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc_id + vpc = local.sg_synth_test-vpc_id } # External. required-connections[0]: (external public internet)->(instance test-vpc/proxy); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--proxy-0" { - group = ibm_is_security_group.test-vpc--proxy.id + group = ibm_is_security_group.test-vpc--proxy.id direction = "inbound" - remote = "0.0.0.0/0" + remote = "0.0.0.0/0" } # Internal. required-connections[1]: (instance test-vpc/proxy)->(instance test-vpc/fe); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc--proxy-1" { - group = ibm_is_security_group.test-vpc--proxy.id + group = ibm_is_security_group.test-vpc--proxy.id direction = "outbound" - remote = ibm_is_security_group.test-vpc--fe.id + remote = ibm_is_security_group.test-vpc--fe.id tcp { port_min = 9000 port_max = 9000 diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf index 07de4293..8f4979ba 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf @@ -1,95 +1,95 @@ ### SG attached to test-vpc0/vsi0-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { - name = "sg-test-vpc0--vsi0-subnet0" + name = "sg-test-vpc0--vsi0-subnet0" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi1-subnet4); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-0" { - group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id direction = "outbound" - remote = ibm_is_security_group.test-vpc0--vsi1-subnet4.id + remote = ibm_is_security_group.test-vpc0--vsi1-subnet4.id } ### SG attached to test-vpc0/vsi0-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { - name = "sg-test-vpc0--vsi0-subnet1" + name = "sg-test-vpc0--vsi0-subnet1" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi0-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { - name = "sg-test-vpc0--vsi0-subnet2" + name = "sg-test-vpc0--vsi0-subnet2" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi0-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { - name = "sg-test-vpc0--vsi0-subnet3" + name = "sg-test-vpc0--vsi0-subnet3" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi0-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { - name = "sg-test-vpc0--vsi0-subnet4" + name = "sg-test-vpc0--vsi0-subnet4" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi0-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { - name = "sg-test-vpc0--vsi0-subnet5" + name = "sg-test-vpc0--vsi0-subnet5" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { - name = "sg-test-vpc0--vsi1-subnet0" + name = "sg-test-vpc0--vsi1-subnet0" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { - name = "sg-test-vpc0--vsi1-subnet1" + name = "sg-test-vpc0--vsi1-subnet1" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { - name = "sg-test-vpc0--vsi1-subnet2" + name = "sg-test-vpc0--vsi1-subnet2" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { - name = "sg-test-vpc0--vsi1-subnet3" + name = "sg-test-vpc0--vsi1-subnet3" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } ### SG attached to test-vpc0/vsi1-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { - name = "sg-test-vpc0--vsi1-subnet4" + name = "sg-test-vpc0--vsi1-subnet4" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } # Internal. required-connections[0]: (instance test-vpc0/vsi0-subnet0)->(instance test-vpc0/vsi1-subnet4); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet4-0" { - group = ibm_is_security_group.test-vpc0--vsi1-subnet4.id + group = ibm_is_security_group.test-vpc0--vsi1-subnet4.id direction = "inbound" - remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id } ### SG attached to test-vpc0/vsi1-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { - name = "sg-test-vpc0--vsi1-subnet5" + name = "sg-test-vpc0--vsi1-subnet5" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc0_id + vpc = local.sg_synth_test-vpc0_id } diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf index a4810cf4..06e11954 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf @@ -1,29 +1,29 @@ ### SG attached to test-vpc1/vsi0-subnet10 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { - name = "sg-test-vpc1--vsi0-subnet10" + name = "sg-test-vpc1--vsi0-subnet10" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id + vpc = local.sg_synth_test-vpc1_id } # Internal. required-connections[2]: (instance test-vpc1/vsi0-subnet10)->(instance test-vpc1/vsi0-subnet11); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet10-0" { - group = ibm_is_security_group.test-vpc1--vsi0-subnet10.id + group = ibm_is_security_group.test-vpc1--vsi0-subnet10.id direction = "outbound" - remote = ibm_is_security_group.test-vpc1--vsi0-subnet11.id + remote = ibm_is_security_group.test-vpc1--vsi0-subnet11.id tcp { } } ### SG attached to test-vpc1/vsi0-subnet11 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { - name = "sg-test-vpc1--vsi0-subnet11" + name = "sg-test-vpc1--vsi0-subnet11" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc1_id + vpc = local.sg_synth_test-vpc1_id } # Internal. required-connections[2]: (instance test-vpc1/vsi0-subnet10)->(instance test-vpc1/vsi0-subnet11); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet11-0" { - group = ibm_is_security_group.test-vpc1--vsi0-subnet11.id + group = ibm_is_security_group.test-vpc1--vsi0-subnet11.id direction = "inbound" - remote = ibm_is_security_group.test-vpc1--vsi0-subnet10.id + remote = ibm_is_security_group.test-vpc1--vsi0-subnet10.id tcp { } } diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf index a4e97bbb..bf96f422 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf @@ -1,14 +1,14 @@ ### SG attached to test-vpc2/vsi0-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { - name = "sg-test-vpc2--vsi0-subnet20" + name = "sg-test-vpc2--vsi0-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } # Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc2--vsi0-subnet20-0" { - group = ibm_is_security_group.test-vpc2--vsi0-subnet20.id + group = ibm_is_security_group.test-vpc2--vsi0-subnet20.id direction = "outbound" - remote = ibm_is_security_group.test-vpc2--vsi2-subnet20.id + remote = ibm_is_security_group.test-vpc2--vsi2-subnet20.id tcp { port_min = 53 port_max = 53 @@ -17,22 +17,22 @@ resource "ibm_is_security_group_rule" "test-vpc2--vsi0-subnet20-0" { ### SG attached to test-vpc2/vsi1-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { - name = "sg-test-vpc2--vsi1-subnet20" + name = "sg-test-vpc2--vsi1-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } ### SG attached to test-vpc2/vsi2-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { - name = "sg-test-vpc2--vsi2-subnet20" + name = "sg-test-vpc2--vsi2-subnet20" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc2_id + vpc = local.sg_synth_test-vpc2_id } # Internal. required-connections[1]: (instance test-vpc2/vsi0-subnet20)->(instance test-vpc2/vsi2-subnet20); allowed-protocols[0] resource "ibm_is_security_group_rule" "test-vpc2--vsi2-subnet20-0" { - group = ibm_is_security_group.test-vpc2--vsi2-subnet20.id + group = ibm_is_security_group.test-vpc2--vsi2-subnet20.id direction = "inbound" - remote = ibm_is_security_group.test-vpc2--vsi0-subnet20.id + remote = ibm_is_security_group.test-vpc2--vsi0-subnet20.id tcp { port_min = 53 port_max = 53 diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf index b01452c6..ef77175b 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf @@ -1,6 +1,6 @@ ### SG attached to test-vpc3/vsi0-subnet30 resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { - name = "sg-test-vpc3--vsi0-subnet30" + name = "sg-test-vpc3--vsi0-subnet30" resource_group = local.sg_synth_resource_group_id - vpc = local.sg_synth_test-vpc3_id + vpc = local.sg_synth_test-vpc3_id } From 28c3a3b8aaafd4a11f5f7bafce4419e4ec8b6079 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 9 Oct 2024 13:56:54 +0300 Subject: [PATCH 065/131] remove utils func --- pkg/utils/utils.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index e3923aa5..ede1bb67 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -9,8 +9,6 @@ import ( "cmp" "maps" "slices" - - "github.com/np-guard/models/pkg/ds" ) func Ptr[T any](t T) *T { @@ -49,11 +47,3 @@ func Int64PointerToIntPointer(v *int64) *int { } return Ptr(int(*v)) } - -// m1 does not have any key of m2 -func MergeSetMaps[T comparable, K ds.Set[K]](m1, m2 map[T]K) map[T]K { - for key, val := range m2 { - m1[key] = val.Copy() - } - return m1 -} From 9cd866330945f7c8107561652de9907a1339b097 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 9 Oct 2024 13:57:46 +0300 Subject: [PATCH 066/131] models v0.5.1 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 78ec72e8..25753169 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.0 require ( github.com/IBM/vpc-go-sdk v0.60.0 github.com/np-guard/cloud-resource-collector v0.15.0 - github.com/np-guard/models v0.5.1-0.20241008132809-1e27bae86fe4 + github.com/np-guard/models v0.5.1 github.com/spf13/cobra v1.8.1 ) diff --git a/go.sum b/go.sum index a83a5162..afa0f647 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.15.0 h1:jkmxql6D1uBr/qmSOsBzUgeDxlUXSCe7dBKfqfK+QZ4= github.com/np-guard/cloud-resource-collector v0.15.0/go.mod h1:klCHnNnuuVcCtGQHA7R1a8fqnvfMCk/5Jdld6V7sN2A= -github.com/np-guard/models v0.5.1-0.20241008132809-1e27bae86fe4 h1:wsf8U4t74ouuhLqdvxrf247pcjCPlrDhEggpUeskiHo= -github.com/np-guard/models v0.5.1-0.20241008132809-1e27bae86fe4/go.mod h1:29M8utxinyUpYaDuIuOyCcMBf7EsMWZcIrRWCjFm0Bw= +github.com/np-guard/models v0.5.1 h1:qxewCB3cBLkBdcpMk05gKJkV1D7qkbteQdIXbN1juW0= +github.com/np-guard/models v0.5.1/go.mod h1:29M8utxinyUpYaDuIuOyCcMBf7EsMWZcIrRWCjFm0Bw= 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= From da1c7d2b9ca92f040108090d86516e09bbb0c928 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 9 Oct 2024 14:14:59 +0300 Subject: [PATCH 067/131] fixed --- pkg/optimize/sg/ipCubesToRules.go | 8 ++ pkg/optimize/sg/rulesToCubes.go | 2 +- .../sg_expected.csv | 7 +- .../sg_expected.md | 7 +- .../sg_expected.tf | 33 ++--- .../optimize_sg_redundant/sg_expected.tf | 20 +++ test/expected/optimize_sg_t/sg_expected.tf | 6 +- .../expected/optimize_sg_t_all/sg_expected.tf | 7 +- test/main_test.go | 136 +++++++++--------- test/update_test.go | 40 +++--- 10 files changed, 149 insertions(+), 117 deletions(-) diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go index d61f4f81..a02da0f0 100644 --- a/pkg/optimize/sg/ipCubesToRules.go +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -28,6 +28,10 @@ func allProtocolIPCubesIPToRules(cubes *netset.IPBlock, direction ir.Direction) // tcpudpIPCubesToRules converts cubes representing tcp or udp protocol rules to SG rules func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], allCubes *netset.IPBlock, direction ir.Direction, isTCP bool) []*ir.SGRule { + if len(cubes) == 0 { + return []*ir.SGRule{} + } + activeRules := make(map[*netset.IPBlock]netp.Protocol) // the key is the first IP result := make([]*ir.SGRule, 0) @@ -65,6 +69,10 @@ func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], all // icmpIPCubesToRules converts cubes representing icmp protocol rules to SG rules func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { + if len(cubes) == 0 { + return []*ir.SGRule{} + } + activeRules := make(map[*netset.IPBlock]netp.Protocol) // the key is the first IP result := make([]*ir.SGRule, 0) diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go index 589aad7e..c8d14fcb 100644 --- a/pkg/optimize/sg/rulesToCubes.go +++ b/pkg/optimize/sg/rulesToCubes.go @@ -77,7 +77,7 @@ func rulesToIPCubes(rules *rulesPerProtocol) *ipCubesPerProtocol { func allProtocolRulesToIPCubes(rules []*ir.SGRule) *netset.IPBlock { res := netset.NewIPBlock() for i := range rules { - res.Union(rules[i].Remote.(*netset.IPBlock)) + res = res.Union(rules[i].Remote.(*netset.IPBlock)) } return res } diff --git a/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv b/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv index 773f874b..ffecbe70 100644 --- a/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv +++ b/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv @@ -1,7 +1,8 @@ SG,Direction,Remote type,Remote,Protocol,Protocol params,Description +sg1,Inbound,CIDR block,Any IP,ALL,, +sg1,Outbound,CIDR block,Any IP,ALL,, test-vpc1--vsi1,Outbound,Security group,test-vpc1--vsi2,ALL,, -test-vpc1--vsi1,Outbound,CIDR block,0.0.0.0/31,TCP,ports 1-1, -test-vpc1--vsi1,Outbound,CIDR block,0.0.0.0/31,UDP,ports 1-1, -test-vpc1--vsi1,Outbound,CIDR block,0.0.0.0/31,ICMP,"Type: Any, Code: Any", +test-vpc1--vsi1,Outbound,CIDR block,0.0.0.0/31,ALL,, test-vpc1--vsi2,Inbound,Security group,test-vpc1--vsi1,ALL,, wombat-hesitate-scorn-subprime,Inbound,Security group,wombat-hesitate-scorn-subprime,ALL,, +wombat-hesitate-scorn-subprime,Outbound,CIDR block,Any IP,ALL,, diff --git a/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md b/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md index 4fdc42e0..502f442e 100644 --- a/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md +++ b/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md @@ -1,8 +1,9 @@ | SG | Direction | Remote type | Remote | Protocol | Protocol params | Description | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | + | sg1 | Inbound | CIDR block | Any IP | ALL | | | + | sg1 | Outbound | CIDR block | Any IP | ALL | | | | test-vpc1--vsi1 | Outbound | Security group | test-vpc1--vsi2 | ALL | | | - | test-vpc1--vsi1 | Outbound | CIDR block | 0.0.0.0/31 | TCP | ports 1-1 | | - | test-vpc1--vsi1 | Outbound | CIDR block | 0.0.0.0/31 | UDP | ports 1-1 | | - | test-vpc1--vsi1 | Outbound | CIDR block | 0.0.0.0/31 | ICMP | Type: Any, Code: Any | | + | test-vpc1--vsi1 | Outbound | CIDR block | 0.0.0.0/31 | ALL | | | | test-vpc1--vsi2 | Inbound | Security group | test-vpc1--vsi1 | ALL | | | | wombat-hesitate-scorn-subprime | Inbound | Security group | wombat-hesitate-scorn-subprime | ALL | | | + | wombat-hesitate-scorn-subprime | Outbound | CIDR block | Any IP | ALL | | | diff --git a/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf b/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf index d8324ff5..7f196edc 100644 --- a/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf +++ b/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf @@ -3,6 +3,16 @@ resource "ibm_is_security_group" "sg1" { resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } +resource "ibm_is_security_group_rule" "sg1-0" { + group = ibm_is_security_group.sg1.id + direction = "inbound" + remote = "0.0.0.0/0" +} +resource "ibm_is_security_group_rule" "sg1-1" { + group = ibm_is_security_group.sg1.id + direction = "outbound" + remote = "0.0.0.0/0" +} resource "ibm_is_security_group" "test-vpc1--vsi1" { @@ -19,24 +29,6 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { group = ibm_is_security_group.test-vpc1--vsi1.id direction = "outbound" remote = "0.0.0.0/31" - tcp { - port_max = 1 - } -} -resource "ibm_is_security_group_rule" "test-vpc1--vsi1-2" { - group = ibm_is_security_group.test-vpc1--vsi1.id - direction = "outbound" - remote = "0.0.0.0/31" - udp { - port_max = 1 - } -} -resource "ibm_is_security_group_rule" "test-vpc1--vsi1-3" { - group = ibm_is_security_group.test-vpc1--vsi1.id - direction = "outbound" - remote = "0.0.0.0/31" - icmp { - } } @@ -76,3 +68,8 @@ resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-0" { direction = "inbound" remote = ibm_is_security_group.wombat-hesitate-scorn-subprime.id } +resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-1" { + group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id + direction = "outbound" + remote = "0.0.0.0/0" +} diff --git a/test/expected/optimize_sg_redundant/sg_expected.tf b/test/expected/optimize_sg_redundant/sg_expected.tf index 15bd1e64..88239143 100644 --- a/test/expected/optimize_sg_redundant/sg_expected.tf +++ b/test/expected/optimize_sg_redundant/sg_expected.tf @@ -3,6 +3,16 @@ resource "ibm_is_security_group" "sg1" { resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } +resource "ibm_is_security_group_rule" "sg1-0" { + group = ibm_is_security_group.sg1.id + direction = "inbound" + remote = "0.0.0.0/0" +} +resource "ibm_is_security_group_rule" "sg1-1" { + group = ibm_is_security_group.sg1.id + direction = "outbound" + remote = "0.0.0.0/0" +} resource "ibm_is_security_group" "test-vpc1--vsi1" { @@ -15,6 +25,11 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { direction = "outbound" remote = ibm_is_security_group.test-vpc1--vsi2.id } +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.0/30" +} resource "ibm_is_security_group" "test-vpc1--vsi2" { @@ -53,3 +68,8 @@ resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-0" { direction = "inbound" remote = ibm_is_security_group.wombat-hesitate-scorn-subprime.id } +resource "ibm_is_security_group_rule" "wombat-hesitate-scorn-subprime-1" { + group = ibm_is_security_group.wombat-hesitate-scorn-subprime.id + direction = "outbound" + remote = "0.0.0.0/0" +} diff --git a/test/expected/optimize_sg_t/sg_expected.tf b/test/expected/optimize_sg_t/sg_expected.tf index 32fd2e3b..448d25d8 100644 --- a/test/expected/optimize_sg_t/sg_expected.tf +++ b/test/expected/optimize_sg_t/sg_expected.tf @@ -23,9 +23,9 @@ resource "ibm_is_security_group" "test-vpc1--vsi1" { resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { group = ibm_is_security_group.test-vpc1--vsi1.id direction = "outbound" - remote = "0.0.0.0/30" + remote = "0.0.0.0/29" tcp { - port_max = 1 + port_max = 10 } } resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { @@ -33,7 +33,7 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { direction = "outbound" remote = "0.0.0.2/31" tcp { - port_max = 1 + port_max = 20 } } diff --git a/test/expected/optimize_sg_t_all/sg_expected.tf b/test/expected/optimize_sg_t_all/sg_expected.tf index f932cb58..0f4d41e0 100644 --- a/test/expected/optimize_sg_t_all/sg_expected.tf +++ b/test/expected/optimize_sg_t_all/sg_expected.tf @@ -25,9 +25,14 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { direction = "outbound" remote = "0.0.0.0/29" tcp { - port_max = 1 + port_max = 10 } } +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.2/31" +} resource "ibm_is_security_group" "test-vpc1--vsi2" { diff --git a/test/main_test.go b/test/main_test.go index 998995de..aabe832d 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -5,84 +5,84 @@ SPDX-License-Identifier: Apache-2.0 package test -// import ( -// "os" -// "path/filepath" -// "regexp" -// "strings" -// "testing" +import ( + "os" + "path/filepath" + "regexp" + "strings" + "testing" -// "github.com/np-guard/vpc-network-config-synthesis/cmd/subcmds" -// ) + "github.com/np-guard/vpc-network-config-synthesis/cmd/subcmds" +) -// func TestMain(t *testing.T) { -// for _, tt := range allMainTests() { -// t.Run(tt.testName, func(t *testing.T) { -// // create a sub folder -// if err := os.MkdirAll(filepath.Join(resultsFolder, tt.testName), defaultDirectoryPermission); err != nil { -// t.Fatalf("Bad test %s; error creating folder for results: %v", tt.testName, err) -// } +func TestMain(t *testing.T) { + for _, tt := range allMainTests() { + t.Run(tt.testName, func(t *testing.T) { + // create a sub folder + if err := os.MkdirAll(filepath.Join(resultsFolder, tt.testName), defaultDirectoryPermission); err != nil { + t.Fatalf("Bad test %s; error creating folder for results: %v", tt.testName, err) + } -// // run command -// if err := subcmds.Main(tt.args.Args(dataFolder, resultsFolder)); err != nil { -// t.Fatalf("Bad test %s; unexpected err: %v", tt.testName, err) -// } + // run command + if err := subcmds.Main(tt.args.Args(dataFolder, resultsFolder)); err != nil { + t.Fatalf("Bad test %s; unexpected err: %v", tt.testName, err) + } -// // compare results -// compareTestResults(t, tt.testName) -// }) -// } -// removeGeneratedFiles() -// } + // compare results + compareTestResults(t, tt.testName) + }) + } + removeGeneratedFiles() +} -// func compareTestResults(t *testing.T, testName string) { -// expectedSubDirPath := filepath.Join(expectedFolder, testName) -// expectedDirFiles := readDir(t, expectedSubDirPath) -// expectedFileNames := strings.Join(expectedDirFiles, ", ") +func compareTestResults(t *testing.T, testName string) { + expectedSubDirPath := filepath.Join(expectedFolder, testName) + expectedDirFiles := readDir(t, expectedSubDirPath) + expectedFileNames := strings.Join(expectedDirFiles, ", ") -// resultsSubDirPath := filepath.Join(resultsFolder, testName) -// resultsDirFiles := readDir(t, resultsSubDirPath) -// resultsFileNames := strings.Join(resultsDirFiles, ", ") + resultsSubDirPath := filepath.Join(resultsFolder, testName) + resultsDirFiles := readDir(t, resultsSubDirPath) + resultsFileNames := strings.Join(resultsDirFiles, ", ") -// if len(expectedDirFiles) != len(resultsDirFiles) { -// t.Fatalf("Bad test: %s; incorrect number of files created.\nexpected: %s\ngot: %s", testName, expectedFileNames, resultsFileNames) -// } + if len(expectedDirFiles) != len(resultsDirFiles) { + t.Fatalf("Bad test: %s; incorrect number of files created.\nexpected: %s\ngot: %s", testName, expectedFileNames, resultsFileNames) + } -// for _, file := range expectedDirFiles { -// if readFile(t, filepath.Join(expectedSubDirPath, file), testName) != readFile(t, filepath.Join(resultsSubDirPath, file), testName) { -// t.Fatalf("Bad test %s; The %s file is different than expected", testName, file) -// } -// } -// } + for _, file := range expectedDirFiles { + if readFile(t, filepath.Join(expectedSubDirPath, file), testName) != readFile(t, filepath.Join(resultsSubDirPath, file), testName) { + t.Fatalf("Bad test %s; The %s file is different than expected", testName, file) + } + } +} -// func readDir(t *testing.T, dirName string) []string { -// entries, err := os.ReadDir(dirName) -// if err != nil { -// t.Fatalf("Bad test %s; error reading folder: %s", dirName, err) -// } +func readDir(t *testing.T, dirName string) []string { + entries, err := os.ReadDir(dirName) + if err != nil { + t.Fatalf("Bad test %s; error reading folder: %s", dirName, err) + } -// result := make([]string, len(entries)) -// for i := range entries { -// result[i] = entries[i].Name() -// } -// return result -// } + result := make([]string, len(entries)) + for i := range entries { + result[i] = entries[i].Name() + } + return result +} -// func readFile(t *testing.T, file, testName string) string { -// buf, err := os.ReadFile(file) -// if err != nil { -// t.Fatalf("Bad test: %s; error reading file %s: %v", testName, file, err) -// } -// return shrinkWhitespace(string(buf)) -// } +func readFile(t *testing.T, file, testName string) string { + buf, err := os.ReadFile(file) + if err != nil { + t.Fatalf("Bad test: %s; error reading file %s: %v", testName, file, err) + } + return shrinkWhitespace(string(buf)) +} -// func shrinkWhitespace(s string) string { -// return regexp.MustCompile(`[ \t]+`).ReplaceAllString(s, " ") -// } +func shrinkWhitespace(s string) string { + return regexp.MustCompile(`[ \t]+`).ReplaceAllString(s, " ") +} -// func removeGeneratedFiles() { -// err := os.RemoveAll(resultsFolder) -// if err != nil { -// panic(err) -// } -// } +func removeGeneratedFiles() { + err := os.RemoveAll(resultsFolder) + if err != nil { + panic(err) + } +} diff --git a/test/update_test.go b/test/update_test.go index 7687fabe..209921cf 100644 --- a/test/update_test.go +++ b/test/update_test.go @@ -5,26 +5,26 @@ SPDX-License-Identifier: Apache-2.0 package test -import ( - "os" - "path/filepath" - "testing" +// import ( +// "os" +// "path/filepath" +// "testing" - "github.com/np-guard/vpc-network-config-synthesis/cmd/subcmds" -) +// "github.com/np-guard/vpc-network-config-synthesis/cmd/subcmds" +// ) -func TestUpdate(t *testing.T) { - for _, tt := range allMainTests() { - t.Run(tt.testName, func(t *testing.T) { - // create a sub folder - if err := os.MkdirAll(filepath.Join(expectedFolder, tt.testName), defaultDirectoryPermission); err != nil { - t.Errorf("Bad test %s: %s", tt.testName, err) - } +// func TestUpdate(t *testing.T) { +// for _, tt := range allMainTests() { +// t.Run(tt.testName, func(t *testing.T) { +// // create a sub folder +// if err := os.MkdirAll(filepath.Join(expectedFolder, tt.testName), defaultDirectoryPermission); err != nil { +// t.Errorf("Bad test %s: %s", tt.testName, err) +// } - err := subcmds.Main(tt.args.Args(dataFolder, expectedFolder)) - if err != nil { - t.Errorf("Bad test %s: %s", tt.testName, err) - } - }) - } -} +// err := subcmds.Main(tt.args.Args(dataFolder, expectedFolder)) +// if err != nil { +// t.Errorf("Bad test %s: %s", tt.testName, err) +// } +// }) +// } +// } From 4f549452df2760eab05023848e219e38fa1a51e8 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 9 Oct 2024 14:47:09 +0300 Subject: [PATCH 068/131] another test, fixed icmp bug --- pkg/optimize/sg/ipCubesToRules.go | 2 +- test/data/optimize_sg_protocols_to_all/config_object.json | 8 +++++++- test/data/optimize_sg_protocols_to_all/conn_spec.json | 5 +++-- test/data/optimize_sg_protocols_to_all/details.txt | 3 ++- .../optimize_sg_protocols_to_all_csv/sg_expected.csv | 1 + .../optimize_sg_protocols_to_all_md/sg_expected.md | 1 + .../optimize_sg_protocols_to_all_tf/sg_expected.tf | 7 +++++++ 7 files changed, 22 insertions(+), 5 deletions(-) diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go index a02da0f0..f7b41bcf 100644 --- a/pkg/optimize/sg/ipCubesToRules.go +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -100,7 +100,7 @@ func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCu // if the cube contains icmp values that are not contained in the active rules, new rules will be created for _, p := range optimize.IcmpsetPartitions(cubes[i].Right) { if !optimize.IcmpRuleToIcmpSet(p).IsSubset(activeICMP) { - activeRules[cubes[i].Left.FirstIPAddressObject()] = &p + activeRules[cubes[i].Left.FirstIPAddressObject()] = p } } } diff --git a/test/data/optimize_sg_protocols_to_all/config_object.json b/test/data/optimize_sg_protocols_to_all/config_object.json index 23a99429..e4d7662a 100644 --- a/test/data/optimize_sg_protocols_to_all/config_object.json +++ b/test/data/optimize_sg_protocols_to_all/config_object.json @@ -42,6 +42,7 @@ "name": "capitol-siren-chirpy-doornail" }, "default_routing_table": { + "crn": null, "href": "href:11", "id": "id:12", "name": "fiscally-fresh-uncanny-ceramics", @@ -156,6 +157,7 @@ }, "resource_type": "subnet", "routing_table": { + "crn": null, "href": "href:11", "id": "id:12", "name": "fiscally-fresh-uncanny-ceramics", @@ -279,6 +281,7 @@ }, "resource_type": "subnet", "routing_table": { + "crn": null, "href": "href:11", "id": "id:12", "name": "fiscally-fresh-uncanny-ceramics", @@ -395,6 +398,7 @@ }, "resource_type": "subnet", "routing_table": { + "crn": null, "href": "href:11", "id": "id:12", "name": "fiscally-fresh-uncanny-ceramics", @@ -1279,7 +1283,7 @@ "cidr_block": "0.0.0.0/0" }, "remote": { - "cidr_block": "0.0.0.0/31" + "cidr_block": "0.0.0.0/30" }, "protocol": "icmp" }, @@ -2164,11 +2168,13 @@ ], "advertise_routes_to": [], "created_at": "2024-09-09T09:09:51.000Z", + "crn": null, "href": "href:11", "id": "id:12", "is_default": true, "lifecycle_state": "stable", "name": "fiscally-fresh-uncanny-ceramics", + "resource_group": null, "resource_type": "routing_table", "route_direct_link_ingress": false, "route_internet_ingress": false, diff --git a/test/data/optimize_sg_protocols_to_all/conn_spec.json b/test/data/optimize_sg_protocols_to_all/conn_spec.json index 32a127fb..4b184550 100644 --- a/test/data/optimize_sg_protocols_to_all/conn_spec.json +++ b/test/data/optimize_sg_protocols_to_all/conn_spec.json @@ -1,6 +1,7 @@ { "externals": { - "e1": "0.0.0.0/31" + "e1": "0.0.0.0/31", + "e2": "0.0.0.0/30" }, "required-connections": [ { @@ -9,7 +10,7 @@ "type": "instance" }, "dst": { - "name": "e1", + "name": "e2", "type": "external" }, "allowed-protocols": [ diff --git a/test/data/optimize_sg_protocols_to_all/details.txt b/test/data/optimize_sg_protocols_to_all/details.txt index ca29dc0f..09b14960 100644 --- a/test/data/optimize_sg_protocols_to_all/details.txt +++ b/test/data/optimize_sg_protocols_to_all/details.txt @@ -1,4 +1,4 @@ -vsi1 --> 0.0.0.0/31 (icmp) +vsi1 --> 0.0.0.0/30 (icmp) vsi1 --> 0.0.0.0/31 (tcp) vsi1 --> 0.0.0.0/31 (udp ports 1-100) vsi1 --> 0.0.0.0/31 (udp ports 50-150) @@ -13,4 +13,5 @@ vsi1 --> vsi2 (udp ports 151-65535) ==================================== vsi1 --> 0.0.0.0/31 (all protocol) +vsi1 --> 0.0.0.0/30 (icmp) vsi1 --> vsi2 (all protocol) \ No newline at end of file diff --git a/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv b/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv index ffecbe70..2e4c7efb 100644 --- a/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv +++ b/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv @@ -2,6 +2,7 @@ SG,Direction,Remote type,Remote,Protocol,Protocol params,Description sg1,Inbound,CIDR block,Any IP,ALL,, sg1,Outbound,CIDR block,Any IP,ALL,, test-vpc1--vsi1,Outbound,Security group,test-vpc1--vsi2,ALL,, +test-vpc1--vsi1,Outbound,CIDR block,0.0.0.0/30,ICMP,"Type: Any, Code: Any", test-vpc1--vsi1,Outbound,CIDR block,0.0.0.0/31,ALL,, test-vpc1--vsi2,Inbound,Security group,test-vpc1--vsi1,ALL,, wombat-hesitate-scorn-subprime,Inbound,Security group,wombat-hesitate-scorn-subprime,ALL,, diff --git a/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md b/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md index 502f442e..52e2f303 100644 --- a/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md +++ b/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md @@ -3,6 +3,7 @@ | sg1 | Inbound | CIDR block | Any IP | ALL | | | | sg1 | Outbound | CIDR block | Any IP | ALL | | | | test-vpc1--vsi1 | Outbound | Security group | test-vpc1--vsi2 | ALL | | | + | test-vpc1--vsi1 | Outbound | CIDR block | 0.0.0.0/30 | ICMP | Type: Any, Code: Any | | | test-vpc1--vsi1 | Outbound | CIDR block | 0.0.0.0/31 | ALL | | | | test-vpc1--vsi2 | Inbound | Security group | test-vpc1--vsi1 | ALL | | | | wombat-hesitate-scorn-subprime | Inbound | Security group | wombat-hesitate-scorn-subprime | ALL | | | diff --git a/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf b/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf index 7f196edc..10f44116 100644 --- a/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf +++ b/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf @@ -26,6 +26,13 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { remote = ibm_is_security_group.test-vpc1--vsi2.id } resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "0.0.0.0/30" + icmp { + } +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-2" { group = ibm_is_security_group.test-vpc1--vsi1.id direction = "outbound" remote = "0.0.0.0/31" From 5f3d0d9aa23c7e7f648f279583270cb9a39ed0cf Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 9 Oct 2024 16:16:17 +0300 Subject: [PATCH 069/131] fixed --- go.mod | 2 +- go.sum | 2 ++ pkg/io/jsonio/unmarshal.go | 21 +++++++++++++++------ pkg/ir/spec.go | 13 ++----------- pkg/ir/unspecified.go | 11 ++++------- pkg/synth/acl.go | 9 ++++----- 6 files changed, 28 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index 2a404e56..25753169 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.0 require ( github.com/IBM/vpc-go-sdk v0.60.0 github.com/np-guard/cloud-resource-collector v0.15.0 - github.com/np-guard/models v0.5.0 + github.com/np-guard/models v0.5.1 github.com/spf13/cobra v1.8.1 ) diff --git a/go.sum b/go.sum index e4aac127..f19ac670 100644 --- a/go.sum +++ b/go.sum @@ -136,6 +136,8 @@ github.com/np-guard/cloud-resource-collector v0.15.0 h1:jkmxql6D1uBr/qmSOsBzUgeD github.com/np-guard/cloud-resource-collector v0.15.0/go.mod h1:klCHnNnuuVcCtGQHA7R1a8fqnvfMCk/5Jdld6V7sN2A= github.com/np-guard/models v0.5.0 h1:P37gCg3RD23hZHymFWtthrF+mGIwyHJkWy0wIWIzokQ= github.com/np-guard/models v0.5.0/go.mod h1:29M8utxinyUpYaDuIuOyCcMBf7EsMWZcIrRWCjFm0Bw= +github.com/np-guard/models v0.5.1 h1:qxewCB3cBLkBdcpMk05gKJkV1D7qkbteQdIXbN1juW0= +github.com/np-guard/models v0.5.1/go.mod h1:29M8utxinyUpYaDuIuOyCcMBf7EsMWZcIrRWCjFm0Bw= 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= diff --git a/pkg/io/jsonio/unmarshal.go b/pkg/io/jsonio/unmarshal.go index 7f6f8c00..b3fe9cbe 100644 --- a/pkg/io/jsonio/unmarshal.go +++ b/pkg/io/jsonio/unmarshal.go @@ -17,6 +17,7 @@ import ( "github.com/np-guard/models/pkg/spec" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) // Reader implements ir.Reader @@ -110,8 +111,10 @@ func parseCidrSegments(jsonSegments spec.SpecSegments, configDefs *ir.ConfigDefs cidrSegments := filterSegmentsByType(jsonSegments, spec.SegmentTypeCidr) result := make(map[ir.ID]*ir.CidrSegmentDetails) for segmentName, segment := range cidrSegments { - // each cidr saves the contained subnets - segmentMap := make(map[*netset.IPBlock]ir.CIDRDetails) + cidrs := netset.NewIPBlock() + containedSubnets := map[string]interface{}{} + overlappingVPCs := map[string]interface{}{} + for _, cidr := range segment { c, err := netset.IPBlockFromCidr(cidr) if err != nil { @@ -122,13 +125,19 @@ func parseCidrSegments(jsonSegments spec.SpecSegments, configDefs *ir.ConfigDefs if err != nil { return nil, err } - segmentMap[c] = ir.CIDRDetails{ - OverlappingVPCs: vpcs, - ContainedSubnets: subnets, + + cidrs = cidrs.Union(c) + for _, vpc := range vpcs { + overlappingVPCs[vpc] = struct{}{} + } + for _, subnet := range subnets { + containedSubnets[subnet] = struct{}{} } } cidrSegmentDetails := ir.CidrSegmentDetails{ - Cidrs: segmentMap, + Cidrs: cidrs, + ContainedSubnets: utils.SortedMapKeys(containedSubnets), + OverlappingVPCs: utils.SortedMapKeys(overlappingVPCs), } result[segmentName] = &cidrSegmentDetails } diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index cb069dc5..aa262729 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -131,10 +131,7 @@ type ( } CidrSegmentDetails struct { - Cidrs map[*netset.IPBlock]CIDRDetails - } - - CIDRDetails struct { + Cidrs *netset.IPBlock ContainedSubnets []ID OverlappingVPCs []ID } @@ -241,13 +238,7 @@ func (s *Definitions) lookupCidrSegment(name string) (Resource, error) { if !ok { return Resource{}, containerNotFoundError(name, ResourceTypeSegment) } - cidrs := make([]*netset.IPBlock, len(cidrSegmentDetails.Cidrs)) - i := 0 - for cidr := range cidrSegmentDetails.Cidrs { - cidrs[i] = cidr - i++ - } - return Resource{name, cidrs, ResourceTypeCidr}, nil + return Resource{name, cidrSegmentDetails.Cidrs.SplitToCidrs(), ResourceTypeCidr}, nil } func (s *Definitions) Lookup(t ResourceType, name string) (Resource, error) { diff --git a/pkg/ir/unspecified.go b/pkg/ir/unspecified.go index 79f75115..3553e582 100644 --- a/pkg/ir/unspecified.go +++ b/pkg/ir/unspecified.go @@ -42,13 +42,10 @@ func (s *Spec) ComputeBlockedSubnets() []ID { // cidr segments which include the subnet cidrSegments := []ID{} for segmentName, cidrSegmentDetails := range s.Defs.CidrSegments { - segmentDetailsLoops: - for _, cidrDetails := range cidrSegmentDetails.Cidrs { - for _, s := range cidrDetails.ContainedSubnets { - if subnet == s { - cidrSegments = append(cidrSegments, segmentName) - break segmentDetailsLoops - } + for _, s := range cidrSegmentDetails.ContainedSubnets { + if subnet == s { + cidrSegments = append(cidrSegments, segmentName) + break } } } diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index 2c318d1d..044d72ce 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -143,7 +143,7 @@ func adjustResource(s *ir.Definitions, addrs *netset.IPBlock, resource ir.Resour result := expandNifToSubnet(s, addrs) return result, result[0].Addrs // return nif's subnet, not its IP address case ir.ResourceTypeCidr: - return adjustCidrSegment(s, addrs, resource.Name), addrs + return adjustCidrSegment(s, resource.Name), addrs } return []*namedAddrs{}, nil // shouldn't happen } @@ -162,11 +162,10 @@ func adjustSubnet(s *ir.Definitions, addrs *netset.IPBlock, resourceName string) return []*namedAddrs{} // shouldn't happen } -func adjustCidrSegment(s *ir.Definitions, cidr *netset.IPBlock, resourceName string) []*namedAddrs { +func adjustCidrSegment(s *ir.Definitions, resourceName string) []*namedAddrs { cidrSegmentDetails := s.CidrSegments[resourceName] - cidrDetails := cidrSegmentDetails.Cidrs[cidr] - result := make([]*namedAddrs, len(cidrDetails.ContainedSubnets)) - for i, subnet := range cidrDetails.ContainedSubnets { + result := make([]*namedAddrs, len(cidrSegmentDetails.ContainedSubnets)) + for i, subnet := range cidrSegmentDetails.ContainedSubnets { result[i] = &namedAddrs{Name: subnet, Addrs: s.Subnets[subnet].Address()} } return result From 68f23ed1f9a46a0ebd0d01e83c0e5304c1a2af4e Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Thu, 10 Oct 2024 17:35:58 +0300 Subject: [PATCH 070/131] wip --- cmd/subcmds/synth.go | 12 +- cmd/subcmds/synthACL.go | 2 +- cmd/subcmds/synthSG.go | 2 +- cmd/subcmds/unmarshal.go | 4 +- go.mod | 2 +- go.sum | 6 +- pkg/io/jsonio/unmarshal.go | 333 ++++++-------------------- pkg/io/jsonio/unmarshalConn.go | 132 ++++++++++ pkg/io/jsonio/unmarshalDefinitions.go | 137 +++++++++++ pkg/ir/spec.go | 258 +++++++++++--------- pkg/synth/acl.go | 146 +++-------- pkg/synth/common.go | 13 +- pkg/synth/sg.go | 98 +++----- test/error_test_list.go | 22 +- 14 files changed, 591 insertions(+), 576 deletions(-) create mode 100644 pkg/io/jsonio/unmarshalConn.go create mode 100644 pkg/io/jsonio/unmarshalDefinitions.go diff --git a/cmd/subcmds/synth.go b/cmd/subcmds/synth.go index ef0f81d4..83bfc550 100644 --- a/cmd/subcmds/synth.go +++ b/cmd/subcmds/synth.go @@ -30,16 +30,12 @@ func NewSynthCommand(args *inArgs) *cobra.Command { return cmd } -func synthesis(cmd *cobra.Command, args *inArgs, newSynthesizer func(*ir.Spec, bool) synth.Synthesizer, single bool) error { +func synthesis(cmd *cobra.Command, args *inArgs, newSynthesizer func(*ir.Spec, bool) synth.Synthesizer, singleacl, isSG bool) error { cmd.SilenceUsage = true // if we got this far, flags are syntactically correct, so no need to print usage - spec, err := unmarshal(args) + spec, err := unmarshal(args, isSG) if err != nil { return err } - synthesizer := newSynthesizer(spec, single) - collection, err := synthesizer.Synth() - if err != nil { - return err - } - return writeOutput(args, collection, utils.MapKeys(spec.Defs.ConfigDefs.VPCs)) + synthesizer := newSynthesizer(spec, singleacl) + return writeOutput(args, synthesizer.Synth(), utils.MapKeys(spec.Defs.ConfigDefs.VPCs)) } diff --git a/cmd/subcmds/synthACL.go b/cmd/subcmds/synthACL.go index 4aee4040..0aa05e61 100644 --- a/cmd/subcmds/synthACL.go +++ b/cmd/subcmds/synthACL.go @@ -19,7 +19,7 @@ func NewSynthACLCommand(args *inArgs) *cobra.Command { Endpoints in the required-connectivity specification may be subnets, subnet segments, CIDR segments and externals.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { - return synthesis(cmd, args, synth.NewACLSynthesizer, args.singleacl) + return synthesis(cmd, args, synth.NewACLSynthesizer, args.singleacl, false) }, } diff --git a/cmd/subcmds/synthSG.go b/cmd/subcmds/synthSG.go index 88bb4a56..a93497e9 100644 --- a/cmd/subcmds/synthSG.go +++ b/cmd/subcmds/synthSG.go @@ -19,7 +19,7 @@ func NewSynthSGCommand(args *inArgs) *cobra.Command { Endpoints in the required-connectivity specification may be Instances (VSIs), Network Interfaces, VPEs and externals.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { - return synthesis(cmd, args, synth.NewSGSynthesizer, false) + return synthesis(cmd, args, synth.NewSGSynthesizer, false, true) }, } return cmd diff --git a/cmd/subcmds/unmarshal.go b/cmd/subcmds/unmarshal.go index 5fa7c720..c1321f97 100644 --- a/cmd/subcmds/unmarshal.go +++ b/cmd/subcmds/unmarshal.go @@ -13,13 +13,13 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -func unmarshal(args *inArgs) (*ir.Spec, error) { +func unmarshal(args *inArgs, isSG bool) (*ir.Spec, error) { defs, err := confio.ReadDefs(args.configFile) if err != nil { return nil, fmt.Errorf("could not parse config file %v: %w", args.configFile, err) } - model, err := jsonio.NewReader().ReadSpec(args.specFile, defs) + model, err := jsonio.NewReader().ReadSpec(args.specFile, defs, isSG) if err != nil { return nil, fmt.Errorf("could not parse connectivity file %s: %w", args.specFile, err) } diff --git a/go.mod b/go.mod index 25753169..f452c820 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.0 require ( github.com/IBM/vpc-go-sdk v0.60.0 github.com/np-guard/cloud-resource-collector v0.15.0 - github.com/np-guard/models v0.5.1 + github.com/np-guard/models v0.5.2-0.20241010083230-9425a786fb15 github.com/spf13/cobra v1.8.1 ) diff --git a/go.sum b/go.sum index f19ac670..d070856e 100644 --- a/go.sum +++ b/go.sum @@ -134,10 +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.15.0 h1:jkmxql6D1uBr/qmSOsBzUgeDxlUXSCe7dBKfqfK+QZ4= github.com/np-guard/cloud-resource-collector v0.15.0/go.mod h1:klCHnNnuuVcCtGQHA7R1a8fqnvfMCk/5Jdld6V7sN2A= -github.com/np-guard/models v0.5.0 h1:P37gCg3RD23hZHymFWtthrF+mGIwyHJkWy0wIWIzokQ= -github.com/np-guard/models v0.5.0/go.mod h1:29M8utxinyUpYaDuIuOyCcMBf7EsMWZcIrRWCjFm0Bw= -github.com/np-guard/models v0.5.1 h1:qxewCB3cBLkBdcpMk05gKJkV1D7qkbteQdIXbN1juW0= -github.com/np-guard/models v0.5.1/go.mod h1:29M8utxinyUpYaDuIuOyCcMBf7EsMWZcIrRWCjFm0Bw= +github.com/np-guard/models v0.5.2-0.20241010083230-9425a786fb15 h1:UYBqJOLWWP3WX9duDDZqsZ4axHnnzOodw9BUZ63MYAY= +github.com/np-guard/models v0.5.2-0.20241010083230-9425a786fb15/go.mod h1:29M8utxinyUpYaDuIuOyCcMBf7EsMWZcIrRWCjFm0Bw= 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= diff --git a/pkg/io/jsonio/unmarshal.go b/pkg/io/jsonio/unmarshal.go index 0c7ca5f3..1140fea9 100644 --- a/pkg/io/jsonio/unmarshal.go +++ b/pkg/io/jsonio/unmarshal.go @@ -8,13 +8,10 @@ package jsonio import ( "encoding/json" + "errors" "fmt" - "log" "os" - "slices" - "github.com/np-guard/models/pkg/netp" - "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" @@ -28,169 +25,71 @@ func NewReader() *Reader { return &Reader{} } -func (*Reader) ReadSpec(filename string, configDefs *ir.ConfigDefs) (*ir.Spec, error) { +func (r *Reader) ReadSpec(filename string, configDefs *ir.ConfigDefs, isSG bool) (*ir.Spec, error) { jsonSpec, err := unmarshal(filename) if err != nil { return nil, err } - - err = validateSegments(jsonSpec.Segments) - if err != nil { - return nil, err - } - - subnetSegments := parseSubnetSegments(jsonSpec.Segments) - - cidrSegments, err := parseCidrSegments(jsonSpec.Segments, configDefs) + defs, err := r.readDefinitions(jsonSpec, configDefs) if err != nil { return nil, err } // replace to fully qualified name - jsonSpec, finalSubnetSegments, err := replaceResourcesName(jsonSpec, subnetSegments, configDefs) + jsonSpec, defs, err = replaceResourcesName(jsonSpec, defs) if err != nil { return nil, err } - externals, err := translateExternals(jsonSpec.Externals) + connections, err := r.transalteConnections(jsonSpec.RequiredConnections, defs, isSG) if err != nil { return nil, err } - defs := &ir.Definitions{ - ConfigDefs: *configDefs, - SubnetSegments: finalSubnetSegments, - CidrSegments: cidrSegments, - Externals: externals, - } - - var connections []ir.Connection - for i := range jsonSpec.RequiredConnections { - bidiConns, err := translateConnection(defs, &jsonSpec.RequiredConnections[i], i) - if err != nil { - return nil, err - } - connections = append(connections, bidiConns...) - } - return &ir.Spec{ Connections: connections, - Defs: *defs, + Defs: defs, }, nil } -func validateSegments(jsonSegments spec.SpecSegments) error { - for _, v := range jsonSegments { - if v.Type != spec.SegmentTypeSubnet && v.Type != spec.SegmentTypeCidr { - return fmt.Errorf("only subnet and cidr segments are supported, not %q", v.Type) - } - } - return nil -} - -func filterSegmentsByType(jsonSegments spec.SpecSegments, segmentType spec.SegmentType) map[string][]string { - result := make(map[string][]string) - for k, v := range jsonSegments { - if v.Type == segmentType { - result[k] = v.Items - } - } - return result -} - -func parseSubnetSegments(jsonSegments spec.SpecSegments) map[string][]ir.ID { - subnetSegments := filterSegmentsByType(jsonSegments, spec.SegmentTypeSubnet) - result := make(map[string][]ir.ID) - for segmentName, subnets := range subnetSegments { - result[segmentName] = subnets - } - return result -} - -func parseCidrSegments(jsonSegments spec.SpecSegments, configDefs *ir.ConfigDefs) (map[ir.ID]*ir.CidrSegmentDetails, error) { - cidrSegments := filterSegmentsByType(jsonSegments, spec.SegmentTypeCidr) - result := make(map[ir.ID]*ir.CidrSegmentDetails) - for segmentName, segment := range cidrSegments { - cidrs := netset.NewIPBlock() - containedSubnets := make([]ir.ID, 0) - overlappingVPCs := make([]ir.ID, 0) - - for _, cidr := range segment { - c, err := netset.IPBlockFromCidr(cidr) - if err != nil { - return nil, err - } - vpcs := parseOverlappingVpcs(c, configDefs.VPCs) - subnets, err := configDefs.SubnetsContainedInCidr(*c) - if err != nil { - return nil, err - } - - cidrs = cidrs.Union(c) - overlappingVPCs = append(overlappingVPCs, vpcs...) - containedSubnets = append(containedSubnets, subnets...) - } - cidrSegmentDetails := ir.CidrSegmentDetails{ - Cidrs: cidrs, - ContainedSubnets: slices.Compact(slices.Sorted(slices.Values(containedSubnets))), - OverlappingVPCs: slices.Compact(slices.Sorted(slices.Values(overlappingVPCs))), - } - result[segmentName] = &cidrSegmentDetails - } - return result, nil -} +// replace all resources names to fully qualified name +func replaceResourcesName(jsonSpec *spec.Spec, defs *ir.Definitions) (*spec.Spec, *ir.Definitions, error) { + config := defs.ConfigDefs -// read externals from conn-spec -func translateExternals(m map[string]string) (map[ir.ID]*ir.ExternalDetails, error) { - result := make(map[ir.ID]*ir.ExternalDetails) - for k, v := range m { - address, err := netset.IPBlockFromCidrOrAddress(v) - if err != nil { - return nil, err - } - result[k] = &ir.ExternalDetails{ExternalAddrs: address} - } - return result, nil -} + // calculate distinct and ambiguous names for every endpoint type + distinctSubnets, ambiguousSubnets := inverseMapToFullyQualifiedName(config.Subnets) + distinctNifs, ambiguousNifs := inverseMapToFullyQualifiedName(config.NIFs) + distinctInstances, ambiguousInstances := inverseMapToFullyQualifiedName(config.Instances) + distinctVpes, ambiguousVpes := inverseMapToFullyQualifiedName(config.VPEs) -// replace all resources names in conn-spec to fully qualified name -func replaceResourcesName(jsonSpec *spec.Spec, subnetSegments map[string][]ir.ID, - config *ir.ConfigDefs) (*spec.Spec, map[ir.ID]*ir.SubnetSegmentDetails, error) { - subnetsCache, ambiguousSubnets := inverseMapToFullyQualifiedName(config.Subnets) - nifsCache, ambiguousNifs := inverseMapToFullyQualifiedName(config.NIFs) - instancesCache, ambiguousInstances := inverseMapToFullyQualifiedName(config.Instances) - vpesCache, ambiguousVpes := inverseMapToFullyQualifiedName(config.VPEs) + // translate segments to fully qualified names + subnetSegments, err1 := replaceSegmentNames(defs.SubnetSegments, distinctSubnets, ambiguousSubnets, spec.ResourceType(spec.SegmentTypeSubnet)) + nifSegments, err2 := replaceSegmentNames(defs.NifSegments, distinctNifs, ambiguousNifs, spec.ResourceType(spec.SegmentTypeNif)) + instanceSegments, err3 := replaceSegmentNames(defs.InstanceSegments, distinctInstances, ambiguousInstances, spec.ResourceType(spec.SegmentTypeInstance)) + vpeSegments, err4 := replaceSegmentNames(defs.VpeSegments, distinctVpes, ambiguousVpes, spec.ResourceType(spec.SegmentTypeVpe)) - // go over subnetSegments - finalSubnetSegments := make(map[ir.ID]*ir.SubnetSegmentDetails) - for segmentName, subnets := range subnetSegments { - subnetsNames := make([]ir.ID, 0) - VPCs := make([]ir.ID, 0) - for _, subnet := range subnets { - fullyQualifiedName, err := replaceResourceName(subnetsCache, ambiguousSubnets, subnet, spec.ResourceTypeSubnet) - if err != nil { - return nil, nil, err - } - subnetsNames = append(subnetsNames, fullyQualifiedName) - VPCs = append(VPCs, config.Subnets[fullyQualifiedName].VPC) - } - finalSubnetSegments[segmentName] = &ir.SubnetSegmentDetails{Subnets: subnetsNames, OverlappingVPCs: ir.UniqueIDValues(VPCs)} + if err := errors.Join(err1, err2, err3, err4); err != nil { + return nil, nil, err } + defs.SubnetSegments = subnetSegments + defs.NifSegments = nifSegments + defs.InstanceSegments = instanceSegments + defs.VpeSegments = vpeSegments + // translate connections resources to fully qualified names var err error - // go over Spec for i := range jsonSpec.RequiredConnections { conn := &jsonSpec.RequiredConnections[i] fullyQualifiedSrc := conn.Src.Name switch conn.Src.Type { case spec.ResourceTypeSubnet: - fullyQualifiedSrc, err = replaceResourceName(subnetsCache, ambiguousSubnets, conn.Src.Name, spec.ResourceTypeSubnet) + fullyQualifiedSrc, err = replaceResourceName(distinctSubnets, ambiguousSubnets, conn.Src.Name, spec.ResourceTypeSubnet) case spec.ResourceTypeNif: - fullyQualifiedSrc, err = replaceResourceName(nifsCache, ambiguousNifs, conn.Src.Name, spec.ResourceTypeNif) + fullyQualifiedSrc, err = replaceResourceName(distinctNifs, ambiguousNifs, conn.Src.Name, spec.ResourceTypeNif) case spec.ResourceTypeInstance: - fullyQualifiedSrc, err = replaceResourceName(instancesCache, ambiguousInstances, conn.Src.Name, spec.ResourceTypeInstance) + fullyQualifiedSrc, err = replaceResourceName(distinctInstances, ambiguousInstances, conn.Src.Name, spec.ResourceTypeInstance) case spec.ResourceTypeVpe: - fullyQualifiedSrc, err = replaceResourceName(vpesCache, ambiguousVpes, conn.Src.Name, spec.ResourceTypeVpe) + fullyQualifiedSrc, err = replaceResourceName(distinctVpes, ambiguousVpes, conn.Src.Name, spec.ResourceTypeVpe) } if err != nil { return nil, nil, err @@ -200,109 +99,70 @@ func replaceResourcesName(jsonSpec *spec.Spec, subnetSegments map[string][]ir.ID fullyQualifiedDst := conn.Dst.Name switch conn.Dst.Type { case spec.ResourceTypeSubnet: - fullyQualifiedDst, err = replaceResourceName(subnetsCache, ambiguousSubnets, conn.Dst.Name, spec.ResourceTypeSubnet) + fullyQualifiedDst, err = replaceResourceName(distinctSubnets, ambiguousSubnets, conn.Dst.Name, spec.ResourceTypeSubnet) case spec.ResourceTypeNif: - fullyQualifiedDst, err = replaceResourceName(nifsCache, ambiguousNifs, conn.Dst.Name, spec.ResourceTypeNif) + fullyQualifiedDst, err = replaceResourceName(distinctNifs, ambiguousNifs, conn.Dst.Name, spec.ResourceTypeNif) case spec.ResourceTypeInstance: - fullyQualifiedDst, err = replaceResourceName(instancesCache, ambiguousInstances, conn.Dst.Name, spec.ResourceTypeInstance) + fullyQualifiedDst, err = replaceResourceName(distinctInstances, ambiguousInstances, conn.Dst.Name, spec.ResourceTypeInstance) case spec.ResourceTypeVpe: - fullyQualifiedDst, err = replaceResourceName(vpesCache, ambiguousVpes, conn.Dst.Name, spec.ResourceTypeVpe) + fullyQualifiedDst, err = replaceResourceName(distinctVpes, ambiguousVpes, conn.Dst.Name, spec.ResourceTypeVpe) } if err != nil { return nil, nil, err } conn.Dst.Name = fullyQualifiedDst } - return jsonSpec, finalSubnetSegments, nil + return jsonSpec, defs, nil } -func translateConnection(defs *ir.Definitions, v *spec.SpecRequiredConnectionsElem, connectionIndex int) ([]ir.Connection, error) { - p, err := translateProtocols(v.AllowedProtocols) - if err != nil { - return nil, err - } - srcResourceType, err := translateResourceType(v.Src.Type) - if err != nil { - return nil, err - } - src, err := defs.Lookup(srcResourceType, v.Src.Name) - if err != nil { - return nil, err - } - dstResourceType, err := translateResourceType(v.Dst.Type) - if err != nil { - return nil, err - } - dst, err := defs.Lookup(dstResourceType, v.Dst.Name) - if err != nil { - return nil, err - } - if srcResourceType == ir.ResourceTypeExternal && dstResourceType == ir.ResourceTypeExternal { - return nil, fmt.Errorf("both source (%s) and destination (%s) are external in required connection", v.Src.Name, v.Dst.Name) - } - - origin := connectionOrigin{ - connectionIndex: connectionIndex, - srcName: resourceName(v.Src), - dstName: resourceName(v.Dst), - } - out := ir.Connection{Src: src, Dst: dst, TrackedProtocols: p, Origin: origin} - if v.Bidirectional { - backOrigin := origin - backOrigin.inverse = true - in := ir.Connection{Src: dst, Dst: src, TrackedProtocols: p, Origin: &backOrigin} - return []ir.Connection{out, in}, nil - } - return []ir.Connection{out}, nil -} - -func translateProtocols(protocols spec.ProtocolList) ([]ir.TrackedProtocol, error) { - var result = make([]ir.TrackedProtocol, len(protocols)) - for i, _p := range protocols { - result[i].Origin = protocolOrigin{protocolIndex: i} - switch p := _p.(type) { - case spec.AnyProtocol: - if len(protocols) != 1 { - log.Println("when allowing any protocol, there is no need in other protocols") - } - result[i].Protocol = netp.AnyProtocol{} - case spec.Icmp: - icmp, err := netp.ICMPFromTypeAndCode(p.Type, p.Code) +func replaceSegmentNames(segments map[ir.ID]*ir.SegmentDetails, distinctNames map[string]ir.ID, ambiguousNames map[string]struct{}, + resourceType spec.ResourceType) (map[ir.ID]*ir.SegmentDetails, error) { + for i, segmentDetails := range segments { + for j, el := range segmentDetails.Elements { + fullName, err := replaceResourceName(distinctNames, ambiguousNames, el, resourceType) if err != nil { return nil, err } - result[i].Protocol = icmp - case spec.TcpUdp: - tcpudp, err := netp.NewTCPUDP(p.Protocol == spec.TcpUdpProtocolTCP, p.MinSourcePort, p.MaxSourcePort, - p.MinDestinationPort, p.MaxDestinationPort) - if err != nil { - return nil, err - } - result[i].Protocol = tcpudp - default: - return nil, fmt.Errorf("impossible protocol: %v", p) + segmentDetails.Elements[j] = fullName } + segments[i] = segmentDetails } - return result, nil + return segments, nil } -func translateResourceType(resourceType spec.ResourceType) (ir.ResourceType, error) { - switch resourceType { - case spec.ResourceTypeExternal: - return ir.ResourceTypeExternal, nil - case spec.ResourceTypeSegment: - return ir.ResourceTypeSegment, nil - case spec.ResourceTypeSubnet: - return ir.ResourceTypeSubnet, nil - case spec.ResourceTypeNif: - return ir.ResourceTypeNIF, nil - case spec.ResourceTypeInstance: - return ir.ResourceTypeInstance, nil - case spec.ResourceTypeVpe: - return ir.ResourceTypeVPE, nil - default: - return ir.ResourceTypeSubnet, fmt.Errorf("unsupported resource type %v", resourceType) +func replaceResourceName(distinctNames map[string]ir.ID, ambiguousNames map[string]struct{}, resourceName string, + resourceType spec.ResourceType) (string, error) { + if len(ir.ScopingComponents(resourceName)) != 1 { + return resourceName, nil + } + if val, ok := distinctNames[resourceName]; ok { + return val, nil } + if _, ok := ambiguousNames[resourceName]; ok { + return "", fmt.Errorf("ambiguous resource name: %s", resourceName) + } + return "", fmt.Errorf("unknown resource name %s (resource type: %q)", resourceName, resourceType) +} + +// inverseMapToFullyQualifiedName returns two maps: one from a name to a fully qualified name, +// and the second is a set of ambiguous names +func inverseMapToFullyQualifiedName[T ir.Named](m map[ir.ID]T) (distinctNames map[string]ir.ID, ambiguousNames map[string]struct{}) { + ambiguousNames = make(map[string]struct{}) + distinctNames = make(map[string]ir.ID) + + for fullNifName, nif := range m { + nifName := nif.Name() + if _, ok := ambiguousNames[nifName]; ok { + continue + } + if _, ok := distinctNames[nifName]; !ok { + distinctNames[nifName] = fullNifName + } else { + delete(distinctNames, nifName) + ambiguousNames[nifName] = struct{}{} + } + } + return distinctNames, ambiguousNames } // unmarshal returns a Spec struct given a file adhering to spec_schema.input @@ -351,46 +211,3 @@ func unmarshal(filename string) (*spec.Spec, error) { } return jsonSpec, err } - -func parseOverlappingVpcs(cidr *netset.IPBlock, vpcs map[ir.ID]*ir.VPCDetails) []ir.ID { - result := make([]ir.ID, 0) - for vpcName, vpcDetails := range vpcs { - if vpcDetails.AddressPrefixes.Overlap(cidr) { - result = append(result, vpcName) - } - } - return result -} - -func replaceResourceName(cache map[string]ir.ID, ambiguous map[string]struct{}, resourceName string, - resourceType spec.ResourceType) (string, error) { - if len(ir.ScopingComponents(resourceName)) != 1 { - return resourceName, nil - } - if val, ok := cache[resourceName]; ok { - return val, nil - } - if _, ok := ambiguous[resourceName]; ok { - return "", fmt.Errorf("ambiguous resource name: %s", resourceName) - } - return "", fmt.Errorf("unknown resource name %s (resource type: %q)", resourceName, resourceType) -} - -func inverseMapToFullyQualifiedName[T ir.Named](m map[ir.ID]T) (cache map[string]ir.ID, ambiguous map[string]struct{}) { - ambiguous = make(map[string]struct{}) - cache = make(map[string]ir.ID) - - for fullNifName, nif := range m { - nifName := nif.Name() - if _, ok := ambiguous[nifName]; ok { - continue - } - if _, ok := cache[nifName]; !ok { - cache[nifName] = fullNifName - } else { - delete(cache, nifName) - ambiguous[nifName] = struct{}{} - } - } - return cache, ambiguous -} diff --git a/pkg/io/jsonio/unmarshalConn.go b/pkg/io/jsonio/unmarshalConn.go new file mode 100644 index 00000000..695e1c79 --- /dev/null +++ b/pkg/io/jsonio/unmarshalConn.go @@ -0,0 +1,132 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +// Package jsonio handles global specification written in a JSON file, as described by spec_schema.input +package jsonio + +import ( + "errors" + "fmt" + "log" + + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/spec" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +// transalteConnections translate requires connections from spec.Spec to []*ir.Connection +func (r *Reader) transalteConnections(conns []spec.SpecRequiredConnectionsElem, defs *ir.Definitions, isSG bool) ([]*ir.Connection, error) { + var connections []*ir.Connection + for i := range conns { + conns, err := translateConnection(defs, &conns[i], i, isSG) + if err != nil { + return nil, err + } + connections = append(connections, conns...) + } + return connections, nil +} + +func translateConnection(defs *ir.Definitions, conn *spec.SpecRequiredConnectionsElem, connIdx int, isSG bool) ([]*ir.Connection, error) { + protocols, err1 := translateProtocols(conn.AllowedProtocols) + srcResource, isSrcExternal, err2 := transalteConnectionResource(defs, &conn.Src, isSG) + dstResource, isDstExternal, err3 := transalteConnectionResource(defs, &conn.Src, isSG) + if err := errors.Join(err1, err2, err3); err != nil { + return nil, err + } + if isSrcExternal && isDstExternal { + return nil, fmt.Errorf("both source (%s) and destination (%s) are external in required connection", conn.Src.Name, conn.Dst.Name) + } + + origin := connectionOrigin{ + connectionIndex: connIdx, + srcName: resourceName(conn.Src), + dstName: resourceName(conn.Dst), + } + out := &ir.Connection{Src: srcResource, Dst: dstResource, TrackedProtocols: protocols, Origin: origin} + if conn.Bidirectional { + backOrigin := origin + backOrigin.inverse = true + in := &ir.Connection{Src: dstResource, Dst: srcResource, TrackedProtocols: protocols, Origin: &backOrigin} + return []*ir.Connection{out, in}, nil + } + return []*ir.Connection{out}, nil +} + +func transalteConnectionResource(defs *ir.Definitions, resource *spec.Resource, isSG bool) (r *ir.Resource, isExternal bool, err error) { + resourceType, err := translateResourceType(defs, resource) + if err != nil { + return nil, false, err + } + var res *ir.Resource + if isSG { + res, err = defs.LookupSG(resourceType, resource.Name) + } else { + res, err = defs.LookupACL(resourceType, resource.Name) + } + return res, resourceType == ir.ResourceTypeExternal, err +} + +func translateProtocols(protocols spec.ProtocolList) ([]*ir.TrackedProtocol, error) { + var result = make([]*ir.TrackedProtocol, len(protocols)) + for i, _p := range protocols { + result[i].Origin = protocolOrigin{protocolIndex: i} + switch p := _p.(type) { + case spec.AnyProtocol: + if len(protocols) != 1 { + log.Println("when allowing any protocol, there is no need in other protocols") + } + result[i].Protocol = netp.AnyProtocol{} + case spec.Icmp: + icmp, err := netp.ICMPFromTypeAndCode(p.Type, p.Code) + if err != nil { + return nil, err + } + result[i].Protocol = icmp + case spec.TcpUdp: + tcpudp, err := netp.NewTCPUDP(p.Protocol == spec.TcpUdpProtocolTCP, p.MinSourcePort, p.MaxSourcePort, + p.MinDestinationPort, p.MaxDestinationPort) + if err != nil { + return nil, err + } + result[i].Protocol = tcpudp + default: + return nil, fmt.Errorf("impossible protocol: %v", p) + } + } + return result, nil +} + +func translateResourceType(defs *ir.Definitions, resource *spec.Resource) (ir.ResourceType, error) { + switch resource.Type { + case spec.ResourceTypeExternal: + return ir.ResourceTypeExternal, nil + case spec.ResourceTypeSubnet: + return ir.ResourceTypeSubnet, nil + case spec.ResourceTypeNif: + return ir.ResourceTypeNIF, nil + case spec.ResourceTypeInstance: + return ir.ResourceTypeInstance, nil + case spec.ResourceTypeVpe: + return ir.ResourceTypeVPE, nil + case spec.ResourceTypeSegment: + if _, ok := defs.SubnetSegments[resource.Name]; ok { + return ir.ResourceTypeSubnetSegment, nil + } + if _, ok := defs.CidrSegments[resource.Name]; ok { + return ir.ResourceTypeCidrSegment, nil + } + if _, ok := defs.NifSegments[resource.Name]; ok { + return ir.ResourceTypeNifSegment, nil + } + if _, ok := defs.InstanceSegments[resource.Name]; ok { + return ir.ResourceTypeInstanceSegment, nil + } + if _, ok := defs.VpeSegments[resource.Name]; ok { + return ir.ResourceTypeVpeSegment, nil + } + } + return ir.ResourceTypeSubnet, fmt.Errorf("unsupported resource type %v (%v)", resource.Type, resource.Name) +} diff --git a/pkg/io/jsonio/unmarshalDefinitions.go b/pkg/io/jsonio/unmarshalDefinitions.go new file mode 100644 index 00000000..45d8b990 --- /dev/null +++ b/pkg/io/jsonio/unmarshalDefinitions.go @@ -0,0 +1,137 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +// Package jsonio handles global specification written in a JSON file, as described by spec_schema.input +package jsonio + +import ( + "fmt" + "slices" + + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/models/pkg/spec" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +type segmentsTypes struct { + subnetSegment map[string][]string + cidrSegment map[string][]string + nifSegment map[string][]string + instanceSegment map[string][]string + vpeSegment map[string][]string +} + +// ReadDefinitions translates segments and externals +func (r *Reader) readDefinitions(jsonSpec *spec.Spec, configDefs *ir.ConfigDefs) (*ir.Definitions, error) { + if err := validateSegments(&jsonSpec.Segments); err != nil { + return nil, err + } + segments := divideSegmentsByType(&jsonSpec.Segments) + subnetSegments := parseSegments(segments.subnetSegment, spec.SegmentTypeSubnet) + nifSegments := parseSegments(segments.nifSegment, spec.SegmentTypeNif) + instanceSegments := parseSegments(segments.instanceSegment, spec.SegmentTypeInstance) + vpeSegments := parseSegments(segments.vpeSegment, spec.SegmentTypeVpe) + cidrSegments, err := parseCidrSegments(segments.cidrSegment, configDefs) + if err != nil { + return nil, err + } + externals, err := translateExternals(jsonSpec.Externals) + if err != nil { + return nil, err + } + return &ir.Definitions{ + ConfigDefs: *configDefs, + SubnetSegments: subnetSegments, + CidrSegments: cidrSegments, + NifSegments: nifSegments, + InstanceSegments: instanceSegments, + VpeSegments: vpeSegments, + Externals: externals, + }, nil +} + +// validateSegments validates that all segments are supported +func validateSegments(jsonSegments *spec.SpecSegments) error { + for _, v := range *jsonSegments { + if v.Type != spec.SegmentTypeSubnet && v.Type != spec.SegmentTypeCidr && + v.Type != spec.SegmentTypeInstance && v.Type != spec.SegmentTypeNif && + v.Type != spec.SegmentTypeVpe { + return fmt.Errorf("only subnet, cidr, instance, nif and vpe segments are supported, not %q", v.Type) + } + } + return nil +} + +// translates segment to ir ds +func parseSegments(segments map[string][]string, segmentType spec.SegmentType) map[ir.ID]*ir.SegmentDetails { + result := make(map[string]*ir.SegmentDetails) + for segmentName, elements := range segments { + result[segmentName] = &ir.SegmentDetails{Elements: elements} + } + return result +} + +// parseCidrSegments translates cidr segments +func parseCidrSegments(cidrSegments map[string][]string, configDefs *ir.ConfigDefs) (map[ir.ID]*ir.CidrSegmentDetails, error) { + result := make(map[ir.ID]*ir.CidrSegmentDetails) + for segmentName, segment := range cidrSegments { + cidrs := netset.NewIPBlock() + containedSubnets := make([]ir.ID, 0) + + for _, cidr := range segment { + c, err := netset.IPBlockFromCidr(cidr) + if err != nil { + return nil, err + } + subnets, err := configDefs.SubnetsContainedInCidr(c) + if err != nil { + return nil, err + } + + cidrs = cidrs.Union(c) + containedSubnets = append(containedSubnets, subnets...) + } + cidrSegmentDetails := ir.CidrSegmentDetails{ + Cidrs: cidrs, + ContainedSubnets: slices.Compact(slices.Sorted(slices.Values(containedSubnets))), + } + result[segmentName] = &cidrSegmentDetails + } + return result, nil +} + +// translateExternals reads externals from spec file +func translateExternals(m map[string]string) (map[ir.ID]*ir.ExternalDetails, error) { + result := make(map[ir.ID]*ir.ExternalDetails) + for k, v := range m { + address, err := netset.IPBlockFromCidrOrAddress(v) + if err != nil { + return nil, err + } + result[k] = &ir.ExternalDetails{ExternalAddrs: address} + } + return result, nil +} + +func divideSegmentsByType(jsonSegments *spec.SpecSegments) segmentsTypes { + res := segmentsTypes{subnetSegment: make(map[string][]string), nifSegment: make(map[string][]string), + instanceSegment: make(map[string][]string), vpeSegment: make(map[string][]string), + cidrSegment: make(map[string][]string)} + for k, v := range *jsonSegments { + switch v.Type { + case spec.SegmentTypeSubnet: + res.subnetSegment[k] = v.Items + case spec.SegmentTypeCidr: + res.cidrSegment[k] = v.Items + case spec.SegmentTypeInstance: + res.instanceSegment[k] = v.Items + case spec.SegmentTypeNif: + res.nifSegment[k] = v.Items + case spec.SegmentTypeVpe: + res.vpeSegment[k] = v.Items + } + } + return res +} diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index aa262729..8b1e51e8 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -13,28 +13,30 @@ import ( "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) type ( - ID = string - NamedEntity string + ID = string + NamedEntity string + ResourceType string Spec struct { // Required connections - Connections []Connection + Connections []*Connection - Defs Definitions + Defs *Definitions } Connection struct { // Egress resource - Src Resource + Src *Resource // Ingress resource - Dst Resource + Dst *Resource // Allowed protocols - TrackedProtocols []TrackedProtocol + TrackedProtocols []*TrackedProtocol // Provenance information Origin fmt.Stringer @@ -42,13 +44,21 @@ type ( Resource struct { // Symbolic name of resource, if available - Name string + Name *string // list of CIDR / Ip addresses. - IPAddrs []*netset.IPBlock + NamedAddrs []*NamedAddrs + + // Cidr list (in case of CIDR segment) + Cidrs []*NamedAddrs // Type of resource - Type ResourceType + Type *ResourceType + } + + NamedAddrs struct { + IPAddrs *netset.IPBlock + Name *string } TrackedProtocol struct { @@ -74,13 +84,18 @@ type ( // Definitions adds to ConfigDefs the spec-specific definitions Definitions struct { ConfigDefs - // Segments are a way for users to create aggregations. - SubnetSegments map[ID]*SubnetSegmentDetails - // Cidr segment might contain some cidrs + SubnetSegments map[ID]*SegmentDetails + CidrSegments map[ID]*CidrSegmentDetails + NifSegments map[ID]*SegmentDetails + + InstanceSegments map[ID]*SegmentDetails + + VpeSegments map[ID]*SegmentDetails + // Externals are a way for users to name IP addresses or ranges external to the VPC. Externals map[ID]*ExternalDetails } @@ -125,21 +140,23 @@ type ( VPC ID } - SubnetSegmentDetails struct { - Subnets []ID - OverlappingVPCs []ID + SegmentDetails struct { + Elements []ID } CidrSegmentDetails struct { Cidrs *netset.IPBlock ContainedSubnets []ID - OverlappingVPCs []ID } ExternalDetails struct { ExternalAddrs *netset.IPBlock } + Reader interface { + ReadSpec(filename string, defs *ConfigDefs) (*Spec, error) + } + Named interface { Name() string } @@ -149,6 +166,23 @@ type ( } ) +const ( + ResourceTypeExternal ResourceType = "external" + ResourceTypeCidr ResourceType = "cidr" + ResourceTypeSubnet ResourceType = "subnet" + ResourceTypeNIF ResourceType = "nif" + ResourceTypeVPE ResourceType = "vpe" + ResourceTypeInstance ResourceType = "instance" + ResourceTypeSubnetSegment ResourceType = "subnetSegment" + ResourceTypeCidrSegment ResourceType = "cidrSegment" + ResourceTypeNifSegment ResourceType = "nifSegment" + ResourceTypeInstanceSegment ResourceType = "instanceSegment" + ResourceTypeVpeSegment ResourceType = "vpeSegment" + + resourceNotFound = "%v %v not found" + containerNotFound = "container %v %v not found" +) + func (n *NamedEntity) Name() string { return string(*n) } @@ -169,24 +203,63 @@ func (e *ExternalDetails) Address() *netset.IPBlock { return e.ExternalAddrs } -type ResourceType string +func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*Resource, error) { + if details, ok := m[name]; ok { + return &Resource{ + Name: &name, + NamedAddrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, + Cidrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, + Type: utils.Ptr(ResourceTypeSubnet), + }, nil + } + return nil, fmt.Errorf(resourceNotFound, name, t) +} -const ( - ResourceTypeExternal ResourceType = "external" - ResourceTypeSegment ResourceType = "segment" - ResourceTypeCidr ResourceType = "cidr" - ResourceTypeSubnet ResourceType = "subnet" - ResourceTypeNIF ResourceType = "nif" - ResourceTypeVPE ResourceType = "vpe" - ResourceTypeInstance ResourceType = "instance" - ResourceTypeAny ResourceType = "any" -) +func (s *Definitions) lookupNifACL(name string) (*Resource, error) { + if nifDetails, ok := s.NIFs[name]; ok { + + } + return nil, fmt.Errorf(resourceNotFound, name, ResourceTypeNIF) +} + +func (s *Definitions) lookupSubnetSegmentACL(name string) (*Resource, error) { + if segmentDetails, ok := s.SubnetSegments[name]; ok { + res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + for _, subnetName := range segmentDetails.Elements { + subnet, err := lookupSingle(s.Subnets, subnetName, ResourceTypeSubnet) + if err != nil { + return nil, fmt.Errorf("%w while looking up %v %v for subnet segment %v", err, ResourceTypeSubnet, subnetName, name) + } + res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) + res.Cidrs = append(res.Cidrs, subnet.Cidrs...) + } + return res, nil + } + return nil, fmt.Errorf(containerNotFound, name, ResourceTypeSubnetSegment) +} + +func (s *Definitions) lookupCidrSegmentACL(name string) (*Resource, error) { + if segmentDetails, ok := s.CidrSegments[name]; ok { + res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + for _, subnetName := range segmentDetails.ContainedSubnets { + subnet, err := lookupSingle(s.Subnets, subnetName, ResourceTypeSubnet) + if err != nil { + return nil, fmt.Errorf("%w while looking up %v %v for cidr segment %v", err, ResourceTypeSubnet, subnetName, name) + } + res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) + } + for _, cidr := range segmentDetails.Cidrs.SplitToCidrs() { + res.Cidrs = append(res.Cidrs, &NamedAddrs{Name: &name, IPAddrs: cidr}) + } + return res, nil + } + return nil, fmt.Errorf(containerNotFound, name, ResourceTypeSubnet) +} + +func (s *Definitions) lookupInstanceACL(name string) (*Resource, error) { + if instnaceDetails, ok := s.Instances[name]; ok { -func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (Resource, error) { - if details, ok := m[name]; ok { - return Resource{name, []*netset.IPBlock{details.Address()}, t}, nil } - return Resource{}, resourceNotFoundError(name, t) } func (s *Definitions) lookupInstance(name string) (Resource, error) { @@ -217,79 +290,62 @@ func (s *Definitions) lookupVPE(name string) (Resource, error) { return Resource{name, ips, ResourceTypeVPE}, nil } -func (s *Definitions) lookupSubnetSegment(name string) (Resource, error) { - if subnetSegmentDetails, ok := s.SubnetSegments[name]; ok { - cidrs := make([]*netset.IPBlock, len(subnetSegmentDetails.Subnets)) - for i, subnetName := range subnetSegmentDetails.Subnets { - subnet, err := s.Lookup(ResourceTypeSubnet, subnetName) - if err != nil { - return Resource{}, fmt.Errorf("%w while looking up %v %v for subnet %v", err, ResourceTypeSubnet, subnetName, name) - } - // each subnet has only one CIDR block. - cidrs[i] = subnet.IPAddrs[0] - } - return Resource{name, cidrs, ResourceTypeSubnet}, nil - } - return Resource{}, containerNotFoundError(name, ResourceTypeSegment) -} - -func (s *Definitions) lookupCidrSegment(name string) (Resource, error) { - cidrSegmentDetails, ok := s.CidrSegments[name] - if !ok { - return Resource{}, containerNotFoundError(name, ResourceTypeSegment) - } - return Resource{name, cidrSegmentDetails.Cidrs.SplitToCidrs(), ResourceTypeCidr}, nil -} - -func (s *Definitions) Lookup(t ResourceType, name string) (Resource, error) { - err := fmt.Errorf("invalid type %v (resource %v)", t, name) +func (s *Definitions) LookupACL(t ResourceType, name string) (*Resource, error) { switch t { case ResourceTypeExternal: return lookupSingle(s.Externals, name, t) case ResourceTypeSubnet: return lookupSingle(s.Subnets, name, t) - case ResourceTypeCidr: - return lookupSingle(s.Subnets, name, t) case ResourceTypeNIF: - return lookupSingle(s.NIFs, name, t) - case ResourceTypeVPE: - return s.lookupVPE(name) + return s.lookupNifACL(s.NIFs, name, t) case ResourceTypeInstance: - return s.lookupInstance(name) - case ResourceTypeSegment: - if _, ok := s.SubnetSegments[name]; ok { // subnet segment - return s.lookupSubnetSegment(name) - } else if _, ok := s.CidrSegments[name]; ok { // cidr segment - return s.lookupCidrSegment(name) - } else { - return Resource{}, err - } - default: - return Resource{}, err + return s.lookupInstanceACL(name) + case ResourceTypeVPE: + return s.lookupVpeACL(name) + case ResourceTypeSubnetSegment: + return s.lookupSubnetSegmentACL(name) + case ResourceTypeCidrSegment: + return s.lookupCidrSegmentACL(name) + case ResourceTypeNifSegment: + return s.lookupNifSegmentACL(name) + case ResourceTypeInstanceSegment: + return s.lookupInstanceSegmentACL(name) + case ResourceTypeVpeSegment: + return s.lookupVpeSegmentACL(name) } + return nil, nil // should not get here } -func inverseLookup[T NWResource](m map[ID]T, address *netset.IPBlock) (result string, ok bool) { - for name, details := range m { - if details.Address().Equal(address) { - return name, true - } +func (s *Definitions) LookupSG(t ResourceType, name string) (*Resource, error) { + switch t { + case ResourceTypeExternal: + return lookupSingle(s.Externals, name, t) + case ResourceTypeSubnet: + return lookupSubnetSG(s.Subnets, name, t) + case ResourceTypeNIF: + return s.lookupNifSG(s.NIFs, name, t) + case ResourceTypeInstance: + return s.lookupInstanceSG(name) + case ResourceTypeVPE: + return s.lookupVpeSG(name) + case ResourceTypeSubnetSegment: + return s.lookupSubnetSegmentSG(name) + case ResourceTypeCidrSegment: + return s.lookupCidrSegmentSG(name) + case ResourceTypeNifSegment: + return s.lookupNifSegmentSG(name) + case ResourceTypeInstanceSegment: + return s.lookupInstanceSegmentSG(name) + case ResourceTypeVpeSegment: + return s.lookupVpeSegmentSG(name) } - return "", false + return nil, nil // should not get here } -func (s *ConfigDefs) NIFFromIP(ip *netset.IPBlock) (string, bool) { - return inverseLookup(s.NIFs, ip) -} - -type Reader interface { - ReadSpec(filename string, defs *ConfigDefs) (*Spec, error) -} - -func (s *ConfigDefs) SubnetsContainedInCidr(cidr netset.IPBlock) ([]ID, error) { +func (s *ConfigDefs) SubnetsContainedInCidr(cidr *netset.IPBlock) ([]ID, error) { var containedSubnets []string for subnet, subnetDetails := range s.Subnets { - if subnetDetails.CIDR.IsSubset(&cidr) { + if subnetDetails.CIDR.IsSubset(cidr) { containedSubnets = append(containedSubnets, subnet) } } @@ -297,28 +353,6 @@ func (s *ConfigDefs) SubnetsContainedInCidr(cidr netset.IPBlock) ([]ID, error) { return containedSubnets, nil } -func resourceNotFoundError(name string, resource ResourceType) error { - return fmt.Errorf("%v %v not found", resource, name) -} - -func containerNotFoundError(name string, resource ResourceType) error { - return fmt.Errorf("container %v %v not found", resource, name) -} - -func UniqueIDValues(s []ID) []ID { - result := make([]ID, 0) - seenValues := make(map[ID]struct{}) - - for _, item := range s { - if _, seen := seenValues[item]; !seen { - seenValues[item] = struct{}{} - result = append(result, item) - } - } - - return result -} - func ScopingComponents(s string) []string { return strings.Split(s, "/") } diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index 044d72ce..7fc86560 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -27,96 +27,76 @@ func NewACLSynthesizer(s *ir.Spec, single bool) Synthesizer { return &ACLSynthesizer{spec: s, singleACL: single, result: ir.NewACLCollection()} } -func (a *ACLSynthesizer) Synth() (ir.Collection, error) { +func (a *ACLSynthesizer) Synth() ir.Collection { return a.makeACL() } // makeACL translates Spec to a collection of nACLs // 1. generate nACL rules for relevant subnets for each connection // 2. generate nACL rules for blocked subnets (subnets that do not appear in Spec) -func (a *ACLSynthesizer) makeACL() (*ir.ACLCollection, error) { +func (a *ACLSynthesizer) makeACL() *ir.ACLCollection { for c := range a.spec.Connections { - err := a.generateACLRulesFromConnection(&a.spec.Connections[c]) - if err != nil { - return nil, err - } + a.generateACLRulesFromConnection(a.spec.Connections[c]) } a.generateACLRulesForBlockedSubnets() - return a.result, nil + return a.result } -// 1. check that both resources are supported in nACL generation. -// 2. check that at least one resource is internal. -// 3. convert src and dst resources to namedAddrs slices to make it more convenient to go through the addrs -// and add the rule to the relevant acl. Note: in case where the resource in a nif, src/dst will be -// updated to be its subnet. -// 4. generate rules and add them to relevant ACL to allow traffic for all pairs of IPAddrs of both resources. -func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection) error { - if !resourceRelevantToACL(conn.Src.Type) { - return fmt.Errorf(ACLTypeNotSupported, string(conn.Src.Type)) - } - if !resourceRelevantToACL(conn.Dst.Type) { - return fmt.Errorf(ACLTypeNotSupported, string(conn.Dst.Type)) +func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection) { + for _, srcSubnet := range conn.Src.NamedAddrs { + for _, dstCidr := range conn.Dst.Cidrs { + if srcSubnet.IPAddrs.Equal(dstCidr.IPAddrs) && *conn.Src.Type != ir.ResourceTypeCidr && *conn.Dst.Type != ir.ResourceTypeCidr { + continue + } + for _, trackedProtocol := range conn.TrackedProtocols { + a.allowConnectionFromSrc(conn, trackedProtocol, srcSubnet, dstCidr.IPAddrs) + } + } } - for _, src := range conn.Src.IPAddrs { - srcSubnets, srcCidr := adjustResource(&a.spec.Defs, src, conn.Src) - for _, dst := range conn.Dst.IPAddrs { - dstSubnets, dstCidr := adjustResource(&a.spec.Defs, dst, conn.Dst) - if src == dst && conn.Src.Type != ir.ResourceTypeCidr && conn.Dst.Type != ir.ResourceTypeCidr { + + for _, srcCidr := range conn.Src.Cidrs { + for _, dstSubnet := range conn.Dst.NamedAddrs { + if dstSubnet.IPAddrs.Equal(srcCidr.IPAddrs) && *conn.Src.Type != ir.ResourceTypeCidr && *conn.Dst.Type != ir.ResourceTypeCidr { continue } for _, trackedProtocol := range conn.TrackedProtocols { - a.allowConnectionFromSrc(conn, trackedProtocol, srcSubnets, dstCidr) - a.allowConnectionToDst(conn, trackedProtocol, dstSubnets, srcCidr) + a.allowConnectionToDst(conn, trackedProtocol, dstSubnet, srcCidr.IPAddrs) } } } - return nil } // if the src in internal, rule(s) will be created to allow traffic. // if the protocol allows response, more rules will be created. -func (a *ACLSynthesizer) allowConnectionFromSrc(conn *ir.Connection, trackedProtocol ir.TrackedProtocol, - srcSubnets []*namedAddrs, dstCidr *netset.IPBlock) { +func (a *ACLSynthesizer) allowConnectionFromSrc(conn *ir.Connection, p *ir.TrackedProtocol, srcSubnet *ir.NamedAddrs, dstCidr *netset.IPBlock) { internalSrc, _, internal := internalConn(conn) - if !internalSrc { + if !internalSrc || srcSubnet.IPAddrs.Equal(dstCidr) { return } - reason := explanation{internal: internal, connectionOrigin: conn.Origin, protocolOrigin: trackedProtocol.Origin} - for _, srcSubnet := range srcSubnets { - if srcSubnet.Addrs.Equal(dstCidr) { // srcSubnet and dstCidr are the same subnet - continue - } - request := &ir.Packet{Src: srcSubnet.Addrs, Dst: dstCidr, Protocol: trackedProtocol.Protocol, Explanation: reason.String()} - a.addRuleToACL(ir.AllowSend(request), srcSubnet, internal, a.singleACL) - if inverseProtocol := trackedProtocol.Protocol.InverseDirection(); inverseProtocol != nil { - response := &ir.Packet{Src: dstCidr, Dst: srcSubnet.Addrs, Protocol: inverseProtocol, Explanation: reason.response().String()} - a.addRuleToACL(ir.AllowReceive(response), srcSubnet, internal, a.singleACL) - } + reason := explanation{internal: internal, connectionOrigin: conn.Origin, protocolOrigin: p.Origin} + request := &ir.Packet{Src: srcSubnet.IPAddrs, Dst: dstCidr, Protocol: p.Protocol, Explanation: reason.String()} + a.addRuleToACL(ir.AllowSend(request), *srcSubnet.Name, internal, a.singleACL) + if inverseProtocol := p.Protocol.InverseDirection(); inverseProtocol != nil { + response := &ir.Packet{Src: dstCidr, Dst: srcSubnet.IPAddrs, Protocol: inverseProtocol, Explanation: reason.response().String()} + a.addRuleToACL(ir.AllowReceive(response), *srcSubnet.Name, internal, a.singleACL) } } // if the dst in internal, rule(s) will be created to allow traffic. // if the protocol allows response, more rules will be created. -func (a *ACLSynthesizer) allowConnectionToDst(conn *ir.Connection, trackedProtocol ir.TrackedProtocol, - dstSubnets []*namedAddrs, srcCidr *netset.IPBlock) { +func (a *ACLSynthesizer) allowConnectionToDst(conn *ir.Connection, p *ir.TrackedProtocol, dstSubnet *ir.NamedAddrs, srcCidr *netset.IPBlock) { _, internalDst, internal := internalConn(conn) - if !internalDst { + if !internalDst || dstSubnet.IPAddrs.Equal(srcCidr) { return } - reason := explanation{internal: internal, connectionOrigin: conn.Origin, protocolOrigin: trackedProtocol.Origin} - for _, dstSubnet := range dstSubnets { - if dstSubnet.Addrs.Equal(srcCidr) { // dstSubnet and srcCidr are the same subnet - continue - } - request := &ir.Packet{Src: srcCidr, Dst: dstSubnet.Addrs, Protocol: trackedProtocol.Protocol, Explanation: reason.String()} - a.addRuleToACL(ir.AllowReceive(request), dstSubnet, internal, a.singleACL) - if inverseProtocol := trackedProtocol.Protocol.InverseDirection(); inverseProtocol != nil { - response := &ir.Packet{Src: dstSubnet.Addrs, Dst: srcCidr, Protocol: inverseProtocol, Explanation: reason.response().String()} - a.addRuleToACL(ir.AllowSend(response), dstSubnet, internal, a.singleACL) - } + reason := explanation{internal: internal, connectionOrigin: conn.Origin, protocolOrigin: p.Origin} + request := &ir.Packet{Src: srcCidr, Dst: dstSubnet.IPAddrs, Protocol: p.Protocol, Explanation: reason.String()} + a.addRuleToACL(ir.AllowReceive(request), *dstSubnet.Name, internal, a.singleACL) + if inverseProtocol := p.Protocol.InverseDirection(); inverseProtocol != nil { + response := &ir.Packet{Src: dstSubnet.IPAddrs, Dst: srcCidr, Protocol: inverseProtocol, Explanation: reason.response().String()} + a.addRuleToACL(ir.AllowSend(response), *dstSubnet.Name, internal, a.singleACL) } } @@ -131,54 +111,6 @@ func (a *ACLSynthesizer) generateACLRulesForBlockedSubnets() { } } -// convert src and dst resources to namedAddrs slices to make it more convenient to go through the addrs and add -// the rule to the relevant acl. Note: in case where the resource in a nif, src/dst will be updated to be its subnet. -func adjustResource(s *ir.Definitions, addrs *netset.IPBlock, resource ir.Resource) ([]*namedAddrs, *netset.IPBlock) { - switch resource.Type { - case ir.ResourceTypeSubnet: - return adjustSubnet(s, addrs, resource.Name), addrs - case ir.ResourceTypeExternal: - return []*namedAddrs{{Name: resource.Name, Addrs: addrs}}, addrs - case ir.ResourceTypeNIF: - result := expandNifToSubnet(s, addrs) - return result, result[0].Addrs // return nif's subnet, not its IP address - case ir.ResourceTypeCidr: - return adjustCidrSegment(s, resource.Name), addrs - } - return []*namedAddrs{}, nil // shouldn't happen -} - -func adjustSubnet(s *ir.Definitions, addrs *netset.IPBlock, resourceName string) []*namedAddrs { - // Todo: Handle the case where there is a subnet and a subnetSegment with the same name - if subnetDetails, ok := s.Subnets[resourceName]; ok { // resource is a subnet - return []*namedAddrs{{Name: resourceName, Addrs: subnetDetails.Address()}} - } - // resource is a subnet segment - for _, subnetName := range s.SubnetSegments[resourceName].Subnets { - if s.Subnets[subnetName].Address().Equal(addrs) { - return []*namedAddrs{{Name: subnetName, Addrs: s.Subnets[subnetName].Address()}} - } - } - return []*namedAddrs{} // shouldn't happen -} - -func adjustCidrSegment(s *ir.Definitions, resourceName string) []*namedAddrs { - cidrSegmentDetails := s.CidrSegments[resourceName] - result := make([]*namedAddrs, len(cidrSegmentDetails.ContainedSubnets)) - for i, subnet := range cidrSegmentDetails.ContainedSubnets { - result[i] = &namedAddrs{Name: subnet, Addrs: s.Subnets[subnet].Address()} - } - return result -} - -func expandNifToSubnet(s *ir.Definitions, addr *netset.IPBlock) []*namedAddrs { - nifName, _ := s.NIFFromIP(addr) // already checked before (Lookup function) that the NIF exists - subnetName := s.NIFs[nifName].Subnet - subnetCidr := s.Subnets[subnetName].Address() - - return []*namedAddrs{{Name: subnetName, Addrs: subnetCidr}} -} - func aclSelector(subnetName ir.ID, single bool) string { if single { return fmt.Sprintf("%s/singleACL", ir.VpcFromScopedResource(subnetName)) @@ -186,12 +118,8 @@ func aclSelector(subnetName ir.ID, single bool) string { return subnetName } -func resourceRelevantToACL(e ir.ResourceType) bool { - return e == ir.ResourceTypeSubnet || e == ir.ResourceTypeCidr || e == ir.ResourceTypeNIF || e == ir.ResourceTypeExternal -} - -func (a *ACLSynthesizer) addRuleToACL(rule *ir.ACLRule, resource *namedAddrs, internal, single bool) { - acl := a.result.LookupOrCreate(aclSelector(resource.Name, single)) +func (a *ACLSynthesizer) addRuleToACL(rule *ir.ACLRule, resourceName ir.ID, internal, single bool) { + acl := a.result.LookupOrCreate(aclSelector(resourceName, single)) if internal { acl.AppendInternal(rule) } else { diff --git a/pkg/synth/common.go b/pkg/synth/common.go index e6e516f3..92d52d8f 100644 --- a/pkg/synth/common.go +++ b/pkg/synth/common.go @@ -8,19 +8,12 @@ package synth import ( "fmt" - "github.com/np-guard/models/pkg/netset" - "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) type ( Synthesizer interface { - Synth() (ir.Collection, error) - } - - namedAddrs struct { - Name ir.ID - Addrs *netset.IPBlock + Synth() ir.Collection } explanation struct { @@ -50,8 +43,8 @@ func (e explanation) String() string { } func internalConn(conn *ir.Connection) (internalSrc, internalDst, internal bool) { - internalSrc = conn.Src.Type != ir.ResourceTypeExternal - internalDst = conn.Dst.Type != ir.ResourceTypeExternal + internalSrc = *conn.Src.Type != ir.ResourceTypeExternal + internalDst = *conn.Dst.Type != ir.ResourceTypeExternal internal = internalSrc && internalDst return } diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index c90b1783..b9f4717e 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -6,8 +6,6 @@ SPDX-License-Identifier: Apache-2.0 package synth import ( - "fmt" - "github.com/np-guard/models/pkg/netp" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" @@ -20,27 +18,24 @@ type SGSynthesizer struct { result *ir.SGCollection } -// NewSGSynthesizer creates and returns a new SGSynthesizer instance +// NewSGSynthesizer creates and returns a new SGSynthesizer instances func NewSGSynthesizer(s *ir.Spec, _ bool) Synthesizer { return &SGSynthesizer{spec: s, result: ir.NewSGCollection()} } -func (s *SGSynthesizer) Synth() (ir.Collection, error) { +func (s *SGSynthesizer) Synth() ir.Collection { return s.makeSG() } // this method translates spec to a collection of Security Groups // 1. generate SGs for relevant endpoints for each connection // 2. generate SGs for blocked endpoints (endpoints that do not appear in Spec) -func (s *SGSynthesizer) makeSG() (*ir.SGCollection, error) { +func (s *SGSynthesizer) makeSG() *ir.SGCollection { for c := range s.spec.Connections { - err := s.generateSGRulesFromConnection(&s.spec.Connections[c]) - if err != nil { - return nil, err - } + s.generateSGRulesFromConnection(s.spec.Connections[c]) } s.generateSGsForBlockedResources() - return s.result, nil + return s.result } // 1. check that both resources are supported in SG generation. @@ -48,52 +43,66 @@ func (s *SGSynthesizer) makeSG() (*ir.SGCollection, error) { // 3. convert src and dst resources to namedAddrs slices to make it more convenient to go through the addrs // and add the rule to the relevant SG. // 4. generate rules and add them to relevant SG to allow traffic for all pairs of IPAddrs of both resources. -func (s *SGSynthesizer) generateSGRulesFromConnection(conn *ir.Connection) error { - if !resourceRelevantToSG(conn.Src.Type) { - return fmt.Errorf(SGTypeNotSupported, string(conn.Src.Type)) - } - if !resourceRelevantToSG(conn.Dst.Type) { - return fmt.Errorf(SGTypeNotSupported, string(conn.Dst.Type)) - } +func (s *SGSynthesizer) generateSGRulesFromConnection(conn *ir.Connection) { internalSrc, internalDst, internalConn := internalConn(conn) - srcEndpoints := updateEndpoints(&s.spec.Defs, conn.Src) - dstEndpoints := updateEndpoints(&s.spec.Defs, conn.Dst) + for _, srcEndpoint := range conn.Src.NamedAddrs { + for _, dstCidr := range conn.Dst.Cidrs { + if srcEndpoint.IPAddrs.Equal(dstCidr.IPAddrs) { + continue + } - for _, srcEndpoint := range srcEndpoints { - for _, dstEndpoint := range dstEndpoints { - if srcEndpoint.Addrs.Equal(dstEndpoint.Addrs) { + for _, trackedProtocol := range conn.TrackedProtocols { + ruleExplanation := explanation{internal: internalConn, connectionOrigin: conn.Origin, protocolOrigin: trackedProtocol.Origin}.String() + s.allowConnectionEndpoint(srcEndpoint, dstCidr, trackedProtocol.Protocol, ir.Outbound, internalSrc, ruleExplanation) + } + } + } + + for _, dstEndpoint := range conn.Dst.NamedAddrs { + for _, srcCidr := range conn.Src.Cidrs { + if dstEndpoint.IPAddrs.Equal(srcCidr.IPAddrs) { continue } for _, trackedProtocol := range conn.TrackedProtocols { ruleExplanation := explanation{internal: internalConn, connectionOrigin: conn.Origin, protocolOrigin: trackedProtocol.Origin}.String() - s.allowConnectionEndpoint(srcEndpoint, dstEndpoint, trackedProtocol.Protocol, ir.Outbound, internalSrc, ruleExplanation) - s.allowConnectionEndpoint(dstEndpoint, srcEndpoint, trackedProtocol.Protocol, ir.Inbound, internalDst, ruleExplanation) + s.allowConnectionEndpoint(dstEndpoint, srcCidr, trackedProtocol.Protocol, ir.Inbound, internalDst, ruleExplanation) } } } - return nil } // if the endpoint in internal, a rule will be created to allow traffic. -func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *namedAddrs, protocol netp.Protocol, - direction ir.Direction, internalEndpoint bool, ruleExplanation string) { +func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *ir.NamedAddrs, p netp.Protocol, direction ir.Direction, + internalEndpoint bool, ruleExplanation string) { if !internalEndpoint { return } - localSGName := ir.SGName(localEndpoint.Name) + localSGName := ir.SGName(*localEndpoint.Name) localSG := s.result.LookupOrCreate(localSGName) localSG.Attached = []ir.ID{ir.ID(localSGName)} rule := &ir.SGRule{ - Remote: sgRemote(&s.spec.Defs, remoteEndpoint), + Remote: sgRemote(s.spec.Defs, remoteEndpoint), Direction: direction, - Protocol: protocol, + Protocol: p, Explanation: ruleExplanation, } localSG.Add(rule) } +// what to do if its a cidr segment? +func sgRemote(s *ir.Definitions, resource *ir.NamedAddrs) ir.RemoteType { + if _, ok := s.Externals[*resource.Name]; ok { + return resource.IPAddrs + } + if _, ok := s.Subnets[*resource.Name]; ok { + return resource.IPAddrs + } + // what to do if its a cidr? + return ir.SGName(*resource.Name) +} + // generate SGs for blocked endpoints (endpoints that do not appear in Spec) func (s *SGSynthesizer) generateSGsForBlockedResources() { blockedResources := s.spec.ComputeBlockedResources() @@ -102,32 +111,3 @@ func (s *SGSynthesizer) generateSGsForBlockedResources() { sg.Attached = []ir.ID{resource} } } - -// convert src and dst resources to namedAddrs slices to make it more convenient to go through the addrs and add -// the rule to the relevant sg. -func updateEndpoints(s *ir.Definitions, resource ir.Resource) []*namedAddrs { - if resource.Type == ir.ResourceTypeExternal { - return []*namedAddrs{{Name: resource.Name, Addrs: resource.IPAddrs[0]}} - } - result := make([]*namedAddrs, len(resource.IPAddrs)) - for i, ip := range resource.IPAddrs { - name := resource.Name - // TODO: delete the following if statement when there will be a support in VSIs with multiple NIFs - if nifDetails, ok := s.NIFs[resource.Name]; ok { - name = nifDetails.Instance - } - result[i] = &namedAddrs{Name: name, Addrs: ip} - } - return result -} - -func sgRemote(s *ir.Definitions, resource *namedAddrs) ir.RemoteType { - if _, ok := s.Externals[resource.Name]; ok { - return resource.Addrs - } - return ir.SGName(resource.Name) -} - -func resourceRelevantToSG(e ir.ResourceType) bool { - return e == ir.ResourceTypeNIF || e == ir.ResourceTypeExternal || e == ir.ResourceTypeVPE -} diff --git a/test/error_test_list.go b/test/error_test_list.go index 72927b3f..edcd1ff8 100644 --- a/test/error_test_list.go +++ b/test/error_test_list.go @@ -140,17 +140,17 @@ func errorTestsList() []testCase { }, // vpe resource in ACL generation - { - testName: "vpe acl", - expectedErr: "ACL: src/dst of type vpe is not supported", - args: &command{ - cmd: synth, - subcmd: acl, - config: "%s/vpe_acl/config_object.json", - spec: "%s/vpe_acl/conn_spec.json", - outputFile: outputPath, - }, - }, + // { + // testName: "vpe acl", + // expectedErr: "ACL: src/dst of type vpe is not supported", + // args: &command{ + // cmd: synth, + // subcmd: acl, + // config: "%s/vpe_acl/config_object.json", + // spec: "%s/vpe_acl/conn_spec.json", + // outputFile: outputPath, + // }, + // }, // impossible resource type { From 38f9fa5364d3145cd13d4cfeaa6385386dbc3469 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Sun, 13 Oct 2024 18:42:46 +0300 Subject: [PATCH 071/131] lookup functions --- .../{unmarshalConn.go => unmarshalConns.go} | 4 +- pkg/io/jsonio/unmarshalDefinitions.go | 11 ++ pkg/ir/lookupForACLSynth.go | 110 ++++++++++++ pkg/ir/lookupForSGSynth.go | 145 +++++++++++++++ pkg/ir/spec.go | 170 +++++------------- pkg/synth/acl.go | 22 +-- pkg/synth/sg.go | 67 +++---- 7 files changed, 355 insertions(+), 174 deletions(-) rename pkg/io/jsonio/{unmarshalConn.go => unmarshalConns.go} (97%) create mode 100644 pkg/ir/lookupForACLSynth.go create mode 100644 pkg/ir/lookupForSGSynth.go diff --git a/pkg/io/jsonio/unmarshalConn.go b/pkg/io/jsonio/unmarshalConns.go similarity index 97% rename from pkg/io/jsonio/unmarshalConn.go rename to pkg/io/jsonio/unmarshalConns.go index 695e1c79..9ab62ec3 100644 --- a/pkg/io/jsonio/unmarshalConn.go +++ b/pkg/io/jsonio/unmarshalConns.go @@ -62,9 +62,9 @@ func transalteConnectionResource(defs *ir.Definitions, resource *spec.Resource, } var res *ir.Resource if isSG { - res, err = defs.LookupSG(resourceType, resource.Name) + res, err = defs.LookupForSGSynth(resourceType, resource.Name) } else { - res, err = defs.LookupACL(resourceType, resource.Name) + res, err = defs.LookupForACLSynth(resourceType, resource.Name) } return res, resourceType == ir.ResourceTypeExternal, err } diff --git a/pkg/io/jsonio/unmarshalDefinitions.go b/pkg/io/jsonio/unmarshalDefinitions.go index 45d8b990..ef6e7c63 100644 --- a/pkg/io/jsonio/unmarshalDefinitions.go +++ b/pkg/io/jsonio/unmarshalDefinitions.go @@ -93,6 +93,9 @@ func parseCidrSegments(cidrSegments map[string][]string, configDefs *ir.ConfigDe cidrs = cidrs.Union(c) containedSubnets = append(containedSubnets, subnets...) } + if !internalCidr(configDefs, cidrs) { + return nil, fmt.Errorf("only internal cidrs are supportd in cidr segment resource type (segment name: %v)", segmentName) + } cidrSegmentDetails := ir.CidrSegmentDetails{ Cidrs: cidrs, ContainedSubnets: slices.Compact(slices.Sorted(slices.Values(containedSubnets))), @@ -135,3 +138,11 @@ func divideSegmentsByType(jsonSegments *spec.SpecSegments) segmentsTypes { } return res } + +func internalCidr(configDefs *ir.ConfigDefs, cidr *netset.IPBlock) bool { + res := cidr + for _, vpcDetails := range configDefs.VPCs { + res = res.Subtract(vpcDetails.AddressPrefixes) + } + return res == netset.NewIPBlock() +} diff --git a/pkg/ir/lookupForACLSynth.go b/pkg/ir/lookupForACLSynth.go new file mode 100644 index 00000000..d218ae6c --- /dev/null +++ b/pkg/ir/lookupForACLSynth.go @@ -0,0 +1,110 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +// Package ir describes the input-format-agnostic specification of the required connectivity +package ir + +import ( + "fmt" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" +) + +func (s *Definitions) LookupForACLSynth(t ResourceType, name string) (*Resource, error) { + switch t { + case ResourceTypeExternal: + return lookupSingle(s.Externals, name, t) + case ResourceTypeSubnet: + return lookupSingle(s.Subnets, name, t) + case ResourceTypeNIF: + return lookupSingleForACLSynth(s.NIFs, s.Subnets, name, t) + case ResourceTypeInstance: + return lookupContainerForACLSynth(s.Instances, s, name, ResourceTypeInstance) + case ResourceTypeVPE: + return lookupContainerForACLSynth(s.VPEs, s, name, ResourceTypeVPE) + case ResourceTypeSubnetSegment: + return s.lookupSegmentForACLSynth(s.SubnetSegments, name, t, ResourceTypeSubnet) + case ResourceTypeCidrSegment: + return s.lookupCidrSegmentACL(name) + case ResourceTypeNifSegment: + return s.lookupSegmentForACLSynth(s.SubnetSegments, name, t, ResourceTypeNIF) + case ResourceTypeInstanceSegment: + return s.lookupSegmentForACLSynth(s.SubnetSegments, name, t, ResourceTypeInstance) + case ResourceTypeVpeSegment: + return s.lookupSegmentForACLSynth(s.SubnetSegments, name, t, ResourceTypeVPE) + } + return nil, nil // should not get here +} + +func lookupSingleForACLSynth[T InternalNWResource](m map[ID]T, subnets map[ID]*SubnetDetails, name string, t ResourceType) (*Resource, error) { + details, ok := m[name] + if !ok { + return nil, fmt.Errorf(resourceNotFound, name, t) + } + + res, err := lookupSingle(subnets, details.SubnetName(), ResourceTypeSubnet) + if err != nil { + return nil, err + } + res.Name = &name // save NIF's name as resource name + return res, nil +} + +func (s *Definitions) lookupSegmentForACLSynth(segment map[ID]*SegmentDetails, name string, t, elementType ResourceType) (*Resource, error) { + segmentDetails, ok := segment[name] + if !ok { + return nil, fmt.Errorf(containerNotFound, name, t) + } + + res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + for _, elementName := range segmentDetails.Elements { + subnet, err := s.LookupForACLSynth(elementType, elementName) + if err != nil { + return nil, err + } + res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) + res.Cidrs = append(res.Cidrs, subnet.Cidrs...) + } + return res, nil +} + +func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definitions, name string, t ResourceType) (*Resource, error) { + containerDetails, ok := m[name] + if !ok { + return nil, fmt.Errorf(containerNotFound, name, ResourceTypeInstance) + } + + res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + endpointMap := containerDetails.endpointMap(defs) + for _, endpointName := range containerDetails.endpointNames() { + subnet, err := lookupSingleForACLSynth(endpointMap, defs.Subnets, endpointName, containerDetails.endpointType()) + if err != nil { + return nil, err + } + res.Cidrs = append(res.Cidrs, subnet.Cidrs...) + res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) + } + return res, nil +} + +func (s *Definitions) lookupCidrSegmentACL(name string) (*Resource, error) { + segmentDetails, ok := s.CidrSegments[name] + if !ok { + return nil, fmt.Errorf(containerNotFound, name, ResourceTypeCidrSegment) + } + + res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + for _, subnetName := range segmentDetails.ContainedSubnets { + subnet, err := lookupSingle(s.Subnets, subnetName, ResourceTypeSubnet) + if err != nil { + return nil, fmt.Errorf("%w while looking up %v %v for cidr segment %v", err, ResourceTypeSubnet, subnetName, name) + } + res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) + } + for _, cidr := range segmentDetails.Cidrs.SplitToCidrs() { + res.Cidrs = append(res.Cidrs, &NamedAddrs{Name: &name, IPAddrs: cidr}) + } + return res, nil +} diff --git a/pkg/ir/lookupForSGSynth.go b/pkg/ir/lookupForSGSynth.go new file mode 100644 index 00000000..fc4db5d9 --- /dev/null +++ b/pkg/ir/lookupForSGSynth.go @@ -0,0 +1,145 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +// Package ir describes the input-format-agnostic specification of the required connectivity +package ir + +import ( + "fmt" + "slices" + + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" +) + +func (s *Definitions) LookupForSGSynth(t ResourceType, name string) (*Resource, error) { + switch t { + case ResourceTypeExternal: + return lookupSingle(s.Externals, name, t) + case ResourceTypeSubnet: + return s.lookupSubnetForSGSynth(name) + case ResourceTypeNIF: + return s.lookupNIFForSGSynth(name) + case ResourceTypeInstance: + return lookupContainerForSGSynth(s.Instances, name, ResourceTypeInstance) + case ResourceTypeVPE: + return lookupContainerForSGSynth(s.Instances, name, ResourceTypeVPE) + case ResourceTypeSubnetSegment: + return s.lookupSubnetSegmentForSGSynth(name) + case ResourceTypeCidrSegment: + return s.lookupCidrSegmentForSGSynth(name) + case ResourceTypeNifSegment: + return s.lookupSegmentForSGSynth(s.NifSegments, name, ResourceTypeNIF) + case ResourceTypeInstanceSegment: + return s.lookupSegmentForSGSynth(s.InstanceSegments, name, ResourceTypeInstance) + case ResourceTypeVpeSegment: + return s.lookupSegmentForSGSynth(s.VpeSegments, name, ResourceTypeVPE) + } + return nil, nil // should not get here +} + +func (s *Definitions) lookupNIFForSGSynth(name string) (*Resource, error) { + if _, ok := s.NIFs[name]; ok { + return &Resource{ + Name: &name, + NamedAddrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, + Cidrs: []*NamedAddrs{}, + Type: utils.Ptr(ResourceTypeNIF), + }, nil + } + return nil, fmt.Errorf(resourceNotFound, ResourceTypeNIF, name) +} + +func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, t ResourceType) (*Resource, error) { + if _, ok := m[name]; ok { + return &Resource{ + Name: &name, + NamedAddrs: []*NamedAddrs{{Name: &name}}, + Cidrs: []*NamedAddrs{}, + Type: utils.Ptr(t), + }, nil + } + return nil, fmt.Errorf(containerNotFound, t, name) +} + +func (s *Definitions) lookupSubnetForSGSynth(name string) (*Resource, error) { + if subnetDetails, ok := s.Subnets[name]; ok { + return &Resource{Name: &name, + NamedAddrs: s.containedResourcesInCidr(subnetDetails.CIDR), + Cidrs: []*NamedAddrs{{IPAddrs: subnetDetails.CIDR}}, + Type: utils.Ptr(ResourceTypeSubnet), + }, nil + } + return nil, fmt.Errorf(resourceNotFound, ResourceTypeSubnet, name) +} + +func (s *Definitions) lookupSubnetSegmentForSGSynth(name string) (*Resource, error) { + segmentDetails, ok := s.SubnetSegments[name] + if !ok { + return nil, fmt.Errorf(containerNotFound, ResourceTypeSubnetSegment, name) + } + + res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + for _, subnetName := range segmentDetails.Elements { + subnetRes, err := s.lookupSubnetForSGSynth(subnetName) + if err != nil { + return nil, err + } + res.NamedAddrs = append(res.NamedAddrs, subnetRes.NamedAddrs...) + res.Cidrs = append(res.Cidrs, subnetRes.Cidrs...) + } + return res, nil +} + +func (s *Definitions) lookupCidrSegmentForSGSynth(name string) (*Resource, error) { + if segmentDetails, ok := s.CidrSegments[name]; ok { + return &Resource{Name: &name, + NamedAddrs: s.containedResourcesInCidr(segmentDetails.Cidrs), + Cidrs: cidrToNamedAddrs(segmentDetails.Cidrs), + Type: utils.Ptr(ResourceTypeCidr), + }, nil + } + return nil, fmt.Errorf(containerNotFound, ResourceTypeCidrSegment, name) +} + +func (s *Definitions) lookupSegmentForSGSynth(segment map[string]*SegmentDetails, name string, t ResourceType) (*Resource, error) { + if segmentDetails, ok := segment[name]; ok { + return &Resource{Name: &name, NamedAddrs: namesToNamedAddrs(segmentDetails.Elements), Cidrs: []*NamedAddrs{}, Type: utils.Ptr(t)}, nil + } + return nil, fmt.Errorf(containerNotFound, name, t) +} + +func (s *Definitions) containedResourcesInCidr(cidr *netset.IPBlock) []*NamedAddrs { + names := make([]string, 0) + for _, nifDetails := range s.NIFs { + if nifDetails.IP.IsSubset(cidr) { + names = append(names, nifDetails.Instance) + } + } + for _, reservedIPName := range s.VPEReservedIPs { + if reservedIPName.IP.IsSubset(cidr) { + names = append(names, reservedIPName.VPEName) + } + } + slices.Compact(slices.Sorted(slices.Values(names))) + return namesToNamedAddrs(names) +} + +func cidrToNamedAddrs(cidr *netset.IPBlock) []*NamedAddrs { + cidrs := cidr.SplitToCidrs() + res := make([]*NamedAddrs, len(cidrs)) + for _, c := range cidrs { + res = append(res, &NamedAddrs{IPAddrs: c}) + } + return res +} + +func namesToNamedAddrs(names []string) []*NamedAddrs { + res := make([]*NamedAddrs, len(names)) + for _, name := range names { + res = append(res, &NamedAddrs{Name: &name}) + } + return res +} diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index 8b1e51e8..f8756549 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -49,7 +49,7 @@ type ( // list of CIDR / Ip addresses. NamedAddrs []*NamedAddrs - // Cidr list (in case of CIDR segment) + // Cidr list Cidrs []*NamedAddrs // Type of resource @@ -164,6 +164,17 @@ type ( NWResource interface { Address() *netset.IPBlock } + + InternalNWResource interface { + NWResource + SubnetName() ID + } + + EndpointProvider interface { + endpointNames() []ID + endpointMap(s *Definitions) map[ID]InternalNWResource + endpointType() ResourceType + } ) const ( @@ -195,151 +206,64 @@ func (n *NifDetails) Address() *netset.IPBlock { return n.IP } +func (n *NifDetails) SubnetName() ID { + return n.Subnet +} + func (v *VPEReservedIPsDetails) Address() *netset.IPBlock { return v.IP } -func (e *ExternalDetails) Address() *netset.IPBlock { - return e.ExternalAddrs +func (v *VPEReservedIPsDetails) SubnetName() ID { + return v.Subnet } -func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*Resource, error) { - if details, ok := m[name]; ok { - return &Resource{ - Name: &name, - NamedAddrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, - Cidrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, - Type: utils.Ptr(ResourceTypeSubnet), - }, nil - } - return nil, fmt.Errorf(resourceNotFound, name, t) -} - -func (s *Definitions) lookupNifACL(name string) (*Resource, error) { - if nifDetails, ok := s.NIFs[name]; ok { - - } - return nil, fmt.Errorf(resourceNotFound, name, ResourceTypeNIF) +func (e *ExternalDetails) Address() *netset.IPBlock { + return e.ExternalAddrs } -func (s *Definitions) lookupSubnetSegmentACL(name string) (*Resource, error) { - if segmentDetails, ok := s.SubnetSegments[name]; ok { - res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} - for _, subnetName := range segmentDetails.Elements { - subnet, err := lookupSingle(s.Subnets, subnetName, ResourceTypeSubnet) - if err != nil { - return nil, fmt.Errorf("%w while looking up %v %v for subnet segment %v", err, ResourceTypeSubnet, subnetName, name) - } - res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) - res.Cidrs = append(res.Cidrs, subnet.Cidrs...) - } - return res, nil - } - return nil, fmt.Errorf(containerNotFound, name, ResourceTypeSubnetSegment) +func (i *InstanceDetails) endpointNames() []ID { + return i.Nifs } -func (s *Definitions) lookupCidrSegmentACL(name string) (*Resource, error) { - if segmentDetails, ok := s.CidrSegments[name]; ok { - res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} - for _, subnetName := range segmentDetails.ContainedSubnets { - subnet, err := lookupSingle(s.Subnets, subnetName, ResourceTypeSubnet) - if err != nil { - return nil, fmt.Errorf("%w while looking up %v %v for cidr segment %v", err, ResourceTypeSubnet, subnetName, name) - } - res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) - } - for _, cidr := range segmentDetails.Cidrs.SplitToCidrs() { - res.Cidrs = append(res.Cidrs, &NamedAddrs{Name: &name, IPAddrs: cidr}) - } - return res, nil +func (i *InstanceDetails) endpointMap(s *Definitions) map[ID]InternalNWResource { + res := make(map[ID]InternalNWResource, len(s.NIFs)) + for k, v := range s.NIFs { + res[k] = v } - return nil, fmt.Errorf(containerNotFound, name, ResourceTypeSubnet) + return res } -func (s *Definitions) lookupInstanceACL(name string) (*Resource, error) { - if instnaceDetails, ok := s.Instances[name]; ok { - - } +func (i *InstanceDetails) endpointType() ResourceType { + return ResourceTypeNIF } -func (s *Definitions) lookupInstance(name string) (Resource, error) { - if instanceDetails, ok := s.Instances[name]; ok { - ips := make([]*netset.IPBlock, len(instanceDetails.Nifs)) - for i, elemName := range instanceDetails.Nifs { - nif, err := s.Lookup(ResourceTypeNIF, elemName) - if err != nil { - return Resource{}, fmt.Errorf("%w while looking up %v %v for instance %v", err, ResourceTypeNIF, elemName, name) - } - // each nif has only one IP address - ips[i] = nif.IPAddrs[0] - } - return Resource{name, ips, ResourceTypeNIF}, nil - } - return Resource{}, containerNotFoundError(name, ResourceTypeInstance) +func (v *VPEDetails) endpointNames() []ID { + return v.VPEReservedIPs } -func (s *Definitions) lookupVPE(name string) (Resource, error) { - VPEDetails, ok := s.VPEs[name] - if !ok { - return Resource{}, resourceNotFoundError(name, ResourceTypeVPE) +func (v *VPEDetails) endpointMap(s *Definitions) map[ID]InternalNWResource { + res := make(map[ID]InternalNWResource, len(s.VPEReservedIPs)) + for k, v := range s.VPEReservedIPs { + res[k] = v } - ips := make([]*netset.IPBlock, len(VPEDetails.VPEReservedIPs)) - for i, vpeEndPoint := range VPEDetails.VPEReservedIPs { - ips[i] = s.VPEReservedIPs[vpeEndPoint].IP - } - return Resource{name, ips, ResourceTypeVPE}, nil + return res } -func (s *Definitions) LookupACL(t ResourceType, name string) (*Resource, error) { - switch t { - case ResourceTypeExternal: - return lookupSingle(s.Externals, name, t) - case ResourceTypeSubnet: - return lookupSingle(s.Subnets, name, t) - case ResourceTypeNIF: - return s.lookupNifACL(s.NIFs, name, t) - case ResourceTypeInstance: - return s.lookupInstanceACL(name) - case ResourceTypeVPE: - return s.lookupVpeACL(name) - case ResourceTypeSubnetSegment: - return s.lookupSubnetSegmentACL(name) - case ResourceTypeCidrSegment: - return s.lookupCidrSegmentACL(name) - case ResourceTypeNifSegment: - return s.lookupNifSegmentACL(name) - case ResourceTypeInstanceSegment: - return s.lookupInstanceSegmentACL(name) - case ResourceTypeVpeSegment: - return s.lookupVpeSegmentACL(name) - } - return nil, nil // should not get here +func (v *VPEDetails) endpointType() ResourceType { + return ResourceTypeVPE } -func (s *Definitions) LookupSG(t ResourceType, name string) (*Resource, error) { - switch t { - case ResourceTypeExternal: - return lookupSingle(s.Externals, name, t) - case ResourceTypeSubnet: - return lookupSubnetSG(s.Subnets, name, t) - case ResourceTypeNIF: - return s.lookupNifSG(s.NIFs, name, t) - case ResourceTypeInstance: - return s.lookupInstanceSG(name) - case ResourceTypeVPE: - return s.lookupVpeSG(name) - case ResourceTypeSubnetSegment: - return s.lookupSubnetSegmentSG(name) - case ResourceTypeCidrSegment: - return s.lookupCidrSegmentSG(name) - case ResourceTypeNifSegment: - return s.lookupNifSegmentSG(name) - case ResourceTypeInstanceSegment: - return s.lookupInstanceSegmentSG(name) - case ResourceTypeVpeSegment: - return s.lookupVpeSegmentSG(name) +func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*Resource, error) { + if details, ok := m[name]; ok { + return &Resource{ + Name: &name, + NamedAddrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, + Cidrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, + Type: utils.Ptr(t), + }, nil } - return nil, nil // should not get here + return nil, fmt.Errorf(resourceNotFound, name, t) } func (s *ConfigDefs) SubnetsContainedInCidr(cidr *netset.IPBlock) ([]ID, error) { diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index 7fc86560..37769bf4 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -100,17 +100,6 @@ func (a *ACLSynthesizer) allowConnectionToDst(conn *ir.Connection, p *ir.Tracked } } -// generate nACL rules for blocked subnets (subnets that do not appear in Spec) -func (a *ACLSynthesizer) generateACLRulesForBlockedSubnets() { - blockedSubnets := a.spec.ComputeBlockedSubnets() - for _, subnet := range blockedSubnets { - acl := a.result.LookupOrCreate(aclSelector(subnet, a.singleACL)) - cidr := a.spec.Defs.Subnets[subnet].Address() - acl.AppendInternal(ir.DenyAllReceive(subnet, cidr)) - acl.AppendInternal(ir.DenyAllSend(subnet, cidr)) - } -} - func aclSelector(subnetName ir.ID, single bool) string { if single { return fmt.Sprintf("%s/singleACL", ir.VpcFromScopedResource(subnetName)) @@ -126,3 +115,14 @@ func (a *ACLSynthesizer) addRuleToACL(rule *ir.ACLRule, resourceName ir.ID, inte acl.AppendExternal(rule) } } + +// generate nACL rules for blocked subnets (subnets that do not appear in Spec) +func (a *ACLSynthesizer) generateACLRulesForBlockedSubnets() { + blockedSubnets := a.spec.ComputeBlockedSubnets() + for _, subnet := range blockedSubnets { + acl := a.result.LookupOrCreate(aclSelector(subnet, a.singleACL)) + cidr := a.spec.Defs.Subnets[subnet].Address() + acl.AppendInternal(ir.DenyAllReceive(subnet, cidr)) + acl.AppendInternal(ir.DenyAllSend(subnet, cidr)) + } +} diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index b9f4717e..3186a8a4 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -32,49 +32,28 @@ func (s *SGSynthesizer) Synth() ir.Collection { // 2. generate SGs for blocked endpoints (endpoints that do not appear in Spec) func (s *SGSynthesizer) makeSG() *ir.SGCollection { for c := range s.spec.Connections { - s.generateSGRulesFromConnection(s.spec.Connections[c]) + s.generateSGRulesFromConnection(s.spec.Connections[c], ir.Outbound) + s.generateSGRulesFromConnection(s.spec.Connections[c], ir.Inbound) } s.generateSGsForBlockedResources() return s.result } -// 1. check that both resources are supported in SG generation. -// 2. check that at least one resource is internal. -// 3. convert src and dst resources to namedAddrs slices to make it more convenient to go through the addrs -// and add the rule to the relevant SG. -// 4. generate rules and add them to relevant SG to allow traffic for all pairs of IPAddrs of both resources. -func (s *SGSynthesizer) generateSGRulesFromConnection(conn *ir.Connection) { - internalSrc, internalDst, internalConn := internalConn(conn) - - for _, srcEndpoint := range conn.Src.NamedAddrs { - for _, dstCidr := range conn.Dst.Cidrs { - if srcEndpoint.IPAddrs.Equal(dstCidr.IPAddrs) { - continue - } - - for _, trackedProtocol := range conn.TrackedProtocols { - ruleExplanation := explanation{internal: internalConn, connectionOrigin: conn.Origin, protocolOrigin: trackedProtocol.Origin}.String() - s.allowConnectionEndpoint(srcEndpoint, dstCidr, trackedProtocol.Protocol, ir.Outbound, internalSrc, ruleExplanation) - } - } - } - - for _, dstEndpoint := range conn.Dst.NamedAddrs { - for _, srcCidr := range conn.Src.Cidrs { - if dstEndpoint.IPAddrs.Equal(srcCidr.IPAddrs) { - continue - } +func (s *SGSynthesizer) generateSGRulesFromConnection(conn *ir.Connection, direction ir.Direction) { + localResource, remoteResource, internalEndpoint, internalConn := connSettings(conn, direction) + for _, localEndpoint := range localResource.NamedAddrs { + for _, remoteCidr := range remoteResource.Cidrs { for _, trackedProtocol := range conn.TrackedProtocols { ruleExplanation := explanation{internal: internalConn, connectionOrigin: conn.Origin, protocolOrigin: trackedProtocol.Origin}.String() - s.allowConnectionEndpoint(dstEndpoint, srcCidr, trackedProtocol.Protocol, ir.Inbound, internalDst, ruleExplanation) + s.allowConnectionEndpoint(localEndpoint, remoteCidr, remoteResource.Type, trackedProtocol.Protocol, direction, internalEndpoint, ruleExplanation) } } } } // if the endpoint in internal, a rule will be created to allow traffic. -func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *ir.NamedAddrs, p netp.Protocol, direction ir.Direction, +func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *ir.NamedAddrs, remoteType *ir.ResourceType, p netp.Protocol, direction ir.Direction, internalEndpoint bool, ruleExplanation string) { if !internalEndpoint { return @@ -83,7 +62,7 @@ func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *i localSG := s.result.LookupOrCreate(localSGName) localSG.Attached = []ir.ID{ir.ID(localSGName)} rule := &ir.SGRule{ - Remote: sgRemote(s.spec.Defs, remoteEndpoint), + Remote: sgRemote(remoteEndpoint, remoteType), Direction: direction, Protocol: p, Explanation: ruleExplanation, @@ -91,16 +70,28 @@ func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *i localSG.Add(rule) } -// what to do if its a cidr segment? -func sgRemote(s *ir.Definitions, resource *ir.NamedAddrs) ir.RemoteType { - if _, ok := s.Externals[*resource.Name]; ok { - return resource.IPAddrs +func sgRemote(resource *ir.NamedAddrs, t *ir.ResourceType) ir.RemoteType { + if isSGRemote(*t) { + return ir.SGName(*resource.Name) } - if _, ok := s.Subnets[*resource.Name]; ok { - return resource.IPAddrs + return resource.IPAddrs +} + +func connSettings(conn *ir.Connection, direction ir.Direction) (*ir.Resource, *ir.Resource, bool, bool) { + internalSrc, internalDst, internalConn := internalConn(conn) + localResource := conn.Src + remoteResource := conn.Dst + internalEndpoint := internalSrc + if direction == ir.Inbound { + localResource = conn.Dst + remoteResource = conn.Src + internalEndpoint = internalDst } - // what to do if its a cidr? - return ir.SGName(*resource.Name) + return localResource, remoteResource, internalEndpoint, internalConn +} + +func isSGRemote(t ir.ResourceType) bool { + return t == ir.ResourceTypeInstance || t == ir.ResourceTypeNIF || t == ir.ResourceTypeVPE } // generate SGs for blocked endpoints (endpoints that do not appear in Spec) From c565d25a248b5c0b545f0eab1432b7af5214ce5c Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 14 Oct 2024 10:50:28 +0300 Subject: [PATCH 072/131] better lookup --- pkg/ir/lookupForACLSynth.go | 26 ++++---------------------- pkg/ir/lookupForSGSynth.go | 35 +++++------------------------------ pkg/ir/spec.go | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 52 deletions(-) diff --git a/pkg/ir/lookupForACLSynth.go b/pkg/ir/lookupForACLSynth.go index d218ae6c..9fdb7f38 100644 --- a/pkg/ir/lookupForACLSynth.go +++ b/pkg/ir/lookupForACLSynth.go @@ -25,15 +25,15 @@ func (s *Definitions) LookupForACLSynth(t ResourceType, name string) (*Resource, case ResourceTypeVPE: return lookupContainerForACLSynth(s.VPEs, s, name, ResourceTypeVPE) case ResourceTypeSubnetSegment: - return s.lookupSegmentForACLSynth(s.SubnetSegments, name, t, ResourceTypeSubnet) + return s.lookupSegment(s.SubnetSegments, name, t, ResourceTypeSubnet, s.LookupForACLSynth) case ResourceTypeCidrSegment: return s.lookupCidrSegmentACL(name) case ResourceTypeNifSegment: - return s.lookupSegmentForACLSynth(s.SubnetSegments, name, t, ResourceTypeNIF) + return s.lookupSegment(s.NifSegments, name, t, ResourceTypeNIF, s.LookupForACLSynth) case ResourceTypeInstanceSegment: - return s.lookupSegmentForACLSynth(s.SubnetSegments, name, t, ResourceTypeInstance) + return s.lookupSegment(s.InstanceSegments, name, t, ResourceTypeInstance, s.LookupForACLSynth) case ResourceTypeVpeSegment: - return s.lookupSegmentForACLSynth(s.SubnetSegments, name, t, ResourceTypeVPE) + return s.lookupSegment(s.VpeSegments, name, t, ResourceTypeVPE, s.LookupForACLSynth) } return nil, nil // should not get here } @@ -52,24 +52,6 @@ func lookupSingleForACLSynth[T InternalNWResource](m map[ID]T, subnets map[ID]*S return res, nil } -func (s *Definitions) lookupSegmentForACLSynth(segment map[ID]*SegmentDetails, name string, t, elementType ResourceType) (*Resource, error) { - segmentDetails, ok := segment[name] - if !ok { - return nil, fmt.Errorf(containerNotFound, name, t) - } - - res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} - for _, elementName := range segmentDetails.Elements { - subnet, err := s.LookupForACLSynth(elementType, elementName) - if err != nil { - return nil, err - } - res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) - res.Cidrs = append(res.Cidrs, subnet.Cidrs...) - } - return res, nil -} - func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definitions, name string, t ResourceType) (*Resource, error) { containerDetails, ok := m[name] if !ok { diff --git a/pkg/ir/lookupForSGSynth.go b/pkg/ir/lookupForSGSynth.go index fc4db5d9..3466794b 100644 --- a/pkg/ir/lookupForSGSynth.go +++ b/pkg/ir/lookupForSGSynth.go @@ -25,17 +25,17 @@ func (s *Definitions) LookupForSGSynth(t ResourceType, name string) (*Resource, case ResourceTypeInstance: return lookupContainerForSGSynth(s.Instances, name, ResourceTypeInstance) case ResourceTypeVPE: - return lookupContainerForSGSynth(s.Instances, name, ResourceTypeVPE) + return lookupContainerForSGSynth(s.VPEs, name, ResourceTypeVPE) case ResourceTypeSubnetSegment: - return s.lookupSubnetSegmentForSGSynth(name) + return s.lookupSegment(s.SubnetSegments, name, t, ResourceTypeSubnet, s.LookupForSGSynth) case ResourceTypeCidrSegment: return s.lookupCidrSegmentForSGSynth(name) case ResourceTypeNifSegment: - return s.lookupSegmentForSGSynth(s.NifSegments, name, ResourceTypeNIF) + return s.lookupSegment(s.NifSegments, name, t, ResourceTypeNIF, s.LookupForSGSynth) case ResourceTypeInstanceSegment: - return s.lookupSegmentForSGSynth(s.InstanceSegments, name, ResourceTypeInstance) + return s.lookupSegment(s.InstanceSegments, name, t, ResourceTypeInstance, s.LookupForSGSynth) case ResourceTypeVpeSegment: - return s.lookupSegmentForSGSynth(s.VpeSegments, name, ResourceTypeVPE) + return s.lookupSegment(s.VpeSegments, name, t, ResourceTypeVPE, s.LookupForSGSynth) } return nil, nil // should not get here } @@ -75,24 +75,6 @@ func (s *Definitions) lookupSubnetForSGSynth(name string) (*Resource, error) { return nil, fmt.Errorf(resourceNotFound, ResourceTypeSubnet, name) } -func (s *Definitions) lookupSubnetSegmentForSGSynth(name string) (*Resource, error) { - segmentDetails, ok := s.SubnetSegments[name] - if !ok { - return nil, fmt.Errorf(containerNotFound, ResourceTypeSubnetSegment, name) - } - - res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} - for _, subnetName := range segmentDetails.Elements { - subnetRes, err := s.lookupSubnetForSGSynth(subnetName) - if err != nil { - return nil, err - } - res.NamedAddrs = append(res.NamedAddrs, subnetRes.NamedAddrs...) - res.Cidrs = append(res.Cidrs, subnetRes.Cidrs...) - } - return res, nil -} - func (s *Definitions) lookupCidrSegmentForSGSynth(name string) (*Resource, error) { if segmentDetails, ok := s.CidrSegments[name]; ok { return &Resource{Name: &name, @@ -104,13 +86,6 @@ func (s *Definitions) lookupCidrSegmentForSGSynth(name string) (*Resource, error return nil, fmt.Errorf(containerNotFound, ResourceTypeCidrSegment, name) } -func (s *Definitions) lookupSegmentForSGSynth(segment map[string]*SegmentDetails, name string, t ResourceType) (*Resource, error) { - if segmentDetails, ok := segment[name]; ok { - return &Resource{Name: &name, NamedAddrs: namesToNamedAddrs(segmentDetails.Elements), Cidrs: []*NamedAddrs{}, Type: utils.Ptr(t)}, nil - } - return nil, fmt.Errorf(containerNotFound, name, t) -} - func (s *Definitions) containedResourcesInCidr(cidr *netset.IPBlock) []*NamedAddrs { names := make([]string, 0) for _, nifDetails := range s.NIFs { diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index f8756549..b0ff6e64 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -266,6 +266,25 @@ func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*Resou return nil, fmt.Errorf(resourceNotFound, name, t) } +func (s *Definitions) lookupSegment(segment map[ID]*SegmentDetails, name string, t, elementType ResourceType, + lookup func(ResourceType, string) (*Resource, error)) (*Resource, error) { + segmentDetails, ok := segment[name] + if !ok { + return nil, fmt.Errorf(containerNotFound, name, t) + } + + res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + for _, elementName := range segmentDetails.Elements { + subnet, err := lookup(elementType, elementName) + if err != nil { + return nil, err + } + res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) + res.Cidrs = append(res.Cidrs, subnet.Cidrs...) + } + return res, nil +} + func (s *ConfigDefs) SubnetsContainedInCidr(cidr *netset.IPBlock) ([]ID, error) { var containedSubnets []string for subnet, subnetDetails := range s.Subnets { From 4ba19c28b739b75117691cb7b3c64a45ce1e7d4b Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 14 Oct 2024 12:53:59 +0300 Subject: [PATCH 073/131] lookup, blocked --- pkg/io/jsonio/unmarshalConns.go | 21 ++++ pkg/io/jsonio/unmarshalDefinitions.go | 26 ++++- pkg/ir/lookupForACLSynth.go | 2 +- pkg/ir/lookupForSGSynth.go | 15 ++- pkg/ir/spec.go | 20 +++- pkg/ir/unspecified.go | 140 -------------------------- pkg/synth/acl.go | 4 +- pkg/synth/sg.go | 4 +- pkg/utils/utils.go | 10 ++ 9 files changed, 85 insertions(+), 157 deletions(-) delete mode 100644 pkg/ir/unspecified.go diff --git a/pkg/io/jsonio/unmarshalConns.go b/pkg/io/jsonio/unmarshalConns.go index 9ab62ec3..d2d522bd 100644 --- a/pkg/io/jsonio/unmarshalConns.go +++ b/pkg/io/jsonio/unmarshalConns.go @@ -63,8 +63,10 @@ func transalteConnectionResource(defs *ir.Definitions, resource *spec.Resource, var res *ir.Resource if isSG { res, err = defs.LookupForSGSynth(resourceType, resource.Name) + updateBlockedResourcesSGSynth(defs, res) } else { res, err = defs.LookupForACLSynth(resourceType, resource.Name) + updateBlockedResourcesACLSynth(defs, res) } return res, resourceType == ir.ResourceTypeExternal, err } @@ -130,3 +132,22 @@ func translateResourceType(defs *ir.Definitions, resource *spec.Resource) (ir.Re } return ir.ResourceTypeSubnet, fmt.Errorf("unsupported resource type %v (%v)", resource.Type, resource.Name) } + +func updateBlockedResourcesSGSynth(defs *ir.Definitions, resource *ir.Resource) { + for _, namedAddrs := range resource.NamedAddrs { + if _, ok := defs.BlockedInstances[*namedAddrs.Name]; ok { + defs.BlockedInstances[*namedAddrs.Name] = false + } + if _, ok := defs.BlockedVPEs[*namedAddrs.Name]; ok { + defs.BlockedVPEs[*namedAddrs.Name] = false + } + } +} + +func updateBlockedResourcesACLSynth(defs *ir.Definitions, resource *ir.Resource) { + for _, namedAddrs := range resource.NamedAddrs { + if _, ok := defs.BlockedSubnets[*namedAddrs.Name]; ok { + defs.BlockedSubnets[*namedAddrs.Name] = false + } + } +} diff --git a/pkg/io/jsonio/unmarshalDefinitions.go b/pkg/io/jsonio/unmarshalDefinitions.go index ef6e7c63..94f8707a 100644 --- a/pkg/io/jsonio/unmarshalDefinitions.go +++ b/pkg/io/jsonio/unmarshalDefinitions.go @@ -13,6 +13,7 @@ import ( "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) type segmentsTypes struct { @@ -29,10 +30,10 @@ func (r *Reader) readDefinitions(jsonSpec *spec.Spec, configDefs *ir.ConfigDefs) return nil, err } segments := divideSegmentsByType(&jsonSpec.Segments) - subnetSegments := parseSegments(segments.subnetSegment, spec.SegmentTypeSubnet) - nifSegments := parseSegments(segments.nifSegment, spec.SegmentTypeNif) - instanceSegments := parseSegments(segments.instanceSegment, spec.SegmentTypeInstance) - vpeSegments := parseSegments(segments.vpeSegment, spec.SegmentTypeVpe) + subnetSegments := parseSegments(segments.subnetSegment) + nifSegments := parseSegments(segments.nifSegment) + instanceSegments := parseSegments(segments.instanceSegment) + vpeSegments := parseSegments(segments.vpeSegment) cidrSegments, err := parseCidrSegments(segments.cidrSegment, configDefs) if err != nil { return nil, err @@ -43,6 +44,7 @@ func (r *Reader) readDefinitions(jsonSpec *spec.Spec, configDefs *ir.ConfigDefs) } return &ir.Definitions{ ConfigDefs: *configDefs, + BlockedResources: prepareBlockedResources(configDefs), SubnetSegments: subnetSegments, CidrSegments: cidrSegments, NifSegments: nifSegments, @@ -65,7 +67,7 @@ func validateSegments(jsonSegments *spec.SpecSegments) error { } // translates segment to ir ds -func parseSegments(segments map[string][]string, segmentType spec.SegmentType) map[ir.ID]*ir.SegmentDetails { +func parseSegments(segments map[string][]string) map[ir.ID]*ir.SegmentDetails { result := make(map[string]*ir.SegmentDetails) for segmentName, elements := range segments { result[segmentName] = &ir.SegmentDetails{Elements: elements} @@ -146,3 +148,17 @@ func internalCidr(configDefs *ir.ConfigDefs, cidr *netset.IPBlock) bool { } return res == netset.NewIPBlock() } + +func prepareBlockedResources(configDefs *ir.ConfigDefs) ir.BlockedResources { + return ir.BlockedResources{BlockedSubnets: sliceToMap(utils.SortedMapKeys(configDefs.Subnets)), + BlockedInstances: sliceToMap(utils.SortedMapKeys(configDefs.Instances)), + BlockedVPEs: sliceToMap(utils.SortedMapKeys(configDefs.VPEs))} +} + +func sliceToMap(slice []string) map[string]bool { + res := make(map[string]bool, len(slice)) + for _, elem := range slice { + res[elem] = true + } + return res +} diff --git a/pkg/ir/lookupForACLSynth.go b/pkg/ir/lookupForACLSynth.go index 9fdb7f38..c1c5a896 100644 --- a/pkg/ir/lookupForACLSynth.go +++ b/pkg/ir/lookupForACLSynth.go @@ -55,7 +55,7 @@ func lookupSingleForACLSynth[T InternalNWResource](m map[ID]T, subnets map[ID]*S func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definitions, name string, t ResourceType) (*Resource, error) { containerDetails, ok := m[name] if !ok { - return nil, fmt.Errorf(containerNotFound, name, ResourceTypeInstance) + return nil, fmt.Errorf(containerNotFound, name, t) } res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} diff --git a/pkg/ir/lookupForSGSynth.go b/pkg/ir/lookupForSGSynth.go index 3466794b..177bfb9d 100644 --- a/pkg/ir/lookupForSGSynth.go +++ b/pkg/ir/lookupForSGSynth.go @@ -45,7 +45,7 @@ func (s *Definitions) lookupNIFForSGSynth(name string) (*Resource, error) { return &Resource{ Name: &name, NamedAddrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, - Cidrs: []*NamedAddrs{}, + Cidrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, Type: utils.Ptr(ResourceTypeNIF), }, nil } @@ -57,7 +57,7 @@ func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, return &Resource{ Name: &name, NamedAddrs: []*NamedAddrs{{Name: &name}}, - Cidrs: []*NamedAddrs{}, + Cidrs: []*NamedAddrs{{Name: &name}}, Type: utils.Ptr(t), }, nil } @@ -98,23 +98,22 @@ func (s *Definitions) containedResourcesInCidr(cidr *netset.IPBlock) []*NamedAdd names = append(names, reservedIPName.VPEName) } } - slices.Compact(slices.Sorted(slices.Values(names))) - return namesToNamedAddrs(names) + return namesToNamedAddrs(slices.Compact(slices.Sorted(slices.Values(names)))) } func cidrToNamedAddrs(cidr *netset.IPBlock) []*NamedAddrs { cidrs := cidr.SplitToCidrs() res := make([]*NamedAddrs, len(cidrs)) - for _, c := range cidrs { - res = append(res, &NamedAddrs{IPAddrs: c}) + for i, c := range cidrs { + res[i] = &NamedAddrs{IPAddrs: c} } return res } func namesToNamedAddrs(names []string) []*NamedAddrs { res := make([]*NamedAddrs, len(names)) - for _, name := range names { - res = append(res, &NamedAddrs{Name: &name}) + for i, name := range names { + res[i] = &NamedAddrs{Name: &name} } return res } diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index b0ff6e64..71a10588 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -8,6 +8,7 @@ package ir import ( "fmt" + "log" "sort" "strings" @@ -84,8 +85,10 @@ type ( // Definitions adds to ConfigDefs the spec-specific definitions Definitions struct { ConfigDefs - // Segments are a way for users to create aggregations. + BlockedResources + + // Segments are a way for users to create aggregations. SubnetSegments map[ID]*SegmentDetails CidrSegments map[ID]*CidrSegmentDetails @@ -100,6 +103,12 @@ type ( Externals map[ID]*ExternalDetails } + BlockedResources struct { + BlockedSubnets map[ID]bool + BlockedInstances map[ID]bool + BlockedVPEs map[ID]bool + } + VPCDetails struct { AddressPrefixes *netset.IPBlock // tg @@ -192,6 +201,9 @@ const ( resourceNotFound = "%v %v not found" containerNotFound = "container %v %v not found" + + WarningUnspecifiedACL = "The following subnets do not have required connections; the generated ACL will block all traffic: " + WarningUnspecifiedSG = "The following endpoints do not have required connections; the generated SGs will block all traffic: " ) func (n *NamedEntity) Name() string { @@ -307,3 +319,9 @@ func VpcFromScopedResource(resource ID) ID { func ChangeScoping(s string) string { return strings.ReplaceAll(s, "/", "--") } + +func PrintUnspecifiedWarning(warning string, blockedResources []ID) { + if len(blockedResources) > 0 { + log.Println(warning, strings.Join(blockedResources, ", ")) + } +} diff --git a/pkg/ir/unspecified.go b/pkg/ir/unspecified.go deleted file mode 100644 index 3553e582..00000000 --- a/pkg/ir/unspecified.go +++ /dev/null @@ -1,140 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package ir - -import ( - "log" - "sort" - "strings" -) - -const ( - warningUnspecifiedACL = "The following subnets do not have required connections; the generated ACL will block all traffic: " - warningUnspecifiedSG = "The following endpoints do not have required connections; the generated SGs will block all traffic: " -) - -//nolint:gocyclo // look for the subnet in spec -func (s *Spec) ComputeBlockedSubnets() []ID { - var blockedSubnets []ID - - for subnet := range s.Defs.Subnets { - if s.findResourceInConnections([]ID{subnet}, ResourceTypeSubnet) { - continue - } - - // subnet segments which include the subnet - segments := []ID{} - for segmentName, segmentDetails := range s.Defs.SubnetSegments { - for _, s := range segmentDetails.Subnets { - if subnet == s { - segments = append(segments, segmentName) - break - } - } - } - if s.findResourceInConnections(segments, ResourceTypeSubnet) { - continue - } - - // cidr segments which include the subnet - cidrSegments := []ID{} - for segmentName, cidrSegmentDetails := range s.Defs.CidrSegments { - for _, s := range cidrSegmentDetails.ContainedSubnets { - if subnet == s { - cidrSegments = append(cidrSegments, segmentName) - break - } - } - } - if s.findResourceInConnections(cidrSegments, ResourceTypeCidr) { - continue - } - - // nifs in the subnet - nifs := []ID{} - for instanceName, instance := range s.Defs.Instances { - instanceInList := false - for _, nif := range instance.Nifs { - if subnet == s.Defs.NIFs[nif].Subnet { - nifs = append(nifs, nif) - if !instanceInList { - nifs = append(nifs, instanceName) - instanceInList = true - } - } - } - } - if !s.findResourceInConnections(nifs, ResourceTypeNIF) { - blockedSubnets = append(blockedSubnets, subnet) - } - } - sort.Strings(blockedSubnets) - printUnspecifiedWarning(warningUnspecifiedACL, blockedSubnets) - return blockedSubnets -} - -func (s *Spec) ComputeBlockedResources() []ID { - blockedResources := append(s.computeBlockedNIFs(), s.computeBlockedVPEs()...) - sort.Strings(blockedResources) - printUnspecifiedWarning(warningUnspecifiedSG, blockedResources) - return blockedResources -} - -func (s *Spec) computeBlockedVPEs() []ID { - var blockedVPEs []ID - for vpe := range s.Defs.VPEs { - if !s.findResourceInConnections([]ID{vpe}, ResourceTypeVPE) { - blockedVPEs = append(blockedVPEs, vpe) - } - } - return blockedVPEs -} - -func (s *Spec) computeBlockedNIFs() []ID { - var blockedResources []ID - for instanceName, instanceDetails := range s.Defs.Instances { - if s.findResourceInConnections([]ID{instanceName}, ResourceTypeNIF) { - continue - } - - // instance is not in spec. look for its NIFs - var blockedNIFs []ID - for _, nif := range instanceDetails.Nifs { - if !s.findResourceInConnections([]ID{nif}, ResourceTypeNIF) { - blockedNIFs = append(blockedNIFs, nif) - } - } - - // instance has only one NIF which was not found - if len(blockedNIFs) > 0 && len(instanceDetails.Nifs) == 1 { - blockedResources = append(blockedResources, instanceName) - } else { - blockedResources = append(blockedResources, blockedNIFs...) - } - } - return blockedResources -} - -func (s *Spec) findResourceInConnections(resources []ID, resourceType ResourceType) bool { - // The slice of IDs represents all resources that include the resource we are looking for - for c := range s.Connections { - for _, resource := range resources { - if s.Connections[c].Src.Type == resourceType && resource == s.Connections[c].Src.Name { - return true - } - if s.Connections[c].Dst.Type == resourceType && resource == s.Connections[c].Dst.Name { - return true - } - } - } - return false -} - -func printUnspecifiedWarning(warning string, blockedResources []ID) { - if len(blockedResources) > 0 { - log.Println(warning, strings.Join(blockedResources, ", ")) - } -} diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index 37769bf4..17bc1c13 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -12,6 +12,7 @@ import ( "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/utils" ) const ACLTypeNotSupported = "ACL: src/dst of type %s is not supported" @@ -118,7 +119,8 @@ func (a *ACLSynthesizer) addRuleToACL(rule *ir.ACLRule, resourceName ir.ID, inte // generate nACL rules for blocked subnets (subnets that do not appear in Spec) func (a *ACLSynthesizer) generateACLRulesForBlockedSubnets() { - blockedSubnets := a.spec.ComputeBlockedSubnets() + blockedSubnets := utils.TrueKeyValues(a.spec.Defs.BlockedSubnets) + ir.PrintUnspecifiedWarning(ir.WarningUnspecifiedACL, blockedSubnets) for _, subnet := range blockedSubnets { acl := a.result.LookupOrCreate(aclSelector(subnet, a.singleACL)) cidr := a.spec.Defs.Subnets[subnet].Address() diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 3186a8a4..5aadd795 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -9,6 +9,7 @@ import ( "github.com/np-guard/models/pkg/netp" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) const SGTypeNotSupported = "SG: src/dst of type %s is not supported" @@ -96,7 +97,8 @@ func isSGRemote(t ir.ResourceType) bool { // generate SGs for blocked endpoints (endpoints that do not appear in Spec) func (s *SGSynthesizer) generateSGsForBlockedResources() { - blockedResources := s.spec.ComputeBlockedResources() + blockedResources := append(utils.TrueKeyValues(s.spec.Defs.BlockedInstances), utils.TrueKeyValues(s.spec.Defs.BlockedVPEs)...) + ir.PrintUnspecifiedWarning(ir.WarningUnspecifiedSG, blockedResources) for _, resource := range blockedResources { sg := s.result.LookupOrCreate(ir.SGName(resource)) // an empty SG allows no connections sg.Attached = []ir.ID{resource} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index acf9e3d2..a1fb8c32 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -31,3 +31,13 @@ func SortedAllInnerMapsKeys[T, K cmp.Ordered, V any](m map[K]map[T]V) []T { slices.Sort(keys) return keys } + +func TrueKeyValues[T comparable](m map[T]bool) []T { + keys := make([]T, 0) + for k, v := range m { + if v { + keys = append(keys, k) + } + } + return keys +} From cd94ff053bc774faaeca4b0e4c85b95b12033a83 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 14 Oct 2024 14:36:56 +0300 Subject: [PATCH 074/131] fix bugs, linter, update old tests --- pkg/io/jsonio/unmarshal.go | 6 ++-- pkg/io/jsonio/unmarshalConns.go | 11 ++++---- pkg/io/jsonio/unmarshalDefinitions.go | 2 +- pkg/ir/lookupForACLSynth.go | 2 +- pkg/ir/spec.go | 12 ++++---- pkg/synth/acl.go | 12 ++++---- pkg/synth/common.go | 2 +- pkg/synth/sg.go | 23 +++++++-------- test/error_test_list.go | 13 --------- .../expected/acl_segments_tf/nacl_expected.tf | 12 ++++---- .../acl_testing5_json/nacl_expected.json | 12 ++++---- .../nacl_single_expected.json | 28 +++++++++---------- .../expected/acl_testing5_tf/nacl_expected.tf | 12 ++++---- .../nacl_single_expected.tf | 28 +++++++++---------- .../acl_tg_multiple_json/nacl_expected.json | 12 ++++---- .../acl_tg_multiple_tf/nacl_expected.tf | 12 ++++---- .../acl_tg_multiple_tf_separate/test-vpc0.tf | 12 ++++---- test/main_test.go | 4 +++ 18 files changed, 105 insertions(+), 110 deletions(-) diff --git a/pkg/io/jsonio/unmarshal.go b/pkg/io/jsonio/unmarshal.go index 1140fea9..6bf2b9ee 100644 --- a/pkg/io/jsonio/unmarshal.go +++ b/pkg/io/jsonio/unmarshal.go @@ -63,10 +63,12 @@ func replaceResourcesName(jsonSpec *spec.Spec, defs *ir.Definitions) (*spec.Spec distinctVpes, ambiguousVpes := inverseMapToFullyQualifiedName(config.VPEs) // translate segments to fully qualified names - subnetSegments, err1 := replaceSegmentNames(defs.SubnetSegments, distinctSubnets, ambiguousSubnets, spec.ResourceType(spec.SegmentTypeSubnet)) nifSegments, err2 := replaceSegmentNames(defs.NifSegments, distinctNifs, ambiguousNifs, spec.ResourceType(spec.SegmentTypeNif)) - instanceSegments, err3 := replaceSegmentNames(defs.InstanceSegments, distinctInstances, ambiguousInstances, spec.ResourceType(spec.SegmentTypeInstance)) vpeSegments, err4 := replaceSegmentNames(defs.VpeSegments, distinctVpes, ambiguousVpes, spec.ResourceType(spec.SegmentTypeVpe)) + subnetSegments, err1 := replaceSegmentNames(defs.SubnetSegments, distinctSubnets, ambiguousSubnets, + spec.ResourceType(spec.SegmentTypeSubnet)) + instanceSegments, err3 := replaceSegmentNames(defs.InstanceSegments, distinctInstances, ambiguousInstances, + spec.ResourceType(spec.SegmentTypeInstance)) if err := errors.Join(err1, err2, err3, err4); err != nil { return nil, nil, err diff --git a/pkg/io/jsonio/unmarshalConns.go b/pkg/io/jsonio/unmarshalConns.go index d2d522bd..82e4952b 100644 --- a/pkg/io/jsonio/unmarshalConns.go +++ b/pkg/io/jsonio/unmarshalConns.go @@ -32,7 +32,7 @@ func (r *Reader) transalteConnections(conns []spec.SpecRequiredConnectionsElem, func translateConnection(defs *ir.Definitions, conn *spec.SpecRequiredConnectionsElem, connIdx int, isSG bool) ([]*ir.Connection, error) { protocols, err1 := translateProtocols(conn.AllowedProtocols) srcResource, isSrcExternal, err2 := transalteConnectionResource(defs, &conn.Src, isSG) - dstResource, isDstExternal, err3 := transalteConnectionResource(defs, &conn.Src, isSG) + dstResource, isDstExternal, err3 := transalteConnectionResource(defs, &conn.Dst, isSG) if err := errors.Join(err1, err2, err3); err != nil { return nil, err } @@ -74,29 +74,30 @@ func transalteConnectionResource(defs *ir.Definitions, resource *spec.Resource, func translateProtocols(protocols spec.ProtocolList) ([]*ir.TrackedProtocol, error) { var result = make([]*ir.TrackedProtocol, len(protocols)) for i, _p := range protocols { - result[i].Origin = protocolOrigin{protocolIndex: i} + res := &ir.TrackedProtocol{Origin: protocolOrigin{protocolIndex: i}} switch p := _p.(type) { case spec.AnyProtocol: if len(protocols) != 1 { log.Println("when allowing any protocol, there is no need in other protocols") } - result[i].Protocol = netp.AnyProtocol{} + res.Protocol = netp.AnyProtocol{} case spec.Icmp: icmp, err := netp.ICMPFromTypeAndCode(p.Type, p.Code) if err != nil { return nil, err } - result[i].Protocol = icmp + res.Protocol = icmp case spec.TcpUdp: tcpudp, err := netp.NewTCPUDP(p.Protocol == spec.TcpUdpProtocolTCP, p.MinSourcePort, p.MaxSourcePort, p.MinDestinationPort, p.MaxDestinationPort) if err != nil { return nil, err } - result[i].Protocol = tcpudp + res.Protocol = tcpudp default: return nil, fmt.Errorf("impossible protocol: %v", p) } + result[i] = res } return result, nil } diff --git a/pkg/io/jsonio/unmarshalDefinitions.go b/pkg/io/jsonio/unmarshalDefinitions.go index 94f8707a..2a550bc4 100644 --- a/pkg/io/jsonio/unmarshalDefinitions.go +++ b/pkg/io/jsonio/unmarshalDefinitions.go @@ -146,7 +146,7 @@ func internalCidr(configDefs *ir.ConfigDefs, cidr *netset.IPBlock) bool { for _, vpcDetails := range configDefs.VPCs { res = res.Subtract(vpcDetails.AddressPrefixes) } - return res == netset.NewIPBlock() + return res.IsEmpty() } func prepareBlockedResources(configDefs *ir.ConfigDefs) ir.BlockedResources { diff --git a/pkg/ir/lookupForACLSynth.go b/pkg/ir/lookupForACLSynth.go index c1c5a896..8f207435 100644 --- a/pkg/ir/lookupForACLSynth.go +++ b/pkg/ir/lookupForACLSynth.go @@ -38,7 +38,7 @@ func (s *Definitions) LookupForACLSynth(t ResourceType, name string) (*Resource, return nil, nil // should not get here } -func lookupSingleForACLSynth[T InternalNWResource](m map[ID]T, subnets map[ID]*SubnetDetails, name string, t ResourceType) (*Resource, error) { +func lookupSingleForACLSynth[T INWResource](m map[ID]T, subnets map[ID]*SubnetDetails, name string, t ResourceType) (*Resource, error) { details, ok := m[name] if !ok { return nil, fmt.Errorf(resourceNotFound, name, t) diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index 71a10588..604b2c69 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -174,14 +174,14 @@ type ( Address() *netset.IPBlock } - InternalNWResource interface { + INWResource interface { NWResource SubnetName() ID } EndpointProvider interface { endpointNames() []ID - endpointMap(s *Definitions) map[ID]InternalNWResource + endpointMap(s *Definitions) map[ID]INWResource endpointType() ResourceType } ) @@ -238,8 +238,8 @@ func (i *InstanceDetails) endpointNames() []ID { return i.Nifs } -func (i *InstanceDetails) endpointMap(s *Definitions) map[ID]InternalNWResource { - res := make(map[ID]InternalNWResource, len(s.NIFs)) +func (i *InstanceDetails) endpointMap(s *Definitions) map[ID]INWResource { + res := make(map[ID]INWResource, len(s.NIFs)) for k, v := range s.NIFs { res[k] = v } @@ -254,8 +254,8 @@ func (v *VPEDetails) endpointNames() []ID { return v.VPEReservedIPs } -func (v *VPEDetails) endpointMap(s *Definitions) map[ID]InternalNWResource { - res := make(map[ID]InternalNWResource, len(s.VPEReservedIPs)) +func (v *VPEDetails) endpointMap(s *Definitions) map[ID]INWResource { + res := make(map[ID]INWResource, len(s.VPEReservedIPs)) for k, v := range s.VPEReservedIPs { res[k] = v } diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index 17bc1c13..3fa7b73a 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -50,7 +50,7 @@ func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection) { continue } for _, trackedProtocol := range conn.TrackedProtocols { - a.allowConnectionFromSrc(conn, trackedProtocol, srcSubnet, dstCidr.IPAddrs) + a.allowConnectionSrc(conn, trackedProtocol, srcSubnet, dstCidr.IPAddrs) } } } @@ -61,7 +61,7 @@ func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection) { continue } for _, trackedProtocol := range conn.TrackedProtocols { - a.allowConnectionToDst(conn, trackedProtocol, dstSubnet, srcCidr.IPAddrs) + a.allowConnectionDst(conn, trackedProtocol, dstSubnet, srcCidr.IPAddrs) } } } @@ -69,8 +69,8 @@ func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection) { // if the src in internal, rule(s) will be created to allow traffic. // if the protocol allows response, more rules will be created. -func (a *ACLSynthesizer) allowConnectionFromSrc(conn *ir.Connection, p *ir.TrackedProtocol, srcSubnet *ir.NamedAddrs, dstCidr *netset.IPBlock) { - internalSrc, _, internal := internalConn(conn) +func (a *ACLSynthesizer) allowConnectionSrc(conn *ir.Connection, p *ir.TrackedProtocol, srcSubnet *ir.NamedAddrs, dstCidr *netset.IPBlock) { + internalSrc, _, internal := internalConnection(conn) if !internalSrc || srcSubnet.IPAddrs.Equal(dstCidr) { return @@ -86,8 +86,8 @@ func (a *ACLSynthesizer) allowConnectionFromSrc(conn *ir.Connection, p *ir.Track // if the dst in internal, rule(s) will be created to allow traffic. // if the protocol allows response, more rules will be created. -func (a *ACLSynthesizer) allowConnectionToDst(conn *ir.Connection, p *ir.TrackedProtocol, dstSubnet *ir.NamedAddrs, srcCidr *netset.IPBlock) { - _, internalDst, internal := internalConn(conn) +func (a *ACLSynthesizer) allowConnectionDst(conn *ir.Connection, p *ir.TrackedProtocol, dstSubnet *ir.NamedAddrs, srcCidr *netset.IPBlock) { + _, internalDst, internal := internalConnection(conn) if !internalDst || dstSubnet.IPAddrs.Equal(srcCidr) { return diff --git a/pkg/synth/common.go b/pkg/synth/common.go index 92d52d8f..101b01c9 100644 --- a/pkg/synth/common.go +++ b/pkg/synth/common.go @@ -42,7 +42,7 @@ func (e explanation) String() string { return result } -func internalConn(conn *ir.Connection) (internalSrc, internalDst, internal bool) { +func internalConnection(conn *ir.Connection) (internalSrc, internalDst, internal bool) { internalSrc = *conn.Src.Type != ir.ResourceTypeExternal internalDst = *conn.Dst.Type != ir.ResourceTypeExternal internal = internalSrc && internalDst diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 5aadd795..1a1fd993 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -47,15 +47,16 @@ func (s *SGSynthesizer) generateSGRulesFromConnection(conn *ir.Connection, direc for _, remoteCidr := range remoteResource.Cidrs { for _, trackedProtocol := range conn.TrackedProtocols { ruleExplanation := explanation{internal: internalConn, connectionOrigin: conn.Origin, protocolOrigin: trackedProtocol.Origin}.String() - s.allowConnectionEndpoint(localEndpoint, remoteCidr, remoteResource.Type, trackedProtocol.Protocol, direction, internalEndpoint, ruleExplanation) + s.allowConnectionEndpoint(localEndpoint, remoteCidr, remoteResource.Type, trackedProtocol.Protocol, direction, + internalEndpoint, ruleExplanation) } } } } // if the endpoint in internal, a rule will be created to allow traffic. -func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *ir.NamedAddrs, remoteType *ir.ResourceType, p netp.Protocol, direction ir.Direction, - internalEndpoint bool, ruleExplanation string) { +func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *ir.NamedAddrs, remoteType *ir.ResourceType, + p netp.Protocol, direction ir.Direction, internalEndpoint bool, ruleExplanation string) { if !internalEndpoint { return } @@ -78,17 +79,17 @@ func sgRemote(resource *ir.NamedAddrs, t *ir.ResourceType) ir.RemoteType { return resource.IPAddrs } -func connSettings(conn *ir.Connection, direction ir.Direction) (*ir.Resource, *ir.Resource, bool, bool) { - internalSrc, internalDst, internalConn := internalConn(conn) - localResource := conn.Src - remoteResource := conn.Dst - internalEndpoint := internalSrc +func connSettings(conn *ir.Connection, direction ir.Direction) (local, remote *ir.Resource, internalEndpoint, internalConn bool) { + internalSrc, internalDst, internalConn := internalConnection(conn) + local = conn.Src + remote = conn.Dst + internalEndpoint = internalSrc if direction == ir.Inbound { - localResource = conn.Dst - remoteResource = conn.Src + local = conn.Dst + remote = conn.Src internalEndpoint = internalDst } - return localResource, remoteResource, internalEndpoint, internalConn + return } func isSGRemote(t ir.ResourceType) bool { diff --git a/test/error_test_list.go b/test/error_test_list.go index edcd1ff8..c0af8603 100644 --- a/test/error_test_list.go +++ b/test/error_test_list.go @@ -139,19 +139,6 @@ func errorTestsList() []testCase { }, }, - // vpe resource in ACL generation - // { - // testName: "vpe acl", - // expectedErr: "ACL: src/dst of type vpe is not supported", - // args: &command{ - // cmd: synth, - // subcmd: acl, - // config: "%s/vpe_acl/config_object.json", - // spec: "%s/vpe_acl/conn_spec.json", - // outputFile: outputPath, - // }, - // }, - // impossible resource type { testName: "impossible resource type", diff --git a/test/expected/acl_segments_tf/nacl_expected.tf b/test/expected/acl_segments_tf/nacl_expected.tf index a781952b..ed48babf 100644 --- a/test/expected/acl_segments_tf/nacl_expected.tf +++ b/test/expected/acl_segments_tf/nacl_expected.tf @@ -195,17 +195,17 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-2" { rules { name = "rule2" action = "allow" - direction = "inbound" - source = "10.240.64.0/24" - destination = "10.240.65.0/24" + direction = "outbound" + source = "10.240.65.0/24" + destination = "10.240.64.0/24" } # Internal. response to required-connections[2]: (segment subnetSegment)->(segment subnetSegment); allowed-protocols[0] rules { name = "rule3" action = "allow" - direction = "outbound" - source = "10.240.65.0/24" - destination = "10.240.64.0/24" + direction = "inbound" + source = "10.240.64.0/24" + destination = "10.240.65.0/24" } } diff --git a/test/expected/acl_testing5_json/nacl_expected.json b/test/expected/acl_testing5_json/nacl_expected.json index 5fbdc8d5..1d5fddb5 100644 --- a/test/expected/acl_testing5_json/nacl_expected.json +++ b/test/expected/acl_testing5_json/nacl_expected.json @@ -2231,13 +2231,13 @@ "name": "rule1" }, "created_at": null, - "destination": "10.240.64.0/24", - "direction": "inbound", + "destination": "10.240.1.0/24", + "direction": "outbound", "href": "fake:href:61", "id": "fake:id:61", "ip_version": "ipv4", "name": "rule0", - "source": "10.240.1.0/24", + "source": "10.240.64.0/24", "protocol": "all" }, { @@ -2248,13 +2248,13 @@ "name": "rule2" }, "created_at": null, - "destination": "10.240.1.0/24", - "direction": "outbound", + "destination": "10.240.64.0/24", + "direction": "inbound", "href": "fake:href:60", "id": "fake:id:60", "ip_version": "ipv4", "name": "rule1", - "source": "10.240.64.0/24", + "source": "10.240.1.0/24", "protocol": "all" }, { diff --git a/test/expected/acl_testing5_json_single/nacl_single_expected.json b/test/expected/acl_testing5_json_single/nacl_single_expected.json index ffa98f09..2a54ad7a 100644 --- a/test/expected/acl_testing5_json_single/nacl_single_expected.json +++ b/test/expected/acl_testing5_json_single/nacl_single_expected.json @@ -1648,13 +1648,13 @@ "name": "rule3" }, "created_at": null, - "destination": "10.240.64.0/24", - "direction": "inbound", + "destination": "10.240.1.0/24", + "direction": "outbound", "href": "fake:href:51", "id": "fake:id:51", "ip_version": "ipv4", "name": "rule2", - "source": "10.240.1.0/24", + "source": "10.240.64.0/24", "protocol": "all" }, { @@ -1665,13 +1665,13 @@ "name": "rule4" }, "created_at": null, - "destination": "10.240.1.0/24", - "direction": "outbound", + "destination": "10.240.64.0/24", + "direction": "inbound", "href": "fake:href:50", "id": "fake:id:50", "ip_version": "ipv4", "name": "rule3", - "source": "10.240.64.0/24", + "source": "10.240.1.0/24", "protocol": "all" }, { @@ -1719,12 +1719,12 @@ }, "created_at": null, "destination": "10.240.128.0/24", - "direction": "inbound", + "direction": "outbound", "href": "fake:href:47", "id": "fake:id:47", "ip_version": "ipv4", "name": "rule6", - "source": "10.240.1.0/24", + "source": "10.240.64.0/24", "protocol": "icmp", "type": 0 }, @@ -1736,8 +1736,8 @@ "name": "rule8" }, "created_at": null, - "destination": "10.240.1.0/24", - "direction": "outbound", + "destination": "10.240.64.0/24", + "direction": "inbound", "href": "fake:href:46", "id": "fake:id:46", "ip_version": "ipv4", @@ -1755,12 +1755,12 @@ }, "created_at": null, "destination": "10.240.128.0/24", - "direction": "outbound", + "direction": "inbound", "href": "fake:href:45", "id": "fake:id:45", "ip_version": "ipv4", "name": "rule8", - "source": "10.240.64.0/24", + "source": "10.240.1.0/24", "protocol": "icmp", "type": 0 }, @@ -1772,8 +1772,8 @@ "name": "rule10" }, "created_at": null, - "destination": "10.240.64.0/24", - "direction": "inbound", + "destination": "10.240.1.0/24", + "direction": "outbound", "href": "fake:href:44", "id": "fake:id:44", "ip_version": "ipv4", diff --git a/test/expected/acl_testing5_tf/nacl_expected.tf b/test/expected/acl_testing5_tf/nacl_expected.tf index 69925897..d3bb9480 100644 --- a/test/expected/acl_testing5_tf/nacl_expected.tf +++ b/test/expected/acl_testing5_tf/nacl_expected.tf @@ -342,17 +342,17 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--sub2-1" { rules { name = "rule0" action = "allow" - direction = "inbound" - source = "10.240.1.0/24" - destination = "10.240.64.0/24" + direction = "outbound" + source = "10.240.64.0/24" + destination = "10.240.1.0/24" } # Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { name = "rule1" action = "allow" - direction = "outbound" - source = "10.240.64.0/24" - destination = "10.240.1.0/24" + direction = "inbound" + source = "10.240.1.0/24" + destination = "10.240.64.0/24" } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { diff --git a/test/expected/acl_testing5_tf_single/nacl_single_expected.tf b/test/expected/acl_testing5_tf_single/nacl_single_expected.tf index 5e3a1e07..233f9a48 100644 --- a/test/expected/acl_testing5_tf_single/nacl_single_expected.tf +++ b/test/expected/acl_testing5_tf_single/nacl_single_expected.tf @@ -22,17 +22,17 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { rules { name = "rule2" action = "allow" - direction = "inbound" - source = "10.240.1.0/24" - destination = "10.240.64.0/24" + direction = "outbound" + source = "10.240.64.0/24" + destination = "10.240.1.0/24" } # Internal. response to required-connections[0]: (segment need-dns)->(segment need-dns); allowed-protocols[0] rules { name = "rule3" action = "allow" - direction = "outbound" - source = "10.240.64.0/24" - destination = "10.240.1.0/24" + direction = "inbound" + source = "10.240.1.0/24" + destination = "10.240.64.0/24" } # Internal. required-connections[2]: (segment need-dns)->(subnet testacl5-vpc/sub3-1); allowed-protocols[0] rules { @@ -60,8 +60,8 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { rules { name = "rule6" action = "allow" - direction = "inbound" - source = "10.240.1.0/24" + direction = "outbound" + source = "10.240.64.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -71,9 +71,9 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { rules { name = "rule7" action = "allow" - direction = "outbound" + direction = "inbound" source = "10.240.128.0/24" - destination = "10.240.1.0/24" + destination = "10.240.64.0/24" icmp { type = 8 } @@ -82,8 +82,8 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { rules { name = "rule8" action = "allow" - direction = "outbound" - source = "10.240.64.0/24" + direction = "inbound" + source = "10.240.1.0/24" destination = "10.240.128.0/24" icmp { type = 0 @@ -93,9 +93,9 @@ resource "ibm_is_network_acl" "acl-testacl5-vpc--singleACL" { rules { name = "rule9" action = "allow" - direction = "inbound" + direction = "outbound" source = "10.240.128.0/24" - destination = "10.240.64.0/24" + destination = "10.240.1.0/24" icmp { type = 8 } diff --git a/test/expected/acl_tg_multiple_json/nacl_expected.json b/test/expected/acl_tg_multiple_json/nacl_expected.json index 717b2f43..65f2591f 100644 --- a/test/expected/acl_tg_multiple_json/nacl_expected.json +++ b/test/expected/acl_tg_multiple_json/nacl_expected.json @@ -2762,13 +2762,13 @@ "name": "rule1" }, "created_at": null, - "destination": "10.240.4.0/24", - "direction": "inbound", + "destination": "10.240.0.0/24", + "direction": "outbound", "href": "fake:href:16", "id": "fake:id:16", "ip_version": "ipv4", "name": "rule0", - "source": "10.240.0.0/24", + "source": "10.240.4.0/24", "protocol": "all" }, { @@ -2779,13 +2779,13 @@ "name": "rule2" }, "created_at": null, - "destination": "10.240.0.0/24", - "direction": "outbound", + "destination": "10.240.4.0/24", + "direction": "inbound", "href": "fake:href:15", "id": "fake:id:15", "ip_version": "ipv4", "name": "rule1", - "source": "10.240.4.0/24", + "source": "10.240.0.0/24", "protocol": "all" }, { diff --git a/test/expected/acl_tg_multiple_tf/nacl_expected.tf b/test/expected/acl_tg_multiple_tf/nacl_expected.tf index da72d490..fc11198a 100644 --- a/test/expected/acl_tg_multiple_tf/nacl_expected.tf +++ b/test/expected/acl_tg_multiple_tf/nacl_expected.tf @@ -65,17 +65,17 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { rules { name = "rule0" action = "allow" - direction = "inbound" - source = "10.240.0.0/24" - destination = "10.240.4.0/24" + direction = "outbound" + source = "10.240.4.0/24" + destination = "10.240.0.0/24" } # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { name = "rule1" action = "allow" - direction = "outbound" - source = "10.240.4.0/24" - destination = "10.240.0.0/24" + direction = "inbound" + source = "10.240.0.0/24" + destination = "10.240.4.0/24" } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { diff --git a/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf b/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf index f4076710..469cecc7 100644 --- a/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf +++ b/test/expected/acl_tg_multiple_tf_separate/test-vpc0.tf @@ -65,17 +65,17 @@ resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { rules { name = "rule0" action = "allow" - direction = "inbound" - source = "10.240.0.0/24" - destination = "10.240.4.0/24" + direction = "outbound" + source = "10.240.4.0/24" + destination = "10.240.0.0/24" } # Internal. response to required-connections[0]: (segment segment1)->(segment segment1); allowed-protocols[0] rules { name = "rule1" action = "allow" - direction = "outbound" - source = "10.240.4.0/24" - destination = "10.240.0.0/24" + direction = "inbound" + source = "10.240.0.0/24" + destination = "10.240.4.0/24" } # Internal. required-connections[1]: (segment segment1)->(subnet test-vpc0/subnet3); allowed-protocols[0] rules { diff --git a/test/main_test.go b/test/main_test.go index e971d82f..206ebb2f 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -15,6 +15,10 @@ import ( ) func TestMain(t *testing.T) { + testMain(t) +} + +func testMain(t *testing.T) { for _, tt := range allMainTests() { t.Run(tt.testName, func(t *testing.T) { // create a sub folder From e763b725ba4b7003e3ee3fd7e2e12e3da83b7ce6 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 14 Oct 2024 14:42:26 +0300 Subject: [PATCH 075/131] readme --- README.md | 11 ++++++----- test/main_test.go | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 66394d5d..54a36496 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,15 @@ Use the `vpcgen` CLI tool with one of the following commands to specify the type ### nACLs Generation Specifying the `--single` flag results in generating a single nACL for all subnets in the same VPC. Otherwise, an nACL is generated for each subnet separately. -The input supports subnets, subnet segments, CIDR segments, NIFs, instances (VSIs) and externals. -**Note 1**: The segments are defined in the `conn_spec.json` file. -**Note 2**: A required connection between NIFs or VSIs implies connectivity will be allowed between the subnets they are contained in. +**Note**: A required connection between NIFs/VSIs/VPEs implies connectivity will be allowed between the subnets they are contained in. -### SGs Generation -The input supports Instances (VSIs), NIFs, VPEs and externals. +### SGs Generation **Note**: A Security Group, generated for a specific VSI (or for one of its NIFs), will be applied to all the NIFs of the VSI. The same goes for Reserved IPs of a VPE. +### Supported types +The input supports subnets, subnet segments, CIDR segments, NIFs, NIF segments, instances (VSIs), instance segments, VPEs, VPE segments and externals. +**Note 1**: The segments are defined in the `conn_spec.json` file. + ### Output 1. If the `output-dir` flag is used, the specified folder will be created, containing one file per VPC. Each generated file will contain the network resources (Security Groups or Network ACLs) relevant to its VPC. File names are set as `prefix_vpc`, where prefix is ​​the value received in the `prefix` flag. If the `prefix` flag is omitted, file names will match VPC names. 2. If the `output-file` flag is used, all generated resources will be written to the specified file. diff --git a/test/main_test.go b/test/main_test.go index 206ebb2f..e8473908 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -14,6 +14,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/cmd/subcmds" ) +// comment lines 18-20 and uncomment `update_test.go` file to update all test outputs func TestMain(t *testing.T) { testMain(t) } From d6fa8c3a88efd6b8eafcbe73e9544b41425bac06 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 14 Oct 2024 14:48:48 +0300 Subject: [PATCH 076/131] rename acl_segment test --- .../config_object.json | 0 .../conn_spec.json | 0 .../nacl_expected.tf | 0 test/synth_test_list.go | 14 +++++++------- 4 files changed, 7 insertions(+), 7 deletions(-) rename test/data/{acl_segments => acl_subnet_cidr_segments}/config_object.json (100%) rename test/data/{acl_segments => acl_subnet_cidr_segments}/conn_spec.json (100%) rename test/expected/{acl_segments_tf => acl_subnet_cidr_segments_tf}/nacl_expected.tf (100%) diff --git a/test/data/acl_segments/config_object.json b/test/data/acl_subnet_cidr_segments/config_object.json similarity index 100% rename from test/data/acl_segments/config_object.json rename to test/data/acl_subnet_cidr_segments/config_object.json diff --git a/test/data/acl_segments/conn_spec.json b/test/data/acl_subnet_cidr_segments/conn_spec.json similarity index 100% rename from test/data/acl_segments/conn_spec.json rename to test/data/acl_subnet_cidr_segments/conn_spec.json diff --git a/test/expected/acl_segments_tf/nacl_expected.tf b/test/expected/acl_subnet_cidr_segments_tf/nacl_expected.tf similarity index 100% rename from test/expected/acl_segments_tf/nacl_expected.tf rename to test/expected/acl_subnet_cidr_segments_tf/nacl_expected.tf diff --git a/test/synth_test_list.go b/test/synth_test_list.go index d8e37147..79f88b52 100644 --- a/test/synth_test_list.go +++ b/test/synth_test_list.go @@ -15,8 +15,8 @@ const ( aclProtocolsConfig = "%s/acl_protocols/config_object.json" aclProtocolsSpec = "%s/acl_protocols/conn_spec.json" - aclSegmentsConfig = "%s/acl_segments/config_object.json" - aclSegmentsSpec = "%s/acl_segments/conn_spec.json" + aclSubnetCidrSegmentsConfig = "%s/acl_subnet_cidr_segments/config_object.json" + aclSubnetCidrSegmentsSpec = "%s/acl_subnet_cidr_segments/conn_spec.json" aclTesting5Config = "%s/acl_testing5/config_object.json" aclTesting5Spec = "%s/acl_testing5/conn_spec.json" @@ -119,15 +119,15 @@ func synthACLTestsList() []testCase { }, }, - // acl segments (bidi) ## acl_testing5 config + // acl subnet and cidr segments (bidi) ## acl_testing5 config { - testName: "acl_segments_tf", + testName: "acl_subnet_cidr_segments_tf", args: &command{ cmd: synth, subcmd: acl, - config: aclSegmentsConfig, - spec: aclSegmentsSpec, - outputFile: "%s/acl_segments_tf/nacl_expected.tf", + config: aclSubnetCidrSegmentsConfig, + spec: aclSubnetCidrSegmentsSpec, + outputFile: "%s/acl_subnet_cidr_segments_tf/nacl_expected.tf", }, }, From 4894fa862652053be3c5b60741f6968c52a409f1 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 14 Oct 2024 15:50:31 +0300 Subject: [PATCH 077/131] generic synth acl func --- pkg/ir/spec.go | 2 -- pkg/synth/acl.go | 29 +++++++++++------------------ 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index 604b2c69..c89d15a2 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -111,8 +111,6 @@ type ( VPCDetails struct { AddressPrefixes *netset.IPBlock - // tg - // lb } SubnetDetails struct { diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index 3fa7b73a..9b4dc8f4 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -36,32 +36,25 @@ func (a *ACLSynthesizer) Synth() ir.Collection { // 1. generate nACL rules for relevant subnets for each connection // 2. generate nACL rules for blocked subnets (subnets that do not appear in Spec) func (a *ACLSynthesizer) makeACL() *ir.ACLCollection { - for c := range a.spec.Connections { - a.generateACLRulesFromConnection(a.spec.Connections[c]) + for i := range a.spec.Connections { + conn := a.spec.Connections[i] + a.generateACLRulesFromConnection(conn, conn.Src, conn.Dst, a.allowConnectionSrc) + a.generateACLRulesFromConnection(conn, conn.Dst, conn.Src, a.allowConnectionDst) } a.generateACLRulesForBlockedSubnets() return a.result } -func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection) { - for _, srcSubnet := range conn.Src.NamedAddrs { - for _, dstCidr := range conn.Dst.Cidrs { - if srcSubnet.IPAddrs.Equal(dstCidr.IPAddrs) && *conn.Src.Type != ir.ResourceTypeCidr && *conn.Dst.Type != ir.ResourceTypeCidr { +func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection, thisResource, otherResource *ir.Resource, + allowConnection func(*ir.Connection, *ir.TrackedProtocol, *ir.NamedAddrs, *netset.IPBlock)) { + for _, thisSubnet := range thisResource.NamedAddrs { + for _, otherCidr := range otherResource.Cidrs { + if thisSubnet.IPAddrs.Equal(otherCidr.IPAddrs) && *thisResource.Type != ir.ResourceTypeCidr && + *otherResource.Type != ir.ResourceTypeCidr { continue } for _, trackedProtocol := range conn.TrackedProtocols { - a.allowConnectionSrc(conn, trackedProtocol, srcSubnet, dstCidr.IPAddrs) - } - } - } - - for _, srcCidr := range conn.Src.Cidrs { - for _, dstSubnet := range conn.Dst.NamedAddrs { - if dstSubnet.IPAddrs.Equal(srcCidr.IPAddrs) && *conn.Src.Type != ir.ResourceTypeCidr && *conn.Dst.Type != ir.ResourceTypeCidr { - continue - } - for _, trackedProtocol := range conn.TrackedProtocols { - a.allowConnectionDst(conn, trackedProtocol, dstSubnet, srcCidr.IPAddrs) + allowConnection(conn, trackedProtocol, thisSubnet, otherCidr.IPAddrs) } } } From dc921299338d494c4832969a8f1292992b805e34 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 14 Oct 2024 16:10:32 +0300 Subject: [PATCH 078/131] added instance nif segment test (acl) --- .../config_object.json | 6269 +++++++++++++++++ .../acl_nif_instance_segments/conn_spec.json | 57 + .../nacl_expected.tf | 373 + test/synth_test_list.go | 15 + 4 files changed, 6714 insertions(+) create mode 100644 test/data/acl_nif_instance_segments/config_object.json create mode 100644 test/data/acl_nif_instance_segments/conn_spec.json create mode 100644 test/expected/acl_nif_instance_segments_tf/nacl_expected.tf diff --git a/test/data/acl_nif_instance_segments/config_object.json b/test/data/acl_nif_instance_segments/config_object.json new file mode 100644 index 00000000..7e94d3b8 --- /dev/null +++ b/test/data/acl_nif_instance_segments/config_object.json @@ -0,0 +1,6269 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-06-25T15:40:20.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.22.215.5" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.22.220.2" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.249.82.12" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "automaker-castle-bird-worried" + }, + "default_routing_table": { + "href": "href:11", + "id": "id:12", + "name": "overtone-sputter-overspend-gorge", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "brute-upon-angles-cubbyhole" + }, + "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": "test-vpc1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "vpc", + "status": "available", + "region": "us-south", + "address_prefixes": [ + { + "cidr": "10.240.80.0/20", + "created_at": "2024-06-25T15:40:39.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": false, + "name": "address-prefix-vpc-1", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.64.0/20", + "created_at": "2024-06-25T15:40:40.000Z", + "has_subnets": true, + "href": "href:20", + "id": "id:21", + "is_default": false, + "name": "address-prefix-vpc-0", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + } + ], + "tags": [] + }, + { + "classic_access": false, + "created_at": "2024-06-25T15:40:19.000Z", + "crn": "crn:22", + "cse_source_ips": [ + { + "ip": { + "address": "10.16.238.56" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.249.200.205" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.249.212.88" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:25", + "href": "href:26", + "id": "id:27", + "name": "ebullient-slacks-revert-turkey" + }, + "default_routing_table": { + "href": "href:28", + "id": "id:29", + "name": "escapade-dynamite-upstage-context", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "basically-drank-bulk-jam" + }, + "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:23", + "id": "id:24", + "name": "test-vpc0", + "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/22", + "created_at": "2024-06-25T15:40:37.000Z", + "has_subnets": true, + "href": "href:33", + "id": "id:34", + "is_default": false, + "name": "address-prefix-vpc-0", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.4.0/22", + "created_at": "2024-06-25T15:40:38.000Z", + "has_subnets": true, + "href": "href:35", + "id": "id:36", + "is_default": false, + "name": "address-prefix-vpc-1", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.8.0/22", + "created_at": "2024-06-25T15:40:39.000Z", + "has_subnets": true, + "href": "href:37", + "id": "id:38", + "is_default": false, + "name": "address-prefix-vpc-2", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + } + ], + "tags": [] + }, + { + "classic_access": false, + "created_at": "2024-06-25T15:40:19.000Z", + "crn": "crn:39", + "cse_source_ips": [ + { + "ip": { + "address": "10.12.125.16" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.22.27.134" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.22.231.90" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:42", + "href": "href:43", + "id": "id:44", + "name": "afoot-grape-fineness-zestfully" + }, + "default_routing_table": { + "href": "href:45", + "id": "id:46", + "name": "quintuple-severity-caddie-manuals", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "glance-cactus-unease-bankroll" + }, + "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:40", + "id": "id:41", + "name": "test-vpc2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "vpc", + "status": "available", + "region": "us-south", + "address_prefixes": [ + { + "cidr": "10.240.128.0/20", + "created_at": "2024-06-25T15:40:39.000Z", + "has_subnets": true, + "href": "href:50", + "id": "id:51", + "is_default": false, + "name": "address-prefix-vpc-0", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [] + }, + { + "classic_access": false, + "created_at": "2024-06-25T15:40:19.000Z", + "crn": "crn:52", + "cse_source_ips": [ + { + "ip": { + "address": "10.22.219.155" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.12.159.11" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.16.253.109" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:55", + "href": "href:56", + "id": "id:57", + "name": "untracked-repayment-triumph-cat" + }, + "default_routing_table": { + "href": "href:58", + "id": "id:59", + "name": "probational-herring-undone-daintily", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:60", + "href": "href:61", + "id": "id:62", + "name": "repeater-upcountry-agreeing-acutely" + }, + "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:53", + "id": "id:54", + "name": "test-vpc3", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "vpc", + "status": "available", + "region": "us-south", + "address_prefixes": [ + { + "cidr": "10.240.192.0/20", + "created_at": "2024-06-25T15:40:38.000Z", + "has_subnets": true, + "href": "href:63", + "id": "id:64", + "is_default": false, + "name": "address-prefix-vpc-0", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 249, + "created_at": "2024-06-25T15:41:47.000Z", + "crn": "crn:65", + "href": "href:66", + "id": "id:67", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.9.0/24", + "name": "subnet5", + "network_acl": { + "crn": "crn:68", + "href": "href:69", + "id": "id:70", + "name": "acl3" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:28", + "id": "id:29", + "name": "escapade-dynamite-upstage-context", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.9.0", + "auto_delete": false, + "created_at": "2024-06-25T15:41:47.000Z", + "href": "href:71", + "id": "id:72", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.9.1", + "auto_delete": false, + "created_at": "2024-06-25T15:41:47.000Z", + "href": "href:73", + "id": "id:74", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.9.2", + "auto_delete": false, + "created_at": "2024-06-25T15:41:47.000Z", + "href": "href:75", + "id": "id:76", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.9.3", + "auto_delete": false, + "created_at": "2024-06-25T15:41:47.000Z", + "href": "href:77", + "id": "id:78", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.9.4", + "auto_delete": false, + "created_at": "2024-06-25T15:42:00.000Z", + "href": "href:79", + "id": "id:80", + "lifecycle_state": "stable", + "name": "ideally-grain-bagpipe-luxuriant", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:81", + "id": "id:82", + "name": "stooped-camera-excluded-juke", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.9.5", + "auto_delete": false, + "created_at": "2024-06-25T15:42:20.000Z", + "href": "href:83", + "id": "id:84", + "lifecycle_state": "stable", + "name": "outskirts-unaligned-passivism-parchment", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:85", + "id": "id:86", + "name": "scratch-outward-raging-hunchback", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.9.255", + "auto_delete": false, + "created_at": "2024-06-25T15:41:47.000Z", + "href": "href:87", + "id": "id:88", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-06-25T15:41:35.000Z", + "crn": "crn:89", + "href": "href:90", + "id": "id:91", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.5.0/24", + "name": "subnet3", + "network_acl": { + "crn": "crn:92", + "href": "href:93", + "id": "id:94", + "name": "acl2" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:28", + "id": "id:29", + "name": "escapade-dynamite-upstage-context", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.5.0", + "auto_delete": false, + "created_at": "2024-06-25T15:41:35.000Z", + "href": "href:95", + "id": "id:96", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.5.1", + "auto_delete": false, + "created_at": "2024-06-25T15:41:35.000Z", + "href": "href:97", + "id": "id:98", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.5.2", + "auto_delete": false, + "created_at": "2024-06-25T15:41:35.000Z", + "href": "href:99", + "id": "id:100", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.5.3", + "auto_delete": false, + "created_at": "2024-06-25T15:41:35.000Z", + "href": "href:101", + "id": "id:102", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.5.4", + "auto_delete": false, + "created_at": "2024-06-25T15:42:00.000Z", + "href": "href:103", + "id": "id:104", + "lifecycle_state": "stable", + "name": "rising-gopher-reentry-graveness", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:105", + "id": "id:106", + "name": "icky-balsamic-outgoing-leached", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.5.5", + "auto_delete": false, + "created_at": "2024-06-25T15:42:16.000Z", + "href": "href:107", + "id": "id:108", + "lifecycle_state": "stable", + "name": "recognize-citable-exerciser-unsecured", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:109", + "id": "id:110", + "name": "squatted-fastball-vacant-knoll", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.5.255", + "auto_delete": false, + "created_at": "2024-06-25T15:41:35.000Z", + "href": "href:111", + "id": "id:112", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-06-25T15:41:23.000Z", + "crn": "crn:113", + "href": "href:114", + "id": "id:115", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.0.0/24", + "name": "subnet0", + "network_acl": { + "crn": "crn:116", + "href": "href:117", + "id": "id:118", + "name": "acl1" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:28", + "id": "id:29", + "name": "escapade-dynamite-upstage-context", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.0.0", + "auto_delete": false, + "created_at": "2024-06-25T15:41:23.000Z", + "href": "href:119", + "id": "id:120", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.0.1", + "auto_delete": false, + "created_at": "2024-06-25T15:41:23.000Z", + "href": "href:121", + "id": "id:122", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.0.2", + "auto_delete": false, + "created_at": "2024-06-25T15:41:23.000Z", + "href": "href:123", + "id": "id:124", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.0.3", + "auto_delete": false, + "created_at": "2024-06-25T15:41:23.000Z", + "href": "href:125", + "id": "id:126", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.0.4", + "auto_delete": false, + "created_at": "2024-06-25T15:42:08.000Z", + "href": "href:127", + "id": "id:128", + "lifecycle_state": "stable", + "name": "pundit-tight-arbitrate-grace", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:129", + "id": "id:130", + "name": "writer-crusher-unsuited-cash", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.0.5", + "auto_delete": false, + "created_at": "2024-06-25T15:42:39.000Z", + "href": "href:131", + "id": "id:132", + "lifecycle_state": "stable", + "name": "relatable-antiques-maturing-brulee", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:133", + "id": "id:134", + "name": "consonant-imperial-simply-ceramics", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.0.255", + "auto_delete": false, + "created_at": "2024-06-25T15:41:23.000Z", + "href": "href:135", + "id": "id:136", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-06-25T15:41:20.000Z", + "crn": "crn:137", + "href": "href:138", + "id": "id:139", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.80.0/24", + "name": "subnet11", + "network_acl": { + "crn": "crn:140", + "href": "href:141", + "id": "id:142", + "name": "acl11" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "overtone-sputter-overspend-gorge", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + }, + "reserved_ips": [ + { + "address": "10.240.80.0", + "auto_delete": false, + "created_at": "2024-06-25T15:41:20.000Z", + "href": "href:143", + "id": "id:144", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.80.1", + "auto_delete": false, + "created_at": "2024-06-25T15:41:20.000Z", + "href": "href:145", + "id": "id:146", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.80.2", + "auto_delete": false, + "created_at": "2024-06-25T15:41:20.000Z", + "href": "href:147", + "id": "id:148", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.80.3", + "auto_delete": false, + "created_at": "2024-06-25T15:41:20.000Z", + "href": "href:149", + "id": "id:150", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.80.4", + "auto_delete": false, + "created_at": "2024-06-25T15:41:40.000Z", + "href": "href:151", + "id": "id:152", + "lifecycle_state": "stable", + "name": "childlike-publish-retainer-movie", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:153", + "id": "id:154", + "name": "stride-woken-backsight-dynastic", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.80.255", + "auto_delete": false, + "created_at": "2024-06-25T15:41:20.000Z", + "href": "href:155", + "id": "id:156", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-06-25T15:41:08.000Z", + "crn": "crn:157", + "href": "href:158", + "id": "id:159", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.4.0/24", + "name": "subnet2", + "network_acl": { + "crn": "crn:92", + "href": "href:93", + "id": "id:94", + "name": "acl2" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:28", + "id": "id:29", + "name": "escapade-dynamite-upstage-context", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.4.0", + "auto_delete": false, + "created_at": "2024-06-25T15:41:08.000Z", + "href": "href:160", + "id": "id:161", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.4.1", + "auto_delete": false, + "created_at": "2024-06-25T15:41:08.000Z", + "href": "href:162", + "id": "id:163", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.4.2", + "auto_delete": false, + "created_at": "2024-06-25T15:41:08.000Z", + "href": "href:164", + "id": "id:165", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.4.3", + "auto_delete": false, + "created_at": "2024-06-25T15:41:08.000Z", + "href": "href:166", + "id": "id:167", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.4.4", + "auto_delete": false, + "created_at": "2024-06-25T15:42:21.000Z", + "href": "href:168", + "id": "id:169", + "lifecycle_state": "stable", + "name": "stood-sitcom-whoops-hurled", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:170", + "id": "id:171", + "name": "graveyard-handmade-ransack-acquaint", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.4.5", + "auto_delete": false, + "created_at": "2024-06-25T15:42:22.000Z", + "href": "href:172", + "id": "id:173", + "lifecycle_state": "stable", + "name": "bark-gatherer-rope-unrivaled", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:174", + "id": "id:175", + "name": "quantum-handbag-dimmed-reassign", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.4.255", + "auto_delete": false, + "created_at": "2024-06-25T15:41:08.000Z", + "href": "href:176", + "id": "id:177", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-06-25T15:41:08.000Z", + "crn": "crn:178", + "href": "href:179", + "id": "id:180", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.64.0/24", + "name": "subnet10", + "network_acl": { + "crn": "crn:140", + "href": "href:141", + "id": "id:142", + "name": "acl11" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "overtone-sputter-overspend-gorge", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "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-25T15:41:08.000Z", + "href": "href:181", + "id": "id:182", + "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-25T15:41:08.000Z", + "href": "href:183", + "id": "id:184", + "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-25T15:41:08.000Z", + "href": "href:185", + "id": "id:186", + "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-25T15:41:08.000Z", + "href": "href:187", + "id": "id:188", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.64.4", + "auto_delete": false, + "created_at": "2024-06-25T15:41:36.000Z", + "href": "href:189", + "id": "id:190", + "lifecycle_state": "stable", + "name": "starry-smasher-ladle-dioxide", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:191", + "id": "id:192", + "name": "enlace-prominent-overhear-perfume", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.64.255", + "auto_delete": false, + "created_at": "2024-06-25T15:41:08.000Z", + "href": "href:193", + "id": "id:194", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 248, + "created_at": "2024-06-25T15:40:57.000Z", + "crn": "crn:195", + "href": "href:196", + "id": "id:197", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.128.0/24", + "name": "subnet20", + "network_acl": { + "crn": "crn:198", + "href": "href:199", + "id": "id:200", + "name": "acl21" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:45", + "id": "id:46", + "name": "quintuple-severity-caddie-manuals", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:39", + "href": "href:40", + "id": "id:41", + "name": "test-vpc2", + "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-25T15:40:57.000Z", + "href": "href:201", + "id": "id:202", + "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-25T15:40:57.000Z", + "href": "href:203", + "id": "id:204", + "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-25T15:40:57.000Z", + "href": "href:205", + "id": "id:206", + "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-25T15:40:57.000Z", + "href": "href:207", + "id": "id:208", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.128.4", + "auto_delete": false, + "created_at": "2024-06-25T15:41:21.000Z", + "href": "href:209", + "id": "id:210", + "lifecycle_state": "stable", + "name": "unmixed-qualify-prescribe-railcar", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:211", + "id": "id:212", + "name": "tavern-far-imprudent-labored", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.128.5", + "auto_delete": false, + "created_at": "2024-06-25T15:41:21.000Z", + "href": "href:213", + "id": "id:214", + "lifecycle_state": "stable", + "name": "customs-recollect-drippy-primate", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:215", + "id": "id:216", + "name": "ought-football-shorter-aviator", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.128.6", + "auto_delete": false, + "created_at": "2024-06-25T15:41:24.000Z", + "href": "href:217", + "id": "id:218", + "lifecycle_state": "stable", + "name": "uniquely-shelter-gracious-sudden", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:219", + "id": "id:220", + "name": "clicker-grumbly-outskirts-greatly", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.128.255", + "auto_delete": false, + "created_at": "2024-06-25T15:40:57.000Z", + "href": "href:221", + "id": "id:222", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-06-25T15:40:56.000Z", + "crn": "crn:223", + "href": "href:224", + "id": "id:225", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.1.0/24", + "name": "subnet1", + "network_acl": { + "crn": "crn:116", + "href": "href:117", + "id": "id:118", + "name": "acl1" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:28", + "id": "id:29", + "name": "escapade-dynamite-upstage-context", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "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-25T15:40:56.000Z", + "href": "href:226", + "id": "id:227", + "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-25T15:40:56.000Z", + "href": "href:228", + "id": "id:229", + "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-25T15:40:56.000Z", + "href": "href:230", + "id": "id:231", + "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-25T15:40:56.000Z", + "href": "href:232", + "id": "id:233", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.1.4", + "auto_delete": false, + "created_at": "2024-06-25T15:42:00.000Z", + "href": "href:234", + "id": "id:235", + "lifecycle_state": "stable", + "name": "excluded-unfair-jailbird-foil", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:236", + "id": "id:237", + "name": "hankie-excitable-outclass-unmanaged", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.1.5", + "auto_delete": false, + "created_at": "2024-06-25T15:42:40.000Z", + "href": "href:238", + "id": "id:239", + "lifecycle_state": "stable", + "name": "affected-johnniecake-monorail-ungraded", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:240", + "id": "id:241", + "name": "scale-clambake-endearing-abridged", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.1.255", + "auto_delete": false, + "created_at": "2024-06-25T15:40:56.000Z", + "href": "href:242", + "id": "id:243", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-06-25T15:40:48.000Z", + "crn": "crn:244", + "href": "href:245", + "id": "id:246", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.192.0/24", + "name": "subnet30", + "network_acl": { + "crn": "crn:247", + "href": "href:248", + "id": "id:249", + "name": "acl31" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:58", + "id": "id:59", + "name": "probational-herring-undone-daintily", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:52", + "href": "href:53", + "id": "id:54", + "name": "test-vpc3", + "resource_type": "vpc" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "reserved_ips": [ + { + "address": "10.240.192.0", + "auto_delete": false, + "created_at": "2024-06-25T15:40:48.000Z", + "href": "href:250", + "id": "id:251", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.192.1", + "auto_delete": false, + "created_at": "2024-06-25T15:40:48.000Z", + "href": "href:252", + "id": "id:253", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.192.2", + "auto_delete": false, + "created_at": "2024-06-25T15:40:48.000Z", + "href": "href:254", + "id": "id:255", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.192.3", + "auto_delete": false, + "created_at": "2024-06-25T15:40:48.000Z", + "href": "href:256", + "id": "id:257", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.192.4", + "auto_delete": false, + "created_at": "2024-06-25T15:41:01.000Z", + "href": "href:258", + "id": "id:259", + "lifecycle_state": "stable", + "name": "legacy-shore-molecule-barometer", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:260", + "id": "id:261", + "name": "snout-given-twiddle-splinter", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.192.255", + "auto_delete": false, + "created_at": "2024-06-25T15:40:48.000Z", + "href": "href:262", + "id": "id:263", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-06-25T15:40:44.000Z", + "crn": "crn:264", + "href": "href:265", + "id": "id:266", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.8.0/24", + "name": "subnet4", + "network_acl": { + "crn": "crn:68", + "href": "href:69", + "id": "id:70", + "name": "acl3" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:28", + "id": "id:29", + "name": "escapade-dynamite-upstage-context", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.8.0", + "auto_delete": false, + "created_at": "2024-06-25T15:40:44.000Z", + "href": "href:267", + "id": "id:268", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.8.1", + "auto_delete": false, + "created_at": "2024-06-25T15:40:44.000Z", + "href": "href:269", + "id": "id:270", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.8.2", + "auto_delete": false, + "created_at": "2024-06-25T15:40:44.000Z", + "href": "href:271", + "id": "id:272", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.8.3", + "auto_delete": false, + "created_at": "2024-06-25T15:40:44.000Z", + "href": "href:273", + "id": "id:274", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.8.4", + "auto_delete": false, + "created_at": "2024-06-25T15:42:00.000Z", + "href": "href:275", + "id": "id:276", + "lifecycle_state": "stable", + "name": "bagged-posture-glaring-cojoined", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:277", + "id": "id:278", + "name": "bullring-ransack-feint-cheer", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.8.5", + "auto_delete": false, + "created_at": "2024-06-25T15:42:16.000Z", + "href": "href:279", + "id": "id:280", + "lifecycle_state": "stable", + "name": "frighten-mystified-freeway-hurtling", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:281", + "id": "id:282", + "name": "speak-princess-washcloth-companion", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.8.255", + "auto_delete": false, + "created_at": "2024-06-25T15:40:44.000Z", + "href": "href:283", + "id": "id:284", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + } + ], + "public_gateways": [], + "floating_ips": [ + { + "address": "52.118.151.238", + "created_at": "2024-06-25T15:43:30.000Z", + "crn": "crn:285", + "href": "href:286", + "id": "id:287", + "name": "fip-0-subnet0", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:129", + "id": "id:130", + "name": "writer-crusher-unsuited-cash", + "primary_ip": { + "address": "10.240.0.4", + "href": "href:127", + "id": "id:128", + "name": "pundit-tight-arbitrate-grace", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + }, + { + "address": "150.239.167.146", + "created_at": "2024-06-25T15:41:59.000Z", + "crn": "crn:288", + "href": "href:289", + "id": "id:290", + "name": "fip-0-subnet10", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:191", + "id": "id:192", + "name": "enlace-prominent-overhear-perfume", + "primary_ip": { + "address": "10.240.64.4", + "href": "href:189", + "id": "id:190", + "name": "starry-smasher-ladle-dioxide", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + }, + "tags": [] + }, + { + "address": "169.48.95.165", + "created_at": "2024-06-25T15:41:50.000Z", + "crn": "crn:291", + "href": "href:292", + "id": "id:293", + "name": "fip-0-subnet20", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:219", + "id": "id:220", + "name": "clicker-grumbly-outskirts-greatly", + "primary_ip": { + "address": "10.240.128.6", + "href": "href:217", + "id": "id:218", + "name": "uniquely-shelter-gracious-sudden", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "tags": [] + }, + { + "address": "52.118.100.239", + "created_at": "2024-06-25T15:41:33.000Z", + "crn": "crn:294", + "href": "href:295", + "id": "id:296", + "name": "fip-0-subnet30", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:260", + "id": "id:261", + "name": "snout-given-twiddle-splinter", + "primary_ip": { + "address": "10.240.192.4", + "href": "href:258", + "id": "id:259", + "name": "legacy-shore-molecule-barometer", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": "2024-06-25T15:40:41.000Z", + "crn": "crn:140", + "href": "href:141", + "id": "id:142", + "name": "acl11", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "deny", + "before": { + "href": "href:299", + "id": "id:300", + "name": "acl11-out-2" + }, + "created_at": "2024-06-25T15:40:42.000Z", + "destination": "10.240.4.0/24", + "direction": "outbound", + "href": "href:297", + "id": "id:298", + "ip_version": "ipv4", + "name": "acl11-out-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:301", + "id": "id:302", + "name": "acl11-in-1" + }, + "created_at": "2024-06-25T15:40:43.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:299", + "id": "id:300", + "ip_version": "ipv4", + "name": "acl11-out-2", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-25T15:40:43.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:301", + "id": "id:302", + "ip_version": "ipv4", + "name": "acl11-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:137", + "href": "href:138", + "id": "id:139", + "name": "subnet11", + "resource_type": "subnet" + }, + { + "crn": "crn:178", + "href": "href:179", + "id": "id:180", + "name": "subnet10", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:40.000Z", + "crn": "crn:247", + "href": "href:248", + "id": "id:249", + "name": "acl31", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:305", + "id": "id:306", + "name": "acl31-in-1" + }, + "created_at": "2024-06-25T15:40:41.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:303", + "id": "id:304", + "ip_version": "ipv4", + "name": "acl31-out-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-25T15:40:41.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:305", + "id": "id:306", + "ip_version": "ipv4", + "name": "acl31-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:244", + "href": "href:245", + "id": "id:246", + "name": "subnet30", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:52", + "href": "href:53", + "id": "id:54", + "name": "test-vpc3", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:40.000Z", + "crn": "crn:198", + "href": "href:199", + "id": "id:200", + "name": "acl21", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:309", + "id": "id:310", + "name": "acl21-in-1" + }, + "created_at": "2024-06-25T15:40:41.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:307", + "id": "id:308", + "ip_version": "ipv4", + "name": "acl21-out-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-25T15:40:42.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:309", + "id": "id:310", + "ip_version": "ipv4", + "name": "acl21-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:195", + "href": "href:196", + "id": "id:197", + "name": "subnet20", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:39", + "href": "href:40", + "id": "id:41", + "name": "test-vpc2", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:38.000Z", + "crn": "crn:92", + "href": "href:93", + "id": "id:94", + "name": "acl2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:313", + "id": "id:314", + "name": "acl1-in-1" + }, + "created_at": "2024-06-25T15:40:38.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:311", + "id": "id:312", + "ip_version": "ipv4", + "name": "acl1-out-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-25T15:40:39.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:313", + "id": "id:314", + "ip_version": "ipv4", + "name": "acl1-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:89", + "href": "href:90", + "id": "id:91", + "name": "subnet3", + "resource_type": "subnet" + }, + { + "crn": "crn:157", + "href": "href:158", + "id": "id:159", + "name": "subnet2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:37.000Z", + "crn": "crn:68", + "href": "href:69", + "id": "id:70", + "name": "acl3", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:317", + "id": "id:318", + "name": "acl1-in-1" + }, + "created_at": "2024-06-25T15:40:38.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:315", + "id": "id:316", + "ip_version": "ipv4", + "name": "acl1-out-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-25T15:40:38.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:317", + "id": "id:318", + "ip_version": "ipv4", + "name": "acl1-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:65", + "href": "href:66", + "id": "id:67", + "name": "subnet5", + "resource_type": "subnet" + }, + { + "crn": "crn:264", + "href": "href:265", + "id": "id:266", + "name": "subnet4", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:37.000Z", + "crn": "crn:116", + "href": "href:117", + "id": "id:118", + "name": "acl1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:321", + "id": "id:322", + "name": "acl1-in-1" + }, + "created_at": "2024-06-25T15:40:38.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:319", + "id": "id:320", + "ip_version": "ipv4", + "name": "acl1-out-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-25T15:40:38.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:321", + "id": "id:322", + "ip_version": "ipv4", + "name": "acl1-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:113", + "href": "href:114", + "id": "id:115", + "name": "subnet0", + "resource_type": "subnet" + }, + { + "crn": "crn:223", + "href": "href:224", + "id": "id:225", + "name": "subnet1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:20.000Z", + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "automaker-castle-bird-worried", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:325", + "id": "id:326", + "name": "allow-outbound" + }, + "created_at": "2024-06-25T15:40:20.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:323", + "id": "id:324", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-25T15:40:20.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:325", + "id": "id:326", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:19.000Z", + "crn": "crn:42", + "href": "href:43", + "id": "id:44", + "name": "afoot-grape-fineness-zestfully", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:329", + "id": "id:330", + "name": "allow-outbound" + }, + "created_at": "2024-06-25T15:40:19.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:327", + "id": "id:328", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-25T15:40:19.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:329", + "id": "id:330", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:39", + "href": "href:40", + "id": "id:41", + "name": "test-vpc2", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:19.000Z", + "crn": "crn:25", + "href": "href:26", + "id": "id:27", + "name": "ebullient-slacks-revert-turkey", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:333", + "id": "id:334", + "name": "allow-outbound" + }, + "created_at": "2024-06-25T15:40:19.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:331", + "id": "id:332", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-25T15:40:19.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:333", + "id": "id:334", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:19.000Z", + "crn": "crn:55", + "href": "href:56", + "id": "id:57", + "name": "untracked-repayment-triumph-cat", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:337", + "id": "id:338", + "name": "allow-outbound" + }, + "created_at": "2024-06-25T15:40:19.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:335", + "id": "id:336", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-25T15:40:19.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:337", + "id": "id:338", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:52", + "href": "href:53", + "id": "id:54", + "name": "test-vpc3", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-06-25T15:40:40.000Z", + "crn": "crn:339", + "href": "href:340", + "id": "id:341", + "name": "sg21", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:342", + "id": "id:343", + "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:344", + "id": "id:345", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + } + ], + "targets": [ + { + "href": "href:211", + "id": "id:212", + "name": "tavern-far-imprudent-labored", + "resource_type": "network_interface" + }, + { + "href": "href:215", + "id": "id:216", + "name": "ought-football-shorter-aviator", + "resource_type": "network_interface" + }, + { + "href": "href:219", + "id": "id:220", + "name": "clicker-grumbly-outskirts-greatly", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:39", + "href": "href:40", + "id": "id:41", + "name": "test-vpc2", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:40.000Z", + "crn": "crn:346", + "href": "href:347", + "id": "id:348", + "name": "sg31", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:349", + "id": "id:350", + "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:351", + "id": "id:352", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + } + ], + "targets": [ + { + "href": "href:260", + "id": "id:261", + "name": "snout-given-twiddle-splinter", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:52", + "href": "href:53", + "id": "id:54", + "name": "test-vpc3", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:40.000Z", + "crn": "crn:353", + "href": "href:354", + "id": "id:355", + "name": "sg11", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:356", + "id": "id:357", + "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:358", + "id": "id:359", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + } + ], + "targets": [ + { + "href": "href:191", + "id": "id:192", + "name": "enlace-prominent-overhear-perfume", + "resource_type": "network_interface" + }, + { + "href": "href:153", + "id": "id:154", + "name": "stride-woken-backsight-dynastic", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:37.000Z", + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:363", + "id": "id:364", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "href:365", + "id": "id:366", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + } + ], + "targets": [ + { + "href": "href:105", + "id": "id:106", + "name": "icky-balsamic-outgoing-leached", + "resource_type": "network_interface" + }, + { + "href": "href:236", + "id": "id:237", + "name": "hankie-excitable-outclass-unmanaged", + "resource_type": "network_interface" + }, + { + "href": "href:277", + "id": "id:278", + "name": "bullring-ransack-feint-cheer", + "resource_type": "network_interface" + }, + { + "href": "href:81", + "id": "id:82", + "name": "stooped-camera-excluded-juke", + "resource_type": "network_interface" + }, + { + "href": "href:129", + "id": "id:130", + "name": "writer-crusher-unsuited-cash", + "resource_type": "network_interface" + }, + { + "href": "href:281", + "id": "id:282", + "name": "speak-princess-washcloth-companion", + "resource_type": "network_interface" + }, + { + "href": "href:109", + "id": "id:110", + "name": "squatted-fastball-vacant-knoll", + "resource_type": "network_interface" + }, + { + "href": "href:85", + "id": "id:86", + "name": "scratch-outward-raging-hunchback", + "resource_type": "network_interface" + }, + { + "href": "href:170", + "id": "id:171", + "name": "graveyard-handmade-ransack-acquaint", + "resource_type": "network_interface" + }, + { + "href": "href:174", + "id": "id:175", + "name": "quantum-handbag-dimmed-reassign", + "resource_type": "network_interface" + }, + { + "href": "href:133", + "id": "id:134", + "name": "consonant-imperial-simply-ceramics", + "resource_type": "network_interface" + }, + { + "href": "href:240", + "id": "id:241", + "name": "scale-clambake-endearing-abridged", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:20.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "brute-upon-angles-cubbyhole", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:367", + "id": "id:368", + "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:369", + "id": "id:370", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "brute-upon-angles-cubbyhole" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:19.000Z", + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "basically-drank-bulk-jam", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:371", + "id": "id:372", + "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:373", + "id": "id:374", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "name": "basically-drank-bulk-jam" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:19.000Z", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "glance-cactus-unease-bankroll", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:375", + "id": "id:376", + "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:377", + "id": "id:378", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "glance-cactus-unease-bankroll" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:39", + "href": "href:40", + "id": "id:41", + "name": "test-vpc2", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-25T15:40:19.000Z", + "crn": "crn:60", + "href": "href:61", + "id": "id:62", + "name": "repeater-upcountry-agreeing-acutely", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:379", + "id": "id:380", + "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:381", + "id": "id:382", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:60", + "href": "href:61", + "id": "id:62", + "name": "repeater-upcountry-agreeing-acutely" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:52", + "href": "href:53", + "id": "id:54", + "name": "test-vpc3", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [], + "instances": [ + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:388" + }, + "href": "href:386", + "id": "id:387", + "name": "thief-monastery-blinks-verdict", + "volume": { + "crn": "crn:389", + "href": "href:390", + "id": "id:391", + "name": "scrabble-gorged-baton-angled", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:40.000Z", + "crn": "crn:383", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:384", + "id": "id:385", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi0-subnet1", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:240", + "id": "id:241", + "name": "scale-clambake-endearing-abridged", + "primary_ip": { + "address": "10.240.1.5", + "href": "href:238", + "id": "id:239", + "name": "affected-johnniecake-monorail-ungraded", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:223", + "href": "href:224", + "id": "id:225", + "name": "subnet1", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:388" + }, + "href": "href:386", + "id": "id:387", + "name": "thief-monastery-blinks-verdict", + "volume": { + "crn": "crn:389", + "href": "href:390", + "id": "id:391", + "name": "scrabble-gorged-baton-angled", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:40.000Z", + "floating_ips": [], + "href": "href:240", + "id": "id:241", + "name": "scale-clambake-endearing-abridged", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.1.5", + "href": "href:238", + "id": "id:239", + "name": "affected-johnniecake-monorail-ungraded", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:223", + "href": "href:224", + "id": "id:225", + "name": "subnet1", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:401" + }, + "href": "href:399", + "id": "id:400", + "name": "hunchback-enginous-dividend-atrium", + "volume": { + "crn": "crn:402", + "href": "href:403", + "id": "id:404", + "name": "subsoil-bobble-bovine-unmoving", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:39.000Z", + "crn": "crn:396", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:397", + "id": "id:398", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1-subnet0", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:133", + "id": "id:134", + "name": "consonant-imperial-simply-ceramics", + "primary_ip": { + "address": "10.240.0.5", + "href": "href:131", + "id": "id:132", + "name": "relatable-antiques-maturing-brulee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:113", + "href": "href:114", + "id": "id:115", + "name": "subnet0", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:401" + }, + "href": "href:399", + "id": "id:400", + "name": "hunchback-enginous-dividend-atrium", + "volume": { + "crn": "crn:402", + "href": "href:403", + "id": "id:404", + "name": "subsoil-bobble-bovine-unmoving", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:39.000Z", + "floating_ips": [], + "href": "href:133", + "id": "id:134", + "name": "consonant-imperial-simply-ceramics", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.0.5", + "href": "href:131", + "id": "id:132", + "name": "relatable-antiques-maturing-brulee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:113", + "href": "href:114", + "id": "id:115", + "name": "subnet0", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:410" + }, + "href": "href:408", + "id": "id:409", + "name": "laboring-overbuilt-growl-headland", + "volume": { + "crn": "crn:411", + "href": "href:412", + "id": "id:413", + "name": "tamper-salvaging-stick-giddily", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:22.000Z", + "crn": "crn:405", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:406", + "id": "id:407", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1-subnet2", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:174", + "id": "id:175", + "name": "quantum-handbag-dimmed-reassign", + "primary_ip": { + "address": "10.240.4.5", + "href": "href:172", + "id": "id:173", + "name": "bark-gatherer-rope-unrivaled", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:157", + "href": "href:158", + "id": "id:159", + "name": "subnet2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:410" + }, + "href": "href:408", + "id": "id:409", + "name": "laboring-overbuilt-growl-headland", + "volume": { + "crn": "crn:411", + "href": "href:412", + "id": "id:413", + "name": "tamper-salvaging-stick-giddily", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:22.000Z", + "floating_ips": [], + "href": "href:174", + "id": "id:175", + "name": "quantum-handbag-dimmed-reassign", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.4.5", + "href": "href:172", + "id": "id:173", + "name": "bark-gatherer-rope-unrivaled", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:157", + "href": "href:158", + "id": "id:159", + "name": "subnet2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:419" + }, + "href": "href:417", + "id": "id:418", + "name": "dollop-partition-helping-palmtree", + "volume": { + "crn": "crn:420", + "href": "href:421", + "id": "id:422", + "name": "ravage-deny-amusable-settling", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:20.000Z", + "crn": "crn:414", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:415", + "id": "id:416", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1-subnet5", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:85", + "id": "id:86", + "name": "scratch-outward-raging-hunchback", + "primary_ip": { + "address": "10.240.9.5", + "href": "href:83", + "id": "id:84", + "name": "outskirts-unaligned-passivism-parchment", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:65", + "href": "href:66", + "id": "id:67", + "name": "subnet5", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:419" + }, + "href": "href:417", + "id": "id:418", + "name": "dollop-partition-helping-palmtree", + "volume": { + "crn": "crn:420", + "href": "href:421", + "id": "id:422", + "name": "ravage-deny-amusable-settling", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:20.000Z", + "floating_ips": [], + "href": "href:85", + "id": "id:86", + "name": "scratch-outward-raging-hunchback", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.9.5", + "href": "href:83", + "id": "id:84", + "name": "outskirts-unaligned-passivism-parchment", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:65", + "href": "href:66", + "id": "id:67", + "name": "subnet5", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:428" + }, + "href": "href:426", + "id": "id:427", + "name": "petted-ethanol-voicing-rocklike", + "volume": { + "crn": "crn:429", + "href": "href:430", + "id": "id:431", + "name": "uptown-striving-unrevised-earthlike", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:20.000Z", + "crn": "crn:423", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:424", + "id": "id:425", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi0-subnet2", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:170", + "id": "id:171", + "name": "graveyard-handmade-ransack-acquaint", + "primary_ip": { + "address": "10.240.4.4", + "href": "href:168", + "id": "id:169", + "name": "stood-sitcom-whoops-hurled", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:157", + "href": "href:158", + "id": "id:159", + "name": "subnet2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:428" + }, + "href": "href:426", + "id": "id:427", + "name": "petted-ethanol-voicing-rocklike", + "volume": { + "crn": "crn:429", + "href": "href:430", + "id": "id:431", + "name": "uptown-striving-unrevised-earthlike", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:20.000Z", + "floating_ips": [], + "href": "href:170", + "id": "id:171", + "name": "graveyard-handmade-ransack-acquaint", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.4.4", + "href": "href:168", + "id": "id:169", + "name": "stood-sitcom-whoops-hurled", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:157", + "href": "href:158", + "id": "id:159", + "name": "subnet2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:437" + }, + "href": "href:435", + "id": "id:436", + "name": "promenade-spyglass-flattop-pushpin", + "volume": { + "crn": "crn:438", + "href": "href:439", + "id": "id:440", + "name": "relax-shaded-prism-jaunt", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:16.000Z", + "crn": "crn:432", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:433", + "id": "id:434", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1-subnet3", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:109", + "id": "id:110", + "name": "squatted-fastball-vacant-knoll", + "primary_ip": { + "address": "10.240.5.5", + "href": "href:107", + "id": "id:108", + "name": "recognize-citable-exerciser-unsecured", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:89", + "href": "href:90", + "id": "id:91", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:437" + }, + "href": "href:435", + "id": "id:436", + "name": "promenade-spyglass-flattop-pushpin", + "volume": { + "crn": "crn:438", + "href": "href:439", + "id": "id:440", + "name": "relax-shaded-prism-jaunt", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:16.000Z", + "floating_ips": [], + "href": "href:109", + "id": "id:110", + "name": "squatted-fastball-vacant-knoll", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.5.5", + "href": "href:107", + "id": "id:108", + "name": "recognize-citable-exerciser-unsecured", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:89", + "href": "href:90", + "id": "id:91", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:446" + }, + "href": "href:444", + "id": "id:445", + "name": "sandbox-federal-sculptor-jugum", + "volume": { + "crn": "crn:447", + "href": "href:448", + "id": "id:449", + "name": "convent-ramrod-cloning-afterward", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:15.000Z", + "crn": "crn:441", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:442", + "id": "id:443", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1-subnet4", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:281", + "id": "id:282", + "name": "speak-princess-washcloth-companion", + "primary_ip": { + "address": "10.240.8.5", + "href": "href:279", + "id": "id:280", + "name": "frighten-mystified-freeway-hurtling", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:264", + "href": "href:265", + "id": "id:266", + "name": "subnet4", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:446" + }, + "href": "href:444", + "id": "id:445", + "name": "sandbox-federal-sculptor-jugum", + "volume": { + "crn": "crn:447", + "href": "href:448", + "id": "id:449", + "name": "convent-ramrod-cloning-afterward", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:15.000Z", + "floating_ips": [], + "href": "href:281", + "id": "id:282", + "name": "speak-princess-washcloth-companion", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.8.5", + "href": "href:279", + "id": "id:280", + "name": "frighten-mystified-freeway-hurtling", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:264", + "href": "href:265", + "id": "id:266", + "name": "subnet4", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:455" + }, + "href": "href:453", + "id": "id:454", + "name": "affidavit-chastise-elsewhere-viewer", + "volume": { + "crn": "crn:456", + "href": "href:457", + "id": "id:458", + "name": "fancy-destiny-shuffling-sandbank", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:07.000Z", + "crn": "crn:450", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:451", + "id": "id:452", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi0-subnet0", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:129", + "id": "id:130", + "name": "writer-crusher-unsuited-cash", + "primary_ip": { + "address": "10.240.0.4", + "href": "href:127", + "id": "id:128", + "name": "pundit-tight-arbitrate-grace", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:113", + "href": "href:114", + "id": "id:115", + "name": "subnet0", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:455" + }, + "href": "href:453", + "id": "id:454", + "name": "affidavit-chastise-elsewhere-viewer", + "volume": { + "crn": "crn:456", + "href": "href:457", + "id": "id:458", + "name": "fancy-destiny-shuffling-sandbank", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:07.000Z", + "floating_ips": [ + { + "address": "52.118.151.238", + "crn": "crn:285", + "href": "href:286", + "id": "id:287", + "name": "fip-0-subnet0" + } + ], + "href": "href:129", + "id": "id:130", + "name": "writer-crusher-unsuited-cash", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.0.4", + "href": "href:127", + "id": "id:128", + "name": "pundit-tight-arbitrate-grace", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:113", + "href": "href:114", + "id": "id:115", + "name": "subnet0", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:464" + }, + "href": "href:462", + "id": "id:463", + "name": "uneven-armoire-scabiosa-letter", + "volume": { + "crn": "crn:465", + "href": "href:466", + "id": "id:467", + "name": "cognition-blinks-humid-oxidant", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:00.000Z", + "crn": "crn:459", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:460", + "id": "id:461", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi0-subnet3", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:105", + "id": "id:106", + "name": "icky-balsamic-outgoing-leached", + "primary_ip": { + "address": "10.240.5.4", + "href": "href:103", + "id": "id:104", + "name": "rising-gopher-reentry-graveness", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:89", + "href": "href:90", + "id": "id:91", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:464" + }, + "href": "href:462", + "id": "id:463", + "name": "uneven-armoire-scabiosa-letter", + "volume": { + "crn": "crn:465", + "href": "href:466", + "id": "id:467", + "name": "cognition-blinks-humid-oxidant", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:00.000Z", + "floating_ips": [], + "href": "href:105", + "id": "id:106", + "name": "icky-balsamic-outgoing-leached", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.5.4", + "href": "href:103", + "id": "id:104", + "name": "rising-gopher-reentry-graveness", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:89", + "href": "href:90", + "id": "id:91", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:473" + }, + "href": "href:471", + "id": "id:472", + "name": "perplexed-impulsivity-august-jaws", + "volume": { + "crn": "crn:474", + "href": "href:475", + "id": "id:476", + "name": "tartar-sixties-fructose-parmesan", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:00.000Z", + "crn": "crn:468", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:469", + "id": "id:470", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1-subnet1", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:236", + "id": "id:237", + "name": "hankie-excitable-outclass-unmanaged", + "primary_ip": { + "address": "10.240.1.4", + "href": "href:234", + "id": "id:235", + "name": "excluded-unfair-jailbird-foil", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:223", + "href": "href:224", + "id": "id:225", + "name": "subnet1", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:473" + }, + "href": "href:471", + "id": "id:472", + "name": "perplexed-impulsivity-august-jaws", + "volume": { + "crn": "crn:474", + "href": "href:475", + "id": "id:476", + "name": "tartar-sixties-fructose-parmesan", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:00.000Z", + "floating_ips": [], + "href": "href:236", + "id": "id:237", + "name": "hankie-excitable-outclass-unmanaged", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.1.4", + "href": "href:234", + "id": "id:235", + "name": "excluded-unfair-jailbird-foil", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:223", + "href": "href:224", + "id": "id:225", + "name": "subnet1", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:482" + }, + "href": "href:480", + "id": "id:481", + "name": "litter-snipping-unclasp-dust", + "volume": { + "crn": "crn:483", + "href": "href:484", + "id": "id:485", + "name": "untried-sulphate-hypnosis-subsidize", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:00.000Z", + "crn": "crn:477", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:478", + "id": "id:479", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi0-subnet4", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:277", + "id": "id:278", + "name": "bullring-ransack-feint-cheer", + "primary_ip": { + "address": "10.240.8.4", + "href": "href:275", + "id": "id:276", + "name": "bagged-posture-glaring-cojoined", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:264", + "href": "href:265", + "id": "id:266", + "name": "subnet4", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:482" + }, + "href": "href:480", + "id": "id:481", + "name": "litter-snipping-unclasp-dust", + "volume": { + "crn": "crn:483", + "href": "href:484", + "id": "id:485", + "name": "untried-sulphate-hypnosis-subsidize", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:00.000Z", + "floating_ips": [], + "href": "href:277", + "id": "id:278", + "name": "bullring-ransack-feint-cheer", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.8.4", + "href": "href:275", + "id": "id:276", + "name": "bagged-posture-glaring-cojoined", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:264", + "href": "href:265", + "id": "id:266", + "name": "subnet4", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:491" + }, + "href": "href:489", + "id": "id:490", + "name": "unlawful-overreach-yarn-rippling", + "volume": { + "crn": "crn:492", + "href": "href:493", + "id": "id:494", + "name": "finer-voter-roving-jailer", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:42:00.000Z", + "crn": "crn:486", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:487", + "id": "id:488", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi0-subnet5", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:81", + "id": "id:82", + "name": "stooped-camera-excluded-juke", + "primary_ip": { + "address": "10.240.9.4", + "href": "href:79", + "id": "id:80", + "name": "ideally-grain-bagpipe-luxuriant", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:65", + "href": "href:66", + "id": "id:67", + "name": "subnet5", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:491" + }, + "href": "href:489", + "id": "id:490", + "name": "unlawful-overreach-yarn-rippling", + "volume": { + "crn": "crn:492", + "href": "href:493", + "id": "id:494", + "name": "finer-voter-roving-jailer", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:42:00.000Z", + "floating_ips": [], + "href": "href:81", + "id": "id:82", + "name": "stooped-camera-excluded-juke", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.9.4", + "href": "href:79", + "id": "id:80", + "name": "ideally-grain-bagpipe-luxuriant", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:360", + "href": "href:361", + "id": "id:362", + "name": "sg1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:65", + "href": "href:66", + "id": "id:67", + "name": "subnet5", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:500" + }, + "href": "href:498", + "id": "id:499", + "name": "mashed-thing-headache-estate", + "volume": { + "crn": "crn:501", + "href": "href:502", + "id": "id:503", + "name": "mountain-harpist-libraries-dreaming", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:41:39.000Z", + "crn": "crn:495", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:496", + "id": "id:497", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi0-subnet11", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:153", + "id": "id:154", + "name": "stride-woken-backsight-dynastic", + "primary_ip": { + "address": "10.240.80.4", + "href": "href:151", + "id": "id:152", + "name": "childlike-publish-retainer-movie", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:137", + "href": "href:138", + "id": "id:139", + "name": "subnet11", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:500" + }, + "href": "href:498", + "id": "id:499", + "name": "mashed-thing-headache-estate", + "volume": { + "crn": "crn:501", + "href": "href:502", + "id": "id:503", + "name": "mountain-harpist-libraries-dreaming", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:41:39.000Z", + "floating_ips": [], + "href": "href:153", + "id": "id:154", + "name": "stride-woken-backsight-dynastic", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.80.4", + "href": "href:151", + "id": "id:152", + "name": "childlike-publish-retainer-movie", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:353", + "href": "href:354", + "id": "id:355", + "name": "sg11" + } + ], + "status": "available", + "subnet": { + "crn": "crn:137", + "href": "href:138", + "id": "id:139", + "name": "subnet11", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:509" + }, + "href": "href:507", + "id": "id:508", + "name": "calzone-cacti-moonlight-subarctic", + "volume": { + "crn": "crn:510", + "href": "href:511", + "id": "id:512", + "name": "blurred-dream-pectin-tapping", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:41:36.000Z", + "crn": "crn:504", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:505", + "id": "id:506", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi0-subnet10", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:191", + "id": "id:192", + "name": "enlace-prominent-overhear-perfume", + "primary_ip": { + "address": "10.240.64.4", + "href": "href:189", + "id": "id:190", + "name": "starry-smasher-ladle-dioxide", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:178", + "href": "href:179", + "id": "id:180", + "name": "subnet10", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:509" + }, + "href": "href:507", + "id": "id:508", + "name": "calzone-cacti-moonlight-subarctic", + "volume": { + "crn": "crn:510", + "href": "href:511", + "id": "id:512", + "name": "blurred-dream-pectin-tapping", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:41:36.000Z", + "floating_ips": [ + { + "address": "150.239.167.146", + "crn": "crn:288", + "href": "href:289", + "id": "id:290", + "name": "fip-0-subnet10" + } + ], + "href": "href:191", + "id": "id:192", + "name": "enlace-prominent-overhear-perfume", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.64.4", + "href": "href:189", + "id": "id:190", + "name": "starry-smasher-ladle-dioxide", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:353", + "href": "href:354", + "id": "id:355", + "name": "sg11" + } + ], + "status": "available", + "subnet": { + "crn": "crn:178", + "href": "href:179", + "id": "id:180", + "name": "subnet10", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:518" + }, + "href": "href:516", + "id": "id:517", + "name": "recoup-blinks-ebullient-renewed", + "volume": { + "crn": "crn:519", + "href": "href:520", + "id": "id:521", + "name": "manmade-unequal-disinfect-cone", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:41:24.000Z", + "crn": "crn:513", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:514", + "id": "id:515", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1-subnet20", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:219", + "id": "id:220", + "name": "clicker-grumbly-outskirts-greatly", + "primary_ip": { + "address": "10.240.128.6", + "href": "href:217", + "id": "id:218", + "name": "uniquely-shelter-gracious-sudden", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:195", + "href": "href:196", + "id": "id:197", + "name": "subnet20", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:518" + }, + "href": "href:516", + "id": "id:517", + "name": "recoup-blinks-ebullient-renewed", + "volume": { + "crn": "crn:519", + "href": "href:520", + "id": "id:521", + "name": "manmade-unequal-disinfect-cone", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:39", + "href": "href:40", + "id": "id:41", + "name": "test-vpc2", + "resource_type": "vpc" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:41:24.000Z", + "floating_ips": [ + { + "address": "169.48.95.165", + "crn": "crn:291", + "href": "href:292", + "id": "id:293", + "name": "fip-0-subnet20" + } + ], + "href": "href:219", + "id": "id:220", + "name": "clicker-grumbly-outskirts-greatly", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.128.6", + "href": "href:217", + "id": "id:218", + "name": "uniquely-shelter-gracious-sudden", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:339", + "href": "href:340", + "id": "id:341", + "name": "sg21" + } + ], + "status": "available", + "subnet": { + "crn": "crn:195", + "href": "href:196", + "id": "id:197", + "name": "subnet20", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:527" + }, + "href": "href:525", + "id": "id:526", + "name": "radio-tightrope-outtakes-moonshine", + "volume": { + "crn": "crn:528", + "href": "href:529", + "id": "id:530", + "name": "tattoo-crescent-unwary-hayride", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:41:21.000Z", + "crn": "crn:522", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:523", + "id": "id:524", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi0-subnet20", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:215", + "id": "id:216", + "name": "ought-football-shorter-aviator", + "primary_ip": { + "address": "10.240.128.5", + "href": "href:213", + "id": "id:214", + "name": "customs-recollect-drippy-primate", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:195", + "href": "href:196", + "id": "id:197", + "name": "subnet20", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:527" + }, + "href": "href:525", + "id": "id:526", + "name": "radio-tightrope-outtakes-moonshine", + "volume": { + "crn": "crn:528", + "href": "href:529", + "id": "id:530", + "name": "tattoo-crescent-unwary-hayride", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:39", + "href": "href:40", + "id": "id:41", + "name": "test-vpc2", + "resource_type": "vpc" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:41:21.000Z", + "floating_ips": [], + "href": "href:215", + "id": "id:216", + "name": "ought-football-shorter-aviator", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.128.5", + "href": "href:213", + "id": "id:214", + "name": "customs-recollect-drippy-primate", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:339", + "href": "href:340", + "id": "id:341", + "name": "sg21" + } + ], + "status": "available", + "subnet": { + "crn": "crn:195", + "href": "href:196", + "id": "id:197", + "name": "subnet20", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:536" + }, + "href": "href:534", + "id": "id:535", + "name": "crumpet-ride-tastiness-phoney", + "volume": { + "crn": "crn:537", + "href": "href:538", + "id": "id:539", + "name": "doorframe-marvelous-refusing-citable", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:41:21.000Z", + "crn": "crn:531", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:532", + "id": "id:533", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi2-subnet20", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:211", + "id": "id:212", + "name": "tavern-far-imprudent-labored", + "primary_ip": { + "address": "10.240.128.4", + "href": "href:209", + "id": "id:210", + "name": "unmixed-qualify-prescribe-railcar", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:195", + "href": "href:196", + "id": "id:197", + "name": "subnet20", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:536" + }, + "href": "href:534", + "id": "id:535", + "name": "crumpet-ride-tastiness-phoney", + "volume": { + "crn": "crn:537", + "href": "href:538", + "id": "id:539", + "name": "doorframe-marvelous-refusing-citable", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:39", + "href": "href:40", + "id": "id:41", + "name": "test-vpc2", + "resource_type": "vpc" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:41:21.000Z", + "floating_ips": [], + "href": "href:211", + "id": "id:212", + "name": "tavern-far-imprudent-labored", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.128.4", + "href": "href:209", + "id": "id:210", + "name": "unmixed-qualify-prescribe-railcar", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:339", + "href": "href:340", + "id": "id:341", + "name": "sg21" + } + ], + "status": "available", + "subnet": { + "crn": "crn:195", + "href": "href:196", + "id": "id:197", + "name": "subnet20", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:545" + }, + "href": "href:543", + "id": "id:544", + "name": "bronzing-vendor-plod-pretzel", + "volume": { + "crn": "crn:546", + "href": "href:547", + "id": "id:548", + "name": "squelch-plop-headlamp-ideologue", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-25T15:41:00.000Z", + "crn": "crn:540", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:541", + "id": "id:542", + "image": { + "crn": "crn:392", + "href": "href:393", + "id": "id:394", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi0-subnet30", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:260", + "id": "id:261", + "name": "snout-given-twiddle-splinter", + "primary_ip": { + "address": "10.240.192.4", + "href": "href:258", + "id": "id:259", + "name": "legacy-shore-molecule-barometer", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:244", + "href": "href:245", + "id": "id:246", + "name": "subnet30", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:395", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:545" + }, + "href": "href:543", + "id": "id:544", + "name": "bronzing-vendor-plod-pretzel", + "volume": { + "crn": "crn:546", + "href": "href:547", + "id": "id:548", + "name": "squelch-plop-headlamp-ideologue", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:52", + "href": "href:53", + "id": "id:54", + "name": "test-vpc3", + "resource_type": "vpc" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-25T15:41:00.000Z", + "floating_ips": [ + { + "address": "52.118.100.239", + "crn": "crn:294", + "href": "href:295", + "id": "id:296", + "name": "fip-0-subnet30" + } + ], + "href": "href:260", + "id": "id:261", + "name": "snout-given-twiddle-splinter", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.192.4", + "href": "href:258", + "id": "id:259", + "name": "legacy-shore-molecule-barometer", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:346", + "href": "href:347", + "id": "id:348", + "name": "sg31" + } + ], + "status": "available", + "subnet": { + "crn": "crn:244", + "href": "href:245", + "id": "id:246", + "name": "subnet30", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + } + ], + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-06-25T15:40:20.000Z", + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "overtone-sputter-overspend-gorge", + "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:137", + "href": "href:138", + "id": "id:139", + "name": "subnet11", + "resource_type": "subnet" + }, + { + "crn": "crn:178", + "href": "href:179", + "id": "id:180", + "name": "subnet10", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + } + }, + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-06-25T15:40:19.000Z", + "href": "href:28", + "id": "id:29", + "is_default": true, + "lifecycle_state": "stable", + "name": "escapade-dynamite-upstage-context", + "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:65", + "href": "href:66", + "id": "id:67", + "name": "subnet5", + "resource_type": "subnet" + }, + { + "crn": "crn:89", + "href": "href:90", + "id": "id:91", + "name": "subnet3", + "resource_type": "subnet" + }, + { + "crn": "crn:113", + "href": "href:114", + "id": "id:115", + "name": "subnet0", + "resource_type": "subnet" + }, + { + "crn": "crn:157", + "href": "href:158", + "id": "id:159", + "name": "subnet2", + "resource_type": "subnet" + }, + { + "crn": "crn:223", + "href": "href:224", + "id": "id:225", + "name": "subnet1", + "resource_type": "subnet" + }, + { + "crn": "crn:264", + "href": "href:265", + "id": "id:266", + "name": "subnet4", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:22", + "href": "href:23", + "id": "id:24", + "name": "test-vpc0", + "resource_type": "vpc" + } + }, + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-06-25T15:40:19.000Z", + "href": "href:45", + "id": "id:46", + "is_default": true, + "lifecycle_state": "stable", + "name": "quintuple-severity-caddie-manuals", + "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:195", + "href": "href:196", + "id": "id:197", + "name": "subnet20", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:39", + "href": "href:40", + "id": "id:41", + "name": "test-vpc2", + "resource_type": "vpc" + } + }, + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-06-25T15:40:19.000Z", + "href": "href:58", + "id": "id:59", + "is_default": true, + "lifecycle_state": "stable", + "name": "probational-herring-undone-daintily", + "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:244", + "href": "href:245", + "id": "id:246", + "name": "subnet30", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:52", + "href": "href:53", + "id": "id:54", + "name": "test-vpc3", + "resource_type": "vpc" + } + } + ], + "load_balancers": [], + "transit_connections": [ + { + "created_at": "2024-06-25T15:41:44.212Z", + "id": "id:549", + "name": "tg3_connection3", + "network_id": "crn:52", + "network_type": "vpc", + "prefix_filters_default": "permit", + "status": "attached", + "transit_gateway": { + "crn": "crn:550", + "id": "id:551", + "name": "local-tg3" + }, + "updated_at": "2024-06-25T15:45:14.206Z" + }, + { + "created_at": "2024-06-25T15:41:54.416Z", + "id": "id:552", + "name": "tg3_connection0", + "network_id": "crn:22", + "network_type": "vpc", + "prefix_filters_default": "permit", + "status": "attached", + "transit_gateway": { + "crn": "crn:550", + "id": "id:551", + "name": "local-tg3" + }, + "updated_at": "2024-06-25T15:45:53.979Z" + }, + { + "created_at": "2024-06-25T15:42:54.772Z", + "id": "id:553", + "name": "tg2_connection3", + "network_id": "crn:52", + "network_type": "vpc", + "prefix_filters_default": "permit", + "status": "attached", + "transit_gateway": { + "crn": "crn:554", + "id": "id:555", + "name": "local-tg2" + }, + "updated_at": "2024-06-25T15:49:08.822Z" + }, + { + "created_at": "2024-06-25T15:43:11.555Z", + "id": "id:556", + "name": "tg2_connection0", + "network_id": "crn:22", + "network_type": "vpc", + "prefix_filters": [ + { + "action": "deny", + "created_at": "2024-06-25T15:46:46.641Z", + "id": "id:557", + "le": 32, + "prefix": "10.240.0.0/22", + "updated_at": "2024-06-25T15:46:46.641Z" + } + ], + "prefix_filters_default": "permit", + "status": "attached", + "transit_gateway": { + "crn": "crn:554", + "id": "id:555", + "name": "local-tg2" + }, + "updated_at": "2024-06-25T15:49:59.395Z" + }, + { + "created_at": "2024-06-25T15:43:12.159Z", + "id": "id:558", + "name": "tg_connection0", + "network_id": "crn:22", + "network_type": "vpc", + "prefix_filters": [ + { + "action": "deny", + "before": "298db67f-2e68-4548-93b9-949f8356d4a0", + "created_at": "2024-06-25T15:45:14.711Z", + "id": "id:559", + "prefix": "10.240.4.0/22", + "updated_at": "2024-06-25T15:45:14.711Z" + }, + { + "action": "deny", + "created_at": "2024-06-25T15:45:25.435Z", + "id": "id:560", + "prefix": "10.240.8.0/22", + "updated_at": "2024-06-25T15:45:25.435Z" + } + ], + "prefix_filters_default": "permit", + "status": "attached", + "transit_gateway": { + "crn": "crn:561", + "id": "id:562", + "name": "local-tg1" + }, + "updated_at": "2024-06-25T15:49:53.837Z" + }, + { + "created_at": "2024-06-25T15:43:41.079Z", + "id": "id:563", + "name": "tg2_connection2", + "network_id": "crn:39", + "network_type": "vpc", + "prefix_filters_default": "permit", + "status": "attached", + "transit_gateway": { + "crn": "crn:554", + "id": "id:555", + "name": "local-tg2" + }, + "updated_at": "2024-06-25T15:49:43.192Z" + }, + { + "created_at": "2024-06-25T15:43:42.335Z", + "id": "id:564", + "name": "tg1_connection1", + "network_id": "crn:1", + "network_type": "vpc", + "prefix_filters_default": "permit", + "status": "attached", + "transit_gateway": { + "crn": "crn:561", + "id": "id:562", + "name": "local-tg1" + }, + "updated_at": "2024-06-25T15:48:45.229Z" + }, + { + "created_at": "2024-06-25T15:44:08.995Z", + "id": "id:565", + "name": "tg1_connection2", + "network_id": "crn:39", + "network_type": "vpc", + "prefix_filters_default": "permit", + "status": "attached", + "transit_gateway": { + "crn": "crn:561", + "id": "id:562", + "name": "local-tg1" + }, + "updated_at": "2024-06-25T15:49:11.976Z" + } + ], + "transit_gateways": [ + { + "id": "id:551", + "crn": "crn:550", + "name": "local-tg3", + "location": "us-south", + "created_at": "2024-06-25T15:40:21.390Z", + "global": false, + "resource_group": { + "id": "id:17", + "href": "href:566" + }, + "status": "available", + "updated_at": "2024-06-25T15:42:12.752Z" + }, + { + "id": "id:555", + "crn": "crn:554", + "name": "local-tg2", + "location": "us-south", + "created_at": "2024-06-25T15:40:25.895Z", + "global": false, + "resource_group": { + "id": "id:17", + "href": "href:566" + }, + "status": "available", + "updated_at": "2024-06-25T15:43:58.196Z" + }, + { + "id": "id:562", + "crn": "crn:561", + "name": "local-tg1", + "location": "us-south", + "created_at": "2024-06-25T15:40:26.455Z", + "global": false, + "resource_group": { + "id": "id:17", + "href": "href:566" + }, + "status": "available", + "updated_at": "2024-06-25T15:43:15.331Z" + } + ], + "iks_clusters": [] +} diff --git a/test/data/acl_nif_instance_segments/conn_spec.json b/test/data/acl_nif_instance_segments/conn_spec.json new file mode 100644 index 00000000..362acd27 --- /dev/null +++ b/test/data/acl_nif_instance_segments/conn_spec.json @@ -0,0 +1,57 @@ +{ + "segments": { + "instanceSegment": { + "type": "instance", + "items": [ + "vsi0-subnet0", + "vsi1-subnet2" + ] + }, + "nifSegment": { + "type": "nif", + "items": [ + "squatted-fastball-vacant-knoll", + "snout-given-twiddle-splinter" + ] + } + }, + "required-connections": [ + { + "src": { + "name": "instanceSegment", + "type": "segment" + }, + "dst": { + "name": "instanceSegment", + "type": "segment" + }, + "allowed-protocols": [ + { + "protocol": "UDP", + "min_destination_port": 53, + "max_destination_port": 54 + } + ] + }, + { + "src": { + "name": "nifSegment", + "type": "segment" + }, + "dst": { + "name": "nifSegment", + "type": "segment" + } + }, + { + "src": { + "name": "instanceSegment", + "type": "segment" + }, + "dst": { + "name": "nifSegment", + "type": "segment" + } + } + ] +} \ No newline at end of file diff --git a/test/expected/acl_nif_instance_segments_tf/nacl_expected.tf b/test/expected/acl_nif_instance_segments_tf/nacl_expected.tf new file mode 100644 index 00000000..11f661e8 --- /dev/null +++ b/test/expected/acl_nif_instance_segments_tf/nacl_expected.tf @@ -0,0 +1,373 @@ +# test-vpc0/subnet0 [10.240.0.0/24] +resource "ibm_is_network_acl" "acl-test-vpc0--subnet0" { + name = "acl-test-vpc0--subnet0" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc0_id + # Internal. required-connections[0]: (segment instanceSegment)->(segment instanceSegment); allowed-protocols[0] + rules { + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" + destination = "10.240.4.0/24" + udp { + port_min = 53 + port_max = 54 + } + } + # Internal. required-connections[0]: (segment instanceSegment)->(segment instanceSegment); allowed-protocols[0] + rules { + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" + destination = "10.240.0.0/24" + udp { + port_min = 53 + port_max = 54 + } + } + # Internal. required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" + destination = "10.240.5.0/24" + } + # Internal. response to required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.5.0/24" + destination = "10.240.0.0/24" + } + # Internal. required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" + destination = "10.240.192.0/24" + } + # Internal. response to required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.192.0/24" + destination = "10.240.0.0/24" + } +} + +# test-vpc0/subnet1 [10.240.1.0/24] +resource "ibm_is_network_acl" "acl-test-vpc0--subnet1" { + name = "acl-test-vpc0--subnet1" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc0_id + # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections + rules { + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" + destination = "10.240.1.0/24" + } + # Deny all communication; subnet test-vpc0/subnet1[10.240.1.0/24] does not have required connections + rules { + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.1.0/24" + destination = "0.0.0.0/0" + } +} + +# test-vpc0/subnet2 [10.240.4.0/24] +resource "ibm_is_network_acl" "acl-test-vpc0--subnet2" { + name = "acl-test-vpc0--subnet2" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc0_id + # Internal. required-connections[0]: (segment instanceSegment)->(segment instanceSegment); allowed-protocols[0] + rules { + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" + destination = "10.240.0.0/24" + udp { + port_min = 53 + port_max = 54 + } + } + # Internal. required-connections[0]: (segment instanceSegment)->(segment instanceSegment); allowed-protocols[0] + rules { + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" + destination = "10.240.4.0/24" + udp { + port_min = 53 + port_max = 54 + } + } + # Internal. required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule2" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" + destination = "10.240.5.0/24" + } + # Internal. response to required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule3" + action = "allow" + direction = "inbound" + source = "10.240.5.0/24" + destination = "10.240.4.0/24" + } + # Internal. required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule4" + action = "allow" + direction = "outbound" + source = "10.240.4.0/24" + destination = "10.240.192.0/24" + } + # Internal. response to required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule5" + action = "allow" + direction = "inbound" + source = "10.240.192.0/24" + destination = "10.240.4.0/24" + } +} + +# test-vpc0/subnet3 [10.240.5.0/24] +resource "ibm_is_network_acl" "acl-test-vpc0--subnet3" { + name = "acl-test-vpc0--subnet3" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc0_id + # Internal. required-connections[1]: (segment nifSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.5.0/24" + destination = "10.240.192.0/24" + } + # Internal. response to required-connections[1]: (segment nifSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.192.0/24" + destination = "10.240.5.0/24" + } + # Internal. required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" + destination = "10.240.5.0/24" + } + # Internal. response to required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.5.0/24" + destination = "10.240.0.0/24" + } + # Internal. required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule4" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" + destination = "10.240.5.0/24" + } + # Internal. response to required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule5" + action = "allow" + direction = "outbound" + source = "10.240.5.0/24" + destination = "10.240.4.0/24" + } +} + +# test-vpc0/subnet4 [10.240.8.0/24] +resource "ibm_is_network_acl" "acl-test-vpc0--subnet4" { + name = "acl-test-vpc0--subnet4" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc0_id + # Deny all communication; subnet test-vpc0/subnet4[10.240.8.0/24] does not have required connections + rules { + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" + destination = "10.240.8.0/24" + } + # Deny all communication; subnet test-vpc0/subnet4[10.240.8.0/24] does not have required connections + rules { + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.8.0/24" + destination = "0.0.0.0/0" + } +} + +# test-vpc0/subnet5 [10.240.9.0/24] +resource "ibm_is_network_acl" "acl-test-vpc0--subnet5" { + name = "acl-test-vpc0--subnet5" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc0_id + # Deny all communication; subnet test-vpc0/subnet5[10.240.9.0/24] does not have required connections + rules { + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" + destination = "10.240.9.0/24" + } + # Deny all communication; subnet test-vpc0/subnet5[10.240.9.0/24] does not have required connections + rules { + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.9.0/24" + destination = "0.0.0.0/0" + } +} + +# test-vpc1/subnet10 [10.240.64.0/24] +resource "ibm_is_network_acl" "acl-test-vpc1--subnet10" { + name = "acl-test-vpc1--subnet10" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc1_id + # Deny all communication; subnet test-vpc1/subnet10[10.240.64.0/24] does not have required connections + rules { + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" + destination = "10.240.64.0/24" + } + # Deny all communication; subnet test-vpc1/subnet10[10.240.64.0/24] does not have required connections + rules { + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.64.0/24" + destination = "0.0.0.0/0" + } +} + +# test-vpc1/subnet11 [10.240.80.0/24] +resource "ibm_is_network_acl" "acl-test-vpc1--subnet11" { + name = "acl-test-vpc1--subnet11" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc1_id + # Deny all communication; subnet test-vpc1/subnet11[10.240.80.0/24] does not have required connections + rules { + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" + destination = "10.240.80.0/24" + } + # Deny all communication; subnet test-vpc1/subnet11[10.240.80.0/24] does not have required connections + rules { + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.80.0/24" + destination = "0.0.0.0/0" + } +} + +# test-vpc2/subnet20 [10.240.128.0/24] +resource "ibm_is_network_acl" "acl-test-vpc2--subnet20" { + name = "acl-test-vpc2--subnet20" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc2_id + # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections + rules { + name = "rule0" + action = "deny" + direction = "inbound" + source = "0.0.0.0/0" + destination = "10.240.128.0/24" + } + # Deny all communication; subnet test-vpc2/subnet20[10.240.128.0/24] does not have required connections + rules { + name = "rule1" + action = "deny" + direction = "outbound" + source = "10.240.128.0/24" + destination = "0.0.0.0/0" + } +} + +# test-vpc3/subnet30 [10.240.192.0/24] +resource "ibm_is_network_acl" "acl-test-vpc3--subnet30" { + name = "acl-test-vpc3--subnet30" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc3_id + # Internal. required-connections[1]: (segment nifSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.192.0/24" + destination = "10.240.5.0/24" + } + # Internal. response to required-connections[1]: (segment nifSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.5.0/24" + destination = "10.240.192.0/24" + } + # Internal. required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" + destination = "10.240.192.0/24" + } + # Internal. response to required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.192.0/24" + destination = "10.240.0.0/24" + } + # Internal. required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule4" + action = "allow" + direction = "inbound" + source = "10.240.4.0/24" + destination = "10.240.192.0/24" + } + # Internal. response to required-connections[2]: (segment instanceSegment)->(segment nifSegment); allowed-protocols[0] + rules { + name = "rule5" + action = "allow" + direction = "outbound" + source = "10.240.192.0/24" + destination = "10.240.4.0/24" + } +} diff --git a/test/synth_test_list.go b/test/synth_test_list.go index 79f88b52..ce00dc88 100644 --- a/test/synth_test_list.go +++ b/test/synth_test_list.go @@ -12,6 +12,9 @@ const ( aclNifConfig = "%s/acl_nif/config_object.json" aclNifSpec = "%s/acl_nif/conn_spec.json" + aclNifInstanceSegmentsConfig = "%s/acl_nif_instance_segments/config_object.json" + aclNifInstanceSegmentsSpec = "%s/acl_nif_instance_segments/conn_spec.json" + aclProtocolsConfig = "%s/acl_protocols/config_object.json" aclProtocolsSpec = "%s/acl_protocols/conn_spec.json" @@ -77,6 +80,18 @@ func synthACLTestsList() []testCase { }, }, + // acl nif instance segments ## tg-multiple config + { + testName: "acl_nif_instance_segments_tf", + args: &command{ + cmd: synth, + subcmd: acl, + config: aclNifInstanceSegmentsConfig, + spec: aclNifInstanceSegmentsSpec, + outputFile: "%s/acl_nif_instance_segments_tf/nacl_expected.tf", + }, + }, + // acl protocols (all output fmts) ## tg-multiple config { testName: "acl_protocols_csv", From e40861d438fdb7b7312fcb6f1ad155e8489999b7 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 14 Oct 2024 16:19:26 +0300 Subject: [PATCH 079/131] added vpe acl test --- test/data/acl_vpe/config_object.json | 2077 +++++++++++++++++++++ test/data/acl_vpe/conn_spec.json | 27 + test/expected/acl_vpe_tf/nacl_expected.tf | 404 ++++ test/synth_test_list.go | 15 + 4 files changed, 2523 insertions(+) create mode 100644 test/data/acl_vpe/config_object.json create mode 100644 test/data/acl_vpe/conn_spec.json create mode 100644 test/expected/acl_vpe_tf/nacl_expected.tf diff --git a/test/data/acl_vpe/config_object.json b/test/data/acl_vpe/config_object.json new file mode 100644 index 00000000..75620661 --- /dev/null +++ b/test/data/acl_vpe/config_object.json @@ -0,0 +1,2077 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-06-19T07:11:56.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.16.239.119" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.22.28.206" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.16.253.77" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "premises-eleven-nursery-coveted" + }, + "default_routing_table": { + "href": "href:11", + "id": "id:12", + "name": "unguarded-corncob-unaired-corner", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "impart-oxidize-chive-escapade" + }, + "dns": { + "enable_hub": false, + "resolution_binding_count": 0, + "resolver": { + "servers": [ + { + "address": "161.26.0.7" + }, + { + "address": "161.26.0.8" + } + ], + "type": "system", + "configuration": "private_resolver" + } + }, + "health_reasons": null, + "health_state": "ok", + "href": "href:2", + "id": "id:3", + "name": "test-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-19T07:11:56.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": true, + "name": "seismic-phosphate-subtext-unleash", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.64.0/18", + "created_at": "2024-06-19T07:11:56.000Z", + "has_subnets": true, + "href": "href:20", + "id": "id:21", + "is_default": true, + "name": "shaded-tribute-glazing-explains", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.128.0/18", + "created_at": "2024-06-19T07:11:56.000Z", + "has_subnets": true, + "href": "href:22", + "id": "id:23", + "is_default": true, + "name": "overlabor-spiffy-economist-clanking", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 249, + "created_at": "2024-06-19T07:12:21.000Z", + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.0.0/24", + "name": "sub1", + "network_acl": { + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl1" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "unguarded-corncob-unaired-corner", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.0.0", + "auto_delete": false, + "created_at": "2024-06-19T07:12:21.000Z", + "href": "href:30", + "id": "id:31", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.0.1", + "auto_delete": false, + "created_at": "2024-06-19T07:12:21.000Z", + "href": "href:32", + "id": "id:33", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.0.2", + "auto_delete": false, + "created_at": "2024-06-19T07:12:21.000Z", + "href": "href:34", + "id": "id:35", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.0.3", + "auto_delete": false, + "created_at": "2024-06-19T07:12:21.000Z", + "href": "href:36", + "id": "id:37", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.0.4", + "auto_delete": true, + "created_at": "2024-06-19T07:12:47.000Z", + "href": "href:38", + "id": "id:39", + "lifecycle_state": "stable", + "name": "portion-send-snout-magazine", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:40", + "id": "id:41", + "name": "bouncing-serpent-graffiti-evasion", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.0.5", + "auto_delete": true, + "created_at": "2024-06-19T11:03:46.000Z", + "href": "href:42", + "id": "id:43", + "lifecycle_state": "stable", + "name": "appdata-vpe1", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "crn": "crn:44", + "href": "href:45", + "id": "id:46", + "name": "appdata-endpoint-gateway", + "resource_type": "endpoint_gateway" + } + }, + { + "address": "10.240.0.255", + "auto_delete": false, + "created_at": "2024-06-19T07:12:21.000Z", + "href": "href:47", + "id": "id:48", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "trust-zone:edge" + ] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-06-19T07:12:20.000Z", + "crn": "crn:49", + "href": "href:50", + "id": "id:51", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.64.0/24", + "name": "sub3", + "network_acl": { + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl1" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "unguarded-corncob-unaired-corner", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-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-19T07:12:20.000Z", + "href": "href:52", + "id": "id:53", + "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-19T07:12:20.000Z", + "href": "href:54", + "id": "id:55", + "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-19T07:12:20.000Z", + "href": "href:56", + "id": "id:57", + "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-19T07:12:20.000Z", + "href": "href:58", + "id": "id:59", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.64.4", + "auto_delete": true, + "created_at": "2024-06-19T11:03:34.000Z", + "href": "href:60", + "id": "id:61", + "lifecycle_state": "stable", + "name": "policydb-vpe3", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "crn": "crn:62", + "href": "href:63", + "id": "id:64", + "name": "policydb-endpoint-gateway", + "resource_type": "endpoint_gateway" + } + }, + { + "address": "10.240.64.255", + "auto_delete": false, + "created_at": "2024-06-19T07:12:20.000Z", + "href": "href:65", + "id": "id:66", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "trust-zone:transit" + ] + }, + { + "available_ipv4_address_count": 246, + "created_at": "2024-06-19T07:12:20.000Z", + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.128.0/24", + "name": "sub2", + "network_acl": { + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl1" + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "subnet", + "routing_table": { + "href": "href:11", + "id": "id:12", + "name": "unguarded-corncob-unaired-corner", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-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-19T07:12:20.000Z", + "href": "href:70", + "id": "id:71", + "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-19T07:12:20.000Z", + "href": "href:72", + "id": "id:73", + "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-19T07:12:20.000Z", + "href": "href:74", + "id": "id:75", + "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-19T07:12:20.000Z", + "href": "href:76", + "id": "id:77", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.128.4", + "auto_delete": true, + "created_at": "2024-06-19T07:12:46.000Z", + "href": "href:78", + "id": "id:79", + "lifecycle_state": "stable", + "name": "magnetism-steersman-botany-hurled", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:80", + "id": "id:81", + "name": "captain-captivity-shorty-crown", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.128.5", + "auto_delete": true, + "created_at": "2024-06-19T07:12:47.000Z", + "href": "href:82", + "id": "id:83", + "lifecycle_state": "stable", + "name": "kilt-snipping-yen-unmanaged", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:84", + "id": "id:85", + "name": "left-pebble-agonizing-wharf", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.128.6", + "auto_delete": true, + "created_at": "2024-06-19T07:12:47.000Z", + "href": "href:86", + "id": "id:87", + "lifecycle_state": "stable", + "name": "manic-nerve-surfboard-cofounder", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:88", + "id": "id:89", + "name": "litigate-bullfrog-improve-shandy", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.128.7", + "auto_delete": true, + "created_at": "2024-06-19T11:03:34.000Z", + "href": "href:90", + "id": "id:91", + "lifecycle_state": "stable", + "name": "policydb-vpe2", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "crn": "crn:62", + "href": "href:63", + "id": "id:64", + "name": "policydb-endpoint-gateway", + "resource_type": "endpoint_gateway" + } + }, + { + "address": "10.240.128.8", + "auto_delete": true, + "created_at": "2024-06-19T11:03:46.000Z", + "href": "href:92", + "id": "id:93", + "lifecycle_state": "stable", + "name": "appdata-vpe2", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "crn": "crn:44", + "href": "href:45", + "id": "id:46", + "name": "appdata-endpoint-gateway", + "resource_type": "endpoint_gateway" + } + }, + { + "address": "10.240.128.255", + "auto_delete": false, + "created_at": "2024-06-19T07:12:20.000Z", + "href": "href:94", + "id": "id:95", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [ + "trust-zone:private" + ] + } + ], + "public_gateways": [], + "floating_ips": [ + { + "address": "52.116.131.7", + "created_at": "2024-06-19T07:13:16.000Z", + "crn": "crn:96", + "href": "href:97", + "id": "id:98", + "name": "floating-ip", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:40", + "id": "id:41", + "name": "bouncing-serpent-graffiti-evasion", + "primary_ip": { + "address": "10.240.0.4", + "href": "href:38", + "id": "id:39", + "name": "portion-send-snout-magazine", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": "2024-06-19T07:12:16.000Z", + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "deny", + "before": { + "href": "href:101", + "id": "id:102", + "name": "acl1-out3" + }, + "created_at": "2024-06-19T07:12:17.000Z", + "destination": "10.240.0.0/24", + "direction": "outbound", + "href": "href:99", + "id": "id:100", + "ip_version": "ipv4", + "name": "acl1-out2", + "source": "10.240.128.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:103", + "id": "id:104", + "name": "acl1-in2" + }, + "created_at": "2024-06-19T07:12:18.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:101", + "id": "id:102", + "ip_version": "ipv4", + "name": "acl1-out3", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-19T07:12:18.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:103", + "id": "id:104", + "ip_version": "ipv4", + "name": "acl1-in2", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "sub1", + "resource_type": "subnet" + }, + { + "crn": "crn:49", + "href": "href:50", + "id": "id:51", + "name": "sub3", + "resource_type": "subnet" + }, + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "sub2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-19T07:11:57.000Z", + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "premises-eleven-nursery-coveted", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:107", + "id": "id:108", + "name": "allow-outbound" + }, + "created_at": "2024-06-19T07:11:57.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:105", + "id": "id:106", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-06-19T07:11:57.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:107", + "id": "id:108", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-06-19T07:12:17.000Z", + "crn": "crn:109", + "href": "href:110", + "id": "id:111", + "name": "opa-sg", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:112", + "id": "id:113", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:114", + "href": "href:115", + "id": "id:116", + "name": "be-sg" + }, + "port_max": 8181, + "port_min": 8181, + "protocol": "tcp" + } + ], + "targets": [ + { + "href": "href:84", + "id": "id:85", + "name": "left-pebble-agonizing-wharf", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-19T07:12:17.000Z", + "crn": "crn:114", + "href": "href:115", + "id": "id:116", + "name": "be-sg", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:117", + "id": "id:118", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:119", + "href": "href:120", + "id": "id:121", + "name": "fe-sg" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "outbound", + "href": "href:122", + "id": "id:123", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:109", + "href": "href:110", + "id": "id:111", + "name": "opa-sg" + }, + "port_max": 8181, + "port_min": 8181, + "protocol": "tcp" + } + ], + "targets": [ + { + "href": "href:80", + "id": "id:81", + "name": "captain-captivity-shorty-crown", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-19T07:12:17.000Z", + "crn": "crn:124", + "href": "href:125", + "id": "id:126", + "name": "policydb-vpe", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:127", + "id": "id:128", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "address": "10.240.128.7" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "outbound", + "href": "href:129", + "id": "id:130", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "address": "10.240.64.4" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + } + ], + "targets": [ + { + "href": "href:80", + "id": "id:81", + "name": "captain-captivity-shorty-crown", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-19T07:12:17.000Z", + "crn": "crn:131", + "href": "href:132", + "id": "id:133", + "name": "proxy-sg", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:134", + "id": "id:135", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "href:136", + "id": "id:137", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:119", + "href": "href:120", + "id": "id:121", + "name": "fe-sg" + }, + "port_max": 9000, + "port_min": 9000, + "protocol": "udp" + } + ], + "targets": [ + { + "href": "href:40", + "id": "id:41", + "name": "bouncing-serpent-graffiti-evasion", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-19T07:12:17.000Z", + "crn": "crn:138", + "href": "href:139", + "id": "id:140", + "name": "appdata-sg", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:141", + "id": "id:142", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + } + ], + "targets": [ + { + "href": "href:45", + "id": "id:46", + "name": "appdata-endpoint-gateway", + "resource_type": "endpoint_gateway", + "crn": "crn:44" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-19T07:12:17.000Z", + "crn": "crn:143", + "href": "href:144", + "id": "id:145", + "name": "appdata-vpe", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:146", + "id": "id:147", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "address": "10.240.128.8" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + } + ], + "targets": [ + { + "href": "href:80", + "id": "id:81", + "name": "captain-captivity-shorty-crown", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-19T07:12:17.000Z", + "crn": "crn:119", + "href": "href:120", + "id": "id:121", + "name": "fe-sg", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:148", + "id": "id:149", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:114", + "href": "href:115", + "id": "id:116", + "name": "be-sg" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "inbound", + "href": "href:150", + "id": "id:151", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:131", + "href": "href:132", + "id": "id:133", + "name": "proxy-sg" + }, + "port_max": 9000, + "port_min": 9000, + "protocol": "udp" + } + ], + "targets": [ + { + "href": "href:88", + "id": "id:89", + "name": "litigate-bullfrog-improve-shandy", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-19T07:12:16.000Z", + "crn": "crn:152", + "href": "href:153", + "id": "id:154", + "name": "policydb-sg", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:155", + "id": "id:156", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + } + ], + "targets": [ + { + "href": "href:63", + "id": "id:64", + "name": "policydb-endpoint-gateway", + "resource_type": "endpoint_gateway", + "crn": "crn:62" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-06-19T07:11:57.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "impart-oxidize-chive-escapade", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:157", + "id": "id:158", + "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:159", + "id": "id:160", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "impart-oxidize-chive-escapade" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [ + { + "allow_dns_resolution_binding": true, + "created_at": "2024-06-19T11:03:31.000Z", + "crn": "crn:62", + "health_state": "ok", + "href": "href:63", + "id": "id:64", + "ips": [ + { + "address": "10.240.64.4", + "href": "href:60", + "id": "id:61", + "name": "policydb-vpe3", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.128.7", + "href": "href:90", + "id": "id:91", + "name": "policydb-vpe2", + "resource_type": "subnet_reserved_ip" + } + ], + "lifecycle_reasons": null, + "lifecycle_state": "stable", + "name": "policydb-endpoint-gateway", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "endpoint_gateway", + "security_groups": [ + { + "crn": "crn:152", + "href": "href:153", + "id": "id:154", + "name": "policydb-sg" + } + ], + "service_endpoint": "0b00984f-c1e1-43b2-ba1e-35b0a55b2fa5.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud", + "service_endpoints": [ + "0b00984f-c1e1-43b2-ba1e-35b0a55b2fa5.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud" + ], + "target": { + "crn": "crn:161", + "resource_type": "provider_cloud_service" + }, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "allow_dns_resolution_binding": true, + "created_at": "2024-06-19T11:03:31.000Z", + "crn": "crn:44", + "health_state": "ok", + "href": "href:45", + "id": "id:46", + "ips": [ + { + "address": "10.240.128.8", + "href": "href:92", + "id": "id:93", + "name": "appdata-vpe2", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.0.5", + "href": "href:42", + "id": "id:43", + "name": "appdata-vpe1", + "resource_type": "subnet_reserved_ip" + } + ], + "lifecycle_reasons": null, + "lifecycle_state": "stable", + "name": "appdata-endpoint-gateway", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "endpoint_gateway", + "security_groups": [ + { + "crn": "crn:138", + "href": "href:139", + "id": "id:140", + "name": "appdata-sg" + } + ], + "service_endpoint": "d60cdc12-7501-488c-a8d7-91a089497ca9-0.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud", + "service_endpoints": [ + "d60cdc12-7501-488c-a8d7-91a089497ca9-0.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud", + "d60cdc12-7501-488c-a8d7-91a089497ca9-1.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud", + "d60cdc12-7501-488c-a8d7-91a089497ca9-2.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud" + ], + "target": { + "crn": "crn:162", + "resource_type": "provider_cloud_service" + }, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "instances": [ + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:168" + }, + "href": "href:166", + "id": "id:167", + "name": "magnitude-aloe-wildlife-vacancy", + "volume": { + "crn": "crn:169", + "href": "href:170", + "id": "id:171", + "name": "catbrier-onto-grapple-fastball", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-19T07:12:47.000Z", + "crn": "crn:163", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:164", + "id": "id:165", + "image": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "proxy", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:40", + "id": "id:41", + "name": "bouncing-serpent-graffiti-evasion", + "primary_ip": { + "address": "10.240.0.4", + "href": "href:38", + "id": "id:39", + "name": "portion-send-snout-magazine", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "sub1", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:175", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:168" + }, + "href": "href:166", + "id": "id:167", + "name": "magnitude-aloe-wildlife-vacancy", + "volume": { + "crn": "crn:169", + "href": "href:170", + "id": "id:171", + "name": "catbrier-onto-grapple-fastball", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-19T07:12:47.000Z", + "floating_ips": [ + { + "address": "52.116.131.7", + "crn": "crn:96", + "href": "href:97", + "id": "id:98", + "name": "floating-ip" + } + ], + "href": "href:40", + "id": "id:41", + "name": "bouncing-serpent-graffiti-evasion", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.0.4", + "href": "href:38", + "id": "id:39", + "name": "portion-send-snout-magazine", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:131", + "href": "href:132", + "id": "id:133", + "name": "proxy-sg" + } + ], + "status": "available", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "sub1", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:181" + }, + "href": "href:179", + "id": "id:180", + "name": "folk-mousy-collar-kleenex", + "volume": { + "crn": "crn:182", + "href": "href:183", + "id": "id:184", + "name": "regalia-pavestone-ramble-stretch", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-19T07:12:46.000Z", + "crn": "crn:176", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:177", + "id": "id:178", + "image": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "opa", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:84", + "id": "id:85", + "name": "left-pebble-agonizing-wharf", + "primary_ip": { + "address": "10.240.128.5", + "href": "href:82", + "id": "id:83", + "name": "kilt-snipping-yen-unmanaged", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "sub2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:175", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:181" + }, + "href": "href:179", + "id": "id:180", + "name": "folk-mousy-collar-kleenex", + "volume": { + "crn": "crn:182", + "href": "href:183", + "id": "id:184", + "name": "regalia-pavestone-ramble-stretch", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-19T07:12:46.000Z", + "floating_ips": [], + "href": "href:84", + "id": "id:85", + "name": "left-pebble-agonizing-wharf", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.128.5", + "href": "href:82", + "id": "id:83", + "name": "kilt-snipping-yen-unmanaged", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:109", + "href": "href:110", + "id": "id:111", + "name": "opa-sg" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "sub2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:190" + }, + "href": "href:188", + "id": "id:189", + "name": "scarily-reapprove-ecologist-gosling", + "volume": { + "crn": "crn:191", + "href": "href:192", + "id": "id:193", + "name": "flattered-laboring-reusable-comic", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-19T07:12:46.000Z", + "crn": "crn:185", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:186", + "id": "id:187", + "image": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "fe", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:88", + "id": "id:89", + "name": "litigate-bullfrog-improve-shandy", + "primary_ip": { + "address": "10.240.128.6", + "href": "href:86", + "id": "id:87", + "name": "manic-nerve-surfboard-cofounder", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "sub2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:175", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:190" + }, + "href": "href:188", + "id": "id:189", + "name": "scarily-reapprove-ecologist-gosling", + "volume": { + "crn": "crn:191", + "href": "href:192", + "id": "id:193", + "name": "flattered-laboring-reusable-comic", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-19T07:12:46.000Z", + "floating_ips": [], + "href": "href:88", + "id": "id:89", + "name": "litigate-bullfrog-improve-shandy", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.128.6", + "href": "href:86", + "id": "id:87", + "name": "manic-nerve-surfboard-cofounder", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:119", + "href": "href:120", + "id": "id:121", + "name": "fe-sg" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "sub2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:199" + }, + "href": "href:197", + "id": "id:198", + "name": "carnival-grimace-mannequin-lumping", + "volume": { + "crn": "crn:200", + "href": "href:201", + "id": "id:202", + "name": "wands-niece-whole-cocoa", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-06-19T07:12:46.000Z", + "crn": "crn:194", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:195", + "id": "id:196", + "image": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "be", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:80", + "id": "id:81", + "name": "captain-captivity-shorty-crown", + "primary_ip": { + "address": "10.240.128.4", + "href": "href:78", + "id": "id:79", + "name": "magnetism-steersman-botany-hurled", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "sub2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:175", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:199" + }, + "href": "href:197", + "id": "id:198", + "name": "carnival-grimace-mannequin-lumping", + "volume": { + "crn": "crn:200", + "href": "href:201", + "id": "id:202", + "name": "wands-niece-whole-cocoa", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-06-19T07:12:46.000Z", + "floating_ips": [], + "href": "href:80", + "id": "id:81", + "name": "captain-captivity-shorty-crown", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.128.4", + "href": "href:78", + "id": "id:79", + "name": "magnetism-steersman-botany-hurled", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "crn:124", + "href": "href:125", + "id": "id:126", + "name": "policydb-vpe" + }, + { + "crn": "crn:114", + "href": "href:115", + "id": "id:116", + "name": "be-sg" + }, + { + "crn": "crn:143", + "href": "href:144", + "id": "id:145", + "name": "appdata-vpe" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "sub2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + } + ], + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-06-19T07:11:57.000Z", + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "unguarded-corncob-unaired-corner", + "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", + "resource_type": "subnet" + }, + { + "crn": "crn:49", + "href": "href:50", + "id": "id:51", + "name": "sub3", + "resource_type": "subnet" + }, + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "sub2", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc", + "resource_type": "vpc" + } + } + ], + "load_balancers": [], + "transit_connections": null, + "transit_gateways": null, + "iks_clusters": [] +} diff --git a/test/data/acl_vpe/conn_spec.json b/test/data/acl_vpe/conn_spec.json new file mode 100644 index 00000000..63a59fc1 --- /dev/null +++ b/test/data/acl_vpe/conn_spec.json @@ -0,0 +1,27 @@ +{ + "externals": { + "public internet": "0.0.0.0/0" + }, + "required-connections": [ + { + "src": { + "name": "public internet", + "type": "external" + }, + "dst": { + "name": "appdata-endpoint-gateway", + "type": "vpe" + } + }, + { + "src": { + "name": "policydb-endpoint-gateway", + "type": "vpe" + }, + "dst": { + "name": "sub1", + "type": "subnet" + } + } + ] +} diff --git a/test/expected/acl_vpe_tf/nacl_expected.tf b/test/expected/acl_vpe_tf/nacl_expected.tf new file mode 100644 index 00000000..7e4bc500 --- /dev/null +++ b/test/expected/acl_vpe_tf/nacl_expected.tf @@ -0,0 +1,404 @@ +# test-vpc/sub1 [10.240.0.0/24] +resource "ibm_is_network_acl" "acl-test-vpc--sub1" { + name = "acl-test-vpc--sub1" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc_id + # Internal. required-connections[1]: (vpe test-vpc/policydb-endpoint-gateway)->(subnet test-vpc/sub1); allowed-protocols[0] + rules { + name = "rule0" + action = "allow" + direction = "inbound" + source = "10.240.64.0/24" + destination = "10.240.0.0/24" + } + # Internal. response to required-connections[1]: (vpe test-vpc/policydb-endpoint-gateway)->(subnet test-vpc/sub1); allowed-protocols[0] + rules { + name = "rule1" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" + destination = "10.240.64.0/24" + } + # Internal. required-connections[1]: (vpe test-vpc/policydb-endpoint-gateway)->(subnet test-vpc/sub1); allowed-protocols[0] + rules { + name = "rule2" + action = "allow" + direction = "inbound" + source = "10.240.128.0/24" + destination = "10.240.0.0/24" + } + # Internal. response to required-connections[1]: (vpe test-vpc/policydb-endpoint-gateway)->(subnet test-vpc/sub1); allowed-protocols[0] + rules { + name = "rule3" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" + destination = "10.240.128.0/24" + } + # Deny other internal communication; see rfc1918#3; item 0,0 + rules { + name = "rule4" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 0,0 + rules { + name = "rule5" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 0,1 + rules { + name = "rule6" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 0,1 + rules { + name = "rule7" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 0,2 + rules { + name = "rule8" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" + destination = "192.168.0.0/16" + } + # Deny other internal communication; see rfc1918#3; item 0,2 + rules { + name = "rule9" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 1,0 + rules { + name = "rule10" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 1,0 + rules { + name = "rule11" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 1,1 + rules { + name = "rule12" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 1,1 + rules { + name = "rule13" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 1,2 + rules { + name = "rule14" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" + destination = "192.168.0.0/16" + } + # Deny other internal communication; see rfc1918#3; item 1,2 + rules { + name = "rule15" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 2,0 + rules { + name = "rule16" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 2,0 + rules { + name = "rule17" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" + destination = "192.168.0.0/16" + } + # Deny other internal communication; see rfc1918#3; item 2,1 + rules { + name = "rule18" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 2,1 + rules { + name = "rule19" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" + destination = "192.168.0.0/16" + } + # Deny other internal communication; see rfc1918#3; item 2,2 + rules { + name = "rule20" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" + destination = "192.168.0.0/16" + } + # Deny other internal communication; see rfc1918#3; item 2,2 + rules { + name = "rule21" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" + destination = "192.168.0.0/16" + } + # External. required-connections[0]: (external public internet)->(vpe test-vpc/appdata-endpoint-gateway); allowed-protocols[0] + rules { + name = "rule22" + action = "allow" + direction = "inbound" + source = "0.0.0.0/0" + destination = "10.240.0.0/24" + } + # External. response to required-connections[0]: (external public internet)->(vpe test-vpc/appdata-endpoint-gateway); allowed-protocols[0] + rules { + name = "rule23" + action = "allow" + direction = "outbound" + source = "10.240.0.0/24" + destination = "0.0.0.0/0" + } +} + +# test-vpc/sub2 [10.240.128.0/24] +resource "ibm_is_network_acl" "acl-test-vpc--sub2" { + name = "acl-test-vpc--sub2" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc_id + # Internal. required-connections[1]: (vpe test-vpc/policydb-endpoint-gateway)->(subnet test-vpc/sub1); allowed-protocols[0] + rules { + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" + destination = "10.240.0.0/24" + } + # Internal. response to required-connections[1]: (vpe test-vpc/policydb-endpoint-gateway)->(subnet test-vpc/sub1); allowed-protocols[0] + rules { + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" + destination = "10.240.128.0/24" + } + # Deny other internal communication; see rfc1918#3; item 0,0 + rules { + name = "rule2" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 0,0 + rules { + name = "rule3" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 0,1 + rules { + name = "rule4" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 0,1 + rules { + name = "rule5" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 0,2 + rules { + name = "rule6" + action = "deny" + direction = "outbound" + source = "10.0.0.0/8" + destination = "192.168.0.0/16" + } + # Deny other internal communication; see rfc1918#3; item 0,2 + rules { + name = "rule7" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 1,0 + rules { + name = "rule8" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 1,0 + rules { + name = "rule9" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 1,1 + rules { + name = "rule10" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 1,1 + rules { + name = "rule11" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 1,2 + rules { + name = "rule12" + action = "deny" + direction = "outbound" + source = "172.16.0.0/12" + destination = "192.168.0.0/16" + } + # Deny other internal communication; see rfc1918#3; item 1,2 + rules { + name = "rule13" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 2,0 + rules { + name = "rule14" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" + destination = "10.0.0.0/8" + } + # Deny other internal communication; see rfc1918#3; item 2,0 + rules { + name = "rule15" + action = "deny" + direction = "inbound" + source = "10.0.0.0/8" + destination = "192.168.0.0/16" + } + # Deny other internal communication; see rfc1918#3; item 2,1 + rules { + name = "rule16" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" + destination = "172.16.0.0/12" + } + # Deny other internal communication; see rfc1918#3; item 2,1 + rules { + name = "rule17" + action = "deny" + direction = "inbound" + source = "172.16.0.0/12" + destination = "192.168.0.0/16" + } + # Deny other internal communication; see rfc1918#3; item 2,2 + rules { + name = "rule18" + action = "deny" + direction = "outbound" + source = "192.168.0.0/16" + destination = "192.168.0.0/16" + } + # Deny other internal communication; see rfc1918#3; item 2,2 + rules { + name = "rule19" + action = "deny" + direction = "inbound" + source = "192.168.0.0/16" + destination = "192.168.0.0/16" + } + # External. required-connections[0]: (external public internet)->(vpe test-vpc/appdata-endpoint-gateway); allowed-protocols[0] + rules { + name = "rule20" + action = "allow" + direction = "inbound" + source = "0.0.0.0/0" + destination = "10.240.128.0/24" + } + # External. response to required-connections[0]: (external public internet)->(vpe test-vpc/appdata-endpoint-gateway); allowed-protocols[0] + rules { + name = "rule21" + action = "allow" + direction = "outbound" + source = "10.240.128.0/24" + destination = "0.0.0.0/0" + } +} + +# test-vpc/sub3 [10.240.64.0/24] +resource "ibm_is_network_acl" "acl-test-vpc--sub3" { + name = "acl-test-vpc--sub3" + resource_group = local.acl_synth_resource_group_id + vpc = local.acl_synth_test-vpc_id + # Internal. required-connections[1]: (vpe test-vpc/policydb-endpoint-gateway)->(subnet test-vpc/sub1); allowed-protocols[0] + rules { + name = "rule0" + action = "allow" + direction = "outbound" + source = "10.240.64.0/24" + destination = "10.240.0.0/24" + } + # Internal. response to required-connections[1]: (vpe test-vpc/policydb-endpoint-gateway)->(subnet test-vpc/sub1); allowed-protocols[0] + rules { + name = "rule1" + action = "allow" + direction = "inbound" + source = "10.240.0.0/24" + destination = "10.240.64.0/24" + } +} diff --git a/test/synth_test_list.go b/test/synth_test_list.go index ce00dc88..fac53a7a 100644 --- a/test/synth_test_list.go +++ b/test/synth_test_list.go @@ -27,6 +27,9 @@ const ( aclTgMultipleConfig = "%s/acl_tg_multiple/config_object.json" aclTgMultipleSpec = "%s/acl_tg_multiple/conn_spec.json" + aclVpeConfig = "%s/acl_vpe/config_object.json" + aclVpeSpec = "%s/acl_vpe/conn_spec.json" + sgProtocolsConfig = "%s/sg_protocols/config_object.json" sgProtocolsSpec = "%s/sg_protocols/conn_spec.json" @@ -222,6 +225,18 @@ func synthACLTestsList() []testCase { format: tfOutputFmt, }, }, + + // acl vpe ## sg_testing3 config + { + testName: "acl_vpe_tf", + args: &command{ + cmd: synth, + subcmd: acl, + config: aclVpeConfig, + spec: aclVpeSpec, + outputFile: "%s/acl_vpe_tf/nacl_expected.tf", + }, + }, } } From 6fa8417d4cabd915aeb5749c708a210970277c65 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 14 Oct 2024 16:28:13 +0300 Subject: [PATCH 080/131] merge test configs --- .../config_object.json | 6269 ----------------- test/data/acl_protocols/config_object.json | 6269 ----------------- .../config_object.json | 1776 ----- .../config_object.json | 0 test/data/acl_tg_multiple/config_object.json | 6269 ----------------- test/data/acl_vpe/config_object.json | 2077 ------ test/data/sg_protocols/config_object.json | 6269 ----------------- test/data/sg_tg_multiple/config_object.json | 6269 ----------------- .../config_object.json | 0 test/synth_test_list.go | 84 +- 10 files changed, 34 insertions(+), 35248 deletions(-) delete mode 100644 test/data/acl_nif_instance_segments/config_object.json delete mode 100644 test/data/acl_protocols/config_object.json delete mode 100644 test/data/acl_subnet_cidr_segments/config_object.json rename test/data/{acl_externals => acl_testing4}/config_object.json (100%) delete mode 100644 test/data/acl_tg_multiple/config_object.json delete mode 100644 test/data/acl_vpe/config_object.json delete mode 100644 test/data/sg_protocols/config_object.json delete mode 100644 test/data/sg_tg_multiple/config_object.json rename test/data/{acl_nif => tg_multiple}/config_object.json (100%) diff --git a/test/data/acl_nif_instance_segments/config_object.json b/test/data/acl_nif_instance_segments/config_object.json deleted file mode 100644 index 7e94d3b8..00000000 --- a/test/data/acl_nif_instance_segments/config_object.json +++ /dev/null @@ -1,6269 +0,0 @@ -{ - "collector_version": "0.11.0", - "provider": "ibm", - "vpcs": [ - { - "classic_access": false, - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:1", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.215.5" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.220.2" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.249.82.12" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "automaker-castle-bird-worried" - }, - "default_routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole" - }, - "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": "test-vpc1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.80.0/20", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:18", - "id": "id:19", - "is_default": false, - "name": "address-prefix-vpc-1", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "cidr": "10.240.64.0/20", - "created_at": "2024-06-25T15:40:40.000Z", - "has_subnets": true, - "href": "href:20", - "id": "id:21", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:22", - "cse_source_ips": [ - { - "ip": { - "address": "10.16.238.56" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.249.200.205" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.249.212.88" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:25", - "href": "href:26", - "id": "id:27", - "name": "ebullient-slacks-revert-turkey" - }, - "default_routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam" - }, - "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:23", - "id": "id:24", - "name": "test-vpc0", - "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/22", - "created_at": "2024-06-25T15:40:37.000Z", - "has_subnets": true, - "href": "href:33", - "id": "id:34", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.4.0/22", - "created_at": "2024-06-25T15:40:38.000Z", - "has_subnets": true, - "href": "href:35", - "id": "id:36", - "is_default": false, - "name": "address-prefix-vpc-1", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.8.0/22", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:37", - "id": "id:38", - "is_default": false, - "name": "address-prefix-vpc-2", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:39", - "cse_source_ips": [ - { - "ip": { - "address": "10.12.125.16" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.27.134" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.22.231.90" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:42", - "href": "href:43", - "id": "id:44", - "name": "afoot-grape-fineness-zestfully" - }, - "default_routing_table": { - "href": "href:45", - "id": "id:46", - "name": "quintuple-severity-caddie-manuals", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll" - }, - "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:40", - "id": "id:41", - "name": "test-vpc2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.128.0/20", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:50", - "id": "id:51", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:52", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.219.155" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.12.159.11" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.16.253.109" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:55", - "href": "href:56", - "id": "id:57", - "name": "untracked-repayment-triumph-cat" - }, - "default_routing_table": { - "href": "href:58", - "id": "id:59", - "name": "probational-herring-undone-daintily", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely" - }, - "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:53", - "id": "id:54", - "name": "test-vpc3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.192.0/20", - "created_at": "2024-06-25T15:40:38.000Z", - "has_subnets": true, - "href": "href:63", - "id": "id:64", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - } - ], - "subnets": [ - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:47.000Z", - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.9.0/24", - "name": "subnet5", - "network_acl": { - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.9.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:71", - "id": "id:72", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:73", - "id": "id:74", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:75", - "id": "id:76", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:77", - "id": "id:78", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:79", - "id": "id:80", - "lifecycle_state": "stable", - "name": "ideally-grain-bagpipe-luxuriant", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.9.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:20.000Z", - "href": "href:83", - "id": "id:84", - "lifecycle_state": "stable", - "name": "outskirts-unaligned-passivism-parchment", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.9.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:87", - "id": "id:88", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:35.000Z", - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.5.0/24", - "name": "subnet3", - "network_acl": { - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.5.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:95", - "id": "id:96", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:97", - "id": "id:98", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:99", - "id": "id:100", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:101", - "id": "id:102", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:103", - "id": "id:104", - "lifecycle_state": "stable", - "name": "rising-gopher-reentry-graveness", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.5.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:16.000Z", - "href": "href:107", - "id": "id:108", - "lifecycle_state": "stable", - "name": "recognize-citable-exerciser-unsecured", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.5.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:111", - "id": "id:112", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:23.000Z", - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.0.0/24", - "name": "subnet0", - "network_acl": { - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.0.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:119", - "id": "id:120", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:121", - "id": "id:122", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:123", - "id": "id:124", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:125", - "id": "id:126", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:08.000Z", - "href": "href:127", - "id": "id:128", - "lifecycle_state": "stable", - "name": "pundit-tight-arbitrate-grace", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:39.000Z", - "href": "href:131", - "id": "id:132", - "lifecycle_state": "stable", - "name": "relatable-antiques-maturing-brulee", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:135", - "id": "id:136", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:41:20.000Z", - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.80.0/24", - "name": "subnet11", - "network_acl": { - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "reserved_ips": [ - { - "address": "10.240.80.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:143", - "id": "id:144", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:145", - "id": "id:146", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:147", - "id": "id:148", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:149", - "id": "id:150", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:40.000Z", - "href": "href:151", - "id": "id:152", - "lifecycle_state": "stable", - "name": "childlike-publish-retainer-movie", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.80.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:155", - "id": "id:156", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:08.000Z", - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.4.0/24", - "name": "subnet2", - "network_acl": { - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.4.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:160", - "id": "id:161", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:162", - "id": "id:163", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:164", - "id": "id:165", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:166", - "id": "id:167", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:21.000Z", - "href": "href:168", - "id": "id:169", - "lifecycle_state": "stable", - "name": "stood-sitcom-whoops-hurled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.4.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:22.000Z", - "href": "href:172", - "id": "id:173", - "lifecycle_state": "stable", - "name": "bark-gatherer-rope-unrivaled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.4.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:176", - "id": "id:177", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:41:08.000Z", - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.64.0/24", - "name": "subnet10", - "network_acl": { - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "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-25T15:41:08.000Z", - "href": "href:181", - "id": "id:182", - "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-25T15:41:08.000Z", - "href": "href:183", - "id": "id:184", - "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-25T15:41:08.000Z", - "href": "href:185", - "id": "id:186", - "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-25T15:41:08.000Z", - "href": "href:187", - "id": "id:188", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.64.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:36.000Z", - "href": "href:189", - "id": "id:190", - "lifecycle_state": "stable", - "name": "starry-smasher-ladle-dioxide", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.64.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:193", - "id": "id:194", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 248, - "created_at": "2024-06-25T15:40:57.000Z", - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.128.0/24", - "name": "subnet20", - "network_acl": { - "crn": "crn:198", - "href": "href:199", - "id": "id:200", - "name": "acl21" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:45", - "id": "id:46", - "name": "quintuple-severity-caddie-manuals", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "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-25T15:40:57.000Z", - "href": "href:201", - "id": "id:202", - "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-25T15:40:57.000Z", - "href": "href:203", - "id": "id:204", - "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-25T15:40:57.000Z", - "href": "href:205", - "id": "id:206", - "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-25T15:40:57.000Z", - "href": "href:207", - "id": "id:208", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.128.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:21.000Z", - "href": "href:209", - "id": "id:210", - "lifecycle_state": "stable", - "name": "unmixed-qualify-prescribe-railcar", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.5", - "auto_delete": false, - "created_at": "2024-06-25T15:41:21.000Z", - "href": "href:213", - "id": "id:214", - "lifecycle_state": "stable", - "name": "customs-recollect-drippy-primate", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.6", - "auto_delete": false, - "created_at": "2024-06-25T15:41:24.000Z", - "href": "href:217", - "id": "id:218", - "lifecycle_state": "stable", - "name": "uniquely-shelter-gracious-sudden", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:57.000Z", - "href": "href:221", - "id": "id:222", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:40:56.000Z", - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.1.0/24", - "name": "subnet1", - "network_acl": { - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "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-25T15:40:56.000Z", - "href": "href:226", - "id": "id:227", - "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-25T15:40:56.000Z", - "href": "href:228", - "id": "id:229", - "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-25T15:40:56.000Z", - "href": "href:230", - "id": "id:231", - "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-25T15:40:56.000Z", - "href": "href:232", - "id": "id:233", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.1.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:234", - "id": "id:235", - "lifecycle_state": "stable", - "name": "excluded-unfair-jailbird-foil", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.1.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:40.000Z", - "href": "href:238", - "id": "id:239", - "lifecycle_state": "stable", - "name": "affected-johnniecake-monorail-ungraded", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.1.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:56.000Z", - "href": "href:242", - "id": "id:243", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:40:48.000Z", - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.192.0/24", - "name": "subnet30", - "network_acl": { - "crn": "crn:247", - "href": "href:248", - "id": "id:249", - "name": "acl31" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:58", - "id": "id:59", - "name": "probational-herring-undone-daintily", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "reserved_ips": [ - { - "address": "10.240.192.0", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:250", - "id": "id:251", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.1", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:252", - "id": "id:253", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.2", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:254", - "id": "id:255", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.3", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:256", - "id": "id:257", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:01.000Z", - "href": "href:258", - "id": "id:259", - "lifecycle_state": "stable", - "name": "legacy-shore-molecule-barometer", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.192.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:262", - "id": "id:263", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:40:44.000Z", - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.8.0/24", - "name": "subnet4", - "network_acl": { - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.8.0", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:267", - "id": "id:268", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.1", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:269", - "id": "id:270", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.2", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:271", - "id": "id:272", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.3", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:273", - "id": "id:274", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:275", - "id": "id:276", - "lifecycle_state": "stable", - "name": "bagged-posture-glaring-cojoined", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.8.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:16.000Z", - "href": "href:279", - "id": "id:280", - "lifecycle_state": "stable", - "name": "frighten-mystified-freeway-hurtling", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.8.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:283", - "id": "id:284", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - } - ], - "public_gateways": [], - "floating_ips": [ - { - "address": "52.118.151.238", - "created_at": "2024-06-25T15:43:30.000Z", - "crn": "crn:285", - "href": "href:286", - "id": "id:287", - "name": "fip-0-subnet0", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - }, - { - "address": "150.239.167.146", - "created_at": "2024-06-25T15:41:59.000Z", - "crn": "crn:288", - "href": "href:289", - "id": "id:290", - "name": "fip-0-subnet10", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "tags": [] - }, - { - "address": "169.48.95.165", - "created_at": "2024-06-25T15:41:50.000Z", - "crn": "crn:291", - "href": "href:292", - "id": "id:293", - "name": "fip-0-subnet20", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "tags": [] - }, - { - "address": "52.118.100.239", - "created_at": "2024-06-25T15:41:33.000Z", - "crn": "crn:294", - "href": "href:295", - "id": "id:296", - "name": "fip-0-subnet30", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "tags": [] - } - ], - "network_acls": [ - { - "created_at": "2024-06-25T15:40:41.000Z", - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "deny", - "before": { - "href": "href:299", - "id": "id:300", - "name": "acl11-out-2" - }, - "created_at": "2024-06-25T15:40:42.000Z", - "destination": "10.240.4.0/24", - "direction": "outbound", - "href": "href:297", - "id": "id:298", - "ip_version": "ipv4", - "name": "acl11-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:301", - "id": "id:302", - "name": "acl11-in-1" - }, - "created_at": "2024-06-25T15:40:43.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:299", - "id": "id:300", - "ip_version": "ipv4", - "name": "acl11-out-2", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:43.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:301", - "id": "id:302", - "ip_version": "ipv4", - "name": "acl11-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:247", - "href": "href:248", - "id": "id:249", - "name": "acl31", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:305", - "id": "id:306", - "name": "acl31-in-1" - }, - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:303", - "id": "id:304", - "ip_version": "ipv4", - "name": "acl31-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:305", - "id": "id:306", - "ip_version": "ipv4", - "name": "acl31-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:198", - "href": "href:199", - "id": "id:200", - "name": "acl21", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:309", - "id": "id:310", - "name": "acl21-in-1" - }, - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:307", - "id": "id:308", - "ip_version": "ipv4", - "name": "acl21-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:42.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:309", - "id": "id:310", - "ip_version": "ipv4", - "name": "acl21-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:38.000Z", - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:313", - "id": "id:314", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:311", - "id": "id:312", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:39.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:313", - "id": "id:314", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:317", - "id": "id:318", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:315", - "id": "id:316", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:317", - "id": "id:318", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:321", - "id": "id:322", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:319", - "id": "id:320", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:321", - "id": "id:322", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "automaker-castle-bird-worried", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:325", - "id": "id:326", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:20.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:323", - "id": "id:324", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:20.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:325", - "id": "id:326", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:42", - "href": "href:43", - "id": "id:44", - "name": "afoot-grape-fineness-zestfully", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:329", - "id": "id:330", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:327", - "id": "id:328", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:329", - "id": "id:330", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:25", - "href": "href:26", - "id": "id:27", - "name": "ebullient-slacks-revert-turkey", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:333", - "id": "id:334", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:331", - "id": "id:332", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:333", - "id": "id:334", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:55", - "href": "href:56", - "id": "id:57", - "name": "untracked-repayment-triumph-cat", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:337", - "id": "id:338", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:335", - "id": "id:336", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:337", - "id": "id:338", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "security_groups": [ - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:342", - "id": "id:343", - "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:344", - "id": "id:345", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "resource_type": "network_interface" - }, - { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "resource_type": "network_interface" - }, - { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:346", - "href": "href:347", - "id": "id:348", - "name": "sg31", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:349", - "id": "id:350", - "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:351", - "id": "id:352", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:356", - "id": "id:357", - "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:358", - "id": "id:359", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "resource_type": "network_interface" - }, - { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:363", - "id": "id:364", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - }, - { - "direction": "outbound", - "href": "href:365", - "id": "id:366", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "resource_type": "network_interface" - }, - { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "resource_type": "network_interface" - }, - { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "resource_type": "network_interface" - }, - { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "resource_type": "network_interface" - }, - { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "resource_type": "network_interface" - }, - { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "resource_type": "network_interface" - }, - { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "resource_type": "network_interface" - }, - { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "resource_type": "network_interface" - }, - { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "resource_type": "network_interface" - }, - { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "resource_type": "network_interface" - }, - { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "resource_type": "network_interface" - }, - { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:367", - "id": "id:368", - "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:369", - "id": "id:370", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:371", - "id": "id:372", - "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:373", - "id": "id:374", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:375", - "id": "id:376", - "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:377", - "id": "id:378", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:379", - "id": "id:380", - "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:381", - "id": "id:382", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "endpoint_gateways": [], - "instances": [ - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:388" - }, - "href": "href:386", - "id": "id:387", - "name": "thief-monastery-blinks-verdict", - "volume": { - "crn": "crn:389", - "href": "href:390", - "id": "id:391", - "name": "scrabble-gorged-baton-angled", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:40.000Z", - "crn": "crn:383", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:384", - "id": "id:385", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "primary_ip": { - "address": "10.240.1.5", - "href": "href:238", - "id": "id:239", - "name": "affected-johnniecake-monorail-ungraded", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:388" - }, - "href": "href:386", - "id": "id:387", - "name": "thief-monastery-blinks-verdict", - "volume": { - "crn": "crn:389", - "href": "href:390", - "id": "id:391", - "name": "scrabble-gorged-baton-angled", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:40.000Z", - "floating_ips": [], - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.1.5", - "href": "href:238", - "id": "id:239", - "name": "affected-johnniecake-monorail-ungraded", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:401" - }, - "href": "href:399", - "id": "id:400", - "name": "hunchback-enginous-dividend-atrium", - "volume": { - "crn": "crn:402", - "href": "href:403", - "id": "id:404", - "name": "subsoil-bobble-bovine-unmoving", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:39.000Z", - "crn": "crn:396", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:397", - "id": "id:398", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet0", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "primary_ip": { - "address": "10.240.0.5", - "href": "href:131", - "id": "id:132", - "name": "relatable-antiques-maturing-brulee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:401" - }, - "href": "href:399", - "id": "id:400", - "name": "hunchback-enginous-dividend-atrium", - "volume": { - "crn": "crn:402", - "href": "href:403", - "id": "id:404", - "name": "subsoil-bobble-bovine-unmoving", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:39.000Z", - "floating_ips": [], - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.5", - "href": "href:131", - "id": "id:132", - "name": "relatable-antiques-maturing-brulee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:410" - }, - "href": "href:408", - "id": "id:409", - "name": "laboring-overbuilt-growl-headland", - "volume": { - "crn": "crn:411", - "href": "href:412", - "id": "id:413", - "name": "tamper-salvaging-stick-giddily", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:22.000Z", - "crn": "crn:405", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:406", - "id": "id:407", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "primary_ip": { - "address": "10.240.4.5", - "href": "href:172", - "id": "id:173", - "name": "bark-gatherer-rope-unrivaled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:410" - }, - "href": "href:408", - "id": "id:409", - "name": "laboring-overbuilt-growl-headland", - "volume": { - "crn": "crn:411", - "href": "href:412", - "id": "id:413", - "name": "tamper-salvaging-stick-giddily", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:22.000Z", - "floating_ips": [], - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.4.5", - "href": "href:172", - "id": "id:173", - "name": "bark-gatherer-rope-unrivaled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:419" - }, - "href": "href:417", - "id": "id:418", - "name": "dollop-partition-helping-palmtree", - "volume": { - "crn": "crn:420", - "href": "href:421", - "id": "id:422", - "name": "ravage-deny-amusable-settling", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:20.000Z", - "crn": "crn:414", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:415", - "id": "id:416", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet5", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "primary_ip": { - "address": "10.240.9.5", - "href": "href:83", - "id": "id:84", - "name": "outskirts-unaligned-passivism-parchment", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:419" - }, - "href": "href:417", - "id": "id:418", - "name": "dollop-partition-helping-palmtree", - "volume": { - "crn": "crn:420", - "href": "href:421", - "id": "id:422", - "name": "ravage-deny-amusable-settling", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:20.000Z", - "floating_ips": [], - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.9.5", - "href": "href:83", - "id": "id:84", - "name": "outskirts-unaligned-passivism-parchment", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:428" - }, - "href": "href:426", - "id": "id:427", - "name": "petted-ethanol-voicing-rocklike", - "volume": { - "crn": "crn:429", - "href": "href:430", - "id": "id:431", - "name": "uptown-striving-unrevised-earthlike", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:20.000Z", - "crn": "crn:423", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:424", - "id": "id:425", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "primary_ip": { - "address": "10.240.4.4", - "href": "href:168", - "id": "id:169", - "name": "stood-sitcom-whoops-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:428" - }, - "href": "href:426", - "id": "id:427", - "name": "petted-ethanol-voicing-rocklike", - "volume": { - "crn": "crn:429", - "href": "href:430", - "id": "id:431", - "name": "uptown-striving-unrevised-earthlike", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:20.000Z", - "floating_ips": [], - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.4.4", - "href": "href:168", - "id": "id:169", - "name": "stood-sitcom-whoops-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:437" - }, - "href": "href:435", - "id": "id:436", - "name": "promenade-spyglass-flattop-pushpin", - "volume": { - "crn": "crn:438", - "href": "href:439", - "id": "id:440", - "name": "relax-shaded-prism-jaunt", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:16.000Z", - "crn": "crn:432", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:433", - "id": "id:434", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet3", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "primary_ip": { - "address": "10.240.5.5", - "href": "href:107", - "id": "id:108", - "name": "recognize-citable-exerciser-unsecured", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:437" - }, - "href": "href:435", - "id": "id:436", - "name": "promenade-spyglass-flattop-pushpin", - "volume": { - "crn": "crn:438", - "href": "href:439", - "id": "id:440", - "name": "relax-shaded-prism-jaunt", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:16.000Z", - "floating_ips": [], - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.5.5", - "href": "href:107", - "id": "id:108", - "name": "recognize-citable-exerciser-unsecured", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:446" - }, - "href": "href:444", - "id": "id:445", - "name": "sandbox-federal-sculptor-jugum", - "volume": { - "crn": "crn:447", - "href": "href:448", - "id": "id:449", - "name": "convent-ramrod-cloning-afterward", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:15.000Z", - "crn": "crn:441", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:442", - "id": "id:443", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet4", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "primary_ip": { - "address": "10.240.8.5", - "href": "href:279", - "id": "id:280", - "name": "frighten-mystified-freeway-hurtling", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:446" - }, - "href": "href:444", - "id": "id:445", - "name": "sandbox-federal-sculptor-jugum", - "volume": { - "crn": "crn:447", - "href": "href:448", - "id": "id:449", - "name": "convent-ramrod-cloning-afterward", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:15.000Z", - "floating_ips": [], - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.8.5", - "href": "href:279", - "id": "id:280", - "name": "frighten-mystified-freeway-hurtling", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:455" - }, - "href": "href:453", - "id": "id:454", - "name": "affidavit-chastise-elsewhere-viewer", - "volume": { - "crn": "crn:456", - "href": "href:457", - "id": "id:458", - "name": "fancy-destiny-shuffling-sandbank", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:07.000Z", - "crn": "crn:450", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:451", - "id": "id:452", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet0", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:455" - }, - "href": "href:453", - "id": "id:454", - "name": "affidavit-chastise-elsewhere-viewer", - "volume": { - "crn": "crn:456", - "href": "href:457", - "id": "id:458", - "name": "fancy-destiny-shuffling-sandbank", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:07.000Z", - "floating_ips": [ - { - "address": "52.118.151.238", - "crn": "crn:285", - "href": "href:286", - "id": "id:287", - "name": "fip-0-subnet0" - } - ], - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:464" - }, - "href": "href:462", - "id": "id:463", - "name": "uneven-armoire-scabiosa-letter", - "volume": { - "crn": "crn:465", - "href": "href:466", - "id": "id:467", - "name": "cognition-blinks-humid-oxidant", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:459", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:460", - "id": "id:461", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet3", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "primary_ip": { - "address": "10.240.5.4", - "href": "href:103", - "id": "id:104", - "name": "rising-gopher-reentry-graveness", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:464" - }, - "href": "href:462", - "id": "id:463", - "name": "uneven-armoire-scabiosa-letter", - "volume": { - "crn": "crn:465", - "href": "href:466", - "id": "id:467", - "name": "cognition-blinks-humid-oxidant", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.5.4", - "href": "href:103", - "id": "id:104", - "name": "rising-gopher-reentry-graveness", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:473" - }, - "href": "href:471", - "id": "id:472", - "name": "perplexed-impulsivity-august-jaws", - "volume": { - "crn": "crn:474", - "href": "href:475", - "id": "id:476", - "name": "tartar-sixties-fructose-parmesan", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:468", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:469", - "id": "id:470", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "primary_ip": { - "address": "10.240.1.4", - "href": "href:234", - "id": "id:235", - "name": "excluded-unfair-jailbird-foil", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:473" - }, - "href": "href:471", - "id": "id:472", - "name": "perplexed-impulsivity-august-jaws", - "volume": { - "crn": "crn:474", - "href": "href:475", - "id": "id:476", - "name": "tartar-sixties-fructose-parmesan", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.1.4", - "href": "href:234", - "id": "id:235", - "name": "excluded-unfair-jailbird-foil", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:482" - }, - "href": "href:480", - "id": "id:481", - "name": "litter-snipping-unclasp-dust", - "volume": { - "crn": "crn:483", - "href": "href:484", - "id": "id:485", - "name": "untried-sulphate-hypnosis-subsidize", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:477", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:478", - "id": "id:479", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet4", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "primary_ip": { - "address": "10.240.8.4", - "href": "href:275", - "id": "id:276", - "name": "bagged-posture-glaring-cojoined", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:482" - }, - "href": "href:480", - "id": "id:481", - "name": "litter-snipping-unclasp-dust", - "volume": { - "crn": "crn:483", - "href": "href:484", - "id": "id:485", - "name": "untried-sulphate-hypnosis-subsidize", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.8.4", - "href": "href:275", - "id": "id:276", - "name": "bagged-posture-glaring-cojoined", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:491" - }, - "href": "href:489", - "id": "id:490", - "name": "unlawful-overreach-yarn-rippling", - "volume": { - "crn": "crn:492", - "href": "href:493", - "id": "id:494", - "name": "finer-voter-roving-jailer", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:486", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:487", - "id": "id:488", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet5", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "primary_ip": { - "address": "10.240.9.4", - "href": "href:79", - "id": "id:80", - "name": "ideally-grain-bagpipe-luxuriant", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:491" - }, - "href": "href:489", - "id": "id:490", - "name": "unlawful-overreach-yarn-rippling", - "volume": { - "crn": "crn:492", - "href": "href:493", - "id": "id:494", - "name": "finer-voter-roving-jailer", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.9.4", - "href": "href:79", - "id": "id:80", - "name": "ideally-grain-bagpipe-luxuriant", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:500" - }, - "href": "href:498", - "id": "id:499", - "name": "mashed-thing-headache-estate", - "volume": { - "crn": "crn:501", - "href": "href:502", - "id": "id:503", - "name": "mountain-harpist-libraries-dreaming", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:39.000Z", - "crn": "crn:495", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:496", - "id": "id:497", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet11", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "primary_ip": { - "address": "10.240.80.4", - "href": "href:151", - "id": "id:152", - "name": "childlike-publish-retainer-movie", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:500" - }, - "href": "href:498", - "id": "id:499", - "name": "mashed-thing-headache-estate", - "volume": { - "crn": "crn:501", - "href": "href:502", - "id": "id:503", - "name": "mountain-harpist-libraries-dreaming", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:39.000Z", - "floating_ips": [], - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.80.4", - "href": "href:151", - "id": "id:152", - "name": "childlike-publish-retainer-movie", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11" - } - ], - "status": "available", - "subnet": { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:509" - }, - "href": "href:507", - "id": "id:508", - "name": "calzone-cacti-moonlight-subarctic", - "volume": { - "crn": "crn:510", - "href": "href:511", - "id": "id:512", - "name": "blurred-dream-pectin-tapping", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:36.000Z", - "crn": "crn:504", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:505", - "id": "id:506", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet10", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:509" - }, - "href": "href:507", - "id": "id:508", - "name": "calzone-cacti-moonlight-subarctic", - "volume": { - "crn": "crn:510", - "href": "href:511", - "id": "id:512", - "name": "blurred-dream-pectin-tapping", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:36.000Z", - "floating_ips": [ - { - "address": "150.239.167.146", - "crn": "crn:288", - "href": "href:289", - "id": "id:290", - "name": "fip-0-subnet10" - } - ], - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11" - } - ], - "status": "available", - "subnet": { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:518" - }, - "href": "href:516", - "id": "id:517", - "name": "recoup-blinks-ebullient-renewed", - "volume": { - "crn": "crn:519", - "href": "href:520", - "id": "id:521", - "name": "manmade-unequal-disinfect-cone", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:24.000Z", - "crn": "crn:513", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:514", - "id": "id:515", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:518" - }, - "href": "href:516", - "id": "id:517", - "name": "recoup-blinks-ebullient-renewed", - "volume": { - "crn": "crn:519", - "href": "href:520", - "id": "id:521", - "name": "manmade-unequal-disinfect-cone", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:24.000Z", - "floating_ips": [ - { - "address": "169.48.95.165", - "crn": "crn:291", - "href": "href:292", - "id": "id:293", - "name": "fip-0-subnet20" - } - ], - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:527" - }, - "href": "href:525", - "id": "id:526", - "name": "radio-tightrope-outtakes-moonshine", - "volume": { - "crn": "crn:528", - "href": "href:529", - "id": "id:530", - "name": "tattoo-crescent-unwary-hayride", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:21.000Z", - "crn": "crn:522", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:523", - "id": "id:524", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "primary_ip": { - "address": "10.240.128.5", - "href": "href:213", - "id": "id:214", - "name": "customs-recollect-drippy-primate", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:527" - }, - "href": "href:525", - "id": "id:526", - "name": "radio-tightrope-outtakes-moonshine", - "volume": { - "crn": "crn:528", - "href": "href:529", - "id": "id:530", - "name": "tattoo-crescent-unwary-hayride", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:21.000Z", - "floating_ips": [], - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.5", - "href": "href:213", - "id": "id:214", - "name": "customs-recollect-drippy-primate", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:536" - }, - "href": "href:534", - "id": "id:535", - "name": "crumpet-ride-tastiness-phoney", - "volume": { - "crn": "crn:537", - "href": "href:538", - "id": "id:539", - "name": "doorframe-marvelous-refusing-citable", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:21.000Z", - "crn": "crn:531", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:532", - "id": "id:533", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi2-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "primary_ip": { - "address": "10.240.128.4", - "href": "href:209", - "id": "id:210", - "name": "unmixed-qualify-prescribe-railcar", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:536" - }, - "href": "href:534", - "id": "id:535", - "name": "crumpet-ride-tastiness-phoney", - "volume": { - "crn": "crn:537", - "href": "href:538", - "id": "id:539", - "name": "doorframe-marvelous-refusing-citable", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:21.000Z", - "floating_ips": [], - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.4", - "href": "href:209", - "id": "id:210", - "name": "unmixed-qualify-prescribe-railcar", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:545" - }, - "href": "href:543", - "id": "id:544", - "name": "bronzing-vendor-plod-pretzel", - "volume": { - "crn": "crn:546", - "href": "href:547", - "id": "id:548", - "name": "squelch-plop-headlamp-ideologue", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:00.000Z", - "crn": "crn:540", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:541", - "id": "id:542", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet30", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:545" - }, - "href": "href:543", - "id": "id:544", - "name": "bronzing-vendor-plod-pretzel", - "volume": { - "crn": "crn:546", - "href": "href:547", - "id": "id:548", - "name": "squelch-plop-headlamp-ideologue", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:00.000Z", - "floating_ips": [ - { - "address": "52.118.100.239", - "crn": "crn:294", - "href": "href:295", - "id": "id:296", - "name": "fip-0-subnet30" - } - ], - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:346", - "href": "href:347", - "id": "id:348", - "name": "sg31" - } - ], - "status": "available", - "subnet": { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - } - ], - "routing_tables": [ - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:20.000Z", - "href": "href:11", - "id": "id:12", - "is_default": true, - "lifecycle_state": "stable", - "name": "overtone-sputter-overspend-gorge", - "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:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:28", - "id": "id:29", - "is_default": true, - "lifecycle_state": "stable", - "name": "escapade-dynamite-upstage-context", - "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:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:45", - "id": "id:46", - "is_default": true, - "lifecycle_state": "stable", - "name": "quintuple-severity-caddie-manuals", - "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:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:58", - "id": "id:59", - "is_default": true, - "lifecycle_state": "stable", - "name": "probational-herring-undone-daintily", - "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:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - } - } - ], - "load_balancers": [], - "transit_connections": [ - { - "created_at": "2024-06-25T15:41:44.212Z", - "id": "id:549", - "name": "tg3_connection3", - "network_id": "crn:52", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:550", - "id": "id:551", - "name": "local-tg3" - }, - "updated_at": "2024-06-25T15:45:14.206Z" - }, - { - "created_at": "2024-06-25T15:41:54.416Z", - "id": "id:552", - "name": "tg3_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:550", - "id": "id:551", - "name": "local-tg3" - }, - "updated_at": "2024-06-25T15:45:53.979Z" - }, - { - "created_at": "2024-06-25T15:42:54.772Z", - "id": "id:553", - "name": "tg2_connection3", - "network_id": "crn:52", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:08.822Z" - }, - { - "created_at": "2024-06-25T15:43:11.555Z", - "id": "id:556", - "name": "tg2_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters": [ - { - "action": "deny", - "created_at": "2024-06-25T15:46:46.641Z", - "id": "id:557", - "le": 32, - "prefix": "10.240.0.0/22", - "updated_at": "2024-06-25T15:46:46.641Z" - } - ], - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:59.395Z" - }, - { - "created_at": "2024-06-25T15:43:12.159Z", - "id": "id:558", - "name": "tg_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters": [ - { - "action": "deny", - "before": "298db67f-2e68-4548-93b9-949f8356d4a0", - "created_at": "2024-06-25T15:45:14.711Z", - "id": "id:559", - "prefix": "10.240.4.0/22", - "updated_at": "2024-06-25T15:45:14.711Z" - }, - { - "action": "deny", - "created_at": "2024-06-25T15:45:25.435Z", - "id": "id:560", - "prefix": "10.240.8.0/22", - "updated_at": "2024-06-25T15:45:25.435Z" - } - ], - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:49:53.837Z" - }, - { - "created_at": "2024-06-25T15:43:41.079Z", - "id": "id:563", - "name": "tg2_connection2", - "network_id": "crn:39", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:43.192Z" - }, - { - "created_at": "2024-06-25T15:43:42.335Z", - "id": "id:564", - "name": "tg1_connection1", - "network_id": "crn:1", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:48:45.229Z" - }, - { - "created_at": "2024-06-25T15:44:08.995Z", - "id": "id:565", - "name": "tg1_connection2", - "network_id": "crn:39", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:49:11.976Z" - } - ], - "transit_gateways": [ - { - "id": "id:551", - "crn": "crn:550", - "name": "local-tg3", - "location": "us-south", - "created_at": "2024-06-25T15:40:21.390Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:42:12.752Z" - }, - { - "id": "id:555", - "crn": "crn:554", - "name": "local-tg2", - "location": "us-south", - "created_at": "2024-06-25T15:40:25.895Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:43:58.196Z" - }, - { - "id": "id:562", - "crn": "crn:561", - "name": "local-tg1", - "location": "us-south", - "created_at": "2024-06-25T15:40:26.455Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:43:15.331Z" - } - ], - "iks_clusters": [] -} diff --git a/test/data/acl_protocols/config_object.json b/test/data/acl_protocols/config_object.json deleted file mode 100644 index 7e94d3b8..00000000 --- a/test/data/acl_protocols/config_object.json +++ /dev/null @@ -1,6269 +0,0 @@ -{ - "collector_version": "0.11.0", - "provider": "ibm", - "vpcs": [ - { - "classic_access": false, - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:1", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.215.5" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.220.2" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.249.82.12" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "automaker-castle-bird-worried" - }, - "default_routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole" - }, - "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": "test-vpc1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.80.0/20", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:18", - "id": "id:19", - "is_default": false, - "name": "address-prefix-vpc-1", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "cidr": "10.240.64.0/20", - "created_at": "2024-06-25T15:40:40.000Z", - "has_subnets": true, - "href": "href:20", - "id": "id:21", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:22", - "cse_source_ips": [ - { - "ip": { - "address": "10.16.238.56" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.249.200.205" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.249.212.88" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:25", - "href": "href:26", - "id": "id:27", - "name": "ebullient-slacks-revert-turkey" - }, - "default_routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam" - }, - "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:23", - "id": "id:24", - "name": "test-vpc0", - "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/22", - "created_at": "2024-06-25T15:40:37.000Z", - "has_subnets": true, - "href": "href:33", - "id": "id:34", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.4.0/22", - "created_at": "2024-06-25T15:40:38.000Z", - "has_subnets": true, - "href": "href:35", - "id": "id:36", - "is_default": false, - "name": "address-prefix-vpc-1", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.8.0/22", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:37", - "id": "id:38", - "is_default": false, - "name": "address-prefix-vpc-2", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:39", - "cse_source_ips": [ - { - "ip": { - "address": "10.12.125.16" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.27.134" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.22.231.90" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:42", - "href": "href:43", - "id": "id:44", - "name": "afoot-grape-fineness-zestfully" - }, - "default_routing_table": { - "href": "href:45", - "id": "id:46", - "name": "quintuple-severity-caddie-manuals", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll" - }, - "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:40", - "id": "id:41", - "name": "test-vpc2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.128.0/20", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:50", - "id": "id:51", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:52", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.219.155" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.12.159.11" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.16.253.109" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:55", - "href": "href:56", - "id": "id:57", - "name": "untracked-repayment-triumph-cat" - }, - "default_routing_table": { - "href": "href:58", - "id": "id:59", - "name": "probational-herring-undone-daintily", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely" - }, - "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:53", - "id": "id:54", - "name": "test-vpc3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.192.0/20", - "created_at": "2024-06-25T15:40:38.000Z", - "has_subnets": true, - "href": "href:63", - "id": "id:64", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - } - ], - "subnets": [ - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:47.000Z", - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.9.0/24", - "name": "subnet5", - "network_acl": { - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.9.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:71", - "id": "id:72", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:73", - "id": "id:74", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:75", - "id": "id:76", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:77", - "id": "id:78", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:79", - "id": "id:80", - "lifecycle_state": "stable", - "name": "ideally-grain-bagpipe-luxuriant", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.9.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:20.000Z", - "href": "href:83", - "id": "id:84", - "lifecycle_state": "stable", - "name": "outskirts-unaligned-passivism-parchment", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.9.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:87", - "id": "id:88", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:35.000Z", - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.5.0/24", - "name": "subnet3", - "network_acl": { - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.5.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:95", - "id": "id:96", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:97", - "id": "id:98", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:99", - "id": "id:100", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:101", - "id": "id:102", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:103", - "id": "id:104", - "lifecycle_state": "stable", - "name": "rising-gopher-reentry-graveness", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.5.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:16.000Z", - "href": "href:107", - "id": "id:108", - "lifecycle_state": "stable", - "name": "recognize-citable-exerciser-unsecured", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.5.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:111", - "id": "id:112", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:23.000Z", - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.0.0/24", - "name": "subnet0", - "network_acl": { - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.0.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:119", - "id": "id:120", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:121", - "id": "id:122", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:123", - "id": "id:124", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:125", - "id": "id:126", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:08.000Z", - "href": "href:127", - "id": "id:128", - "lifecycle_state": "stable", - "name": "pundit-tight-arbitrate-grace", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:39.000Z", - "href": "href:131", - "id": "id:132", - "lifecycle_state": "stable", - "name": "relatable-antiques-maturing-brulee", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:135", - "id": "id:136", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:41:20.000Z", - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.80.0/24", - "name": "subnet11", - "network_acl": { - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "reserved_ips": [ - { - "address": "10.240.80.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:143", - "id": "id:144", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:145", - "id": "id:146", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:147", - "id": "id:148", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:149", - "id": "id:150", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:40.000Z", - "href": "href:151", - "id": "id:152", - "lifecycle_state": "stable", - "name": "childlike-publish-retainer-movie", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.80.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:155", - "id": "id:156", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:08.000Z", - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.4.0/24", - "name": "subnet2", - "network_acl": { - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.4.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:160", - "id": "id:161", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:162", - "id": "id:163", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:164", - "id": "id:165", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:166", - "id": "id:167", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:21.000Z", - "href": "href:168", - "id": "id:169", - "lifecycle_state": "stable", - "name": "stood-sitcom-whoops-hurled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.4.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:22.000Z", - "href": "href:172", - "id": "id:173", - "lifecycle_state": "stable", - "name": "bark-gatherer-rope-unrivaled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.4.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:176", - "id": "id:177", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:41:08.000Z", - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.64.0/24", - "name": "subnet10", - "network_acl": { - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "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-25T15:41:08.000Z", - "href": "href:181", - "id": "id:182", - "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-25T15:41:08.000Z", - "href": "href:183", - "id": "id:184", - "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-25T15:41:08.000Z", - "href": "href:185", - "id": "id:186", - "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-25T15:41:08.000Z", - "href": "href:187", - "id": "id:188", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.64.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:36.000Z", - "href": "href:189", - "id": "id:190", - "lifecycle_state": "stable", - "name": "starry-smasher-ladle-dioxide", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.64.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:193", - "id": "id:194", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 248, - "created_at": "2024-06-25T15:40:57.000Z", - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.128.0/24", - "name": "subnet20", - "network_acl": { - "crn": "crn:198", - "href": "href:199", - "id": "id:200", - "name": "acl21" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:45", - "id": "id:46", - "name": "quintuple-severity-caddie-manuals", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "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-25T15:40:57.000Z", - "href": "href:201", - "id": "id:202", - "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-25T15:40:57.000Z", - "href": "href:203", - "id": "id:204", - "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-25T15:40:57.000Z", - "href": "href:205", - "id": "id:206", - "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-25T15:40:57.000Z", - "href": "href:207", - "id": "id:208", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.128.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:21.000Z", - "href": "href:209", - "id": "id:210", - "lifecycle_state": "stable", - "name": "unmixed-qualify-prescribe-railcar", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.5", - "auto_delete": false, - "created_at": "2024-06-25T15:41:21.000Z", - "href": "href:213", - "id": "id:214", - "lifecycle_state": "stable", - "name": "customs-recollect-drippy-primate", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.6", - "auto_delete": false, - "created_at": "2024-06-25T15:41:24.000Z", - "href": "href:217", - "id": "id:218", - "lifecycle_state": "stable", - "name": "uniquely-shelter-gracious-sudden", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:57.000Z", - "href": "href:221", - "id": "id:222", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:40:56.000Z", - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.1.0/24", - "name": "subnet1", - "network_acl": { - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "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-25T15:40:56.000Z", - "href": "href:226", - "id": "id:227", - "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-25T15:40:56.000Z", - "href": "href:228", - "id": "id:229", - "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-25T15:40:56.000Z", - "href": "href:230", - "id": "id:231", - "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-25T15:40:56.000Z", - "href": "href:232", - "id": "id:233", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.1.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:234", - "id": "id:235", - "lifecycle_state": "stable", - "name": "excluded-unfair-jailbird-foil", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.1.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:40.000Z", - "href": "href:238", - "id": "id:239", - "lifecycle_state": "stable", - "name": "affected-johnniecake-monorail-ungraded", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.1.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:56.000Z", - "href": "href:242", - "id": "id:243", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:40:48.000Z", - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.192.0/24", - "name": "subnet30", - "network_acl": { - "crn": "crn:247", - "href": "href:248", - "id": "id:249", - "name": "acl31" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:58", - "id": "id:59", - "name": "probational-herring-undone-daintily", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "reserved_ips": [ - { - "address": "10.240.192.0", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:250", - "id": "id:251", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.1", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:252", - "id": "id:253", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.2", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:254", - "id": "id:255", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.3", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:256", - "id": "id:257", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:01.000Z", - "href": "href:258", - "id": "id:259", - "lifecycle_state": "stable", - "name": "legacy-shore-molecule-barometer", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.192.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:262", - "id": "id:263", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:40:44.000Z", - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.8.0/24", - "name": "subnet4", - "network_acl": { - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.8.0", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:267", - "id": "id:268", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.1", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:269", - "id": "id:270", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.2", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:271", - "id": "id:272", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.3", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:273", - "id": "id:274", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:275", - "id": "id:276", - "lifecycle_state": "stable", - "name": "bagged-posture-glaring-cojoined", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.8.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:16.000Z", - "href": "href:279", - "id": "id:280", - "lifecycle_state": "stable", - "name": "frighten-mystified-freeway-hurtling", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.8.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:283", - "id": "id:284", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - } - ], - "public_gateways": [], - "floating_ips": [ - { - "address": "52.118.151.238", - "created_at": "2024-06-25T15:43:30.000Z", - "crn": "crn:285", - "href": "href:286", - "id": "id:287", - "name": "fip-0-subnet0", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - }, - { - "address": "150.239.167.146", - "created_at": "2024-06-25T15:41:59.000Z", - "crn": "crn:288", - "href": "href:289", - "id": "id:290", - "name": "fip-0-subnet10", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "tags": [] - }, - { - "address": "169.48.95.165", - "created_at": "2024-06-25T15:41:50.000Z", - "crn": "crn:291", - "href": "href:292", - "id": "id:293", - "name": "fip-0-subnet20", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "tags": [] - }, - { - "address": "52.118.100.239", - "created_at": "2024-06-25T15:41:33.000Z", - "crn": "crn:294", - "href": "href:295", - "id": "id:296", - "name": "fip-0-subnet30", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "tags": [] - } - ], - "network_acls": [ - { - "created_at": "2024-06-25T15:40:41.000Z", - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "deny", - "before": { - "href": "href:299", - "id": "id:300", - "name": "acl11-out-2" - }, - "created_at": "2024-06-25T15:40:42.000Z", - "destination": "10.240.4.0/24", - "direction": "outbound", - "href": "href:297", - "id": "id:298", - "ip_version": "ipv4", - "name": "acl11-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:301", - "id": "id:302", - "name": "acl11-in-1" - }, - "created_at": "2024-06-25T15:40:43.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:299", - "id": "id:300", - "ip_version": "ipv4", - "name": "acl11-out-2", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:43.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:301", - "id": "id:302", - "ip_version": "ipv4", - "name": "acl11-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:247", - "href": "href:248", - "id": "id:249", - "name": "acl31", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:305", - "id": "id:306", - "name": "acl31-in-1" - }, - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:303", - "id": "id:304", - "ip_version": "ipv4", - "name": "acl31-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:305", - "id": "id:306", - "ip_version": "ipv4", - "name": "acl31-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:198", - "href": "href:199", - "id": "id:200", - "name": "acl21", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:309", - "id": "id:310", - "name": "acl21-in-1" - }, - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:307", - "id": "id:308", - "ip_version": "ipv4", - "name": "acl21-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:42.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:309", - "id": "id:310", - "ip_version": "ipv4", - "name": "acl21-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:38.000Z", - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:313", - "id": "id:314", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:311", - "id": "id:312", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:39.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:313", - "id": "id:314", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:317", - "id": "id:318", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:315", - "id": "id:316", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:317", - "id": "id:318", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:321", - "id": "id:322", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:319", - "id": "id:320", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:321", - "id": "id:322", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "automaker-castle-bird-worried", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:325", - "id": "id:326", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:20.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:323", - "id": "id:324", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:20.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:325", - "id": "id:326", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:42", - "href": "href:43", - "id": "id:44", - "name": "afoot-grape-fineness-zestfully", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:329", - "id": "id:330", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:327", - "id": "id:328", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:329", - "id": "id:330", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:25", - "href": "href:26", - "id": "id:27", - "name": "ebullient-slacks-revert-turkey", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:333", - "id": "id:334", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:331", - "id": "id:332", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:333", - "id": "id:334", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:55", - "href": "href:56", - "id": "id:57", - "name": "untracked-repayment-triumph-cat", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:337", - "id": "id:338", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:335", - "id": "id:336", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:337", - "id": "id:338", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "security_groups": [ - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:342", - "id": "id:343", - "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:344", - "id": "id:345", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "resource_type": "network_interface" - }, - { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "resource_type": "network_interface" - }, - { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:346", - "href": "href:347", - "id": "id:348", - "name": "sg31", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:349", - "id": "id:350", - "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:351", - "id": "id:352", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:356", - "id": "id:357", - "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:358", - "id": "id:359", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "resource_type": "network_interface" - }, - { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:363", - "id": "id:364", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - }, - { - "direction": "outbound", - "href": "href:365", - "id": "id:366", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "resource_type": "network_interface" - }, - { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "resource_type": "network_interface" - }, - { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "resource_type": "network_interface" - }, - { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "resource_type": "network_interface" - }, - { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "resource_type": "network_interface" - }, - { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "resource_type": "network_interface" - }, - { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "resource_type": "network_interface" - }, - { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "resource_type": "network_interface" - }, - { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "resource_type": "network_interface" - }, - { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "resource_type": "network_interface" - }, - { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "resource_type": "network_interface" - }, - { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:367", - "id": "id:368", - "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:369", - "id": "id:370", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:371", - "id": "id:372", - "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:373", - "id": "id:374", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:375", - "id": "id:376", - "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:377", - "id": "id:378", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:379", - "id": "id:380", - "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:381", - "id": "id:382", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "endpoint_gateways": [], - "instances": [ - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:388" - }, - "href": "href:386", - "id": "id:387", - "name": "thief-monastery-blinks-verdict", - "volume": { - "crn": "crn:389", - "href": "href:390", - "id": "id:391", - "name": "scrabble-gorged-baton-angled", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:40.000Z", - "crn": "crn:383", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:384", - "id": "id:385", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "primary_ip": { - "address": "10.240.1.5", - "href": "href:238", - "id": "id:239", - "name": "affected-johnniecake-monorail-ungraded", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:388" - }, - "href": "href:386", - "id": "id:387", - "name": "thief-monastery-blinks-verdict", - "volume": { - "crn": "crn:389", - "href": "href:390", - "id": "id:391", - "name": "scrabble-gorged-baton-angled", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:40.000Z", - "floating_ips": [], - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.1.5", - "href": "href:238", - "id": "id:239", - "name": "affected-johnniecake-monorail-ungraded", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:401" - }, - "href": "href:399", - "id": "id:400", - "name": "hunchback-enginous-dividend-atrium", - "volume": { - "crn": "crn:402", - "href": "href:403", - "id": "id:404", - "name": "subsoil-bobble-bovine-unmoving", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:39.000Z", - "crn": "crn:396", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:397", - "id": "id:398", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet0", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "primary_ip": { - "address": "10.240.0.5", - "href": "href:131", - "id": "id:132", - "name": "relatable-antiques-maturing-brulee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:401" - }, - "href": "href:399", - "id": "id:400", - "name": "hunchback-enginous-dividend-atrium", - "volume": { - "crn": "crn:402", - "href": "href:403", - "id": "id:404", - "name": "subsoil-bobble-bovine-unmoving", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:39.000Z", - "floating_ips": [], - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.5", - "href": "href:131", - "id": "id:132", - "name": "relatable-antiques-maturing-brulee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:410" - }, - "href": "href:408", - "id": "id:409", - "name": "laboring-overbuilt-growl-headland", - "volume": { - "crn": "crn:411", - "href": "href:412", - "id": "id:413", - "name": "tamper-salvaging-stick-giddily", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:22.000Z", - "crn": "crn:405", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:406", - "id": "id:407", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "primary_ip": { - "address": "10.240.4.5", - "href": "href:172", - "id": "id:173", - "name": "bark-gatherer-rope-unrivaled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:410" - }, - "href": "href:408", - "id": "id:409", - "name": "laboring-overbuilt-growl-headland", - "volume": { - "crn": "crn:411", - "href": "href:412", - "id": "id:413", - "name": "tamper-salvaging-stick-giddily", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:22.000Z", - "floating_ips": [], - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.4.5", - "href": "href:172", - "id": "id:173", - "name": "bark-gatherer-rope-unrivaled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:419" - }, - "href": "href:417", - "id": "id:418", - "name": "dollop-partition-helping-palmtree", - "volume": { - "crn": "crn:420", - "href": "href:421", - "id": "id:422", - "name": "ravage-deny-amusable-settling", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:20.000Z", - "crn": "crn:414", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:415", - "id": "id:416", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet5", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "primary_ip": { - "address": "10.240.9.5", - "href": "href:83", - "id": "id:84", - "name": "outskirts-unaligned-passivism-parchment", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:419" - }, - "href": "href:417", - "id": "id:418", - "name": "dollop-partition-helping-palmtree", - "volume": { - "crn": "crn:420", - "href": "href:421", - "id": "id:422", - "name": "ravage-deny-amusable-settling", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:20.000Z", - "floating_ips": [], - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.9.5", - "href": "href:83", - "id": "id:84", - "name": "outskirts-unaligned-passivism-parchment", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:428" - }, - "href": "href:426", - "id": "id:427", - "name": "petted-ethanol-voicing-rocklike", - "volume": { - "crn": "crn:429", - "href": "href:430", - "id": "id:431", - "name": "uptown-striving-unrevised-earthlike", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:20.000Z", - "crn": "crn:423", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:424", - "id": "id:425", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "primary_ip": { - "address": "10.240.4.4", - "href": "href:168", - "id": "id:169", - "name": "stood-sitcom-whoops-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:428" - }, - "href": "href:426", - "id": "id:427", - "name": "petted-ethanol-voicing-rocklike", - "volume": { - "crn": "crn:429", - "href": "href:430", - "id": "id:431", - "name": "uptown-striving-unrevised-earthlike", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:20.000Z", - "floating_ips": [], - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.4.4", - "href": "href:168", - "id": "id:169", - "name": "stood-sitcom-whoops-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:437" - }, - "href": "href:435", - "id": "id:436", - "name": "promenade-spyglass-flattop-pushpin", - "volume": { - "crn": "crn:438", - "href": "href:439", - "id": "id:440", - "name": "relax-shaded-prism-jaunt", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:16.000Z", - "crn": "crn:432", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:433", - "id": "id:434", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet3", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "primary_ip": { - "address": "10.240.5.5", - "href": "href:107", - "id": "id:108", - "name": "recognize-citable-exerciser-unsecured", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:437" - }, - "href": "href:435", - "id": "id:436", - "name": "promenade-spyglass-flattop-pushpin", - "volume": { - "crn": "crn:438", - "href": "href:439", - "id": "id:440", - "name": "relax-shaded-prism-jaunt", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:16.000Z", - "floating_ips": [], - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.5.5", - "href": "href:107", - "id": "id:108", - "name": "recognize-citable-exerciser-unsecured", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:446" - }, - "href": "href:444", - "id": "id:445", - "name": "sandbox-federal-sculptor-jugum", - "volume": { - "crn": "crn:447", - "href": "href:448", - "id": "id:449", - "name": "convent-ramrod-cloning-afterward", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:15.000Z", - "crn": "crn:441", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:442", - "id": "id:443", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet4", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "primary_ip": { - "address": "10.240.8.5", - "href": "href:279", - "id": "id:280", - "name": "frighten-mystified-freeway-hurtling", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:446" - }, - "href": "href:444", - "id": "id:445", - "name": "sandbox-federal-sculptor-jugum", - "volume": { - "crn": "crn:447", - "href": "href:448", - "id": "id:449", - "name": "convent-ramrod-cloning-afterward", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:15.000Z", - "floating_ips": [], - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.8.5", - "href": "href:279", - "id": "id:280", - "name": "frighten-mystified-freeway-hurtling", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:455" - }, - "href": "href:453", - "id": "id:454", - "name": "affidavit-chastise-elsewhere-viewer", - "volume": { - "crn": "crn:456", - "href": "href:457", - "id": "id:458", - "name": "fancy-destiny-shuffling-sandbank", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:07.000Z", - "crn": "crn:450", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:451", - "id": "id:452", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet0", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:455" - }, - "href": "href:453", - "id": "id:454", - "name": "affidavit-chastise-elsewhere-viewer", - "volume": { - "crn": "crn:456", - "href": "href:457", - "id": "id:458", - "name": "fancy-destiny-shuffling-sandbank", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:07.000Z", - "floating_ips": [ - { - "address": "52.118.151.238", - "crn": "crn:285", - "href": "href:286", - "id": "id:287", - "name": "fip-0-subnet0" - } - ], - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:464" - }, - "href": "href:462", - "id": "id:463", - "name": "uneven-armoire-scabiosa-letter", - "volume": { - "crn": "crn:465", - "href": "href:466", - "id": "id:467", - "name": "cognition-blinks-humid-oxidant", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:459", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:460", - "id": "id:461", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet3", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "primary_ip": { - "address": "10.240.5.4", - "href": "href:103", - "id": "id:104", - "name": "rising-gopher-reentry-graveness", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:464" - }, - "href": "href:462", - "id": "id:463", - "name": "uneven-armoire-scabiosa-letter", - "volume": { - "crn": "crn:465", - "href": "href:466", - "id": "id:467", - "name": "cognition-blinks-humid-oxidant", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.5.4", - "href": "href:103", - "id": "id:104", - "name": "rising-gopher-reentry-graveness", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:473" - }, - "href": "href:471", - "id": "id:472", - "name": "perplexed-impulsivity-august-jaws", - "volume": { - "crn": "crn:474", - "href": "href:475", - "id": "id:476", - "name": "tartar-sixties-fructose-parmesan", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:468", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:469", - "id": "id:470", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "primary_ip": { - "address": "10.240.1.4", - "href": "href:234", - "id": "id:235", - "name": "excluded-unfair-jailbird-foil", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:473" - }, - "href": "href:471", - "id": "id:472", - "name": "perplexed-impulsivity-august-jaws", - "volume": { - "crn": "crn:474", - "href": "href:475", - "id": "id:476", - "name": "tartar-sixties-fructose-parmesan", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.1.4", - "href": "href:234", - "id": "id:235", - "name": "excluded-unfair-jailbird-foil", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:482" - }, - "href": "href:480", - "id": "id:481", - "name": "litter-snipping-unclasp-dust", - "volume": { - "crn": "crn:483", - "href": "href:484", - "id": "id:485", - "name": "untried-sulphate-hypnosis-subsidize", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:477", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:478", - "id": "id:479", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet4", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "primary_ip": { - "address": "10.240.8.4", - "href": "href:275", - "id": "id:276", - "name": "bagged-posture-glaring-cojoined", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:482" - }, - "href": "href:480", - "id": "id:481", - "name": "litter-snipping-unclasp-dust", - "volume": { - "crn": "crn:483", - "href": "href:484", - "id": "id:485", - "name": "untried-sulphate-hypnosis-subsidize", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.8.4", - "href": "href:275", - "id": "id:276", - "name": "bagged-posture-glaring-cojoined", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:491" - }, - "href": "href:489", - "id": "id:490", - "name": "unlawful-overreach-yarn-rippling", - "volume": { - "crn": "crn:492", - "href": "href:493", - "id": "id:494", - "name": "finer-voter-roving-jailer", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:486", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:487", - "id": "id:488", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet5", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "primary_ip": { - "address": "10.240.9.4", - "href": "href:79", - "id": "id:80", - "name": "ideally-grain-bagpipe-luxuriant", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:491" - }, - "href": "href:489", - "id": "id:490", - "name": "unlawful-overreach-yarn-rippling", - "volume": { - "crn": "crn:492", - "href": "href:493", - "id": "id:494", - "name": "finer-voter-roving-jailer", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.9.4", - "href": "href:79", - "id": "id:80", - "name": "ideally-grain-bagpipe-luxuriant", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:500" - }, - "href": "href:498", - "id": "id:499", - "name": "mashed-thing-headache-estate", - "volume": { - "crn": "crn:501", - "href": "href:502", - "id": "id:503", - "name": "mountain-harpist-libraries-dreaming", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:39.000Z", - "crn": "crn:495", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:496", - "id": "id:497", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet11", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "primary_ip": { - "address": "10.240.80.4", - "href": "href:151", - "id": "id:152", - "name": "childlike-publish-retainer-movie", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:500" - }, - "href": "href:498", - "id": "id:499", - "name": "mashed-thing-headache-estate", - "volume": { - "crn": "crn:501", - "href": "href:502", - "id": "id:503", - "name": "mountain-harpist-libraries-dreaming", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:39.000Z", - "floating_ips": [], - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.80.4", - "href": "href:151", - "id": "id:152", - "name": "childlike-publish-retainer-movie", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11" - } - ], - "status": "available", - "subnet": { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:509" - }, - "href": "href:507", - "id": "id:508", - "name": "calzone-cacti-moonlight-subarctic", - "volume": { - "crn": "crn:510", - "href": "href:511", - "id": "id:512", - "name": "blurred-dream-pectin-tapping", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:36.000Z", - "crn": "crn:504", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:505", - "id": "id:506", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet10", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:509" - }, - "href": "href:507", - "id": "id:508", - "name": "calzone-cacti-moonlight-subarctic", - "volume": { - "crn": "crn:510", - "href": "href:511", - "id": "id:512", - "name": "blurred-dream-pectin-tapping", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:36.000Z", - "floating_ips": [ - { - "address": "150.239.167.146", - "crn": "crn:288", - "href": "href:289", - "id": "id:290", - "name": "fip-0-subnet10" - } - ], - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11" - } - ], - "status": "available", - "subnet": { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:518" - }, - "href": "href:516", - "id": "id:517", - "name": "recoup-blinks-ebullient-renewed", - "volume": { - "crn": "crn:519", - "href": "href:520", - "id": "id:521", - "name": "manmade-unequal-disinfect-cone", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:24.000Z", - "crn": "crn:513", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:514", - "id": "id:515", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:518" - }, - "href": "href:516", - "id": "id:517", - "name": "recoup-blinks-ebullient-renewed", - "volume": { - "crn": "crn:519", - "href": "href:520", - "id": "id:521", - "name": "manmade-unequal-disinfect-cone", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:24.000Z", - "floating_ips": [ - { - "address": "169.48.95.165", - "crn": "crn:291", - "href": "href:292", - "id": "id:293", - "name": "fip-0-subnet20" - } - ], - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:527" - }, - "href": "href:525", - "id": "id:526", - "name": "radio-tightrope-outtakes-moonshine", - "volume": { - "crn": "crn:528", - "href": "href:529", - "id": "id:530", - "name": "tattoo-crescent-unwary-hayride", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:21.000Z", - "crn": "crn:522", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:523", - "id": "id:524", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "primary_ip": { - "address": "10.240.128.5", - "href": "href:213", - "id": "id:214", - "name": "customs-recollect-drippy-primate", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:527" - }, - "href": "href:525", - "id": "id:526", - "name": "radio-tightrope-outtakes-moonshine", - "volume": { - "crn": "crn:528", - "href": "href:529", - "id": "id:530", - "name": "tattoo-crescent-unwary-hayride", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:21.000Z", - "floating_ips": [], - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.5", - "href": "href:213", - "id": "id:214", - "name": "customs-recollect-drippy-primate", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:536" - }, - "href": "href:534", - "id": "id:535", - "name": "crumpet-ride-tastiness-phoney", - "volume": { - "crn": "crn:537", - "href": "href:538", - "id": "id:539", - "name": "doorframe-marvelous-refusing-citable", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:21.000Z", - "crn": "crn:531", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:532", - "id": "id:533", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi2-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "primary_ip": { - "address": "10.240.128.4", - "href": "href:209", - "id": "id:210", - "name": "unmixed-qualify-prescribe-railcar", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:536" - }, - "href": "href:534", - "id": "id:535", - "name": "crumpet-ride-tastiness-phoney", - "volume": { - "crn": "crn:537", - "href": "href:538", - "id": "id:539", - "name": "doorframe-marvelous-refusing-citable", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:21.000Z", - "floating_ips": [], - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.4", - "href": "href:209", - "id": "id:210", - "name": "unmixed-qualify-prescribe-railcar", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:545" - }, - "href": "href:543", - "id": "id:544", - "name": "bronzing-vendor-plod-pretzel", - "volume": { - "crn": "crn:546", - "href": "href:547", - "id": "id:548", - "name": "squelch-plop-headlamp-ideologue", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:00.000Z", - "crn": "crn:540", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:541", - "id": "id:542", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet30", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:545" - }, - "href": "href:543", - "id": "id:544", - "name": "bronzing-vendor-plod-pretzel", - "volume": { - "crn": "crn:546", - "href": "href:547", - "id": "id:548", - "name": "squelch-plop-headlamp-ideologue", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:00.000Z", - "floating_ips": [ - { - "address": "52.118.100.239", - "crn": "crn:294", - "href": "href:295", - "id": "id:296", - "name": "fip-0-subnet30" - } - ], - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:346", - "href": "href:347", - "id": "id:348", - "name": "sg31" - } - ], - "status": "available", - "subnet": { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - } - ], - "routing_tables": [ - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:20.000Z", - "href": "href:11", - "id": "id:12", - "is_default": true, - "lifecycle_state": "stable", - "name": "overtone-sputter-overspend-gorge", - "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:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:28", - "id": "id:29", - "is_default": true, - "lifecycle_state": "stable", - "name": "escapade-dynamite-upstage-context", - "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:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:45", - "id": "id:46", - "is_default": true, - "lifecycle_state": "stable", - "name": "quintuple-severity-caddie-manuals", - "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:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:58", - "id": "id:59", - "is_default": true, - "lifecycle_state": "stable", - "name": "probational-herring-undone-daintily", - "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:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - } - } - ], - "load_balancers": [], - "transit_connections": [ - { - "created_at": "2024-06-25T15:41:44.212Z", - "id": "id:549", - "name": "tg3_connection3", - "network_id": "crn:52", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:550", - "id": "id:551", - "name": "local-tg3" - }, - "updated_at": "2024-06-25T15:45:14.206Z" - }, - { - "created_at": "2024-06-25T15:41:54.416Z", - "id": "id:552", - "name": "tg3_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:550", - "id": "id:551", - "name": "local-tg3" - }, - "updated_at": "2024-06-25T15:45:53.979Z" - }, - { - "created_at": "2024-06-25T15:42:54.772Z", - "id": "id:553", - "name": "tg2_connection3", - "network_id": "crn:52", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:08.822Z" - }, - { - "created_at": "2024-06-25T15:43:11.555Z", - "id": "id:556", - "name": "tg2_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters": [ - { - "action": "deny", - "created_at": "2024-06-25T15:46:46.641Z", - "id": "id:557", - "le": 32, - "prefix": "10.240.0.0/22", - "updated_at": "2024-06-25T15:46:46.641Z" - } - ], - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:59.395Z" - }, - { - "created_at": "2024-06-25T15:43:12.159Z", - "id": "id:558", - "name": "tg_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters": [ - { - "action": "deny", - "before": "298db67f-2e68-4548-93b9-949f8356d4a0", - "created_at": "2024-06-25T15:45:14.711Z", - "id": "id:559", - "prefix": "10.240.4.0/22", - "updated_at": "2024-06-25T15:45:14.711Z" - }, - { - "action": "deny", - "created_at": "2024-06-25T15:45:25.435Z", - "id": "id:560", - "prefix": "10.240.8.0/22", - "updated_at": "2024-06-25T15:45:25.435Z" - } - ], - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:49:53.837Z" - }, - { - "created_at": "2024-06-25T15:43:41.079Z", - "id": "id:563", - "name": "tg2_connection2", - "network_id": "crn:39", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:43.192Z" - }, - { - "created_at": "2024-06-25T15:43:42.335Z", - "id": "id:564", - "name": "tg1_connection1", - "network_id": "crn:1", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:48:45.229Z" - }, - { - "created_at": "2024-06-25T15:44:08.995Z", - "id": "id:565", - "name": "tg1_connection2", - "network_id": "crn:39", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:49:11.976Z" - } - ], - "transit_gateways": [ - { - "id": "id:551", - "crn": "crn:550", - "name": "local-tg3", - "location": "us-south", - "created_at": "2024-06-25T15:40:21.390Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:42:12.752Z" - }, - { - "id": "id:555", - "crn": "crn:554", - "name": "local-tg2", - "location": "us-south", - "created_at": "2024-06-25T15:40:25.895Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:43:58.196Z" - }, - { - "id": "id:562", - "crn": "crn:561", - "name": "local-tg1", - "location": "us-south", - "created_at": "2024-06-25T15:40:26.455Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:43:15.331Z" - } - ], - "iks_clusters": [] -} diff --git a/test/data/acl_subnet_cidr_segments/config_object.json b/test/data/acl_subnet_cidr_segments/config_object.json deleted file mode 100644 index 5b755e7e..00000000 --- a/test/data/acl_subnet_cidr_segments/config_object.json +++ /dev/null @@ -1,1776 +0,0 @@ -{ - "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": { - "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": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1-2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "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": "crn:43", - "href": "href:44", - "id": "id:45", - "name": "acl1-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": { - "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": "crn:62", - "href": "href:63", - "id": "id:64", - "name": "acl2-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": { - "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": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1-2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "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": "crn:94", - "href": "href:95", - "id": "id:96", - "name": "acl2-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": { - "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": "crn:110", - "href": "href:111", - "id": "id:112", - "name": "acl3-1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "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": "2024-06-25T12:21:16.000Z", - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1-2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "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", - "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", - "ip_version": "ipv4", - "name": "i1", - "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", - "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", - "source_port_max": 65535, - "source_port_min": 1 - } - ], - "subnets": [ - { - "crn": "crn:24", - "href": "href:25", - "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": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "testacl5-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T12:21:15.000Z", - "crn": "crn:94", - "href": "href:95", - "id": "id:96", - "name": "acl2-2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "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", - "direction": "outbound", - "href": "href:137", - "id": "id:138", - "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" - } - ], - "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": "2024-06-25T12:21:15.000Z", - "crn": "crn:110", - "href": "href:111", - "id": "id:112", - "name": "acl3-1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:143", - "id": "id:144", - "name": "o2" - }, - "created_at": "2024-06-25T12:21:16.000Z", - "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", - "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 - } - ], - "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": [] - }, - { - "created_at": "2024-06-25T12:21:15.000Z", - "crn": "crn:43", - "href": "href:44", - "id": "id:45", - "name": "acl1-1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "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", - "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", - "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 - } - ], - "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": "2024-06-25T12:21:15.000Z", - "crn": "crn:62", - "href": "href:63", - "id": "id:64", - "name": "acl2-1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "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", - "destination": "10.240.128.0/24", - "direction": "outbound", - "href": "href:171", - "id": "id:172", - "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", - "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 - } - ], - "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": "2024-06-25T12:20:45.000Z", - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "disallow-laborious-compress-abiding", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "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", - "direction": "inbound", - "href": "href:181", - "id": "id:182", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "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" - } - ], - "subnets": [], - "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": [], - "routing_tables": [ - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T12:20:45.000Z", - "href": "href:11", - "id": "id:12", - "is_default": true, - "lifecycle_state": "stable", - "name": "traffic-overeasy-festoonery-illusive", - "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": [] -} diff --git a/test/data/acl_externals/config_object.json b/test/data/acl_testing4/config_object.json similarity index 100% rename from test/data/acl_externals/config_object.json rename to test/data/acl_testing4/config_object.json diff --git a/test/data/acl_tg_multiple/config_object.json b/test/data/acl_tg_multiple/config_object.json deleted file mode 100644 index 7e94d3b8..00000000 --- a/test/data/acl_tg_multiple/config_object.json +++ /dev/null @@ -1,6269 +0,0 @@ -{ - "collector_version": "0.11.0", - "provider": "ibm", - "vpcs": [ - { - "classic_access": false, - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:1", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.215.5" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.220.2" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.249.82.12" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "automaker-castle-bird-worried" - }, - "default_routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole" - }, - "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": "test-vpc1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.80.0/20", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:18", - "id": "id:19", - "is_default": false, - "name": "address-prefix-vpc-1", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "cidr": "10.240.64.0/20", - "created_at": "2024-06-25T15:40:40.000Z", - "has_subnets": true, - "href": "href:20", - "id": "id:21", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:22", - "cse_source_ips": [ - { - "ip": { - "address": "10.16.238.56" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.249.200.205" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.249.212.88" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:25", - "href": "href:26", - "id": "id:27", - "name": "ebullient-slacks-revert-turkey" - }, - "default_routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam" - }, - "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:23", - "id": "id:24", - "name": "test-vpc0", - "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/22", - "created_at": "2024-06-25T15:40:37.000Z", - "has_subnets": true, - "href": "href:33", - "id": "id:34", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.4.0/22", - "created_at": "2024-06-25T15:40:38.000Z", - "has_subnets": true, - "href": "href:35", - "id": "id:36", - "is_default": false, - "name": "address-prefix-vpc-1", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.8.0/22", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:37", - "id": "id:38", - "is_default": false, - "name": "address-prefix-vpc-2", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:39", - "cse_source_ips": [ - { - "ip": { - "address": "10.12.125.16" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.27.134" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.22.231.90" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:42", - "href": "href:43", - "id": "id:44", - "name": "afoot-grape-fineness-zestfully" - }, - "default_routing_table": { - "href": "href:45", - "id": "id:46", - "name": "quintuple-severity-caddie-manuals", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll" - }, - "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:40", - "id": "id:41", - "name": "test-vpc2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.128.0/20", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:50", - "id": "id:51", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:52", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.219.155" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.12.159.11" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.16.253.109" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:55", - "href": "href:56", - "id": "id:57", - "name": "untracked-repayment-triumph-cat" - }, - "default_routing_table": { - "href": "href:58", - "id": "id:59", - "name": "probational-herring-undone-daintily", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely" - }, - "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:53", - "id": "id:54", - "name": "test-vpc3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.192.0/20", - "created_at": "2024-06-25T15:40:38.000Z", - "has_subnets": true, - "href": "href:63", - "id": "id:64", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - } - ], - "subnets": [ - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:47.000Z", - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.9.0/24", - "name": "subnet5", - "network_acl": { - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.9.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:71", - "id": "id:72", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:73", - "id": "id:74", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:75", - "id": "id:76", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:77", - "id": "id:78", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:79", - "id": "id:80", - "lifecycle_state": "stable", - "name": "ideally-grain-bagpipe-luxuriant", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.9.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:20.000Z", - "href": "href:83", - "id": "id:84", - "lifecycle_state": "stable", - "name": "outskirts-unaligned-passivism-parchment", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.9.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:87", - "id": "id:88", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:35.000Z", - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.5.0/24", - "name": "subnet3", - "network_acl": { - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.5.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:95", - "id": "id:96", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:97", - "id": "id:98", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:99", - "id": "id:100", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:101", - "id": "id:102", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:103", - "id": "id:104", - "lifecycle_state": "stable", - "name": "rising-gopher-reentry-graveness", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.5.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:16.000Z", - "href": "href:107", - "id": "id:108", - "lifecycle_state": "stable", - "name": "recognize-citable-exerciser-unsecured", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.5.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:111", - "id": "id:112", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:23.000Z", - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.0.0/24", - "name": "subnet0", - "network_acl": { - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.0.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:119", - "id": "id:120", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:121", - "id": "id:122", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:123", - "id": "id:124", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:125", - "id": "id:126", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:08.000Z", - "href": "href:127", - "id": "id:128", - "lifecycle_state": "stable", - "name": "pundit-tight-arbitrate-grace", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:39.000Z", - "href": "href:131", - "id": "id:132", - "lifecycle_state": "stable", - "name": "relatable-antiques-maturing-brulee", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:135", - "id": "id:136", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:41:20.000Z", - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.80.0/24", - "name": "subnet11", - "network_acl": { - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "reserved_ips": [ - { - "address": "10.240.80.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:143", - "id": "id:144", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:145", - "id": "id:146", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:147", - "id": "id:148", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:149", - "id": "id:150", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:40.000Z", - "href": "href:151", - "id": "id:152", - "lifecycle_state": "stable", - "name": "childlike-publish-retainer-movie", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.80.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:155", - "id": "id:156", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:08.000Z", - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.4.0/24", - "name": "subnet2", - "network_acl": { - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.4.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:160", - "id": "id:161", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:162", - "id": "id:163", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:164", - "id": "id:165", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:166", - "id": "id:167", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:21.000Z", - "href": "href:168", - "id": "id:169", - "lifecycle_state": "stable", - "name": "stood-sitcom-whoops-hurled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.4.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:22.000Z", - "href": "href:172", - "id": "id:173", - "lifecycle_state": "stable", - "name": "bark-gatherer-rope-unrivaled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.4.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:176", - "id": "id:177", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:41:08.000Z", - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.64.0/24", - "name": "subnet10", - "network_acl": { - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "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-25T15:41:08.000Z", - "href": "href:181", - "id": "id:182", - "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-25T15:41:08.000Z", - "href": "href:183", - "id": "id:184", - "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-25T15:41:08.000Z", - "href": "href:185", - "id": "id:186", - "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-25T15:41:08.000Z", - "href": "href:187", - "id": "id:188", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.64.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:36.000Z", - "href": "href:189", - "id": "id:190", - "lifecycle_state": "stable", - "name": "starry-smasher-ladle-dioxide", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.64.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:193", - "id": "id:194", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 248, - "created_at": "2024-06-25T15:40:57.000Z", - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.128.0/24", - "name": "subnet20", - "network_acl": { - "crn": "crn:198", - "href": "href:199", - "id": "id:200", - "name": "acl21" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:45", - "id": "id:46", - "name": "quintuple-severity-caddie-manuals", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "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-25T15:40:57.000Z", - "href": "href:201", - "id": "id:202", - "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-25T15:40:57.000Z", - "href": "href:203", - "id": "id:204", - "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-25T15:40:57.000Z", - "href": "href:205", - "id": "id:206", - "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-25T15:40:57.000Z", - "href": "href:207", - "id": "id:208", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.128.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:21.000Z", - "href": "href:209", - "id": "id:210", - "lifecycle_state": "stable", - "name": "unmixed-qualify-prescribe-railcar", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.5", - "auto_delete": false, - "created_at": "2024-06-25T15:41:21.000Z", - "href": "href:213", - "id": "id:214", - "lifecycle_state": "stable", - "name": "customs-recollect-drippy-primate", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.6", - "auto_delete": false, - "created_at": "2024-06-25T15:41:24.000Z", - "href": "href:217", - "id": "id:218", - "lifecycle_state": "stable", - "name": "uniquely-shelter-gracious-sudden", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:57.000Z", - "href": "href:221", - "id": "id:222", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:40:56.000Z", - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.1.0/24", - "name": "subnet1", - "network_acl": { - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "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-25T15:40:56.000Z", - "href": "href:226", - "id": "id:227", - "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-25T15:40:56.000Z", - "href": "href:228", - "id": "id:229", - "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-25T15:40:56.000Z", - "href": "href:230", - "id": "id:231", - "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-25T15:40:56.000Z", - "href": "href:232", - "id": "id:233", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.1.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:234", - "id": "id:235", - "lifecycle_state": "stable", - "name": "excluded-unfair-jailbird-foil", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.1.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:40.000Z", - "href": "href:238", - "id": "id:239", - "lifecycle_state": "stable", - "name": "affected-johnniecake-monorail-ungraded", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.1.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:56.000Z", - "href": "href:242", - "id": "id:243", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:40:48.000Z", - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.192.0/24", - "name": "subnet30", - "network_acl": { - "crn": "crn:247", - "href": "href:248", - "id": "id:249", - "name": "acl31" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:58", - "id": "id:59", - "name": "probational-herring-undone-daintily", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "reserved_ips": [ - { - "address": "10.240.192.0", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:250", - "id": "id:251", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.1", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:252", - "id": "id:253", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.2", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:254", - "id": "id:255", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.3", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:256", - "id": "id:257", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:01.000Z", - "href": "href:258", - "id": "id:259", - "lifecycle_state": "stable", - "name": "legacy-shore-molecule-barometer", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.192.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:262", - "id": "id:263", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:40:44.000Z", - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.8.0/24", - "name": "subnet4", - "network_acl": { - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.8.0", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:267", - "id": "id:268", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.1", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:269", - "id": "id:270", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.2", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:271", - "id": "id:272", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.3", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:273", - "id": "id:274", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:275", - "id": "id:276", - "lifecycle_state": "stable", - "name": "bagged-posture-glaring-cojoined", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.8.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:16.000Z", - "href": "href:279", - "id": "id:280", - "lifecycle_state": "stable", - "name": "frighten-mystified-freeway-hurtling", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.8.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:283", - "id": "id:284", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - } - ], - "public_gateways": [], - "floating_ips": [ - { - "address": "52.118.151.238", - "created_at": "2024-06-25T15:43:30.000Z", - "crn": "crn:285", - "href": "href:286", - "id": "id:287", - "name": "fip-0-subnet0", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - }, - { - "address": "150.239.167.146", - "created_at": "2024-06-25T15:41:59.000Z", - "crn": "crn:288", - "href": "href:289", - "id": "id:290", - "name": "fip-0-subnet10", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "tags": [] - }, - { - "address": "169.48.95.165", - "created_at": "2024-06-25T15:41:50.000Z", - "crn": "crn:291", - "href": "href:292", - "id": "id:293", - "name": "fip-0-subnet20", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "tags": [] - }, - { - "address": "52.118.100.239", - "created_at": "2024-06-25T15:41:33.000Z", - "crn": "crn:294", - "href": "href:295", - "id": "id:296", - "name": "fip-0-subnet30", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "tags": [] - } - ], - "network_acls": [ - { - "created_at": "2024-06-25T15:40:41.000Z", - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "deny", - "before": { - "href": "href:299", - "id": "id:300", - "name": "acl11-out-2" - }, - "created_at": "2024-06-25T15:40:42.000Z", - "destination": "10.240.4.0/24", - "direction": "outbound", - "href": "href:297", - "id": "id:298", - "ip_version": "ipv4", - "name": "acl11-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:301", - "id": "id:302", - "name": "acl11-in-1" - }, - "created_at": "2024-06-25T15:40:43.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:299", - "id": "id:300", - "ip_version": "ipv4", - "name": "acl11-out-2", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:43.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:301", - "id": "id:302", - "ip_version": "ipv4", - "name": "acl11-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:247", - "href": "href:248", - "id": "id:249", - "name": "acl31", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:305", - "id": "id:306", - "name": "acl31-in-1" - }, - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:303", - "id": "id:304", - "ip_version": "ipv4", - "name": "acl31-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:305", - "id": "id:306", - "ip_version": "ipv4", - "name": "acl31-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:198", - "href": "href:199", - "id": "id:200", - "name": "acl21", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:309", - "id": "id:310", - "name": "acl21-in-1" - }, - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:307", - "id": "id:308", - "ip_version": "ipv4", - "name": "acl21-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:42.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:309", - "id": "id:310", - "ip_version": "ipv4", - "name": "acl21-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:38.000Z", - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:313", - "id": "id:314", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:311", - "id": "id:312", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:39.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:313", - "id": "id:314", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:317", - "id": "id:318", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:315", - "id": "id:316", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:317", - "id": "id:318", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:321", - "id": "id:322", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:319", - "id": "id:320", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:321", - "id": "id:322", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "automaker-castle-bird-worried", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:325", - "id": "id:326", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:20.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:323", - "id": "id:324", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:20.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:325", - "id": "id:326", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:42", - "href": "href:43", - "id": "id:44", - "name": "afoot-grape-fineness-zestfully", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:329", - "id": "id:330", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:327", - "id": "id:328", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:329", - "id": "id:330", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:25", - "href": "href:26", - "id": "id:27", - "name": "ebullient-slacks-revert-turkey", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:333", - "id": "id:334", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:331", - "id": "id:332", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:333", - "id": "id:334", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:55", - "href": "href:56", - "id": "id:57", - "name": "untracked-repayment-triumph-cat", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:337", - "id": "id:338", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:335", - "id": "id:336", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:337", - "id": "id:338", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "security_groups": [ - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:342", - "id": "id:343", - "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:344", - "id": "id:345", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "resource_type": "network_interface" - }, - { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "resource_type": "network_interface" - }, - { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:346", - "href": "href:347", - "id": "id:348", - "name": "sg31", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:349", - "id": "id:350", - "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:351", - "id": "id:352", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:356", - "id": "id:357", - "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:358", - "id": "id:359", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "resource_type": "network_interface" - }, - { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:363", - "id": "id:364", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - }, - { - "direction": "outbound", - "href": "href:365", - "id": "id:366", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "resource_type": "network_interface" - }, - { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "resource_type": "network_interface" - }, - { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "resource_type": "network_interface" - }, - { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "resource_type": "network_interface" - }, - { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "resource_type": "network_interface" - }, - { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "resource_type": "network_interface" - }, - { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "resource_type": "network_interface" - }, - { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "resource_type": "network_interface" - }, - { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "resource_type": "network_interface" - }, - { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "resource_type": "network_interface" - }, - { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "resource_type": "network_interface" - }, - { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:367", - "id": "id:368", - "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:369", - "id": "id:370", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:371", - "id": "id:372", - "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:373", - "id": "id:374", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:375", - "id": "id:376", - "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:377", - "id": "id:378", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:379", - "id": "id:380", - "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:381", - "id": "id:382", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "endpoint_gateways": [], - "instances": [ - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:388" - }, - "href": "href:386", - "id": "id:387", - "name": "thief-monastery-blinks-verdict", - "volume": { - "crn": "crn:389", - "href": "href:390", - "id": "id:391", - "name": "scrabble-gorged-baton-angled", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:40.000Z", - "crn": "crn:383", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:384", - "id": "id:385", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "primary_ip": { - "address": "10.240.1.5", - "href": "href:238", - "id": "id:239", - "name": "affected-johnniecake-monorail-ungraded", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:388" - }, - "href": "href:386", - "id": "id:387", - "name": "thief-monastery-blinks-verdict", - "volume": { - "crn": "crn:389", - "href": "href:390", - "id": "id:391", - "name": "scrabble-gorged-baton-angled", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:40.000Z", - "floating_ips": [], - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.1.5", - "href": "href:238", - "id": "id:239", - "name": "affected-johnniecake-monorail-ungraded", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:401" - }, - "href": "href:399", - "id": "id:400", - "name": "hunchback-enginous-dividend-atrium", - "volume": { - "crn": "crn:402", - "href": "href:403", - "id": "id:404", - "name": "subsoil-bobble-bovine-unmoving", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:39.000Z", - "crn": "crn:396", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:397", - "id": "id:398", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet0", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "primary_ip": { - "address": "10.240.0.5", - "href": "href:131", - "id": "id:132", - "name": "relatable-antiques-maturing-brulee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:401" - }, - "href": "href:399", - "id": "id:400", - "name": "hunchback-enginous-dividend-atrium", - "volume": { - "crn": "crn:402", - "href": "href:403", - "id": "id:404", - "name": "subsoil-bobble-bovine-unmoving", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:39.000Z", - "floating_ips": [], - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.5", - "href": "href:131", - "id": "id:132", - "name": "relatable-antiques-maturing-brulee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:410" - }, - "href": "href:408", - "id": "id:409", - "name": "laboring-overbuilt-growl-headland", - "volume": { - "crn": "crn:411", - "href": "href:412", - "id": "id:413", - "name": "tamper-salvaging-stick-giddily", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:22.000Z", - "crn": "crn:405", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:406", - "id": "id:407", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "primary_ip": { - "address": "10.240.4.5", - "href": "href:172", - "id": "id:173", - "name": "bark-gatherer-rope-unrivaled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:410" - }, - "href": "href:408", - "id": "id:409", - "name": "laboring-overbuilt-growl-headland", - "volume": { - "crn": "crn:411", - "href": "href:412", - "id": "id:413", - "name": "tamper-salvaging-stick-giddily", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:22.000Z", - "floating_ips": [], - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.4.5", - "href": "href:172", - "id": "id:173", - "name": "bark-gatherer-rope-unrivaled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:419" - }, - "href": "href:417", - "id": "id:418", - "name": "dollop-partition-helping-palmtree", - "volume": { - "crn": "crn:420", - "href": "href:421", - "id": "id:422", - "name": "ravage-deny-amusable-settling", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:20.000Z", - "crn": "crn:414", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:415", - "id": "id:416", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet5", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "primary_ip": { - "address": "10.240.9.5", - "href": "href:83", - "id": "id:84", - "name": "outskirts-unaligned-passivism-parchment", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:419" - }, - "href": "href:417", - "id": "id:418", - "name": "dollop-partition-helping-palmtree", - "volume": { - "crn": "crn:420", - "href": "href:421", - "id": "id:422", - "name": "ravage-deny-amusable-settling", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:20.000Z", - "floating_ips": [], - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.9.5", - "href": "href:83", - "id": "id:84", - "name": "outskirts-unaligned-passivism-parchment", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:428" - }, - "href": "href:426", - "id": "id:427", - "name": "petted-ethanol-voicing-rocklike", - "volume": { - "crn": "crn:429", - "href": "href:430", - "id": "id:431", - "name": "uptown-striving-unrevised-earthlike", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:20.000Z", - "crn": "crn:423", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:424", - "id": "id:425", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "primary_ip": { - "address": "10.240.4.4", - "href": "href:168", - "id": "id:169", - "name": "stood-sitcom-whoops-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:428" - }, - "href": "href:426", - "id": "id:427", - "name": "petted-ethanol-voicing-rocklike", - "volume": { - "crn": "crn:429", - "href": "href:430", - "id": "id:431", - "name": "uptown-striving-unrevised-earthlike", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:20.000Z", - "floating_ips": [], - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.4.4", - "href": "href:168", - "id": "id:169", - "name": "stood-sitcom-whoops-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:437" - }, - "href": "href:435", - "id": "id:436", - "name": "promenade-spyglass-flattop-pushpin", - "volume": { - "crn": "crn:438", - "href": "href:439", - "id": "id:440", - "name": "relax-shaded-prism-jaunt", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:16.000Z", - "crn": "crn:432", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:433", - "id": "id:434", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet3", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "primary_ip": { - "address": "10.240.5.5", - "href": "href:107", - "id": "id:108", - "name": "recognize-citable-exerciser-unsecured", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:437" - }, - "href": "href:435", - "id": "id:436", - "name": "promenade-spyglass-flattop-pushpin", - "volume": { - "crn": "crn:438", - "href": "href:439", - "id": "id:440", - "name": "relax-shaded-prism-jaunt", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:16.000Z", - "floating_ips": [], - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.5.5", - "href": "href:107", - "id": "id:108", - "name": "recognize-citable-exerciser-unsecured", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:446" - }, - "href": "href:444", - "id": "id:445", - "name": "sandbox-federal-sculptor-jugum", - "volume": { - "crn": "crn:447", - "href": "href:448", - "id": "id:449", - "name": "convent-ramrod-cloning-afterward", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:15.000Z", - "crn": "crn:441", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:442", - "id": "id:443", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet4", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "primary_ip": { - "address": "10.240.8.5", - "href": "href:279", - "id": "id:280", - "name": "frighten-mystified-freeway-hurtling", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:446" - }, - "href": "href:444", - "id": "id:445", - "name": "sandbox-federal-sculptor-jugum", - "volume": { - "crn": "crn:447", - "href": "href:448", - "id": "id:449", - "name": "convent-ramrod-cloning-afterward", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:15.000Z", - "floating_ips": [], - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.8.5", - "href": "href:279", - "id": "id:280", - "name": "frighten-mystified-freeway-hurtling", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:455" - }, - "href": "href:453", - "id": "id:454", - "name": "affidavit-chastise-elsewhere-viewer", - "volume": { - "crn": "crn:456", - "href": "href:457", - "id": "id:458", - "name": "fancy-destiny-shuffling-sandbank", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:07.000Z", - "crn": "crn:450", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:451", - "id": "id:452", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet0", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:455" - }, - "href": "href:453", - "id": "id:454", - "name": "affidavit-chastise-elsewhere-viewer", - "volume": { - "crn": "crn:456", - "href": "href:457", - "id": "id:458", - "name": "fancy-destiny-shuffling-sandbank", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:07.000Z", - "floating_ips": [ - { - "address": "52.118.151.238", - "crn": "crn:285", - "href": "href:286", - "id": "id:287", - "name": "fip-0-subnet0" - } - ], - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:464" - }, - "href": "href:462", - "id": "id:463", - "name": "uneven-armoire-scabiosa-letter", - "volume": { - "crn": "crn:465", - "href": "href:466", - "id": "id:467", - "name": "cognition-blinks-humid-oxidant", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:459", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:460", - "id": "id:461", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet3", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "primary_ip": { - "address": "10.240.5.4", - "href": "href:103", - "id": "id:104", - "name": "rising-gopher-reentry-graveness", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:464" - }, - "href": "href:462", - "id": "id:463", - "name": "uneven-armoire-scabiosa-letter", - "volume": { - "crn": "crn:465", - "href": "href:466", - "id": "id:467", - "name": "cognition-blinks-humid-oxidant", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.5.4", - "href": "href:103", - "id": "id:104", - "name": "rising-gopher-reentry-graveness", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:473" - }, - "href": "href:471", - "id": "id:472", - "name": "perplexed-impulsivity-august-jaws", - "volume": { - "crn": "crn:474", - "href": "href:475", - "id": "id:476", - "name": "tartar-sixties-fructose-parmesan", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:468", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:469", - "id": "id:470", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "primary_ip": { - "address": "10.240.1.4", - "href": "href:234", - "id": "id:235", - "name": "excluded-unfair-jailbird-foil", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:473" - }, - "href": "href:471", - "id": "id:472", - "name": "perplexed-impulsivity-august-jaws", - "volume": { - "crn": "crn:474", - "href": "href:475", - "id": "id:476", - "name": "tartar-sixties-fructose-parmesan", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.1.4", - "href": "href:234", - "id": "id:235", - "name": "excluded-unfair-jailbird-foil", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:482" - }, - "href": "href:480", - "id": "id:481", - "name": "litter-snipping-unclasp-dust", - "volume": { - "crn": "crn:483", - "href": "href:484", - "id": "id:485", - "name": "untried-sulphate-hypnosis-subsidize", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:477", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:478", - "id": "id:479", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet4", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "primary_ip": { - "address": "10.240.8.4", - "href": "href:275", - "id": "id:276", - "name": "bagged-posture-glaring-cojoined", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:482" - }, - "href": "href:480", - "id": "id:481", - "name": "litter-snipping-unclasp-dust", - "volume": { - "crn": "crn:483", - "href": "href:484", - "id": "id:485", - "name": "untried-sulphate-hypnosis-subsidize", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.8.4", - "href": "href:275", - "id": "id:276", - "name": "bagged-posture-glaring-cojoined", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:491" - }, - "href": "href:489", - "id": "id:490", - "name": "unlawful-overreach-yarn-rippling", - "volume": { - "crn": "crn:492", - "href": "href:493", - "id": "id:494", - "name": "finer-voter-roving-jailer", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:486", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:487", - "id": "id:488", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet5", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "primary_ip": { - "address": "10.240.9.4", - "href": "href:79", - "id": "id:80", - "name": "ideally-grain-bagpipe-luxuriant", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:491" - }, - "href": "href:489", - "id": "id:490", - "name": "unlawful-overreach-yarn-rippling", - "volume": { - "crn": "crn:492", - "href": "href:493", - "id": "id:494", - "name": "finer-voter-roving-jailer", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.9.4", - "href": "href:79", - "id": "id:80", - "name": "ideally-grain-bagpipe-luxuriant", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:500" - }, - "href": "href:498", - "id": "id:499", - "name": "mashed-thing-headache-estate", - "volume": { - "crn": "crn:501", - "href": "href:502", - "id": "id:503", - "name": "mountain-harpist-libraries-dreaming", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:39.000Z", - "crn": "crn:495", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:496", - "id": "id:497", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet11", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "primary_ip": { - "address": "10.240.80.4", - "href": "href:151", - "id": "id:152", - "name": "childlike-publish-retainer-movie", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:500" - }, - "href": "href:498", - "id": "id:499", - "name": "mashed-thing-headache-estate", - "volume": { - "crn": "crn:501", - "href": "href:502", - "id": "id:503", - "name": "mountain-harpist-libraries-dreaming", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:39.000Z", - "floating_ips": [], - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.80.4", - "href": "href:151", - "id": "id:152", - "name": "childlike-publish-retainer-movie", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11" - } - ], - "status": "available", - "subnet": { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:509" - }, - "href": "href:507", - "id": "id:508", - "name": "calzone-cacti-moonlight-subarctic", - "volume": { - "crn": "crn:510", - "href": "href:511", - "id": "id:512", - "name": "blurred-dream-pectin-tapping", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:36.000Z", - "crn": "crn:504", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:505", - "id": "id:506", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet10", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:509" - }, - "href": "href:507", - "id": "id:508", - "name": "calzone-cacti-moonlight-subarctic", - "volume": { - "crn": "crn:510", - "href": "href:511", - "id": "id:512", - "name": "blurred-dream-pectin-tapping", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:36.000Z", - "floating_ips": [ - { - "address": "150.239.167.146", - "crn": "crn:288", - "href": "href:289", - "id": "id:290", - "name": "fip-0-subnet10" - } - ], - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11" - } - ], - "status": "available", - "subnet": { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:518" - }, - "href": "href:516", - "id": "id:517", - "name": "recoup-blinks-ebullient-renewed", - "volume": { - "crn": "crn:519", - "href": "href:520", - "id": "id:521", - "name": "manmade-unequal-disinfect-cone", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:24.000Z", - "crn": "crn:513", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:514", - "id": "id:515", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:518" - }, - "href": "href:516", - "id": "id:517", - "name": "recoup-blinks-ebullient-renewed", - "volume": { - "crn": "crn:519", - "href": "href:520", - "id": "id:521", - "name": "manmade-unequal-disinfect-cone", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:24.000Z", - "floating_ips": [ - { - "address": "169.48.95.165", - "crn": "crn:291", - "href": "href:292", - "id": "id:293", - "name": "fip-0-subnet20" - } - ], - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:527" - }, - "href": "href:525", - "id": "id:526", - "name": "radio-tightrope-outtakes-moonshine", - "volume": { - "crn": "crn:528", - "href": "href:529", - "id": "id:530", - "name": "tattoo-crescent-unwary-hayride", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:21.000Z", - "crn": "crn:522", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:523", - "id": "id:524", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "primary_ip": { - "address": "10.240.128.5", - "href": "href:213", - "id": "id:214", - "name": "customs-recollect-drippy-primate", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:527" - }, - "href": "href:525", - "id": "id:526", - "name": "radio-tightrope-outtakes-moonshine", - "volume": { - "crn": "crn:528", - "href": "href:529", - "id": "id:530", - "name": "tattoo-crescent-unwary-hayride", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:21.000Z", - "floating_ips": [], - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.5", - "href": "href:213", - "id": "id:214", - "name": "customs-recollect-drippy-primate", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:536" - }, - "href": "href:534", - "id": "id:535", - "name": "crumpet-ride-tastiness-phoney", - "volume": { - "crn": "crn:537", - "href": "href:538", - "id": "id:539", - "name": "doorframe-marvelous-refusing-citable", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:21.000Z", - "crn": "crn:531", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:532", - "id": "id:533", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi2-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "primary_ip": { - "address": "10.240.128.4", - "href": "href:209", - "id": "id:210", - "name": "unmixed-qualify-prescribe-railcar", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:536" - }, - "href": "href:534", - "id": "id:535", - "name": "crumpet-ride-tastiness-phoney", - "volume": { - "crn": "crn:537", - "href": "href:538", - "id": "id:539", - "name": "doorframe-marvelous-refusing-citable", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:21.000Z", - "floating_ips": [], - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.4", - "href": "href:209", - "id": "id:210", - "name": "unmixed-qualify-prescribe-railcar", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:545" - }, - "href": "href:543", - "id": "id:544", - "name": "bronzing-vendor-plod-pretzel", - "volume": { - "crn": "crn:546", - "href": "href:547", - "id": "id:548", - "name": "squelch-plop-headlamp-ideologue", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:00.000Z", - "crn": "crn:540", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:541", - "id": "id:542", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet30", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:545" - }, - "href": "href:543", - "id": "id:544", - "name": "bronzing-vendor-plod-pretzel", - "volume": { - "crn": "crn:546", - "href": "href:547", - "id": "id:548", - "name": "squelch-plop-headlamp-ideologue", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:00.000Z", - "floating_ips": [ - { - "address": "52.118.100.239", - "crn": "crn:294", - "href": "href:295", - "id": "id:296", - "name": "fip-0-subnet30" - } - ], - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:346", - "href": "href:347", - "id": "id:348", - "name": "sg31" - } - ], - "status": "available", - "subnet": { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - } - ], - "routing_tables": [ - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:20.000Z", - "href": "href:11", - "id": "id:12", - "is_default": true, - "lifecycle_state": "stable", - "name": "overtone-sputter-overspend-gorge", - "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:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:28", - "id": "id:29", - "is_default": true, - "lifecycle_state": "stable", - "name": "escapade-dynamite-upstage-context", - "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:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:45", - "id": "id:46", - "is_default": true, - "lifecycle_state": "stable", - "name": "quintuple-severity-caddie-manuals", - "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:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:58", - "id": "id:59", - "is_default": true, - "lifecycle_state": "stable", - "name": "probational-herring-undone-daintily", - "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:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - } - } - ], - "load_balancers": [], - "transit_connections": [ - { - "created_at": "2024-06-25T15:41:44.212Z", - "id": "id:549", - "name": "tg3_connection3", - "network_id": "crn:52", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:550", - "id": "id:551", - "name": "local-tg3" - }, - "updated_at": "2024-06-25T15:45:14.206Z" - }, - { - "created_at": "2024-06-25T15:41:54.416Z", - "id": "id:552", - "name": "tg3_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:550", - "id": "id:551", - "name": "local-tg3" - }, - "updated_at": "2024-06-25T15:45:53.979Z" - }, - { - "created_at": "2024-06-25T15:42:54.772Z", - "id": "id:553", - "name": "tg2_connection3", - "network_id": "crn:52", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:08.822Z" - }, - { - "created_at": "2024-06-25T15:43:11.555Z", - "id": "id:556", - "name": "tg2_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters": [ - { - "action": "deny", - "created_at": "2024-06-25T15:46:46.641Z", - "id": "id:557", - "le": 32, - "prefix": "10.240.0.0/22", - "updated_at": "2024-06-25T15:46:46.641Z" - } - ], - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:59.395Z" - }, - { - "created_at": "2024-06-25T15:43:12.159Z", - "id": "id:558", - "name": "tg_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters": [ - { - "action": "deny", - "before": "298db67f-2e68-4548-93b9-949f8356d4a0", - "created_at": "2024-06-25T15:45:14.711Z", - "id": "id:559", - "prefix": "10.240.4.0/22", - "updated_at": "2024-06-25T15:45:14.711Z" - }, - { - "action": "deny", - "created_at": "2024-06-25T15:45:25.435Z", - "id": "id:560", - "prefix": "10.240.8.0/22", - "updated_at": "2024-06-25T15:45:25.435Z" - } - ], - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:49:53.837Z" - }, - { - "created_at": "2024-06-25T15:43:41.079Z", - "id": "id:563", - "name": "tg2_connection2", - "network_id": "crn:39", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:43.192Z" - }, - { - "created_at": "2024-06-25T15:43:42.335Z", - "id": "id:564", - "name": "tg1_connection1", - "network_id": "crn:1", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:48:45.229Z" - }, - { - "created_at": "2024-06-25T15:44:08.995Z", - "id": "id:565", - "name": "tg1_connection2", - "network_id": "crn:39", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:49:11.976Z" - } - ], - "transit_gateways": [ - { - "id": "id:551", - "crn": "crn:550", - "name": "local-tg3", - "location": "us-south", - "created_at": "2024-06-25T15:40:21.390Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:42:12.752Z" - }, - { - "id": "id:555", - "crn": "crn:554", - "name": "local-tg2", - "location": "us-south", - "created_at": "2024-06-25T15:40:25.895Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:43:58.196Z" - }, - { - "id": "id:562", - "crn": "crn:561", - "name": "local-tg1", - "location": "us-south", - "created_at": "2024-06-25T15:40:26.455Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:43:15.331Z" - } - ], - "iks_clusters": [] -} diff --git a/test/data/acl_vpe/config_object.json b/test/data/acl_vpe/config_object.json deleted file mode 100644 index 75620661..00000000 --- a/test/data/acl_vpe/config_object.json +++ /dev/null @@ -1,2077 +0,0 @@ -{ - "collector_version": "0.11.0", - "provider": "ibm", - "vpcs": [ - { - "classic_access": false, - "created_at": "2024-06-19T07:11:56.000Z", - "crn": "crn:1", - "cse_source_ips": [ - { - "ip": { - "address": "10.16.239.119" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.28.206" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.16.253.77" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "premises-eleven-nursery-coveted" - }, - "default_routing_table": { - "href": "href:11", - "id": "id:12", - "name": "unguarded-corncob-unaired-corner", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "impart-oxidize-chive-escapade" - }, - "dns": { - "enable_hub": false, - "resolution_binding_count": 0, - "resolver": { - "servers": [ - { - "address": "161.26.0.7" - }, - { - "address": "161.26.0.8" - } - ], - "type": "system", - "configuration": "private_resolver" - } - }, - "health_reasons": null, - "health_state": "ok", - "href": "href:2", - "id": "id:3", - "name": "test-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-19T07:11:56.000Z", - "has_subnets": true, - "href": "href:18", - "id": "id:19", - "is_default": true, - "name": "seismic-phosphate-subtext-unleash", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.64.0/18", - "created_at": "2024-06-19T07:11:56.000Z", - "has_subnets": true, - "href": "href:20", - "id": "id:21", - "is_default": true, - "name": "shaded-tribute-glazing-explains", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "cidr": "10.240.128.0/18", - "created_at": "2024-06-19T07:11:56.000Z", - "has_subnets": true, - "href": "href:22", - "id": "id:23", - "is_default": true, - "name": "overlabor-spiffy-economist-clanking", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - } - ], - "subnets": [ - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-19T07:12:21.000Z", - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.0.0/24", - "name": "sub1", - "network_acl": { - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "unguarded-corncob-unaired-corner", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.0.0", - "auto_delete": false, - "created_at": "2024-06-19T07:12:21.000Z", - "href": "href:30", - "id": "id:31", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.1", - "auto_delete": false, - "created_at": "2024-06-19T07:12:21.000Z", - "href": "href:32", - "id": "id:33", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.2", - "auto_delete": false, - "created_at": "2024-06-19T07:12:21.000Z", - "href": "href:34", - "id": "id:35", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.3", - "auto_delete": false, - "created_at": "2024-06-19T07:12:21.000Z", - "href": "href:36", - "id": "id:37", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.4", - "auto_delete": true, - "created_at": "2024-06-19T07:12:47.000Z", - "href": "href:38", - "id": "id:39", - "lifecycle_state": "stable", - "name": "portion-send-snout-magazine", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:40", - "id": "id:41", - "name": "bouncing-serpent-graffiti-evasion", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.5", - "auto_delete": true, - "created_at": "2024-06-19T11:03:46.000Z", - "href": "href:42", - "id": "id:43", - "lifecycle_state": "stable", - "name": "appdata-vpe1", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "crn": "crn:44", - "href": "href:45", - "id": "id:46", - "name": "appdata-endpoint-gateway", - "resource_type": "endpoint_gateway" - } - }, - { - "address": "10.240.0.255", - "auto_delete": false, - "created_at": "2024-06-19T07:12:21.000Z", - "href": "href:47", - "id": "id:48", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [ - "trust-zone:edge" - ] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-19T07:12:20.000Z", - "crn": "crn:49", - "href": "href:50", - "id": "id:51", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.64.0/24", - "name": "sub3", - "network_acl": { - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "unguarded-corncob-unaired-corner", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-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-19T07:12:20.000Z", - "href": "href:52", - "id": "id:53", - "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-19T07:12:20.000Z", - "href": "href:54", - "id": "id:55", - "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-19T07:12:20.000Z", - "href": "href:56", - "id": "id:57", - "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-19T07:12:20.000Z", - "href": "href:58", - "id": "id:59", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.64.4", - "auto_delete": true, - "created_at": "2024-06-19T11:03:34.000Z", - "href": "href:60", - "id": "id:61", - "lifecycle_state": "stable", - "name": "policydb-vpe3", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "crn": "crn:62", - "href": "href:63", - "id": "id:64", - "name": "policydb-endpoint-gateway", - "resource_type": "endpoint_gateway" - } - }, - { - "address": "10.240.64.255", - "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:65", - "id": "id:66", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [ - "trust-zone:transit" - ] - }, - { - "available_ipv4_address_count": 246, - "created_at": "2024-06-19T07:12:20.000Z", - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.128.0/24", - "name": "sub2", - "network_acl": { - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "unguarded-corncob-unaired-corner", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-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-19T07:12:20.000Z", - "href": "href:70", - "id": "id:71", - "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-19T07:12:20.000Z", - "href": "href:72", - "id": "id:73", - "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-19T07:12:20.000Z", - "href": "href:74", - "id": "id:75", - "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-19T07:12:20.000Z", - "href": "href:76", - "id": "id:77", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.128.4", - "auto_delete": true, - "created_at": "2024-06-19T07:12:46.000Z", - "href": "href:78", - "id": "id:79", - "lifecycle_state": "stable", - "name": "magnetism-steersman-botany-hurled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:80", - "id": "id:81", - "name": "captain-captivity-shorty-crown", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.5", - "auto_delete": true, - "created_at": "2024-06-19T07:12:47.000Z", - "href": "href:82", - "id": "id:83", - "lifecycle_state": "stable", - "name": "kilt-snipping-yen-unmanaged", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:84", - "id": "id:85", - "name": "left-pebble-agonizing-wharf", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.6", - "auto_delete": true, - "created_at": "2024-06-19T07:12:47.000Z", - "href": "href:86", - "id": "id:87", - "lifecycle_state": "stable", - "name": "manic-nerve-surfboard-cofounder", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:88", - "id": "id:89", - "name": "litigate-bullfrog-improve-shandy", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.7", - "auto_delete": true, - "created_at": "2024-06-19T11:03:34.000Z", - "href": "href:90", - "id": "id:91", - "lifecycle_state": "stable", - "name": "policydb-vpe2", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "crn": "crn:62", - "href": "href:63", - "id": "id:64", - "name": "policydb-endpoint-gateway", - "resource_type": "endpoint_gateway" - } - }, - { - "address": "10.240.128.8", - "auto_delete": true, - "created_at": "2024-06-19T11:03:46.000Z", - "href": "href:92", - "id": "id:93", - "lifecycle_state": "stable", - "name": "appdata-vpe2", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "crn": "crn:44", - "href": "href:45", - "id": "id:46", - "name": "appdata-endpoint-gateway", - "resource_type": "endpoint_gateway" - } - }, - { - "address": "10.240.128.255", - "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:94", - "id": "id:95", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [ - "trust-zone:private" - ] - } - ], - "public_gateways": [], - "floating_ips": [ - { - "address": "52.116.131.7", - "created_at": "2024-06-19T07:13:16.000Z", - "crn": "crn:96", - "href": "href:97", - "id": "id:98", - "name": "floating-ip", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:40", - "id": "id:41", - "name": "bouncing-serpent-graffiti-evasion", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:38", - "id": "id:39", - "name": "portion-send-snout-magazine", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - } - ], - "network_acls": [ - { - "created_at": "2024-06-19T07:12:16.000Z", - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "deny", - "before": { - "href": "href:101", - "id": "id:102", - "name": "acl1-out3" - }, - "created_at": "2024-06-19T07:12:17.000Z", - "destination": "10.240.0.0/24", - "direction": "outbound", - "href": "href:99", - "id": "id:100", - "ip_version": "ipv4", - "name": "acl1-out2", - "source": "10.240.128.0/24", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:103", - "id": "id:104", - "name": "acl1-in2" - }, - "created_at": "2024-06-19T07:12:18.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:101", - "id": "id:102", - "ip_version": "ipv4", - "name": "acl1-out3", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-19T07:12:18.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:103", - "id": "id:104", - "ip_version": "ipv4", - "name": "acl1-in2", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "name": "sub1", - "resource_type": "subnet" - }, - { - "crn": "crn:49", - "href": "href:50", - "id": "id:51", - "name": "sub3", - "resource_type": "subnet" - }, - { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "sub2", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-19T07:11:57.000Z", - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "premises-eleven-nursery-coveted", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:107", - "id": "id:108", - "name": "allow-outbound" - }, - "created_at": "2024-06-19T07:11:57.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:105", - "id": "id:106", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-19T07:11:57.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:107", - "id": "id:108", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "security_groups": [ - { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:109", - "href": "href:110", - "id": "id:111", - "name": "opa-sg", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:112", - "id": "id:113", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:114", - "href": "href:115", - "id": "id:116", - "name": "be-sg" - }, - "port_max": 8181, - "port_min": 8181, - "protocol": "tcp" - } - ], - "targets": [ - { - "href": "href:84", - "id": "id:85", - "name": "left-pebble-agonizing-wharf", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:114", - "href": "href:115", - "id": "id:116", - "name": "be-sg", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:117", - "id": "id:118", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:119", - "href": "href:120", - "id": "id:121", - "name": "fe-sg" - }, - "port_max": 65535, - "port_min": 1, - "protocol": "tcp" - }, - { - "direction": "outbound", - "href": "href:122", - "id": "id:123", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:109", - "href": "href:110", - "id": "id:111", - "name": "opa-sg" - }, - "port_max": 8181, - "port_min": 8181, - "protocol": "tcp" - } - ], - "targets": [ - { - "href": "href:80", - "id": "id:81", - "name": "captain-captivity-shorty-crown", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:124", - "href": "href:125", - "id": "id:126", - "name": "policydb-vpe", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:127", - "id": "id:128", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "address": "10.240.128.7" - }, - "port_max": 65535, - "port_min": 1, - "protocol": "tcp" - }, - { - "direction": "outbound", - "href": "href:129", - "id": "id:130", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "address": "10.240.64.4" - }, - "port_max": 65535, - "port_min": 1, - "protocol": "tcp" - } - ], - "targets": [ - { - "href": "href:80", - "id": "id:81", - "name": "captain-captivity-shorty-crown", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:131", - "href": "href:132", - "id": "id:133", - "name": "proxy-sg", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:134", - "id": "id:135", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - }, - { - "direction": "outbound", - "href": "href:136", - "id": "id:137", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:119", - "href": "href:120", - "id": "id:121", - "name": "fe-sg" - }, - "port_max": 9000, - "port_min": 9000, - "protocol": "udp" - } - ], - "targets": [ - { - "href": "href:40", - "id": "id:41", - "name": "bouncing-serpent-graffiti-evasion", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:138", - "href": "href:139", - "id": "id:140", - "name": "appdata-sg", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:141", - "id": "id:142", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "port_max": 65535, - "port_min": 1, - "protocol": "tcp" - } - ], - "targets": [ - { - "href": "href:45", - "id": "id:46", - "name": "appdata-endpoint-gateway", - "resource_type": "endpoint_gateway", - "crn": "crn:44" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:143", - "href": "href:144", - "id": "id:145", - "name": "appdata-vpe", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:146", - "id": "id:147", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "address": "10.240.128.8" - }, - "port_max": 65535, - "port_min": 1, - "protocol": "tcp" - } - ], - "targets": [ - { - "href": "href:80", - "id": "id:81", - "name": "captain-captivity-shorty-crown", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:119", - "href": "href:120", - "id": "id:121", - "name": "fe-sg", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:148", - "id": "id:149", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:114", - "href": "href:115", - "id": "id:116", - "name": "be-sg" - }, - "port_max": 65535, - "port_min": 1, - "protocol": "tcp" - }, - { - "direction": "inbound", - "href": "href:150", - "id": "id:151", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:131", - "href": "href:132", - "id": "id:133", - "name": "proxy-sg" - }, - "port_max": 9000, - "port_min": 9000, - "protocol": "udp" - } - ], - "targets": [ - { - "href": "href:88", - "id": "id:89", - "name": "litigate-bullfrog-improve-shandy", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-19T07:12:16.000Z", - "crn": "crn:152", - "href": "href:153", - "id": "id:154", - "name": "policydb-sg", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:155", - "id": "id:156", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "port_max": 65535, - "port_min": 1, - "protocol": "tcp" - } - ], - "targets": [ - { - "href": "href:63", - "id": "id:64", - "name": "policydb-endpoint-gateway", - "resource_type": "endpoint_gateway", - "crn": "crn:62" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-19T07:11:57.000Z", - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "impart-oxidize-chive-escapade", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:157", - "id": "id:158", - "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:159", - "id": "id:160", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "impart-oxidize-chive-escapade" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "endpoint_gateways": [ - { - "allow_dns_resolution_binding": true, - "created_at": "2024-06-19T11:03:31.000Z", - "crn": "crn:62", - "health_state": "ok", - "href": "href:63", - "id": "id:64", - "ips": [ - { - "address": "10.240.64.4", - "href": "href:60", - "id": "id:61", - "name": "policydb-vpe3", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.128.7", - "href": "href:90", - "id": "id:91", - "name": "policydb-vpe2", - "resource_type": "subnet_reserved_ip" - } - ], - "lifecycle_reasons": null, - "lifecycle_state": "stable", - "name": "policydb-endpoint-gateway", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "endpoint_gateway", - "security_groups": [ - { - "crn": "crn:152", - "href": "href:153", - "id": "id:154", - "name": "policydb-sg" - } - ], - "service_endpoint": "0b00984f-c1e1-43b2-ba1e-35b0a55b2fa5.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud", - "service_endpoints": [ - "0b00984f-c1e1-43b2-ba1e-35b0a55b2fa5.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud" - ], - "target": { - "crn": "crn:161", - "resource_type": "provider_cloud_service" - }, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "allow_dns_resolution_binding": true, - "created_at": "2024-06-19T11:03:31.000Z", - "crn": "crn:44", - "health_state": "ok", - "href": "href:45", - "id": "id:46", - "ips": [ - { - "address": "10.240.128.8", - "href": "href:92", - "id": "id:93", - "name": "appdata-vpe2", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.5", - "href": "href:42", - "id": "id:43", - "name": "appdata-vpe1", - "resource_type": "subnet_reserved_ip" - } - ], - "lifecycle_reasons": null, - "lifecycle_state": "stable", - "name": "appdata-endpoint-gateway", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "endpoint_gateway", - "security_groups": [ - { - "crn": "crn:138", - "href": "href:139", - "id": "id:140", - "name": "appdata-sg" - } - ], - "service_endpoint": "d60cdc12-7501-488c-a8d7-91a089497ca9-0.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud", - "service_endpoints": [ - "d60cdc12-7501-488c-a8d7-91a089497ca9-0.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud", - "d60cdc12-7501-488c-a8d7-91a089497ca9-1.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud", - "d60cdc12-7501-488c-a8d7-91a089497ca9-2.6131b73286f34215871dfad7254b4f7d.private.databases.appdomain.cloud" - ], - "target": { - "crn": "crn:162", - "resource_type": "provider_cloud_service" - }, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "instances": [ - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:168" - }, - "href": "href:166", - "id": "id:167", - "name": "magnitude-aloe-wildlife-vacancy", - "volume": { - "crn": "crn:169", - "href": "href:170", - "id": "id:171", - "name": "catbrier-onto-grapple-fastball", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-19T07:12:47.000Z", - "crn": "crn:163", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:164", - "id": "id:165", - "image": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "proxy", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:40", - "id": "id:41", - "name": "bouncing-serpent-graffiti-evasion", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:38", - "id": "id:39", - "name": "portion-send-snout-magazine", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "name": "sub1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:175", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:168" - }, - "href": "href:166", - "id": "id:167", - "name": "magnitude-aloe-wildlife-vacancy", - "volume": { - "crn": "crn:169", - "href": "href:170", - "id": "id:171", - "name": "catbrier-onto-grapple-fastball", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-19T07:12:47.000Z", - "floating_ips": [ - { - "address": "52.116.131.7", - "crn": "crn:96", - "href": "href:97", - "id": "id:98", - "name": "floating-ip" - } - ], - "href": "href:40", - "id": "id:41", - "name": "bouncing-serpent-graffiti-evasion", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.4", - "href": "href:38", - "id": "id:39", - "name": "portion-send-snout-magazine", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:131", - "href": "href:132", - "id": "id:133", - "name": "proxy-sg" - } - ], - "status": "available", - "subnet": { - "crn": "crn:24", - "href": "href:25", - "id": "id:26", - "name": "sub1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:181" - }, - "href": "href:179", - "id": "id:180", - "name": "folk-mousy-collar-kleenex", - "volume": { - "crn": "crn:182", - "href": "href:183", - "id": "id:184", - "name": "regalia-pavestone-ramble-stretch", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-19T07:12:46.000Z", - "crn": "crn:176", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:177", - "id": "id:178", - "image": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "opa", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:84", - "id": "id:85", - "name": "left-pebble-agonizing-wharf", - "primary_ip": { - "address": "10.240.128.5", - "href": "href:82", - "id": "id:83", - "name": "kilt-snipping-yen-unmanaged", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "sub2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:175", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:181" - }, - "href": "href:179", - "id": "id:180", - "name": "folk-mousy-collar-kleenex", - "volume": { - "crn": "crn:182", - "href": "href:183", - "id": "id:184", - "name": "regalia-pavestone-ramble-stretch", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-19T07:12:46.000Z", - "floating_ips": [], - "href": "href:84", - "id": "id:85", - "name": "left-pebble-agonizing-wharf", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.5", - "href": "href:82", - "id": "id:83", - "name": "kilt-snipping-yen-unmanaged", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:109", - "href": "href:110", - "id": "id:111", - "name": "opa-sg" - } - ], - "status": "available", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "sub2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:190" - }, - "href": "href:188", - "id": "id:189", - "name": "scarily-reapprove-ecologist-gosling", - "volume": { - "crn": "crn:191", - "href": "href:192", - "id": "id:193", - "name": "flattered-laboring-reusable-comic", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-19T07:12:46.000Z", - "crn": "crn:185", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:186", - "id": "id:187", - "image": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "fe", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:88", - "id": "id:89", - "name": "litigate-bullfrog-improve-shandy", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:86", - "id": "id:87", - "name": "manic-nerve-surfboard-cofounder", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "sub2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:175", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:190" - }, - "href": "href:188", - "id": "id:189", - "name": "scarily-reapprove-ecologist-gosling", - "volume": { - "crn": "crn:191", - "href": "href:192", - "id": "id:193", - "name": "flattered-laboring-reusable-comic", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-19T07:12:46.000Z", - "floating_ips": [], - "href": "href:88", - "id": "id:89", - "name": "litigate-bullfrog-improve-shandy", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.6", - "href": "href:86", - "id": "id:87", - "name": "manic-nerve-surfboard-cofounder", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:119", - "href": "href:120", - "id": "id:121", - "name": "fe-sg" - } - ], - "status": "available", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "sub2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:199" - }, - "href": "href:197", - "id": "id:198", - "name": "carnival-grimace-mannequin-lumping", - "volume": { - "crn": "crn:200", - "href": "href:201", - "id": "id:202", - "name": "wands-niece-whole-cocoa", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-19T07:12:46.000Z", - "crn": "crn:194", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:195", - "id": "id:196", - "image": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "be", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:80", - "id": "id:81", - "name": "captain-captivity-shorty-crown", - "primary_ip": { - "address": "10.240.128.4", - "href": "href:78", - "id": "id:79", - "name": "magnetism-steersman-botany-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "sub2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:175", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:199" - }, - "href": "href:197", - "id": "id:198", - "name": "carnival-grimace-mannequin-lumping", - "volume": { - "crn": "crn:200", - "href": "href:201", - "id": "id:202", - "name": "wands-niece-whole-cocoa", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-19T07:12:46.000Z", - "floating_ips": [], - "href": "href:80", - "id": "id:81", - "name": "captain-captivity-shorty-crown", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.4", - "href": "href:78", - "id": "id:79", - "name": "magnetism-steersman-botany-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:124", - "href": "href:125", - "id": "id:126", - "name": "policydb-vpe" - }, - { - "crn": "crn:114", - "href": "href:115", - "id": "id:116", - "name": "be-sg" - }, - { - "crn": "crn:143", - "href": "href:144", - "id": "id:145", - "name": "appdata-vpe" - } - ], - "status": "available", - "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "sub2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - } - ], - "routing_tables": [ - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-19T07:11:57.000Z", - "href": "href:11", - "id": "id:12", - "is_default": true, - "lifecycle_state": "stable", - "name": "unguarded-corncob-unaired-corner", - "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", - "resource_type": "subnet" - }, - { - "crn": "crn:49", - "href": "href:50", - "id": "id:51", - "name": "sub3", - "resource_type": "subnet" - }, - { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "sub2", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc", - "resource_type": "vpc" - } - } - ], - "load_balancers": [], - "transit_connections": null, - "transit_gateways": null, - "iks_clusters": [] -} diff --git a/test/data/sg_protocols/config_object.json b/test/data/sg_protocols/config_object.json deleted file mode 100644 index 7e94d3b8..00000000 --- a/test/data/sg_protocols/config_object.json +++ /dev/null @@ -1,6269 +0,0 @@ -{ - "collector_version": "0.11.0", - "provider": "ibm", - "vpcs": [ - { - "classic_access": false, - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:1", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.215.5" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.220.2" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.249.82.12" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "automaker-castle-bird-worried" - }, - "default_routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole" - }, - "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": "test-vpc1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.80.0/20", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:18", - "id": "id:19", - "is_default": false, - "name": "address-prefix-vpc-1", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "cidr": "10.240.64.0/20", - "created_at": "2024-06-25T15:40:40.000Z", - "has_subnets": true, - "href": "href:20", - "id": "id:21", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:22", - "cse_source_ips": [ - { - "ip": { - "address": "10.16.238.56" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.249.200.205" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.249.212.88" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:25", - "href": "href:26", - "id": "id:27", - "name": "ebullient-slacks-revert-turkey" - }, - "default_routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam" - }, - "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:23", - "id": "id:24", - "name": "test-vpc0", - "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/22", - "created_at": "2024-06-25T15:40:37.000Z", - "has_subnets": true, - "href": "href:33", - "id": "id:34", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.4.0/22", - "created_at": "2024-06-25T15:40:38.000Z", - "has_subnets": true, - "href": "href:35", - "id": "id:36", - "is_default": false, - "name": "address-prefix-vpc-1", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.8.0/22", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:37", - "id": "id:38", - "is_default": false, - "name": "address-prefix-vpc-2", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:39", - "cse_source_ips": [ - { - "ip": { - "address": "10.12.125.16" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.27.134" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.22.231.90" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:42", - "href": "href:43", - "id": "id:44", - "name": "afoot-grape-fineness-zestfully" - }, - "default_routing_table": { - "href": "href:45", - "id": "id:46", - "name": "quintuple-severity-caddie-manuals", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll" - }, - "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:40", - "id": "id:41", - "name": "test-vpc2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.128.0/20", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:50", - "id": "id:51", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:52", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.219.155" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.12.159.11" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.16.253.109" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:55", - "href": "href:56", - "id": "id:57", - "name": "untracked-repayment-triumph-cat" - }, - "default_routing_table": { - "href": "href:58", - "id": "id:59", - "name": "probational-herring-undone-daintily", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely" - }, - "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:53", - "id": "id:54", - "name": "test-vpc3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.192.0/20", - "created_at": "2024-06-25T15:40:38.000Z", - "has_subnets": true, - "href": "href:63", - "id": "id:64", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - } - ], - "subnets": [ - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:47.000Z", - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.9.0/24", - "name": "subnet5", - "network_acl": { - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.9.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:71", - "id": "id:72", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:73", - "id": "id:74", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:75", - "id": "id:76", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:77", - "id": "id:78", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:79", - "id": "id:80", - "lifecycle_state": "stable", - "name": "ideally-grain-bagpipe-luxuriant", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.9.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:20.000Z", - "href": "href:83", - "id": "id:84", - "lifecycle_state": "stable", - "name": "outskirts-unaligned-passivism-parchment", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.9.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:87", - "id": "id:88", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:35.000Z", - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.5.0/24", - "name": "subnet3", - "network_acl": { - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.5.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:95", - "id": "id:96", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:97", - "id": "id:98", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:99", - "id": "id:100", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:101", - "id": "id:102", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:103", - "id": "id:104", - "lifecycle_state": "stable", - "name": "rising-gopher-reentry-graveness", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.5.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:16.000Z", - "href": "href:107", - "id": "id:108", - "lifecycle_state": "stable", - "name": "recognize-citable-exerciser-unsecured", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.5.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:111", - "id": "id:112", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:23.000Z", - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.0.0/24", - "name": "subnet0", - "network_acl": { - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.0.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:119", - "id": "id:120", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:121", - "id": "id:122", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:123", - "id": "id:124", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:125", - "id": "id:126", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:08.000Z", - "href": "href:127", - "id": "id:128", - "lifecycle_state": "stable", - "name": "pundit-tight-arbitrate-grace", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:39.000Z", - "href": "href:131", - "id": "id:132", - "lifecycle_state": "stable", - "name": "relatable-antiques-maturing-brulee", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:135", - "id": "id:136", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:41:20.000Z", - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.80.0/24", - "name": "subnet11", - "network_acl": { - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "reserved_ips": [ - { - "address": "10.240.80.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:143", - "id": "id:144", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:145", - "id": "id:146", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:147", - "id": "id:148", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:149", - "id": "id:150", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:40.000Z", - "href": "href:151", - "id": "id:152", - "lifecycle_state": "stable", - "name": "childlike-publish-retainer-movie", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.80.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:155", - "id": "id:156", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:08.000Z", - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.4.0/24", - "name": "subnet2", - "network_acl": { - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.4.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:160", - "id": "id:161", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:162", - "id": "id:163", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:164", - "id": "id:165", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:166", - "id": "id:167", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:21.000Z", - "href": "href:168", - "id": "id:169", - "lifecycle_state": "stable", - "name": "stood-sitcom-whoops-hurled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.4.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:22.000Z", - "href": "href:172", - "id": "id:173", - "lifecycle_state": "stable", - "name": "bark-gatherer-rope-unrivaled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.4.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:176", - "id": "id:177", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:41:08.000Z", - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.64.0/24", - "name": "subnet10", - "network_acl": { - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "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-25T15:41:08.000Z", - "href": "href:181", - "id": "id:182", - "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-25T15:41:08.000Z", - "href": "href:183", - "id": "id:184", - "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-25T15:41:08.000Z", - "href": "href:185", - "id": "id:186", - "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-25T15:41:08.000Z", - "href": "href:187", - "id": "id:188", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.64.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:36.000Z", - "href": "href:189", - "id": "id:190", - "lifecycle_state": "stable", - "name": "starry-smasher-ladle-dioxide", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.64.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:193", - "id": "id:194", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 248, - "created_at": "2024-06-25T15:40:57.000Z", - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.128.0/24", - "name": "subnet20", - "network_acl": { - "crn": "crn:198", - "href": "href:199", - "id": "id:200", - "name": "acl21" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:45", - "id": "id:46", - "name": "quintuple-severity-caddie-manuals", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "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-25T15:40:57.000Z", - "href": "href:201", - "id": "id:202", - "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-25T15:40:57.000Z", - "href": "href:203", - "id": "id:204", - "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-25T15:40:57.000Z", - "href": "href:205", - "id": "id:206", - "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-25T15:40:57.000Z", - "href": "href:207", - "id": "id:208", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.128.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:21.000Z", - "href": "href:209", - "id": "id:210", - "lifecycle_state": "stable", - "name": "unmixed-qualify-prescribe-railcar", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.5", - "auto_delete": false, - "created_at": "2024-06-25T15:41:21.000Z", - "href": "href:213", - "id": "id:214", - "lifecycle_state": "stable", - "name": "customs-recollect-drippy-primate", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.6", - "auto_delete": false, - "created_at": "2024-06-25T15:41:24.000Z", - "href": "href:217", - "id": "id:218", - "lifecycle_state": "stable", - "name": "uniquely-shelter-gracious-sudden", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:57.000Z", - "href": "href:221", - "id": "id:222", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:40:56.000Z", - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.1.0/24", - "name": "subnet1", - "network_acl": { - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "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-25T15:40:56.000Z", - "href": "href:226", - "id": "id:227", - "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-25T15:40:56.000Z", - "href": "href:228", - "id": "id:229", - "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-25T15:40:56.000Z", - "href": "href:230", - "id": "id:231", - "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-25T15:40:56.000Z", - "href": "href:232", - "id": "id:233", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.1.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:234", - "id": "id:235", - "lifecycle_state": "stable", - "name": "excluded-unfair-jailbird-foil", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.1.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:40.000Z", - "href": "href:238", - "id": "id:239", - "lifecycle_state": "stable", - "name": "affected-johnniecake-monorail-ungraded", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.1.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:56.000Z", - "href": "href:242", - "id": "id:243", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:40:48.000Z", - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.192.0/24", - "name": "subnet30", - "network_acl": { - "crn": "crn:247", - "href": "href:248", - "id": "id:249", - "name": "acl31" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:58", - "id": "id:59", - "name": "probational-herring-undone-daintily", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "reserved_ips": [ - { - "address": "10.240.192.0", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:250", - "id": "id:251", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.1", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:252", - "id": "id:253", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.2", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:254", - "id": "id:255", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.3", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:256", - "id": "id:257", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:01.000Z", - "href": "href:258", - "id": "id:259", - "lifecycle_state": "stable", - "name": "legacy-shore-molecule-barometer", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.192.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:262", - "id": "id:263", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:40:44.000Z", - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.8.0/24", - "name": "subnet4", - "network_acl": { - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.8.0", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:267", - "id": "id:268", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.1", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:269", - "id": "id:270", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.2", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:271", - "id": "id:272", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.3", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:273", - "id": "id:274", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:275", - "id": "id:276", - "lifecycle_state": "stable", - "name": "bagged-posture-glaring-cojoined", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.8.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:16.000Z", - "href": "href:279", - "id": "id:280", - "lifecycle_state": "stable", - "name": "frighten-mystified-freeway-hurtling", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.8.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:283", - "id": "id:284", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - } - ], - "public_gateways": [], - "floating_ips": [ - { - "address": "52.118.151.238", - "created_at": "2024-06-25T15:43:30.000Z", - "crn": "crn:285", - "href": "href:286", - "id": "id:287", - "name": "fip-0-subnet0", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - }, - { - "address": "150.239.167.146", - "created_at": "2024-06-25T15:41:59.000Z", - "crn": "crn:288", - "href": "href:289", - "id": "id:290", - "name": "fip-0-subnet10", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "tags": [] - }, - { - "address": "169.48.95.165", - "created_at": "2024-06-25T15:41:50.000Z", - "crn": "crn:291", - "href": "href:292", - "id": "id:293", - "name": "fip-0-subnet20", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "tags": [] - }, - { - "address": "52.118.100.239", - "created_at": "2024-06-25T15:41:33.000Z", - "crn": "crn:294", - "href": "href:295", - "id": "id:296", - "name": "fip-0-subnet30", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "tags": [] - } - ], - "network_acls": [ - { - "created_at": "2024-06-25T15:40:41.000Z", - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "deny", - "before": { - "href": "href:299", - "id": "id:300", - "name": "acl11-out-2" - }, - "created_at": "2024-06-25T15:40:42.000Z", - "destination": "10.240.4.0/24", - "direction": "outbound", - "href": "href:297", - "id": "id:298", - "ip_version": "ipv4", - "name": "acl11-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:301", - "id": "id:302", - "name": "acl11-in-1" - }, - "created_at": "2024-06-25T15:40:43.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:299", - "id": "id:300", - "ip_version": "ipv4", - "name": "acl11-out-2", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:43.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:301", - "id": "id:302", - "ip_version": "ipv4", - "name": "acl11-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:247", - "href": "href:248", - "id": "id:249", - "name": "acl31", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:305", - "id": "id:306", - "name": "acl31-in-1" - }, - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:303", - "id": "id:304", - "ip_version": "ipv4", - "name": "acl31-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:305", - "id": "id:306", - "ip_version": "ipv4", - "name": "acl31-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:198", - "href": "href:199", - "id": "id:200", - "name": "acl21", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:309", - "id": "id:310", - "name": "acl21-in-1" - }, - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:307", - "id": "id:308", - "ip_version": "ipv4", - "name": "acl21-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:42.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:309", - "id": "id:310", - "ip_version": "ipv4", - "name": "acl21-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:38.000Z", - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:313", - "id": "id:314", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:311", - "id": "id:312", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:39.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:313", - "id": "id:314", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:317", - "id": "id:318", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:315", - "id": "id:316", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:317", - "id": "id:318", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:321", - "id": "id:322", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:319", - "id": "id:320", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:321", - "id": "id:322", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "automaker-castle-bird-worried", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:325", - "id": "id:326", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:20.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:323", - "id": "id:324", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:20.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:325", - "id": "id:326", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:42", - "href": "href:43", - "id": "id:44", - "name": "afoot-grape-fineness-zestfully", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:329", - "id": "id:330", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:327", - "id": "id:328", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:329", - "id": "id:330", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:25", - "href": "href:26", - "id": "id:27", - "name": "ebullient-slacks-revert-turkey", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:333", - "id": "id:334", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:331", - "id": "id:332", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:333", - "id": "id:334", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:55", - "href": "href:56", - "id": "id:57", - "name": "untracked-repayment-triumph-cat", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:337", - "id": "id:338", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:335", - "id": "id:336", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:337", - "id": "id:338", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "security_groups": [ - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:342", - "id": "id:343", - "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:344", - "id": "id:345", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "resource_type": "network_interface" - }, - { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "resource_type": "network_interface" - }, - { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:346", - "href": "href:347", - "id": "id:348", - "name": "sg31", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:349", - "id": "id:350", - "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:351", - "id": "id:352", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:356", - "id": "id:357", - "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:358", - "id": "id:359", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "resource_type": "network_interface" - }, - { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:363", - "id": "id:364", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - }, - { - "direction": "outbound", - "href": "href:365", - "id": "id:366", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "resource_type": "network_interface" - }, - { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "resource_type": "network_interface" - }, - { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "resource_type": "network_interface" - }, - { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "resource_type": "network_interface" - }, - { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "resource_type": "network_interface" - }, - { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "resource_type": "network_interface" - }, - { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "resource_type": "network_interface" - }, - { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "resource_type": "network_interface" - }, - { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "resource_type": "network_interface" - }, - { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "resource_type": "network_interface" - }, - { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "resource_type": "network_interface" - }, - { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:367", - "id": "id:368", - "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:369", - "id": "id:370", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:371", - "id": "id:372", - "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:373", - "id": "id:374", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:375", - "id": "id:376", - "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:377", - "id": "id:378", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:379", - "id": "id:380", - "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:381", - "id": "id:382", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "endpoint_gateways": [], - "instances": [ - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:388" - }, - "href": "href:386", - "id": "id:387", - "name": "thief-monastery-blinks-verdict", - "volume": { - "crn": "crn:389", - "href": "href:390", - "id": "id:391", - "name": "scrabble-gorged-baton-angled", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:40.000Z", - "crn": "crn:383", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:384", - "id": "id:385", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "primary_ip": { - "address": "10.240.1.5", - "href": "href:238", - "id": "id:239", - "name": "affected-johnniecake-monorail-ungraded", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:388" - }, - "href": "href:386", - "id": "id:387", - "name": "thief-monastery-blinks-verdict", - "volume": { - "crn": "crn:389", - "href": "href:390", - "id": "id:391", - "name": "scrabble-gorged-baton-angled", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:40.000Z", - "floating_ips": [], - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.1.5", - "href": "href:238", - "id": "id:239", - "name": "affected-johnniecake-monorail-ungraded", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:401" - }, - "href": "href:399", - "id": "id:400", - "name": "hunchback-enginous-dividend-atrium", - "volume": { - "crn": "crn:402", - "href": "href:403", - "id": "id:404", - "name": "subsoil-bobble-bovine-unmoving", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:39.000Z", - "crn": "crn:396", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:397", - "id": "id:398", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet0", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "primary_ip": { - "address": "10.240.0.5", - "href": "href:131", - "id": "id:132", - "name": "relatable-antiques-maturing-brulee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:401" - }, - "href": "href:399", - "id": "id:400", - "name": "hunchback-enginous-dividend-atrium", - "volume": { - "crn": "crn:402", - "href": "href:403", - "id": "id:404", - "name": "subsoil-bobble-bovine-unmoving", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:39.000Z", - "floating_ips": [], - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.5", - "href": "href:131", - "id": "id:132", - "name": "relatable-antiques-maturing-brulee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:410" - }, - "href": "href:408", - "id": "id:409", - "name": "laboring-overbuilt-growl-headland", - "volume": { - "crn": "crn:411", - "href": "href:412", - "id": "id:413", - "name": "tamper-salvaging-stick-giddily", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:22.000Z", - "crn": "crn:405", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:406", - "id": "id:407", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "primary_ip": { - "address": "10.240.4.5", - "href": "href:172", - "id": "id:173", - "name": "bark-gatherer-rope-unrivaled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:410" - }, - "href": "href:408", - "id": "id:409", - "name": "laboring-overbuilt-growl-headland", - "volume": { - "crn": "crn:411", - "href": "href:412", - "id": "id:413", - "name": "tamper-salvaging-stick-giddily", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:22.000Z", - "floating_ips": [], - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.4.5", - "href": "href:172", - "id": "id:173", - "name": "bark-gatherer-rope-unrivaled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:419" - }, - "href": "href:417", - "id": "id:418", - "name": "dollop-partition-helping-palmtree", - "volume": { - "crn": "crn:420", - "href": "href:421", - "id": "id:422", - "name": "ravage-deny-amusable-settling", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:20.000Z", - "crn": "crn:414", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:415", - "id": "id:416", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet5", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "primary_ip": { - "address": "10.240.9.5", - "href": "href:83", - "id": "id:84", - "name": "outskirts-unaligned-passivism-parchment", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:419" - }, - "href": "href:417", - "id": "id:418", - "name": "dollop-partition-helping-palmtree", - "volume": { - "crn": "crn:420", - "href": "href:421", - "id": "id:422", - "name": "ravage-deny-amusable-settling", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:20.000Z", - "floating_ips": [], - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.9.5", - "href": "href:83", - "id": "id:84", - "name": "outskirts-unaligned-passivism-parchment", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:428" - }, - "href": "href:426", - "id": "id:427", - "name": "petted-ethanol-voicing-rocklike", - "volume": { - "crn": "crn:429", - "href": "href:430", - "id": "id:431", - "name": "uptown-striving-unrevised-earthlike", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:20.000Z", - "crn": "crn:423", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:424", - "id": "id:425", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "primary_ip": { - "address": "10.240.4.4", - "href": "href:168", - "id": "id:169", - "name": "stood-sitcom-whoops-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:428" - }, - "href": "href:426", - "id": "id:427", - "name": "petted-ethanol-voicing-rocklike", - "volume": { - "crn": "crn:429", - "href": "href:430", - "id": "id:431", - "name": "uptown-striving-unrevised-earthlike", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:20.000Z", - "floating_ips": [], - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.4.4", - "href": "href:168", - "id": "id:169", - "name": "stood-sitcom-whoops-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:437" - }, - "href": "href:435", - "id": "id:436", - "name": "promenade-spyglass-flattop-pushpin", - "volume": { - "crn": "crn:438", - "href": "href:439", - "id": "id:440", - "name": "relax-shaded-prism-jaunt", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:16.000Z", - "crn": "crn:432", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:433", - "id": "id:434", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet3", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "primary_ip": { - "address": "10.240.5.5", - "href": "href:107", - "id": "id:108", - "name": "recognize-citable-exerciser-unsecured", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:437" - }, - "href": "href:435", - "id": "id:436", - "name": "promenade-spyglass-flattop-pushpin", - "volume": { - "crn": "crn:438", - "href": "href:439", - "id": "id:440", - "name": "relax-shaded-prism-jaunt", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:16.000Z", - "floating_ips": [], - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.5.5", - "href": "href:107", - "id": "id:108", - "name": "recognize-citable-exerciser-unsecured", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:446" - }, - "href": "href:444", - "id": "id:445", - "name": "sandbox-federal-sculptor-jugum", - "volume": { - "crn": "crn:447", - "href": "href:448", - "id": "id:449", - "name": "convent-ramrod-cloning-afterward", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:15.000Z", - "crn": "crn:441", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:442", - "id": "id:443", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet4", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "primary_ip": { - "address": "10.240.8.5", - "href": "href:279", - "id": "id:280", - "name": "frighten-mystified-freeway-hurtling", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:446" - }, - "href": "href:444", - "id": "id:445", - "name": "sandbox-federal-sculptor-jugum", - "volume": { - "crn": "crn:447", - "href": "href:448", - "id": "id:449", - "name": "convent-ramrod-cloning-afterward", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:15.000Z", - "floating_ips": [], - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.8.5", - "href": "href:279", - "id": "id:280", - "name": "frighten-mystified-freeway-hurtling", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:455" - }, - "href": "href:453", - "id": "id:454", - "name": "affidavit-chastise-elsewhere-viewer", - "volume": { - "crn": "crn:456", - "href": "href:457", - "id": "id:458", - "name": "fancy-destiny-shuffling-sandbank", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:07.000Z", - "crn": "crn:450", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:451", - "id": "id:452", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet0", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:455" - }, - "href": "href:453", - "id": "id:454", - "name": "affidavit-chastise-elsewhere-viewer", - "volume": { - "crn": "crn:456", - "href": "href:457", - "id": "id:458", - "name": "fancy-destiny-shuffling-sandbank", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:07.000Z", - "floating_ips": [ - { - "address": "52.118.151.238", - "crn": "crn:285", - "href": "href:286", - "id": "id:287", - "name": "fip-0-subnet0" - } - ], - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:464" - }, - "href": "href:462", - "id": "id:463", - "name": "uneven-armoire-scabiosa-letter", - "volume": { - "crn": "crn:465", - "href": "href:466", - "id": "id:467", - "name": "cognition-blinks-humid-oxidant", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:459", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:460", - "id": "id:461", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet3", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "primary_ip": { - "address": "10.240.5.4", - "href": "href:103", - "id": "id:104", - "name": "rising-gopher-reentry-graveness", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:464" - }, - "href": "href:462", - "id": "id:463", - "name": "uneven-armoire-scabiosa-letter", - "volume": { - "crn": "crn:465", - "href": "href:466", - "id": "id:467", - "name": "cognition-blinks-humid-oxidant", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.5.4", - "href": "href:103", - "id": "id:104", - "name": "rising-gopher-reentry-graveness", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:473" - }, - "href": "href:471", - "id": "id:472", - "name": "perplexed-impulsivity-august-jaws", - "volume": { - "crn": "crn:474", - "href": "href:475", - "id": "id:476", - "name": "tartar-sixties-fructose-parmesan", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:468", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:469", - "id": "id:470", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "primary_ip": { - "address": "10.240.1.4", - "href": "href:234", - "id": "id:235", - "name": "excluded-unfair-jailbird-foil", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:473" - }, - "href": "href:471", - "id": "id:472", - "name": "perplexed-impulsivity-august-jaws", - "volume": { - "crn": "crn:474", - "href": "href:475", - "id": "id:476", - "name": "tartar-sixties-fructose-parmesan", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.1.4", - "href": "href:234", - "id": "id:235", - "name": "excluded-unfair-jailbird-foil", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:482" - }, - "href": "href:480", - "id": "id:481", - "name": "litter-snipping-unclasp-dust", - "volume": { - "crn": "crn:483", - "href": "href:484", - "id": "id:485", - "name": "untried-sulphate-hypnosis-subsidize", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:477", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:478", - "id": "id:479", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet4", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "primary_ip": { - "address": "10.240.8.4", - "href": "href:275", - "id": "id:276", - "name": "bagged-posture-glaring-cojoined", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:482" - }, - "href": "href:480", - "id": "id:481", - "name": "litter-snipping-unclasp-dust", - "volume": { - "crn": "crn:483", - "href": "href:484", - "id": "id:485", - "name": "untried-sulphate-hypnosis-subsidize", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.8.4", - "href": "href:275", - "id": "id:276", - "name": "bagged-posture-glaring-cojoined", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:491" - }, - "href": "href:489", - "id": "id:490", - "name": "unlawful-overreach-yarn-rippling", - "volume": { - "crn": "crn:492", - "href": "href:493", - "id": "id:494", - "name": "finer-voter-roving-jailer", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:486", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:487", - "id": "id:488", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet5", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "primary_ip": { - "address": "10.240.9.4", - "href": "href:79", - "id": "id:80", - "name": "ideally-grain-bagpipe-luxuriant", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:491" - }, - "href": "href:489", - "id": "id:490", - "name": "unlawful-overreach-yarn-rippling", - "volume": { - "crn": "crn:492", - "href": "href:493", - "id": "id:494", - "name": "finer-voter-roving-jailer", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.9.4", - "href": "href:79", - "id": "id:80", - "name": "ideally-grain-bagpipe-luxuriant", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:500" - }, - "href": "href:498", - "id": "id:499", - "name": "mashed-thing-headache-estate", - "volume": { - "crn": "crn:501", - "href": "href:502", - "id": "id:503", - "name": "mountain-harpist-libraries-dreaming", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:39.000Z", - "crn": "crn:495", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:496", - "id": "id:497", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet11", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "primary_ip": { - "address": "10.240.80.4", - "href": "href:151", - "id": "id:152", - "name": "childlike-publish-retainer-movie", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:500" - }, - "href": "href:498", - "id": "id:499", - "name": "mashed-thing-headache-estate", - "volume": { - "crn": "crn:501", - "href": "href:502", - "id": "id:503", - "name": "mountain-harpist-libraries-dreaming", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:39.000Z", - "floating_ips": [], - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.80.4", - "href": "href:151", - "id": "id:152", - "name": "childlike-publish-retainer-movie", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11" - } - ], - "status": "available", - "subnet": { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:509" - }, - "href": "href:507", - "id": "id:508", - "name": "calzone-cacti-moonlight-subarctic", - "volume": { - "crn": "crn:510", - "href": "href:511", - "id": "id:512", - "name": "blurred-dream-pectin-tapping", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:36.000Z", - "crn": "crn:504", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:505", - "id": "id:506", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet10", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:509" - }, - "href": "href:507", - "id": "id:508", - "name": "calzone-cacti-moonlight-subarctic", - "volume": { - "crn": "crn:510", - "href": "href:511", - "id": "id:512", - "name": "blurred-dream-pectin-tapping", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:36.000Z", - "floating_ips": [ - { - "address": "150.239.167.146", - "crn": "crn:288", - "href": "href:289", - "id": "id:290", - "name": "fip-0-subnet10" - } - ], - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11" - } - ], - "status": "available", - "subnet": { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:518" - }, - "href": "href:516", - "id": "id:517", - "name": "recoup-blinks-ebullient-renewed", - "volume": { - "crn": "crn:519", - "href": "href:520", - "id": "id:521", - "name": "manmade-unequal-disinfect-cone", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:24.000Z", - "crn": "crn:513", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:514", - "id": "id:515", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:518" - }, - "href": "href:516", - "id": "id:517", - "name": "recoup-blinks-ebullient-renewed", - "volume": { - "crn": "crn:519", - "href": "href:520", - "id": "id:521", - "name": "manmade-unequal-disinfect-cone", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:24.000Z", - "floating_ips": [ - { - "address": "169.48.95.165", - "crn": "crn:291", - "href": "href:292", - "id": "id:293", - "name": "fip-0-subnet20" - } - ], - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:527" - }, - "href": "href:525", - "id": "id:526", - "name": "radio-tightrope-outtakes-moonshine", - "volume": { - "crn": "crn:528", - "href": "href:529", - "id": "id:530", - "name": "tattoo-crescent-unwary-hayride", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:21.000Z", - "crn": "crn:522", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:523", - "id": "id:524", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "primary_ip": { - "address": "10.240.128.5", - "href": "href:213", - "id": "id:214", - "name": "customs-recollect-drippy-primate", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:527" - }, - "href": "href:525", - "id": "id:526", - "name": "radio-tightrope-outtakes-moonshine", - "volume": { - "crn": "crn:528", - "href": "href:529", - "id": "id:530", - "name": "tattoo-crescent-unwary-hayride", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:21.000Z", - "floating_ips": [], - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.5", - "href": "href:213", - "id": "id:214", - "name": "customs-recollect-drippy-primate", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:536" - }, - "href": "href:534", - "id": "id:535", - "name": "crumpet-ride-tastiness-phoney", - "volume": { - "crn": "crn:537", - "href": "href:538", - "id": "id:539", - "name": "doorframe-marvelous-refusing-citable", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:21.000Z", - "crn": "crn:531", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:532", - "id": "id:533", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi2-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "primary_ip": { - "address": "10.240.128.4", - "href": "href:209", - "id": "id:210", - "name": "unmixed-qualify-prescribe-railcar", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:536" - }, - "href": "href:534", - "id": "id:535", - "name": "crumpet-ride-tastiness-phoney", - "volume": { - "crn": "crn:537", - "href": "href:538", - "id": "id:539", - "name": "doorframe-marvelous-refusing-citable", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:21.000Z", - "floating_ips": [], - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.4", - "href": "href:209", - "id": "id:210", - "name": "unmixed-qualify-prescribe-railcar", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:545" - }, - "href": "href:543", - "id": "id:544", - "name": "bronzing-vendor-plod-pretzel", - "volume": { - "crn": "crn:546", - "href": "href:547", - "id": "id:548", - "name": "squelch-plop-headlamp-ideologue", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:00.000Z", - "crn": "crn:540", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:541", - "id": "id:542", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet30", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:545" - }, - "href": "href:543", - "id": "id:544", - "name": "bronzing-vendor-plod-pretzel", - "volume": { - "crn": "crn:546", - "href": "href:547", - "id": "id:548", - "name": "squelch-plop-headlamp-ideologue", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:00.000Z", - "floating_ips": [ - { - "address": "52.118.100.239", - "crn": "crn:294", - "href": "href:295", - "id": "id:296", - "name": "fip-0-subnet30" - } - ], - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:346", - "href": "href:347", - "id": "id:348", - "name": "sg31" - } - ], - "status": "available", - "subnet": { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - } - ], - "routing_tables": [ - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:20.000Z", - "href": "href:11", - "id": "id:12", - "is_default": true, - "lifecycle_state": "stable", - "name": "overtone-sputter-overspend-gorge", - "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:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:28", - "id": "id:29", - "is_default": true, - "lifecycle_state": "stable", - "name": "escapade-dynamite-upstage-context", - "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:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:45", - "id": "id:46", - "is_default": true, - "lifecycle_state": "stable", - "name": "quintuple-severity-caddie-manuals", - "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:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:58", - "id": "id:59", - "is_default": true, - "lifecycle_state": "stable", - "name": "probational-herring-undone-daintily", - "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:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - } - } - ], - "load_balancers": [], - "transit_connections": [ - { - "created_at": "2024-06-25T15:41:44.212Z", - "id": "id:549", - "name": "tg3_connection3", - "network_id": "crn:52", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:550", - "id": "id:551", - "name": "local-tg3" - }, - "updated_at": "2024-06-25T15:45:14.206Z" - }, - { - "created_at": "2024-06-25T15:41:54.416Z", - "id": "id:552", - "name": "tg3_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:550", - "id": "id:551", - "name": "local-tg3" - }, - "updated_at": "2024-06-25T15:45:53.979Z" - }, - { - "created_at": "2024-06-25T15:42:54.772Z", - "id": "id:553", - "name": "tg2_connection3", - "network_id": "crn:52", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:08.822Z" - }, - { - "created_at": "2024-06-25T15:43:11.555Z", - "id": "id:556", - "name": "tg2_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters": [ - { - "action": "deny", - "created_at": "2024-06-25T15:46:46.641Z", - "id": "id:557", - "le": 32, - "prefix": "10.240.0.0/22", - "updated_at": "2024-06-25T15:46:46.641Z" - } - ], - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:59.395Z" - }, - { - "created_at": "2024-06-25T15:43:12.159Z", - "id": "id:558", - "name": "tg_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters": [ - { - "action": "deny", - "before": "298db67f-2e68-4548-93b9-949f8356d4a0", - "created_at": "2024-06-25T15:45:14.711Z", - "id": "id:559", - "prefix": "10.240.4.0/22", - "updated_at": "2024-06-25T15:45:14.711Z" - }, - { - "action": "deny", - "created_at": "2024-06-25T15:45:25.435Z", - "id": "id:560", - "prefix": "10.240.8.0/22", - "updated_at": "2024-06-25T15:45:25.435Z" - } - ], - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:49:53.837Z" - }, - { - "created_at": "2024-06-25T15:43:41.079Z", - "id": "id:563", - "name": "tg2_connection2", - "network_id": "crn:39", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:43.192Z" - }, - { - "created_at": "2024-06-25T15:43:42.335Z", - "id": "id:564", - "name": "tg1_connection1", - "network_id": "crn:1", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:48:45.229Z" - }, - { - "created_at": "2024-06-25T15:44:08.995Z", - "id": "id:565", - "name": "tg1_connection2", - "network_id": "crn:39", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:49:11.976Z" - } - ], - "transit_gateways": [ - { - "id": "id:551", - "crn": "crn:550", - "name": "local-tg3", - "location": "us-south", - "created_at": "2024-06-25T15:40:21.390Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:42:12.752Z" - }, - { - "id": "id:555", - "crn": "crn:554", - "name": "local-tg2", - "location": "us-south", - "created_at": "2024-06-25T15:40:25.895Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:43:58.196Z" - }, - { - "id": "id:562", - "crn": "crn:561", - "name": "local-tg1", - "location": "us-south", - "created_at": "2024-06-25T15:40:26.455Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:43:15.331Z" - } - ], - "iks_clusters": [] -} diff --git a/test/data/sg_tg_multiple/config_object.json b/test/data/sg_tg_multiple/config_object.json deleted file mode 100644 index 7e94d3b8..00000000 --- a/test/data/sg_tg_multiple/config_object.json +++ /dev/null @@ -1,6269 +0,0 @@ -{ - "collector_version": "0.11.0", - "provider": "ibm", - "vpcs": [ - { - "classic_access": false, - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:1", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.215.5" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.220.2" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.249.82.12" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "automaker-castle-bird-worried" - }, - "default_routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole" - }, - "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": "test-vpc1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.80.0/20", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:18", - "id": "id:19", - "is_default": false, - "name": "address-prefix-vpc-1", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "cidr": "10.240.64.0/20", - "created_at": "2024-06-25T15:40:40.000Z", - "has_subnets": true, - "href": "href:20", - "id": "id:21", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:6", - "name": "us-south-2" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:22", - "cse_source_ips": [ - { - "ip": { - "address": "10.16.238.56" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.249.200.205" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.249.212.88" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:25", - "href": "href:26", - "id": "id:27", - "name": "ebullient-slacks-revert-turkey" - }, - "default_routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam" - }, - "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:23", - "id": "id:24", - "name": "test-vpc0", - "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/22", - "created_at": "2024-06-25T15:40:37.000Z", - "has_subnets": true, - "href": "href:33", - "id": "id:34", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.4.0/22", - "created_at": "2024-06-25T15:40:38.000Z", - "has_subnets": true, - "href": "href:35", - "id": "id:36", - "is_default": false, - "name": "address-prefix-vpc-1", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "cidr": "10.240.8.0/22", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:37", - "id": "id:38", - "is_default": false, - "name": "address-prefix-vpc-2", - "zone": { - "href": "href:5", - "name": "us-south-1" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:39", - "cse_source_ips": [ - { - "ip": { - "address": "10.12.125.16" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.22.27.134" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.22.231.90" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:42", - "href": "href:43", - "id": "id:44", - "name": "afoot-grape-fineness-zestfully" - }, - "default_routing_table": { - "href": "href:45", - "id": "id:46", - "name": "quintuple-severity-caddie-manuals", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll" - }, - "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:40", - "id": "id:41", - "name": "test-vpc2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.128.0/20", - "created_at": "2024-06-25T15:40:39.000Z", - "has_subnets": true, - "href": "href:50", - "id": "id:51", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - }, - { - "classic_access": false, - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:52", - "cse_source_ips": [ - { - "ip": { - "address": "10.22.219.155" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - } - }, - { - "ip": { - "address": "10.12.159.11" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - } - }, - { - "ip": { - "address": "10.16.253.109" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "default_network_acl": { - "crn": "crn:55", - "href": "href:56", - "id": "id:57", - "name": "untracked-repayment-triumph-cat" - }, - "default_routing_table": { - "href": "href:58", - "id": "id:59", - "name": "probational-herring-undone-daintily", - "resource_type": "routing_table" - }, - "default_security_group": { - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely" - }, - "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:53", - "id": "id:54", - "name": "test-vpc3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "vpc", - "status": "available", - "region": "us-south", - "address_prefixes": [ - { - "cidr": "10.240.192.0/20", - "created_at": "2024-06-25T15:40:38.000Z", - "has_subnets": true, - "href": "href:63", - "id": "id:64", - "is_default": false, - "name": "address-prefix-vpc-0", - "zone": { - "href": "href:7", - "name": "us-south-3" - } - } - ], - "tags": [] - } - ], - "subnets": [ - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:47.000Z", - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.9.0/24", - "name": "subnet5", - "network_acl": { - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.9.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:71", - "id": "id:72", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:73", - "id": "id:74", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:75", - "id": "id:76", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:77", - "id": "id:78", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.9.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:79", - "id": "id:80", - "lifecycle_state": "stable", - "name": "ideally-grain-bagpipe-luxuriant", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.9.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:20.000Z", - "href": "href:83", - "id": "id:84", - "lifecycle_state": "stable", - "name": "outskirts-unaligned-passivism-parchment", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.9.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:47.000Z", - "href": "href:87", - "id": "id:88", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:35.000Z", - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.5.0/24", - "name": "subnet3", - "network_acl": { - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.5.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:95", - "id": "id:96", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:97", - "id": "id:98", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:99", - "id": "id:100", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:101", - "id": "id:102", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.5.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:103", - "id": "id:104", - "lifecycle_state": "stable", - "name": "rising-gopher-reentry-graveness", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.5.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:16.000Z", - "href": "href:107", - "id": "id:108", - "lifecycle_state": "stable", - "name": "recognize-citable-exerciser-unsecured", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.5.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:35.000Z", - "href": "href:111", - "id": "id:112", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:23.000Z", - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.0.0/24", - "name": "subnet0", - "network_acl": { - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.0.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:119", - "id": "id:120", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:121", - "id": "id:122", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:123", - "id": "id:124", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:125", - "id": "id:126", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.0.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:08.000Z", - "href": "href:127", - "id": "id:128", - "lifecycle_state": "stable", - "name": "pundit-tight-arbitrate-grace", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:39.000Z", - "href": "href:131", - "id": "id:132", - "lifecycle_state": "stable", - "name": "relatable-antiques-maturing-brulee", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.0.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:23.000Z", - "href": "href:135", - "id": "id:136", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:41:20.000Z", - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.80.0/24", - "name": "subnet11", - "network_acl": { - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "reserved_ips": [ - { - "address": "10.240.80.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:143", - "id": "id:144", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:145", - "id": "id:146", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:147", - "id": "id:148", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:149", - "id": "id:150", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.80.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:40.000Z", - "href": "href:151", - "id": "id:152", - "lifecycle_state": "stable", - "name": "childlike-publish-retainer-movie", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.80.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:20.000Z", - "href": "href:155", - "id": "id:156", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:41:08.000Z", - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.4.0/24", - "name": "subnet2", - "network_acl": { - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.4.0", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:160", - "id": "id:161", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.1", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:162", - "id": "id:163", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.2", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:164", - "id": "id:165", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.3", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:166", - "id": "id:167", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.4.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:21.000Z", - "href": "href:168", - "id": "id:169", - "lifecycle_state": "stable", - "name": "stood-sitcom-whoops-hurled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.4.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:22.000Z", - "href": "href:172", - "id": "id:173", - "lifecycle_state": "stable", - "name": "bark-gatherer-rope-unrivaled", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.4.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:176", - "id": "id:177", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:41:08.000Z", - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.64.0/24", - "name": "subnet10", - "network_acl": { - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:11", - "id": "id:12", - "name": "overtone-sputter-overspend-gorge", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "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-25T15:41:08.000Z", - "href": "href:181", - "id": "id:182", - "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-25T15:41:08.000Z", - "href": "href:183", - "id": "id:184", - "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-25T15:41:08.000Z", - "href": "href:185", - "id": "id:186", - "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-25T15:41:08.000Z", - "href": "href:187", - "id": "id:188", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.64.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:36.000Z", - "href": "href:189", - "id": "id:190", - "lifecycle_state": "stable", - "name": "starry-smasher-ladle-dioxide", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.64.255", - "auto_delete": false, - "created_at": "2024-06-25T15:41:08.000Z", - "href": "href:193", - "id": "id:194", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 248, - "created_at": "2024-06-25T15:40:57.000Z", - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.128.0/24", - "name": "subnet20", - "network_acl": { - "crn": "crn:198", - "href": "href:199", - "id": "id:200", - "name": "acl21" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:45", - "id": "id:46", - "name": "quintuple-severity-caddie-manuals", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "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-25T15:40:57.000Z", - "href": "href:201", - "id": "id:202", - "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-25T15:40:57.000Z", - "href": "href:203", - "id": "id:204", - "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-25T15:40:57.000Z", - "href": "href:205", - "id": "id:206", - "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-25T15:40:57.000Z", - "href": "href:207", - "id": "id:208", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.128.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:21.000Z", - "href": "href:209", - "id": "id:210", - "lifecycle_state": "stable", - "name": "unmixed-qualify-prescribe-railcar", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.5", - "auto_delete": false, - "created_at": "2024-06-25T15:41:21.000Z", - "href": "href:213", - "id": "id:214", - "lifecycle_state": "stable", - "name": "customs-recollect-drippy-primate", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.6", - "auto_delete": false, - "created_at": "2024-06-25T15:41:24.000Z", - "href": "href:217", - "id": "id:218", - "lifecycle_state": "stable", - "name": "uniquely-shelter-gracious-sudden", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.128.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:57.000Z", - "href": "href:221", - "id": "id:222", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:40:56.000Z", - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.1.0/24", - "name": "subnet1", - "network_acl": { - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "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-25T15:40:56.000Z", - "href": "href:226", - "id": "id:227", - "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-25T15:40:56.000Z", - "href": "href:228", - "id": "id:229", - "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-25T15:40:56.000Z", - "href": "href:230", - "id": "id:231", - "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-25T15:40:56.000Z", - "href": "href:232", - "id": "id:233", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.1.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:234", - "id": "id:235", - "lifecycle_state": "stable", - "name": "excluded-unfair-jailbird-foil", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.1.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:40.000Z", - "href": "href:238", - "id": "id:239", - "lifecycle_state": "stable", - "name": "affected-johnniecake-monorail-ungraded", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.1.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:56.000Z", - "href": "href:242", - "id": "id:243", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 250, - "created_at": "2024-06-25T15:40:48.000Z", - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.192.0/24", - "name": "subnet30", - "network_acl": { - "crn": "crn:247", - "href": "href:248", - "id": "id:249", - "name": "acl31" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:58", - "id": "id:59", - "name": "probational-herring-undone-daintily", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "reserved_ips": [ - { - "address": "10.240.192.0", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:250", - "id": "id:251", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.1", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:252", - "id": "id:253", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.2", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:254", - "id": "id:255", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.3", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:256", - "id": "id:257", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.192.4", - "auto_delete": false, - "created_at": "2024-06-25T15:41:01.000Z", - "href": "href:258", - "id": "id:259", - "lifecycle_state": "stable", - "name": "legacy-shore-molecule-barometer", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.192.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:48.000Z", - "href": "href:262", - "id": "id:263", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - }, - { - "available_ipv4_address_count": 249, - "created_at": "2024-06-25T15:40:44.000Z", - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "ip_version": "ipv4", - "ipv4_cidr_block": "10.240.8.0/24", - "name": "subnet4", - "network_acl": { - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3" - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "subnet", - "routing_table": { - "href": "href:28", - "id": "id:29", - "name": "escapade-dynamite-upstage-context", - "resource_type": "routing_table" - }, - "status": "available", - "total_ipv4_address_count": 256, - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "reserved_ips": [ - { - "address": "10.240.8.0", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:267", - "id": "id:268", - "lifecycle_state": "stable", - "name": "ibm-network-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.1", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:269", - "id": "id:270", - "lifecycle_state": "stable", - "name": "ibm-default-gateway", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.2", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:271", - "id": "id:272", - "lifecycle_state": "stable", - "name": "ibm-dns-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.3", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:273", - "id": "id:274", - "lifecycle_state": "stable", - "name": "ibm-reserved-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - }, - { - "address": "10.240.8.4", - "auto_delete": false, - "created_at": "2024-06-25T15:42:00.000Z", - "href": "href:275", - "id": "id:276", - "lifecycle_state": "stable", - "name": "bagged-posture-glaring-cojoined", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.8.5", - "auto_delete": false, - "created_at": "2024-06-25T15:42:16.000Z", - "href": "href:279", - "id": "id:280", - "lifecycle_state": "stable", - "name": "frighten-mystified-freeway-hurtling", - "owner": "user", - "resource_type": "subnet_reserved_ip", - "target": { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "resource_type": "network_interface" - } - }, - { - "address": "10.240.8.255", - "auto_delete": false, - "created_at": "2024-06-25T15:40:44.000Z", - "href": "href:283", - "id": "id:284", - "lifecycle_state": "stable", - "name": "ibm-broadcast-address", - "owner": "provider", - "resource_type": "subnet_reserved_ip" - } - ], - "tags": [] - } - ], - "public_gateways": [], - "floating_ips": [ - { - "address": "52.118.151.238", - "created_at": "2024-06-25T15:43:30.000Z", - "crn": "crn:285", - "href": "href:286", - "id": "id:287", - "name": "fip-0-subnet0", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "tags": [] - }, - { - "address": "150.239.167.146", - "created_at": "2024-06-25T15:41:59.000Z", - "crn": "crn:288", - "href": "href:289", - "id": "id:290", - "name": "fip-0-subnet10", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "tags": [] - }, - { - "address": "169.48.95.165", - "created_at": "2024-06-25T15:41:50.000Z", - "crn": "crn:291", - "href": "href:292", - "id": "id:293", - "name": "fip-0-subnet20", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "tags": [] - }, - { - "address": "52.118.100.239", - "created_at": "2024-06-25T15:41:33.000Z", - "crn": "crn:294", - "href": "href:295", - "id": "id:296", - "name": "fip-0-subnet30", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "status": "available", - "target": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "tags": [] - } - ], - "network_acls": [ - { - "created_at": "2024-06-25T15:40:41.000Z", - "crn": "crn:140", - "href": "href:141", - "id": "id:142", - "name": "acl11", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "deny", - "before": { - "href": "href:299", - "id": "id:300", - "name": "acl11-out-2" - }, - "created_at": "2024-06-25T15:40:42.000Z", - "destination": "10.240.4.0/24", - "direction": "outbound", - "href": "href:297", - "id": "id:298", - "ip_version": "ipv4", - "name": "acl11-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "before": { - "href": "href:301", - "id": "id:302", - "name": "acl11-in-1" - }, - "created_at": "2024-06-25T15:40:43.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:299", - "id": "id:300", - "ip_version": "ipv4", - "name": "acl11-out-2", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:43.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:301", - "id": "id:302", - "ip_version": "ipv4", - "name": "acl11-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:247", - "href": "href:248", - "id": "id:249", - "name": "acl31", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:305", - "id": "id:306", - "name": "acl31-in-1" - }, - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:303", - "id": "id:304", - "ip_version": "ipv4", - "name": "acl31-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:305", - "id": "id:306", - "ip_version": "ipv4", - "name": "acl31-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:198", - "href": "href:199", - "id": "id:200", - "name": "acl21", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:309", - "id": "id:310", - "name": "acl21-in-1" - }, - "created_at": "2024-06-25T15:40:41.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:307", - "id": "id:308", - "ip_version": "ipv4", - "name": "acl21-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:42.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:309", - "id": "id:310", - "ip_version": "ipv4", - "name": "acl21-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:38.000Z", - "crn": "crn:92", - "href": "href:93", - "id": "id:94", - "name": "acl2", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:313", - "id": "id:314", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:311", - "id": "id:312", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:39.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:313", - "id": "id:314", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:68", - "href": "href:69", - "id": "id:70", - "name": "acl3", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:317", - "id": "id:318", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:315", - "id": "id:316", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:317", - "id": "id:318", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:116", - "href": "href:117", - "id": "id:118", - "name": "acl1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:321", - "id": "id:322", - "name": "acl1-in-1" - }, - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:319", - "id": "id:320", - "ip_version": "ipv4", - "name": "acl1-out-1", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:38.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:321", - "id": "id:322", - "ip_version": "ipv4", - "name": "acl1-in-1", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [ - { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:8", - "href": "href:9", - "id": "id:10", - "name": "automaker-castle-bird-worried", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:325", - "id": "id:326", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:20.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:323", - "id": "id:324", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:20.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:325", - "id": "id:326", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:42", - "href": "href:43", - "id": "id:44", - "name": "afoot-grape-fineness-zestfully", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:329", - "id": "id:330", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:327", - "id": "id:328", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:329", - "id": "id:330", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:25", - "href": "href:26", - "id": "id:27", - "name": "ebullient-slacks-revert-turkey", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:333", - "id": "id:334", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:331", - "id": "id:332", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:333", - "id": "id:334", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:55", - "href": "href:56", - "id": "id:57", - "name": "untracked-repayment-triumph-cat", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "action": "allow", - "before": { - "href": "href:337", - "id": "id:338", - "name": "allow-outbound" - }, - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", - "href": "href:335", - "id": "id:336", - "ip_version": "ipv4", - "name": "allow-inbound", - "source": "0.0.0.0/0", - "protocol": "all" - }, - { - "action": "allow", - "created_at": "2024-06-25T15:40:19.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", - "href": "href:337", - "id": "id:338", - "ip_version": "ipv4", - "name": "allow-outbound", - "source": "0.0.0.0/0", - "protocol": "all" - } - ], - "subnets": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "security_groups": [ - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:342", - "id": "id:343", - "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:344", - "id": "id:345", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "resource_type": "network_interface" - }, - { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "resource_type": "network_interface" - }, - { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:346", - "href": "href:347", - "id": "id:348", - "name": "sg31", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:349", - "id": "id:350", - "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:351", - "id": "id:352", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:40.000Z", - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:356", - "id": "id:357", - "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:358", - "id": "id:359", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "resource_type": "network_interface" - }, - { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:37.000Z", - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "inbound", - "href": "href:363", - "id": "id:364", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - }, - { - "direction": "outbound", - "href": "href:365", - "id": "id:366", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "cidr_block": "0.0.0.0/0" - }, - "protocol": "all" - } - ], - "targets": [ - { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "resource_type": "network_interface" - }, - { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "resource_type": "network_interface" - }, - { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "resource_type": "network_interface" - }, - { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "resource_type": "network_interface" - }, - { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "resource_type": "network_interface" - }, - { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "resource_type": "network_interface" - }, - { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "resource_type": "network_interface" - }, - { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "resource_type": "network_interface" - }, - { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "resource_type": "network_interface" - }, - { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "resource_type": "network_interface" - }, - { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "resource_type": "network_interface" - }, - { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "resource_type": "network_interface" - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:20.000Z", - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:367", - "id": "id:368", - "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:369", - "id": "id:370", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:13", - "href": "href:14", - "id": "id:15", - "name": "brute-upon-angles-cubbyhole" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:371", - "id": "id:372", - "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:373", - "id": "id:374", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:30", - "href": "href:31", - "id": "id:32", - "name": "basically-drank-bulk-jam" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:375", - "id": "id:376", - "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:377", - "id": "id:378", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:47", - "href": "href:48", - "id": "id:49", - "name": "glance-cactus-unease-bankroll" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "tags": [] - }, - { - "created_at": "2024-06-25T15:40:19.000Z", - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely", - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "rules": [ - { - "direction": "outbound", - "href": "href:379", - "id": "id:380", - "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:381", - "id": "id:382", - "ip_version": "ipv4", - "local": { - "cidr_block": "0.0.0.0/0" - }, - "remote": { - "crn": "crn:60", - "href": "href:61", - "id": "id:62", - "name": "repeater-upcountry-agreeing-acutely" - }, - "protocol": "all" - } - ], - "targets": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "tags": [] - } - ], - "endpoint_gateways": [], - "instances": [ - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:388" - }, - "href": "href:386", - "id": "id:387", - "name": "thief-monastery-blinks-verdict", - "volume": { - "crn": "crn:389", - "href": "href:390", - "id": "id:391", - "name": "scrabble-gorged-baton-angled", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:40.000Z", - "crn": "crn:383", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:384", - "id": "id:385", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "primary_ip": { - "address": "10.240.1.5", - "href": "href:238", - "id": "id:239", - "name": "affected-johnniecake-monorail-ungraded", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:388" - }, - "href": "href:386", - "id": "id:387", - "name": "thief-monastery-blinks-verdict", - "volume": { - "crn": "crn:389", - "href": "href:390", - "id": "id:391", - "name": "scrabble-gorged-baton-angled", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:40.000Z", - "floating_ips": [], - "href": "href:240", - "id": "id:241", - "name": "scale-clambake-endearing-abridged", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.1.5", - "href": "href:238", - "id": "id:239", - "name": "affected-johnniecake-monorail-ungraded", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:401" - }, - "href": "href:399", - "id": "id:400", - "name": "hunchback-enginous-dividend-atrium", - "volume": { - "crn": "crn:402", - "href": "href:403", - "id": "id:404", - "name": "subsoil-bobble-bovine-unmoving", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:39.000Z", - "crn": "crn:396", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:397", - "id": "id:398", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet0", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "primary_ip": { - "address": "10.240.0.5", - "href": "href:131", - "id": "id:132", - "name": "relatable-antiques-maturing-brulee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:401" - }, - "href": "href:399", - "id": "id:400", - "name": "hunchback-enginous-dividend-atrium", - "volume": { - "crn": "crn:402", - "href": "href:403", - "id": "id:404", - "name": "subsoil-bobble-bovine-unmoving", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:39.000Z", - "floating_ips": [], - "href": "href:133", - "id": "id:134", - "name": "consonant-imperial-simply-ceramics", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.5", - "href": "href:131", - "id": "id:132", - "name": "relatable-antiques-maturing-brulee", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:410" - }, - "href": "href:408", - "id": "id:409", - "name": "laboring-overbuilt-growl-headland", - "volume": { - "crn": "crn:411", - "href": "href:412", - "id": "id:413", - "name": "tamper-salvaging-stick-giddily", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:22.000Z", - "crn": "crn:405", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:406", - "id": "id:407", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "primary_ip": { - "address": "10.240.4.5", - "href": "href:172", - "id": "id:173", - "name": "bark-gatherer-rope-unrivaled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:410" - }, - "href": "href:408", - "id": "id:409", - "name": "laboring-overbuilt-growl-headland", - "volume": { - "crn": "crn:411", - "href": "href:412", - "id": "id:413", - "name": "tamper-salvaging-stick-giddily", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:22.000Z", - "floating_ips": [], - "href": "href:174", - "id": "id:175", - "name": "quantum-handbag-dimmed-reassign", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.4.5", - "href": "href:172", - "id": "id:173", - "name": "bark-gatherer-rope-unrivaled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:419" - }, - "href": "href:417", - "id": "id:418", - "name": "dollop-partition-helping-palmtree", - "volume": { - "crn": "crn:420", - "href": "href:421", - "id": "id:422", - "name": "ravage-deny-amusable-settling", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:20.000Z", - "crn": "crn:414", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:415", - "id": "id:416", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet5", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "primary_ip": { - "address": "10.240.9.5", - "href": "href:83", - "id": "id:84", - "name": "outskirts-unaligned-passivism-parchment", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:419" - }, - "href": "href:417", - "id": "id:418", - "name": "dollop-partition-helping-palmtree", - "volume": { - "crn": "crn:420", - "href": "href:421", - "id": "id:422", - "name": "ravage-deny-amusable-settling", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:20.000Z", - "floating_ips": [], - "href": "href:85", - "id": "id:86", - "name": "scratch-outward-raging-hunchback", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.9.5", - "href": "href:83", - "id": "id:84", - "name": "outskirts-unaligned-passivism-parchment", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:428" - }, - "href": "href:426", - "id": "id:427", - "name": "petted-ethanol-voicing-rocklike", - "volume": { - "crn": "crn:429", - "href": "href:430", - "id": "id:431", - "name": "uptown-striving-unrevised-earthlike", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:20.000Z", - "crn": "crn:423", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:424", - "id": "id:425", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet2", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "primary_ip": { - "address": "10.240.4.4", - "href": "href:168", - "id": "id:169", - "name": "stood-sitcom-whoops-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:428" - }, - "href": "href:426", - "id": "id:427", - "name": "petted-ethanol-voicing-rocklike", - "volume": { - "crn": "crn:429", - "href": "href:430", - "id": "id:431", - "name": "uptown-striving-unrevised-earthlike", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:20.000Z", - "floating_ips": [], - "href": "href:170", - "id": "id:171", - "name": "graveyard-handmade-ransack-acquaint", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.4.4", - "href": "href:168", - "id": "id:169", - "name": "stood-sitcom-whoops-hurled", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:437" - }, - "href": "href:435", - "id": "id:436", - "name": "promenade-spyglass-flattop-pushpin", - "volume": { - "crn": "crn:438", - "href": "href:439", - "id": "id:440", - "name": "relax-shaded-prism-jaunt", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:16.000Z", - "crn": "crn:432", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:433", - "id": "id:434", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet3", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "primary_ip": { - "address": "10.240.5.5", - "href": "href:107", - "id": "id:108", - "name": "recognize-citable-exerciser-unsecured", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:437" - }, - "href": "href:435", - "id": "id:436", - "name": "promenade-spyglass-flattop-pushpin", - "volume": { - "crn": "crn:438", - "href": "href:439", - "id": "id:440", - "name": "relax-shaded-prism-jaunt", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:16.000Z", - "floating_ips": [], - "href": "href:109", - "id": "id:110", - "name": "squatted-fastball-vacant-knoll", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.5.5", - "href": "href:107", - "id": "id:108", - "name": "recognize-citable-exerciser-unsecured", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:446" - }, - "href": "href:444", - "id": "id:445", - "name": "sandbox-federal-sculptor-jugum", - "volume": { - "crn": "crn:447", - "href": "href:448", - "id": "id:449", - "name": "convent-ramrod-cloning-afterward", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:15.000Z", - "crn": "crn:441", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:442", - "id": "id:443", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet4", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "primary_ip": { - "address": "10.240.8.5", - "href": "href:279", - "id": "id:280", - "name": "frighten-mystified-freeway-hurtling", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:446" - }, - "href": "href:444", - "id": "id:445", - "name": "sandbox-federal-sculptor-jugum", - "volume": { - "crn": "crn:447", - "href": "href:448", - "id": "id:449", - "name": "convent-ramrod-cloning-afterward", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:15.000Z", - "floating_ips": [], - "href": "href:281", - "id": "id:282", - "name": "speak-princess-washcloth-companion", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.8.5", - "href": "href:279", - "id": "id:280", - "name": "frighten-mystified-freeway-hurtling", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:455" - }, - "href": "href:453", - "id": "id:454", - "name": "affidavit-chastise-elsewhere-viewer", - "volume": { - "crn": "crn:456", - "href": "href:457", - "id": "id:458", - "name": "fancy-destiny-shuffling-sandbank", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:07.000Z", - "crn": "crn:450", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:451", - "id": "id:452", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet0", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:455" - }, - "href": "href:453", - "id": "id:454", - "name": "affidavit-chastise-elsewhere-viewer", - "volume": { - "crn": "crn:456", - "href": "href:457", - "id": "id:458", - "name": "fancy-destiny-shuffling-sandbank", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:07.000Z", - "floating_ips": [ - { - "address": "52.118.151.238", - "crn": "crn:285", - "href": "href:286", - "id": "id:287", - "name": "fip-0-subnet0" - } - ], - "href": "href:129", - "id": "id:130", - "name": "writer-crusher-unsuited-cash", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.0.4", - "href": "href:127", - "id": "id:128", - "name": "pundit-tight-arbitrate-grace", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:464" - }, - "href": "href:462", - "id": "id:463", - "name": "uneven-armoire-scabiosa-letter", - "volume": { - "crn": "crn:465", - "href": "href:466", - "id": "id:467", - "name": "cognition-blinks-humid-oxidant", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:459", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:460", - "id": "id:461", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet3", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "primary_ip": { - "address": "10.240.5.4", - "href": "href:103", - "id": "id:104", - "name": "rising-gopher-reentry-graveness", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:464" - }, - "href": "href:462", - "id": "id:463", - "name": "uneven-armoire-scabiosa-letter", - "volume": { - "crn": "crn:465", - "href": "href:466", - "id": "id:467", - "name": "cognition-blinks-humid-oxidant", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:105", - "id": "id:106", - "name": "icky-balsamic-outgoing-leached", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.5.4", - "href": "href:103", - "id": "id:104", - "name": "rising-gopher-reentry-graveness", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:473" - }, - "href": "href:471", - "id": "id:472", - "name": "perplexed-impulsivity-august-jaws", - "volume": { - "crn": "crn:474", - "href": "href:475", - "id": "id:476", - "name": "tartar-sixties-fructose-parmesan", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:468", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:469", - "id": "id:470", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet1", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "primary_ip": { - "address": "10.240.1.4", - "href": "href:234", - "id": "id:235", - "name": "excluded-unfair-jailbird-foil", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:473" - }, - "href": "href:471", - "id": "id:472", - "name": "perplexed-impulsivity-august-jaws", - "volume": { - "crn": "crn:474", - "href": "href:475", - "id": "id:476", - "name": "tartar-sixties-fructose-parmesan", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:236", - "id": "id:237", - "name": "hankie-excitable-outclass-unmanaged", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.1.4", - "href": "href:234", - "id": "id:235", - "name": "excluded-unfair-jailbird-foil", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:482" - }, - "href": "href:480", - "id": "id:481", - "name": "litter-snipping-unclasp-dust", - "volume": { - "crn": "crn:483", - "href": "href:484", - "id": "id:485", - "name": "untried-sulphate-hypnosis-subsidize", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:477", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:478", - "id": "id:479", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet4", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "primary_ip": { - "address": "10.240.8.4", - "href": "href:275", - "id": "id:276", - "name": "bagged-posture-glaring-cojoined", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:482" - }, - "href": "href:480", - "id": "id:481", - "name": "litter-snipping-unclasp-dust", - "volume": { - "crn": "crn:483", - "href": "href:484", - "id": "id:485", - "name": "untried-sulphate-hypnosis-subsidize", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:277", - "id": "id:278", - "name": "bullring-ransack-feint-cheer", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.8.4", - "href": "href:275", - "id": "id:276", - "name": "bagged-posture-glaring-cojoined", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:491" - }, - "href": "href:489", - "id": "id:490", - "name": "unlawful-overreach-yarn-rippling", - "volume": { - "crn": "crn:492", - "href": "href:493", - "id": "id:494", - "name": "finer-voter-roving-jailer", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:42:00.000Z", - "crn": "crn:486", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:487", - "id": "id:488", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet5", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "primary_ip": { - "address": "10.240.9.4", - "href": "href:79", - "id": "id:80", - "name": "ideally-grain-bagpipe-luxuriant", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:491" - }, - "href": "href:489", - "id": "id:490", - "name": "unlawful-overreach-yarn-rippling", - "volume": { - "crn": "crn:492", - "href": "href:493", - "id": "id:494", - "name": "finer-voter-roving-jailer", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - }, - "zone": { - "href": "href:5", - "name": "us-south-1" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:42:00.000Z", - "floating_ips": [], - "href": "href:81", - "id": "id:82", - "name": "stooped-camera-excluded-juke", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.9.4", - "href": "href:79", - "id": "id:80", - "name": "ideally-grain-bagpipe-luxuriant", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:360", - "href": "href:361", - "id": "id:362", - "name": "sg1" - } - ], - "status": "available", - "subnet": { - "crn": "crn:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:500" - }, - "href": "href:498", - "id": "id:499", - "name": "mashed-thing-headache-estate", - "volume": { - "crn": "crn:501", - "href": "href:502", - "id": "id:503", - "name": "mountain-harpist-libraries-dreaming", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:39.000Z", - "crn": "crn:495", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:496", - "id": "id:497", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet11", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "primary_ip": { - "address": "10.240.80.4", - "href": "href:151", - "id": "id:152", - "name": "childlike-publish-retainer-movie", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:500" - }, - "href": "href:498", - "id": "id:499", - "name": "mashed-thing-headache-estate", - "volume": { - "crn": "crn:501", - "href": "href:502", - "id": "id:503", - "name": "mountain-harpist-libraries-dreaming", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:39.000Z", - "floating_ips": [], - "href": "href:153", - "id": "id:154", - "name": "stride-woken-backsight-dynastic", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.80.4", - "href": "href:151", - "id": "id:152", - "name": "childlike-publish-retainer-movie", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11" - } - ], - "status": "available", - "subnet": { - "crn": "crn:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:509" - }, - "href": "href:507", - "id": "id:508", - "name": "calzone-cacti-moonlight-subarctic", - "volume": { - "crn": "crn:510", - "href": "href:511", - "id": "id:512", - "name": "blurred-dream-pectin-tapping", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:36.000Z", - "crn": "crn:504", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:505", - "id": "id:506", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet10", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:509" - }, - "href": "href:507", - "id": "id:508", - "name": "calzone-cacti-moonlight-subarctic", - "volume": { - "crn": "crn:510", - "href": "href:511", - "id": "id:512", - "name": "blurred-dream-pectin-tapping", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - }, - "zone": { - "href": "href:6", - "name": "us-south-2" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:36.000Z", - "floating_ips": [ - { - "address": "150.239.167.146", - "crn": "crn:288", - "href": "href:289", - "id": "id:290", - "name": "fip-0-subnet10" - } - ], - "href": "href:191", - "id": "id:192", - "name": "enlace-prominent-overhear-perfume", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.64.4", - "href": "href:189", - "id": "id:190", - "name": "starry-smasher-ladle-dioxide", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:353", - "href": "href:354", - "id": "id:355", - "name": "sg11" - } - ], - "status": "available", - "subnet": { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:518" - }, - "href": "href:516", - "id": "id:517", - "name": "recoup-blinks-ebullient-renewed", - "volume": { - "crn": "crn:519", - "href": "href:520", - "id": "id:521", - "name": "manmade-unequal-disinfect-cone", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:24.000Z", - "crn": "crn:513", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:514", - "id": "id:515", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi1-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:518" - }, - "href": "href:516", - "id": "id:517", - "name": "recoup-blinks-ebullient-renewed", - "volume": { - "crn": "crn:519", - "href": "href:520", - "id": "id:521", - "name": "manmade-unequal-disinfect-cone", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:24.000Z", - "floating_ips": [ - { - "address": "169.48.95.165", - "crn": "crn:291", - "href": "href:292", - "id": "id:293", - "name": "fip-0-subnet20" - } - ], - "href": "href:219", - "id": "id:220", - "name": "clicker-grumbly-outskirts-greatly", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.6", - "href": "href:217", - "id": "id:218", - "name": "uniquely-shelter-gracious-sudden", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:527" - }, - "href": "href:525", - "id": "id:526", - "name": "radio-tightrope-outtakes-moonshine", - "volume": { - "crn": "crn:528", - "href": "href:529", - "id": "id:530", - "name": "tattoo-crescent-unwary-hayride", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:21.000Z", - "crn": "crn:522", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:523", - "id": "id:524", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "primary_ip": { - "address": "10.240.128.5", - "href": "href:213", - "id": "id:214", - "name": "customs-recollect-drippy-primate", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:527" - }, - "href": "href:525", - "id": "id:526", - "name": "radio-tightrope-outtakes-moonshine", - "volume": { - "crn": "crn:528", - "href": "href:529", - "id": "id:530", - "name": "tattoo-crescent-unwary-hayride", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:21.000Z", - "floating_ips": [], - "href": "href:215", - "id": "id:216", - "name": "ought-football-shorter-aviator", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.5", - "href": "href:213", - "id": "id:214", - "name": "customs-recollect-drippy-primate", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:536" - }, - "href": "href:534", - "id": "id:535", - "name": "crumpet-ride-tastiness-phoney", - "volume": { - "crn": "crn:537", - "href": "href:538", - "id": "id:539", - "name": "doorframe-marvelous-refusing-citable", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:21.000Z", - "crn": "crn:531", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:532", - "id": "id:533", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi2-subnet20", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "primary_ip": { - "address": "10.240.128.4", - "href": "href:209", - "id": "id:210", - "name": "unmixed-qualify-prescribe-railcar", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:536" - }, - "href": "href:534", - "id": "id:535", - "name": "crumpet-ride-tastiness-phoney", - "volume": { - "crn": "crn:537", - "href": "href:538", - "id": "id:539", - "name": "doorframe-marvelous-refusing-citable", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:21.000Z", - "floating_ips": [], - "href": "href:211", - "id": "id:212", - "name": "tavern-far-imprudent-labored", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.128.4", - "href": "href:209", - "id": "id:210", - "name": "unmixed-qualify-prescribe-railcar", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:339", - "href": "href:340", - "id": "id:341", - "name": "sg21" - } - ], - "status": "available", - "subnet": { - "crn": "crn:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - }, - { - "availability_policy": { - "host_failure": "restart" - }, - "bandwidth": 4000, - "boot_volume_attachment": { - "device": { - "id": "id:545" - }, - "href": "href:543", - "id": "id:544", - "name": "bronzing-vendor-plod-pretzel", - "volume": { - "crn": "crn:546", - "href": "href:547", - "id": "id:548", - "name": "squelch-plop-headlamp-ideologue", - "resource_type": "volume" - } - }, - "confidential_compute_mode": "disabled", - "created_at": "2024-06-25T15:41:00.000Z", - "crn": "crn:540", - "disks": [], - "enable_secure_boot": false, - "health_reasons": [], - "health_state": "ok", - "href": "href:541", - "id": "id:542", - "image": { - "crn": "crn:392", - "href": "href:393", - "id": "id:394", - "name": "server-9080", - "resource_type": "image" - }, - "lifecycle_reasons": [], - "lifecycle_state": "stable", - "memory": 4, - "metadata_service": { - "enabled": false, - "protocol": "http", - "response_hop_limit": 1 - }, - "name": "vsi0-subnet30", - "network_attachments": [], - "numa_count": 1, - "primary_network_interface": { - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "subnet": { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - }, - "profile": { - "href": "href:395", - "name": "cx2-2x4", - "resource_type": "instance_profile" - }, - "reservation_affinity": { - "policy": "disabled", - "pool": [] - }, - "resource_group": { - "href": "href:16", - "id": "id:17", - "name": "name:4" - }, - "resource_type": "instance", - "startable": true, - "status": "running", - "status_reasons": [], - "total_network_bandwidth": 3000, - "total_volume_bandwidth": 1000, - "vcpu": { - "architecture": "amd64", - "count": 2, - "manufacturer": "intel" - }, - "volume_attachments": [ - { - "device": { - "id": "id:545" - }, - "href": "href:543", - "id": "id:544", - "name": "bronzing-vendor-plod-pretzel", - "volume": { - "crn": "crn:546", - "href": "href:547", - "id": "id:548", - "name": "squelch-plop-headlamp-ideologue", - "resource_type": "volume" - } - } - ], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - }, - "zone": { - "href": "href:7", - "name": "us-south-3" - }, - "network_interfaces": [ - { - "allow_ip_spoofing": false, - "created_at": "2024-06-25T15:41:00.000Z", - "floating_ips": [ - { - "address": "52.118.100.239", - "crn": "crn:294", - "href": "href:295", - "id": "id:296", - "name": "fip-0-subnet30" - } - ], - "href": "href:260", - "id": "id:261", - "name": "snout-given-twiddle-splinter", - "port_speed": 3000, - "primary_ip": { - "address": "10.240.192.4", - "href": "href:258", - "id": "id:259", - "name": "legacy-shore-molecule-barometer", - "resource_type": "subnet_reserved_ip" - }, - "resource_type": "network_interface", - "security_groups": [ - { - "crn": "crn:346", - "href": "href:347", - "id": "id:348", - "name": "sg31" - } - ], - "status": "available", - "subnet": { - "crn": "crn:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - }, - "type": "primary" - } - ], - "tags": [] - } - ], - "routing_tables": [ - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:20.000Z", - "href": "href:11", - "id": "id:12", - "is_default": true, - "lifecycle_state": "stable", - "name": "overtone-sputter-overspend-gorge", - "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:137", - "href": "href:138", - "id": "id:139", - "name": "subnet11", - "resource_type": "subnet" - }, - { - "crn": "crn:178", - "href": "href:179", - "id": "id:180", - "name": "subnet10", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:1", - "href": "href:2", - "id": "id:3", - "name": "test-vpc1", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:28", - "id": "id:29", - "is_default": true, - "lifecycle_state": "stable", - "name": "escapade-dynamite-upstage-context", - "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:65", - "href": "href:66", - "id": "id:67", - "name": "subnet5", - "resource_type": "subnet" - }, - { - "crn": "crn:89", - "href": "href:90", - "id": "id:91", - "name": "subnet3", - "resource_type": "subnet" - }, - { - "crn": "crn:113", - "href": "href:114", - "id": "id:115", - "name": "subnet0", - "resource_type": "subnet" - }, - { - "crn": "crn:157", - "href": "href:158", - "id": "id:159", - "name": "subnet2", - "resource_type": "subnet" - }, - { - "crn": "crn:223", - "href": "href:224", - "id": "id:225", - "name": "subnet1", - "resource_type": "subnet" - }, - { - "crn": "crn:264", - "href": "href:265", - "id": "id:266", - "name": "subnet4", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:22", - "href": "href:23", - "id": "id:24", - "name": "test-vpc0", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:45", - "id": "id:46", - "is_default": true, - "lifecycle_state": "stable", - "name": "quintuple-severity-caddie-manuals", - "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:195", - "href": "href:196", - "id": "id:197", - "name": "subnet20", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:39", - "href": "href:40", - "id": "id:41", - "name": "test-vpc2", - "resource_type": "vpc" - } - }, - { - "accept_routes_from": [ - { - "resource_type": "vpn_gateway" - }, - { - "resource_type": "vpn_server" - } - ], - "advertise_routes_to": [], - "created_at": "2024-06-25T15:40:19.000Z", - "href": "href:58", - "id": "id:59", - "is_default": true, - "lifecycle_state": "stable", - "name": "probational-herring-undone-daintily", - "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:244", - "href": "href:245", - "id": "id:246", - "name": "subnet30", - "resource_type": "subnet" - } - ], - "routes": [], - "vpc": { - "crn": "crn:52", - "href": "href:53", - "id": "id:54", - "name": "test-vpc3", - "resource_type": "vpc" - } - } - ], - "load_balancers": [], - "transit_connections": [ - { - "created_at": "2024-06-25T15:41:44.212Z", - "id": "id:549", - "name": "tg3_connection3", - "network_id": "crn:52", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:550", - "id": "id:551", - "name": "local-tg3" - }, - "updated_at": "2024-06-25T15:45:14.206Z" - }, - { - "created_at": "2024-06-25T15:41:54.416Z", - "id": "id:552", - "name": "tg3_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:550", - "id": "id:551", - "name": "local-tg3" - }, - "updated_at": "2024-06-25T15:45:53.979Z" - }, - { - "created_at": "2024-06-25T15:42:54.772Z", - "id": "id:553", - "name": "tg2_connection3", - "network_id": "crn:52", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:08.822Z" - }, - { - "created_at": "2024-06-25T15:43:11.555Z", - "id": "id:556", - "name": "tg2_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters": [ - { - "action": "deny", - "created_at": "2024-06-25T15:46:46.641Z", - "id": "id:557", - "le": 32, - "prefix": "10.240.0.0/22", - "updated_at": "2024-06-25T15:46:46.641Z" - } - ], - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:59.395Z" - }, - { - "created_at": "2024-06-25T15:43:12.159Z", - "id": "id:558", - "name": "tg_connection0", - "network_id": "crn:22", - "network_type": "vpc", - "prefix_filters": [ - { - "action": "deny", - "before": "298db67f-2e68-4548-93b9-949f8356d4a0", - "created_at": "2024-06-25T15:45:14.711Z", - "id": "id:559", - "prefix": "10.240.4.0/22", - "updated_at": "2024-06-25T15:45:14.711Z" - }, - { - "action": "deny", - "created_at": "2024-06-25T15:45:25.435Z", - "id": "id:560", - "prefix": "10.240.8.0/22", - "updated_at": "2024-06-25T15:45:25.435Z" - } - ], - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:49:53.837Z" - }, - { - "created_at": "2024-06-25T15:43:41.079Z", - "id": "id:563", - "name": "tg2_connection2", - "network_id": "crn:39", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:554", - "id": "id:555", - "name": "local-tg2" - }, - "updated_at": "2024-06-25T15:49:43.192Z" - }, - { - "created_at": "2024-06-25T15:43:42.335Z", - "id": "id:564", - "name": "tg1_connection1", - "network_id": "crn:1", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:48:45.229Z" - }, - { - "created_at": "2024-06-25T15:44:08.995Z", - "id": "id:565", - "name": "tg1_connection2", - "network_id": "crn:39", - "network_type": "vpc", - "prefix_filters_default": "permit", - "status": "attached", - "transit_gateway": { - "crn": "crn:561", - "id": "id:562", - "name": "local-tg1" - }, - "updated_at": "2024-06-25T15:49:11.976Z" - } - ], - "transit_gateways": [ - { - "id": "id:551", - "crn": "crn:550", - "name": "local-tg3", - "location": "us-south", - "created_at": "2024-06-25T15:40:21.390Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:42:12.752Z" - }, - { - "id": "id:555", - "crn": "crn:554", - "name": "local-tg2", - "location": "us-south", - "created_at": "2024-06-25T15:40:25.895Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:43:58.196Z" - }, - { - "id": "id:562", - "crn": "crn:561", - "name": "local-tg1", - "location": "us-south", - "created_at": "2024-06-25T15:40:26.455Z", - "global": false, - "resource_group": { - "id": "id:17", - "href": "href:566" - }, - "status": "available", - "updated_at": "2024-06-25T15:43:15.331Z" - } - ], - "iks_clusters": [] -} diff --git a/test/data/acl_nif/config_object.json b/test/data/tg_multiple/config_object.json similarity index 100% rename from test/data/acl_nif/config_object.json rename to test/data/tg_multiple/config_object.json diff --git a/test/synth_test_list.go b/test/synth_test_list.go index fac53a7a..de3ed502 100644 --- a/test/synth_test_list.go +++ b/test/synth_test_list.go @@ -6,38 +6,22 @@ SPDX-License-Identifier: Apache-2.0 package test const ( - aclExtenalsConfig = "%s/acl_externals/config_object.json" - aclExternalsSpec = "%s/acl_externals/conn_spec.json" - - aclNifConfig = "%s/acl_nif/config_object.json" - aclNifSpec = "%s/acl_nif/conn_spec.json" - - aclNifInstanceSegmentsConfig = "%s/acl_nif_instance_segments/config_object.json" - aclNifInstanceSegmentsSpec = "%s/acl_nif_instance_segments/conn_spec.json" - - aclProtocolsConfig = "%s/acl_protocols/config_object.json" - aclProtocolsSpec = "%s/acl_protocols/conn_spec.json" - - aclSubnetCidrSegmentsConfig = "%s/acl_subnet_cidr_segments/config_object.json" - aclSubnetCidrSegmentsSpec = "%s/acl_subnet_cidr_segments/conn_spec.json" - + tgMultipleConfig = "%s/tg_multiple/config_object.json" + sgTesting3Config = "%s/sg_testing3/config_object.json" + aclTesting4Config = "%s/acl_testing4/config_object.json" aclTesting5Config = "%s/acl_testing5/config_object.json" - aclTesting5Spec = "%s/acl_testing5/conn_spec.json" - - aclTgMultipleConfig = "%s/acl_tg_multiple/config_object.json" - aclTgMultipleSpec = "%s/acl_tg_multiple/conn_spec.json" - aclVpeConfig = "%s/acl_vpe/config_object.json" - aclVpeSpec = "%s/acl_vpe/conn_spec.json" - - sgProtocolsConfig = "%s/sg_protocols/config_object.json" - sgProtocolsSpec = "%s/sg_protocols/conn_spec.json" - - sgTesting3Config = "%s/sg_testing3/config_object.json" - sgTesting3Spec = "%s/sg_testing3/conn_spec.json" - - sgTgMultipleConfig = "%s/sg_tg_multiple/config_object.json" - sgTgMultipleSpec = "%s/sg_tg_multiple/conn_spec.json" + aclExternalsSpec = "%s/acl_externals/conn_spec.json" + aclNifSpec = "%s/acl_nif/conn_spec.json" + aclNifInstanceSegmentsSpec = "%s/acl_nif_instance_segments/conn_spec.json" + aclProtocolsSpec = "%s/acl_protocols/conn_spec.json" + aclSubnetCidrSegmentsSpec = "%s/acl_subnet_cidr_segments/conn_spec.json" + aclTesting5Spec = "%s/acl_testing5/conn_spec.json" + aclTgMultipleSpec = "%s/acl_tg_multiple/conn_spec.json" + aclVpeSpec = "%s/acl_vpe/conn_spec.json" + sgProtocolsSpec = "%s/sg_protocols/conn_spec.json" + sgTesting3Spec = "%s/sg_testing3/conn_spec.json" + sgTgMultipleSpec = "%s/sg_tg_multiple/conn_spec.json" tfOutputFmt = "tf" ) @@ -49,13 +33,13 @@ func allMainTests() []testCase { //nolint:funlen //all acl synthesis tests func synthACLTestsList() []testCase { return []testCase{ - // acl externals ## acl_testing4 config + // acl externals { testName: "acl_externals_json", args: &command{ cmd: synth, subcmd: acl, - config: aclExtenalsConfig, + config: aclTesting4Config, spec: aclExternalsSpec, outputFile: "%s/acl_externals_json/nacl_expected.json", }, @@ -65,7 +49,7 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclExtenalsConfig, + config: aclTesting4Config, spec: aclExternalsSpec, outputFile: "%s/acl_externals_tf/nacl_expected.tf", }, @@ -77,7 +61,7 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclNifConfig, + config: tgMultipleConfig, spec: aclNifSpec, outputFile: "%s/acl_nif_tf/nacl_expected.tf", }, @@ -89,7 +73,7 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclNifInstanceSegmentsConfig, + config: tgMultipleConfig, spec: aclNifInstanceSegmentsSpec, outputFile: "%s/acl_nif_instance_segments_tf/nacl_expected.tf", }, @@ -101,7 +85,7 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclProtocolsConfig, + config: tgMultipleConfig, spec: aclProtocolsSpec, outputFile: "%s/acl_protocols_csv/nacl_expected.csv", }, @@ -111,7 +95,7 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclProtocolsConfig, + config: tgMultipleConfig, spec: aclProtocolsSpec, outputFile: "%s/acl_protocols_json/nacl_expected.json", }, @@ -121,7 +105,7 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclProtocolsConfig, + config: tgMultipleConfig, spec: aclProtocolsSpec, outputFile: "%s/acl_protocols_md/nacl_expected.md", }, @@ -131,19 +115,19 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclProtocolsConfig, + config: tgMultipleConfig, spec: aclProtocolsSpec, outputFile: "%s/acl_protocols_tf/nacl_expected.tf", }, }, - // acl subnet and cidr segments (bidi) ## acl_testing5 config + // acl subnet and cidr segments (bidi) { testName: "acl_subnet_cidr_segments_tf", args: &command{ cmd: synth, subcmd: acl, - config: aclSubnetCidrSegmentsConfig, + config: aclTesting5Config, spec: aclSubnetCidrSegmentsSpec, outputFile: "%s/acl_subnet_cidr_segments_tf/nacl_expected.tf", }, @@ -199,7 +183,7 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclTgMultipleConfig, + config: tgMultipleConfig, spec: aclTgMultipleSpec, outputFile: "%s/acl_tg_multiple_json/nacl_expected.json", }, @@ -209,7 +193,7 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclTgMultipleConfig, + config: tgMultipleConfig, spec: aclTgMultipleSpec, outputFile: "%s/acl_tg_multiple_tf/nacl_expected.tf", }, @@ -219,7 +203,7 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclTgMultipleConfig, + config: tgMultipleConfig, spec: aclTgMultipleSpec, outputDir: "%s/acl_tg_multiple_tf_separate", format: tfOutputFmt, @@ -232,7 +216,7 @@ func synthACLTestsList() []testCase { args: &command{ cmd: synth, subcmd: acl, - config: aclVpeConfig, + config: sgTesting3Config, spec: aclVpeSpec, outputFile: "%s/acl_vpe_tf/nacl_expected.tf", }, @@ -248,7 +232,7 @@ func synthSGTestsList() []testCase { args: &command{ cmd: synth, subcmd: sg, - config: sgProtocolsConfig, + config: tgMultipleConfig, spec: sgProtocolsSpec, outputFile: "%s/sg_protocols_csv/sg_expected.csv", }, @@ -258,7 +242,7 @@ func synthSGTestsList() []testCase { args: &command{ cmd: synth, subcmd: sg, - config: sgProtocolsConfig, + config: tgMultipleConfig, spec: sgProtocolsSpec, outputFile: "%s/sg_protocols_json/sg_expected.json", }, @@ -268,7 +252,7 @@ func synthSGTestsList() []testCase { args: &command{ cmd: synth, subcmd: sg, - config: sgProtocolsConfig, + config: tgMultipleConfig, spec: sgProtocolsSpec, outputFile: "%s/sg_protocols_md/sg_expected.md", }, @@ -278,7 +262,7 @@ func synthSGTestsList() []testCase { args: &command{ cmd: synth, subcmd: sg, - config: sgProtocolsConfig, + config: tgMultipleConfig, spec: sgProtocolsSpec, outputFile: "%s/sg_protocols_tf/sg_expected.tf", }, @@ -332,7 +316,7 @@ func synthSGTestsList() []testCase { args: &command{ cmd: synth, subcmd: sg, - config: sgTgMultipleConfig, + config: tgMultipleConfig, spec: sgTgMultipleSpec, outputDir: "%s/sg_tg_multiple_tf_separate", format: tfOutputFmt, From e34acb022945738ca3d9ca73d60823bc7b9e6486 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 14 Oct 2024 17:49:35 +0300 Subject: [PATCH 081/131] added sg segment tests --- pkg/io/jsonio/unmarshalConns.go | 1 + pkg/ir/spec.go | 2 +- test/data/sg_segments1/conn_spec.json | 22 +++ test/data/sg_segments2/conn_spec.json | 30 +++ test/data/sg_segments3/conn_spec.json | 30 +++ test/data/sg_segments4/conn_spec.json | 30 +++ test/expected/sg_segments1_tf/sg_expected.tf | 173 ++++++++++++++++ test/expected/sg_segments2_tf/sg_expected.tf | 185 +++++++++++++++++ test/expected/sg_segments3_tf/sg_expected.tf | 197 +++++++++++++++++++ test/expected/sg_segments4_tf/sg_expected.tf | 89 +++++++++ test/synth_test_list.go | 53 +++++ 11 files changed, 811 insertions(+), 1 deletion(-) create mode 100644 test/data/sg_segments1/conn_spec.json create mode 100644 test/data/sg_segments2/conn_spec.json create mode 100644 test/data/sg_segments3/conn_spec.json create mode 100644 test/data/sg_segments4/conn_spec.json create mode 100644 test/expected/sg_segments1_tf/sg_expected.tf create mode 100644 test/expected/sg_segments2_tf/sg_expected.tf create mode 100644 test/expected/sg_segments3_tf/sg_expected.tf create mode 100644 test/expected/sg_segments4_tf/sg_expected.tf diff --git a/pkg/io/jsonio/unmarshalConns.go b/pkg/io/jsonio/unmarshalConns.go index 82e4952b..e28f904a 100644 --- a/pkg/io/jsonio/unmarshalConns.go +++ b/pkg/io/jsonio/unmarshalConns.go @@ -130,6 +130,7 @@ func translateResourceType(defs *ir.Definitions, resource *spec.Resource) (ir.Re if _, ok := defs.VpeSegments[resource.Name]; ok { return ir.ResourceTypeVpeSegment, nil } + return ir.ResourceTypeSubnet, fmt.Errorf("could not find segment %v", resource.Name) } return ir.ResourceTypeSubnet, fmt.Errorf("unsupported resource type %v (%v)", resource.Type, resource.Name) } diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index c89d15a2..83258e3e 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -283,7 +283,7 @@ func (s *Definitions) lookupSegment(segment map[ID]*SegmentDetails, name string, return nil, fmt.Errorf(containerNotFound, name, t) } - res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(elementType)} for _, elementName := range segmentDetails.Elements { subnet, err := lookup(elementType, elementName) if err != nil { diff --git a/test/data/sg_segments1/conn_spec.json b/test/data/sg_segments1/conn_spec.json new file mode 100644 index 00000000..103589eb --- /dev/null +++ b/test/data/sg_segments1/conn_spec.json @@ -0,0 +1,22 @@ +{ + "segments": { + "cidrSegment": { + "type": "cidr", + "items": [ + "10.240.0.0/23" + ] + } + }, + "required-connections": [ + { + "src": { + "name": "cidrSegment", + "type": "segment" + }, + "dst": { + "name": "cidrSegment", + "type": "segment" + } + } + ] +} \ No newline at end of file diff --git a/test/data/sg_segments2/conn_spec.json b/test/data/sg_segments2/conn_spec.json new file mode 100644 index 00000000..f6181a3c --- /dev/null +++ b/test/data/sg_segments2/conn_spec.json @@ -0,0 +1,30 @@ +{ + "segments": { + "cidrSegment": { + "type": "cidr", + "items": [ + "10.240.0.0/23" + ] + }, + "instanceSegment": { + "type": "instance", + "items": [ + "vsi0-subnet11", + "vsi0-subnet5" + ] + } + }, + "required-connections": [ + { + + "src": { + "name": "instanceSegment", + "type": "segment" + }, + "dst": { + "name": "cidrSegment", + "type": "segment" + } + } + ] +} \ No newline at end of file diff --git a/test/data/sg_segments3/conn_spec.json b/test/data/sg_segments3/conn_spec.json new file mode 100644 index 00000000..448a9c07 --- /dev/null +++ b/test/data/sg_segments3/conn_spec.json @@ -0,0 +1,30 @@ +{ + "segments": { + "subnetSegment": { + "type": "subnet", + "items": [ + "subnet10", + "subnet20" + ] + }, + "nifSegment": { + "type": "nif", + "items": [ + "bullring-ransack-feint-cheer", + "scratch-outward-raging-hunchback" + ] + } + }, + "required-connections": [ + { + "src": { + "name": "subnetSegment", + "type": "segment" + }, + "dst": { + "name": "nifSegment", + "type": "segment" + } + } + ] +} \ No newline at end of file diff --git a/test/data/sg_segments4/conn_spec.json b/test/data/sg_segments4/conn_spec.json new file mode 100644 index 00000000..b2ef94ff --- /dev/null +++ b/test/data/sg_segments4/conn_spec.json @@ -0,0 +1,30 @@ +{ + "segments": { + "vpeSegment": { + "type": "vpe", + "items": [ + "appdata-endpoint-gateway", + "policydb-endpoint-gateway" + ] + }, + "instanceSegment": { + "type": "instance", + "items": [ + "fe", + "be" + ] + } + }, + "required-connections": [ + { + "src": { + "name": "vpeSegment", + "type": "segment" + }, + "dst": { + "name": "instanceSegment", + "type": "segment" + } + } + ] +} \ No newline at end of file diff --git a/test/expected/sg_segments1_tf/sg_expected.tf b/test/expected/sg_segments1_tf/sg_expected.tf new file mode 100644 index 00000000..7e8c7c2d --- /dev/null +++ b/test/expected/sg_segments1_tf/sg_expected.tf @@ -0,0 +1,173 @@ +### SG attached to test-vpc0/vsi0-subnet0 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { + name = "sg-test-vpc0--vsi0-subnet0" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-0" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + direction = "inbound" + remote = "10.240.0.0/23" +} +# Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-1" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + direction = "outbound" + remote = "10.240.0.0/23" +} + +### SG attached to test-vpc0/vsi0-subnet1 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { + name = "sg-test-vpc0--vsi0-subnet1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-0" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + direction = "inbound" + remote = "10.240.0.0/23" +} +# Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-1" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + direction = "outbound" + remote = "10.240.0.0/23" +} + +### SG attached to test-vpc0/vsi0-subnet2 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { + name = "sg-test-vpc0--vsi0-subnet2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi0-subnet3 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { + name = "sg-test-vpc0--vsi0-subnet3" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi0-subnet4 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { + name = "sg-test-vpc0--vsi0-subnet4" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi0-subnet5 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { + name = "sg-test-vpc0--vsi0-subnet5" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet0 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { + name = "sg-test-vpc0--vsi1-subnet0" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-0" { + group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + direction = "inbound" + remote = "10.240.0.0/23" +} +# Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-1" { + group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + direction = "outbound" + remote = "10.240.0.0/23" +} + +### SG attached to test-vpc0/vsi1-subnet1 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { + name = "sg-test-vpc0--vsi1-subnet1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-0" { + group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + direction = "inbound" + remote = "10.240.0.0/23" +} +# Internal. required-connections[0]: (segment cidrSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-1" { + group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + direction = "outbound" + remote = "10.240.0.0/23" +} + +### SG attached to test-vpc0/vsi1-subnet2 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { + name = "sg-test-vpc0--vsi1-subnet2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet3 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { + name = "sg-test-vpc0--vsi1-subnet3" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet4 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { + name = "sg-test-vpc0--vsi1-subnet4" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet5 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { + name = "sg-test-vpc0--vsi1-subnet5" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc1/vsi0-subnet10 +resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { + name = "sg-test-vpc1--vsi0-subnet10" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + +### SG attached to test-vpc1/vsi0-subnet11 +resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { + name = "sg-test-vpc1--vsi0-subnet11" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + +### SG attached to test-vpc2/vsi0-subnet20 +resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { + name = "sg-test-vpc2--vsi0-subnet20" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc2_id +} + +### SG attached to test-vpc2/vsi1-subnet20 +resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { + name = "sg-test-vpc2--vsi1-subnet20" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc2_id +} + +### SG attached to test-vpc2/vsi2-subnet20 +resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { + name = "sg-test-vpc2--vsi2-subnet20" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc2_id +} + +### SG attached to test-vpc3/vsi0-subnet30 +resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { + name = "sg-test-vpc3--vsi0-subnet30" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc3_id +} diff --git a/test/expected/sg_segments2_tf/sg_expected.tf b/test/expected/sg_segments2_tf/sg_expected.tf new file mode 100644 index 00000000..0ecc69d1 --- /dev/null +++ b/test/expected/sg_segments2_tf/sg_expected.tf @@ -0,0 +1,185 @@ +### SG attached to test-vpc0/vsi0-subnet0 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { + name = "sg-test-vpc0--vsi0-subnet0" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment instanceSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-0" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc1--vsi0-subnet11.id +} +# Internal. required-connections[0]: (segment instanceSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-1" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet0.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc0--vsi0-subnet5.id +} + +### SG attached to test-vpc0/vsi0-subnet1 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { + name = "sg-test-vpc0--vsi0-subnet1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment instanceSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-0" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc1--vsi0-subnet11.id +} +# Internal. required-connections[0]: (segment instanceSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-1" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet1.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc0--vsi0-subnet5.id +} + +### SG attached to test-vpc0/vsi0-subnet2 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { + name = "sg-test-vpc0--vsi0-subnet2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi0-subnet3 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { + name = "sg-test-vpc0--vsi0-subnet3" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi0-subnet4 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { + name = "sg-test-vpc0--vsi0-subnet4" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi0-subnet5 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { + name = "sg-test-vpc0--vsi0-subnet5" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment instanceSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet5-0" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet5.id + direction = "outbound" + remote = "10.240.0.0/23" +} + +### SG attached to test-vpc0/vsi1-subnet0 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { + name = "sg-test-vpc0--vsi1-subnet0" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment instanceSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-0" { + group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc1--vsi0-subnet11.id +} +# Internal. required-connections[0]: (segment instanceSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-1" { + group = ibm_is_security_group.test-vpc0--vsi1-subnet0.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc0--vsi0-subnet5.id +} + +### SG attached to test-vpc0/vsi1-subnet1 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { + name = "sg-test-vpc0--vsi1-subnet1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment instanceSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-0" { + group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc1--vsi0-subnet11.id +} +# Internal. required-connections[0]: (segment instanceSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-1" { + group = ibm_is_security_group.test-vpc0--vsi1-subnet1.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc0--vsi0-subnet5.id +} + +### SG attached to test-vpc0/vsi1-subnet2 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { + name = "sg-test-vpc0--vsi1-subnet2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet3 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { + name = "sg-test-vpc0--vsi1-subnet3" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet4 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { + name = "sg-test-vpc0--vsi1-subnet4" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet5 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { + name = "sg-test-vpc0--vsi1-subnet5" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc1/vsi0-subnet10 +resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { + name = "sg-test-vpc1--vsi0-subnet10" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + +### SG attached to test-vpc1/vsi0-subnet11 +resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { + name = "sg-test-vpc1--vsi0-subnet11" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +# Internal. required-connections[0]: (segment instanceSegment)->(segment cidrSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet11-0" { + group = ibm_is_security_group.test-vpc1--vsi0-subnet11.id + direction = "outbound" + remote = "10.240.0.0/23" +} + +### SG attached to test-vpc2/vsi0-subnet20 +resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { + name = "sg-test-vpc2--vsi0-subnet20" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc2_id +} + +### SG attached to test-vpc2/vsi1-subnet20 +resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { + name = "sg-test-vpc2--vsi1-subnet20" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc2_id +} + +### SG attached to test-vpc2/vsi2-subnet20 +resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { + name = "sg-test-vpc2--vsi2-subnet20" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc2_id +} + +### SG attached to test-vpc3/vsi0-subnet30 +resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { + name = "sg-test-vpc3--vsi0-subnet30" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc3_id +} diff --git a/test/expected/sg_segments3_tf/sg_expected.tf b/test/expected/sg_segments3_tf/sg_expected.tf new file mode 100644 index 00000000..a14bcf10 --- /dev/null +++ b/test/expected/sg_segments3_tf/sg_expected.tf @@ -0,0 +1,197 @@ +### SG attached to test-vpc0/vsi0-subnet0 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { + name = "sg-test-vpc0--vsi0-subnet0" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi0-subnet1 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { + name = "sg-test-vpc0--vsi0-subnet1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi0-subnet2 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { + name = "sg-test-vpc0--vsi0-subnet2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi0-subnet3 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { + name = "sg-test-vpc0--vsi0-subnet3" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi0-subnet4 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { + name = "sg-test-vpc0--vsi0-subnet4" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet4-0" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet4.id + direction = "inbound" + remote = "10.240.64.0/24" +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet4-1" { + group = ibm_is_security_group.test-vpc0--vsi0-subnet4.id + direction = "inbound" + remote = "10.240.128.0/24" +} + +### SG attached to test-vpc0/vsi0-subnet5 +resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { + name = "sg-test-vpc0--vsi0-subnet5" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet0 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { + name = "sg-test-vpc0--vsi1-subnet0" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet1 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { + name = "sg-test-vpc0--vsi1-subnet1" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet2 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { + name = "sg-test-vpc0--vsi1-subnet2" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet3 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { + name = "sg-test-vpc0--vsi1-subnet3" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet4 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { + name = "sg-test-vpc0--vsi1-subnet4" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} + +### SG attached to test-vpc0/vsi1-subnet5 +resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { + name = "sg-test-vpc0--vsi1-subnet5" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc0_id +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet5-0" { + group = ibm_is_security_group.test-vpc0--vsi1-subnet5.id + direction = "inbound" + remote = "10.240.64.0/24" +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet5-1" { + group = ibm_is_security_group.test-vpc0--vsi1-subnet5.id + direction = "inbound" + remote = "10.240.128.0/24" +} + +### SG attached to test-vpc1/vsi0-subnet10 +resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { + name = "sg-test-vpc1--vsi0-subnet10" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet10-0" { + group = ibm_is_security_group.test-vpc1--vsi0-subnet10.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc0--vsi0-subnet4.id +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet10-1" { + group = ibm_is_security_group.test-vpc1--vsi0-subnet10.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc0--vsi1-subnet5.id +} + +### SG attached to test-vpc1/vsi0-subnet11 +resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { + name = "sg-test-vpc1--vsi0-subnet11" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc1_id +} + +### SG attached to test-vpc2/vsi0-subnet20 +resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { + name = "sg-test-vpc2--vsi0-subnet20" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc2_id +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc2--vsi0-subnet20-0" { + group = ibm_is_security_group.test-vpc2--vsi0-subnet20.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc0--vsi0-subnet4.id +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc2--vsi0-subnet20-1" { + group = ibm_is_security_group.test-vpc2--vsi0-subnet20.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc0--vsi1-subnet5.id +} + +### SG attached to test-vpc2/vsi1-subnet20 +resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { + name = "sg-test-vpc2--vsi1-subnet20" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc2_id +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc2--vsi1-subnet20-0" { + group = ibm_is_security_group.test-vpc2--vsi1-subnet20.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc0--vsi0-subnet4.id +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc2--vsi1-subnet20-1" { + group = ibm_is_security_group.test-vpc2--vsi1-subnet20.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc0--vsi1-subnet5.id +} + +### SG attached to test-vpc2/vsi2-subnet20 +resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { + name = "sg-test-vpc2--vsi2-subnet20" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc2_id +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc2--vsi2-subnet20-0" { + group = ibm_is_security_group.test-vpc2--vsi2-subnet20.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc0--vsi0-subnet4.id +} +# Internal. required-connections[0]: (segment subnetSegment)->(segment nifSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc2--vsi2-subnet20-1" { + group = ibm_is_security_group.test-vpc2--vsi2-subnet20.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc0--vsi1-subnet5.id +} + +### SG attached to test-vpc3/vsi0-subnet30 +resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { + name = "sg-test-vpc3--vsi0-subnet30" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc3_id +} diff --git a/test/expected/sg_segments4_tf/sg_expected.tf b/test/expected/sg_segments4_tf/sg_expected.tf new file mode 100644 index 00000000..07166fff --- /dev/null +++ b/test/expected/sg_segments4_tf/sg_expected.tf @@ -0,0 +1,89 @@ +### SG attached to test-vpc/appdata-endpoint-gateway +resource "ibm_is_security_group" "test-vpc--appdata-endpoint-gateway" { + name = "sg-test-vpc--appdata-endpoint-gateway" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc_id +} +# Internal. required-connections[0]: (segment vpeSegment)->(segment instanceSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc--appdata-endpoint-gateway-0" { + group = ibm_is_security_group.test-vpc--appdata-endpoint-gateway.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc--fe.id +} +# Internal. required-connections[0]: (segment vpeSegment)->(segment instanceSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc--appdata-endpoint-gateway-1" { + group = ibm_is_security_group.test-vpc--appdata-endpoint-gateway.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc--be.id +} + +### SG attached to test-vpc/be +resource "ibm_is_security_group" "test-vpc--be" { + name = "sg-test-vpc--be" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc_id +} +# Internal. required-connections[0]: (segment vpeSegment)->(segment instanceSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc--be-0" { + group = ibm_is_security_group.test-vpc--be.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc--appdata-endpoint-gateway.id +} +# Internal. required-connections[0]: (segment vpeSegment)->(segment instanceSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc--be-1" { + group = ibm_is_security_group.test-vpc--be.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id +} + +### SG attached to test-vpc/fe +resource "ibm_is_security_group" "test-vpc--fe" { + name = "sg-test-vpc--fe" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc_id +} +# Internal. required-connections[0]: (segment vpeSegment)->(segment instanceSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc--fe-0" { + group = ibm_is_security_group.test-vpc--fe.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc--appdata-endpoint-gateway.id +} +# Internal. required-connections[0]: (segment vpeSegment)->(segment instanceSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc--fe-1" { + group = ibm_is_security_group.test-vpc--fe.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id +} + +### SG attached to test-vpc/opa +resource "ibm_is_security_group" "test-vpc--opa" { + name = "sg-test-vpc--opa" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc_id +} + +### SG attached to test-vpc/policydb-endpoint-gateway +resource "ibm_is_security_group" "test-vpc--policydb-endpoint-gateway" { + name = "sg-test-vpc--policydb-endpoint-gateway" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc_id +} +# Internal. required-connections[0]: (segment vpeSegment)->(segment instanceSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc--policydb-endpoint-gateway-0" { + group = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc--fe.id +} +# Internal. required-connections[0]: (segment vpeSegment)->(segment instanceSegment); allowed-protocols[0] +resource "ibm_is_security_group_rule" "test-vpc--policydb-endpoint-gateway-1" { + group = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc--be.id +} + +### SG attached to test-vpc/proxy +resource "ibm_is_security_group" "test-vpc--proxy" { + name = "sg-test-vpc--proxy" + resource_group = local.sg_synth_resource_group_id + vpc = local.sg_synth_test-vpc_id +} diff --git a/test/synth_test_list.go b/test/synth_test_list.go index de3ed502..cf49b8f2 100644 --- a/test/synth_test_list.go +++ b/test/synth_test_list.go @@ -20,6 +20,10 @@ const ( aclTgMultipleSpec = "%s/acl_tg_multiple/conn_spec.json" aclVpeSpec = "%s/acl_vpe/conn_spec.json" sgProtocolsSpec = "%s/sg_protocols/conn_spec.json" + sgSegments1Spec = "%s/sg_segments1/conn_spec.json" + sgSegments2Spec = "%s/sg_segments2/conn_spec.json" + sgSegments3Spec = "%s/sg_segments3/conn_spec.json" + sgSegments4Spec = "%s/sg_segments4/conn_spec.json" sgTesting3Spec = "%s/sg_testing3/conn_spec.json" sgTgMultipleSpec = "%s/sg_tg_multiple/conn_spec.json" @@ -224,6 +228,7 @@ func synthACLTestsList() []testCase { } } +//nolint:funlen // test cases func synthSGTestsList() []testCase { return []testCase{ // sg protocols (all output fmts, externals, scoping, nif as a resource) ## tg-multiple config @@ -268,6 +273,54 @@ func synthSGTestsList() []testCase { }, }, + // sg segments1 (cidrSegment -> cidrSegment) + { + testName: "sg_segments1_tf", + args: &command{ + cmd: synth, + subcmd: sg, + config: tgMultipleConfig, + spec: sgSegments1Spec, + outputFile: "%s/sg_segments1_tf/sg_expected.tf", + }, + }, + + // sg segments2 (instanceSegment -> cidrSegment) + { + testName: "sg_segments2_tf", + args: &command{ + cmd: synth, + subcmd: sg, + config: tgMultipleConfig, + spec: sgSegments2Spec, + outputFile: "%s/sg_segments2_tf/sg_expected.tf", + }, + }, + + // sg segments3 (subnetSegment -> nifSegment) + { + testName: "sg_segments3_tf", + args: &command{ + cmd: synth, + subcmd: sg, + config: tgMultipleConfig, + spec: sgSegments3Spec, + outputFile: "%s/sg_segments3_tf/sg_expected.tf", + }, + }, + + // sg segments4 (vpeSegment -> instanceSegment) + { + testName: "sg_segments4_tf", + args: &command{ + cmd: synth, + subcmd: sg, + config: sgTesting3Config, + spec: sgSegments4Spec, + outputFile: "%s/sg_segments4_tf/sg_expected.tf", + }, + }, + // sg testing 3 (all fmts, VPEs are included) { testName: "sg_testing3_csv", From fe6f4e3cad9ecc08cae173880ea6ecded0c6bba9 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Sun, 20 Oct 2024 10:09:16 +0300 Subject: [PATCH 082/131] small fixes --- pkg/optimize/sg/reduceCubes.go | 31 +++++++++++++------------------ pkg/optimize/sg/rulesToCubes.go | 20 ++++++++++---------- pkg/optimize/sg/sg.go | 4 ++-- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/pkg/optimize/sg/reduceCubes.go b/pkg/optimize/sg/reduceCubes.go index b597b894..44d9a9d7 100644 --- a/pkg/optimize/sg/reduceCubes.go +++ b/pkg/optimize/sg/reduceCubes.go @@ -13,23 +13,22 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" ) -func reduceSGCubes(spans *sgCubesPerProtocol) *sgCubesPerProtocol { - spans = deleteOtherProtocolIfAllProtocolExists(spans) - return compressThreeProtocolsToAllProtocol(spans) +func reduceSGCubes(spans *sgCubesPerProtocol) { + deleteOtherProtocolIfAllProtocolExists(spans) + compressThreeProtocolsToAllProtocol(spans) } // delete other protocols rules if all protocol rule exists -func deleteOtherProtocolIfAllProtocolExists(spans *sgCubesPerProtocol) *sgCubesPerProtocol { +func deleteOtherProtocolIfAllProtocolExists(spans *sgCubesPerProtocol) { for _, sgName := range spans.all { delete(spans.tcp, sgName) delete(spans.udp, sgName) delete(spans.icmp, sgName) } - return spans } // merge tcp, udp and icmp rules into all protocol rule -func compressThreeProtocolsToAllProtocol(spans *sgCubesPerProtocol) *sgCubesPerProtocol { +func compressThreeProtocolsToAllProtocol(spans *sgCubesPerProtocol) { for sgName, tcpPorts := range spans.tcp { if udpPorts, ok := spans.udp[sgName]; ok { if ic, ok := spans.icmp[sgName]; ok { @@ -42,19 +41,17 @@ func compressThreeProtocolsToAllProtocol(spans *sgCubesPerProtocol) *sgCubesPerP } } } - return spans } // observation: It pays to switch to all protocol rule when we have rules that cover all other protocols // on exactly the same cidr (only one protocol can exceed). // //nolint:gocyclo // multiple if statments -func reduceIPCubes(cubes *ipCubesPerProtocol) *ipCubesPerProtocol { +func reduceIPCubes(cubes *ipCubesPerProtocol) { tcpPtr := 0 udpPtr := 0 icmpPtr := 0 - var changed bool for tcpPtr < len(cubes.tcp) && udpPtr < len(cubes.udp) && icmpPtr < len(cubes.icmp) { if !cubes.tcp[tcpPtr].Right.Equal(netset.AllPorts()) { tcpPtr++ @@ -69,8 +66,7 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) *ipCubesPerProtocol { continue } - cubes, changed = compressToAllCube(cubes, tcpPtr, udpPtr, icmpPtr) - if changed { + if compressedToAllCube(cubes, tcpPtr, udpPtr, icmpPtr) { continue } @@ -79,7 +75,7 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) *ipCubesPerProtocol { icmpIP := cubes.icmp[icmpPtr].Left switch { - // one protocol ipb contains two other ipbs. advance the smaller ipb + // one protocol ipb contains two other ipbs ==> advance the smaller ipb case udpIP.IsSubset(tcpIP) && icmpIP.IsSubset(tcpIP) && optimize.LessIPBlock(udpIP, icmpIP): udpPtr++ case udpIP.IsSubset(tcpIP) && icmpIP.IsSubset(tcpIP) && optimize.LessIPBlock(icmpIP, udpIP): @@ -102,11 +98,10 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) *ipCubesPerProtocol { icmpPtr++ } } - return cubes } // compress three protocol rules to all protocol rule (and maybe another protocol rule) -func compressToAllCube(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) (*ipCubesPerProtocol, bool) { +func compressedToAllCube(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) bool { tcpIP := cubes.tcp[tcpPtr].Left udpIP := cubes.udp[udpPtr].Left icmpIP := cubes.icmp[icmpPtr].Left @@ -119,17 +114,17 @@ func compressToAllCube(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) ( cubes.udp = slices.Delete(cubes.udp, udpPtr, udpPtr+1) cubes.icmp = slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) cubes.all = cubes.all.Union(udpIP) - return cubes, true + return true case tcpIP.IsSubset(udpIP) && tcpIP.Equal(icmpIP): cubes.tcp = slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) cubes.icmp = slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) cubes.all = cubes.all.Union(tcpIP) - return cubes, true + return true case tcpIP.IsSubset(icmpIP) && tcpIP.Equal(udpIP): cubes.tcp = slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) cubes.udp = slices.Delete(cubes.udp, udpPtr, udpPtr+1) cubes.all = cubes.all.Union(tcpIP) - return cubes, true + return true } - return cubes, false + return false } diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go index c8d14fcb..f3802ef1 100644 --- a/pkg/optimize/sg/rulesToCubes.go +++ b/pkg/optimize/sg/rulesToCubes.go @@ -18,11 +18,11 @@ import ( // SG remote func rulesToSGCubes(rules *rulesPerProtocol) *sgCubesPerProtocol { - tcpSpan := tcpudpRulesSGCubes(rules.tcp) - udpSpan := tcpudpRulesSGCubes(rules.udp) - icmpSpan := icmpRulesSGCubes(rules.icmp) - allSpan := allProtocolRulesToSGCubes(rules.all) - return &sgCubesPerProtocol{tcp: tcpSpan, udp: udpSpan, icmp: icmpSpan, all: allSpan} + return &sgCubesPerProtocol{tcp: tcpudpRulesSGCubes(rules.tcp), + udp: tcpudpRulesSGCubes(rules.udp), + icmp: icmpRulesSGCubes(rules.icmp), + all: allProtocolRulesToSGCubes(rules.all), + } } // all protocol rules to cubes @@ -66,11 +66,11 @@ func icmpRulesSGCubes(rules []*ir.SGRule) map[ir.SGName]*netset.ICMPSet { // IP remote func rulesToIPCubes(rules *rulesPerProtocol) *ipCubesPerProtocol { - tcpCubes := tcpudpRulesToIPCubes(rules.tcp) - udpCubes := tcpudpRulesToIPCubes(rules.udp) - icmpCubes := icmpRulesToIPCubes(rules.icmp) - allCubes := allProtocolRulesToIPCubes(rules.all) - return &ipCubesPerProtocol{tcp: tcpCubes, udp: udpCubes, icmp: icmpCubes, all: allCubes} + return &ipCubesPerProtocol{tcp: tcpudpRulesToIPCubes(rules.tcp), + udp: tcpudpRulesToIPCubes(rules.udp), + icmp: icmpRulesToIPCubes(rules.icmp), + all: allProtocolRulesToIPCubes(rules.all), + } } // all protocol rules to cubes diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index 2427c265..0da688a2 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -137,7 +137,7 @@ func (s *sgOptimizer) reduceRules(rules []*ir.SGRule, direction ir.Direction) [] } func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*ir.SGRule { - cubes = reduceSGCubes(cubes) + reduceSGCubes(cubes) // cubes to SG rules tcpRules := tcpudpSGCubesToRules(cubes.tcp, direction, true) @@ -150,7 +150,7 @@ func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*i } func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction) []*ir.SGRule { - cubes = reduceIPCubes(cubes) + reduceIPCubes(cubes) // cubes to SG rules tcpRules := tcpudpIPCubesToRules(cubes.tcp, cubes.all, direction, true) From 2f08925b395c785b2088f25ffcc86b8249436ee0 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Sun, 20 Oct 2024 13:06:34 +0300 Subject: [PATCH 083/131] fixed --- cmd/subcmds/output.go | 7 +- pkg/io/{csvio => }/common.go | 48 ++++----- pkg/io/{csvio/acl.go => commonACL.go} | 70 +++++-------- pkg/io/{csvio/sg.go => commonSG.go} | 57 ++++------ pkg/io/csvWriter.go | 38 +++++++ pkg/io/mdWriter.go | 71 +++++++++++++ pkg/io/mdio/acl.go | 138 ------------------------ pkg/io/mdio/common.go | 82 --------------- pkg/io/mdio/sg.go | 144 -------------------------- 9 files changed, 182 insertions(+), 473 deletions(-) rename pkg/io/{csvio => }/common.go (77%) rename pkg/io/{csvio/acl.go => commonACL.go} (68%) rename pkg/io/{csvio/sg.go => commonSG.go} (80%) create mode 100644 pkg/io/csvWriter.go create mode 100644 pkg/io/mdWriter.go delete mode 100644 pkg/io/mdio/acl.go delete mode 100644 pkg/io/mdio/common.go delete mode 100644 pkg/io/mdio/sg.go diff --git a/cmd/subcmds/output.go b/cmd/subcmds/output.go index b3f71013..66bf752a 100644 --- a/cmd/subcmds/output.go +++ b/cmd/subcmds/output.go @@ -12,9 +12,8 @@ import ( "os" "path/filepath" + "github.com/np-guard/vpc-network-config-synthesis/pkg/io" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/confio" - "github.com/np-guard/vpc-network-config-synthesis/pkg/io/csvio" - "github.com/np-guard/vpc-network-config-synthesis/pkg/io/mdio" "github.com/np-guard/vpc-network-config-synthesis/pkg/io/tfio" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -77,9 +76,9 @@ func pickWriter(args *inArgs, data *bytes.Buffer, isSynth bool) (ir.Writer, erro case tfOutputFormat: return tfio.NewWriter(w), nil case csvOutputFormat: - return csvio.NewWriter(w), nil + return io.NewCSVWriter(w), nil case mdOutputFormat: - return mdio.NewWriter(w), nil + return io.NewMDWriter(w), nil case jsonOutputFormat: if isSynth { return confio.NewWriter(w, args.configFile) diff --git a/pkg/io/csvio/common.go b/pkg/io/common.go similarity index 77% rename from pkg/io/csvio/common.go rename to pkg/io/common.go index 41cd664d..4e4f9e33 100644 --- a/pkg/io/csvio/common.go +++ b/pkg/io/common.go @@ -3,33 +3,22 @@ Copyright 2023- IBM Inc. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -// Package csvio implements output of ACLs and security groups in CSV format -package csvio +package io import ( - "encoding/csv" "fmt" - "io" "strconv" "strings" + "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -// Writer implements ir.Writer -type Writer struct { - w *csv.Writer -} - -func NewWriter(w io.Writer) *Writer { - return &Writer{w: csv.NewWriter(w)} -} - const ( anyProtocol = "ALL" - nonIcmp = "-" // IBM cloud uses "—" + nonIcmp = "-" anyIcmpValue = "Any" ) @@ -40,6 +29,25 @@ func direction(d ir.Direction) string { return "Outbound" } +func printProtocolName(protocol netp.Protocol) string { + switch p := protocol.(type) { + case netp.ICMP: + return "ICMP" + case netp.TCPUDP: + return strings.ToUpper(string(p.ProtocolString())) + case netp.AnyProtocol: + return anyProtocol + } + return "" +} + +func printPorts(p interval.Interval) string { + if p.Equal(netp.AllPorts()) { + return "any port" + } + return fmt.Sprintf("ports %v-%v", p.Start(), p.End()) +} + func printICMPTypeCode(protocol netp.Protocol) string { p, ok := protocol.(netp.ICMP) if !ok { @@ -55,15 +63,3 @@ func printICMPTypeCode(protocol netp.Protocol) string { } return fmt.Sprintf("Type: %v, Code: %v", icmpType, icmpCode) } - -func printProtocolName(protocol netp.Protocol) string { - switch p := protocol.(type) { - case netp.ICMP: - return "ICMP" - case netp.TCPUDP: - return strings.ToUpper(string(p.ProtocolString())) - case netp.AnyProtocol: - return anyProtocol - } - return "" -} diff --git a/pkg/io/csvio/acl.go b/pkg/io/commonACL.go similarity index 68% rename from pkg/io/csvio/acl.go rename to pkg/io/commonACL.go index 643dfe38..99a1f0be 100644 --- a/pkg/io/csvio/acl.go +++ b/pkg/io/commonACL.go @@ -3,36 +3,44 @@ Copyright 2023- IBM Inc. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package csvio +package io import ( "errors" "fmt" "strconv" - "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" - "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -// Write prints an entire collection of acls as a single CSV table. -func (w *Writer) WriteACL(collection *ir.ACLCollection, vpc string) error { - if err := w.w.WriteAll(aclHeader()); err != nil { - return err - } +func WriteACL(collection *ir.ACLCollection, vpc string) ([][]string, error) { + res := make([][]string, 0) for _, subnet := range collection.SortedACLSubnets(vpc) { vpcName := ir.VpcFromScopedResource(subnet) aclTable, err := makeACLTable(collection.ACLs[vpcName][subnet], subnet) if err != nil { - return err - } - if err := w.w.WriteAll(aclTable); err != nil { - return err + return nil, err } + res = append(res, aclTable...) } - return nil + return res, nil +} + +func ACLHeader() [][]string { + return [][]string{{ + "Acl", + "Subnet", + "Direction", + "Rule priority", + "Allow or deny", + "Protocol", + "Source", + "Destination", + "Value", + "Description", + }} } func makeACLTable(t *ir.ACL, subnet string) ([][]string, error) { @@ -48,13 +56,6 @@ func makeACLTable(t *ir.ACL, subnet string) ([][]string, error) { return rows, nil } -func aclPort(p interval.Interval) string { - if p.Equal(netp.AllPorts()) { - return "any port" //nolint:goconst // independent decision for SG and ACL - } - return fmt.Sprintf("ports %v-%v", p.Start(), p.End()) -} - func action(a ir.Action) string { if a == ir.Deny { return "Deny" @@ -62,24 +63,9 @@ func action(a ir.Action) string { return "Allow" } -func aclHeader() [][]string { - return [][]string{{ - "Acl", - "Subnet", - "Direction", - "Rule priority", - "Allow or deny", - "Protocol", - "Source", - "Destination", - "Value", - "Description", - }} -} - func makeACLRow(priority int, rule *ir.ACLRule, aclName, subnet string) ([]string, error) { - srcProtocol, err1 := printIP(rule.Source, rule.Protocol, true) - dstProtocol, err2 := printIP(rule.Destination, rule.Protocol, false) + src, err1 := printIP(rule.Source, rule.Protocol, true) + dst, err2 := printIP(rule.Destination, rule.Protocol, false) if errors.Join(err1, err2) != nil { return nil, errors.Join(err1, err2) } @@ -91,8 +77,8 @@ func makeACLRow(priority int, rule *ir.ACLRule, aclName, subnet string) ([]strin strconv.Itoa(priority), action(rule.Action), printProtocolName(rule.Protocol), - srcProtocol, - dstProtocol, + src, + dst, printICMPTypeCode(rule.Protocol), rule.Explanation, }, nil @@ -107,13 +93,11 @@ func printIP(ip *netset.IPBlock, protocol netp.Protocol, isSource bool) (string, case netp.ICMP: return ipString, nil case netp.TCPUDP: - var r interval.Interval + r := p.DstPorts() if isSource { r = p.SrcPorts() - } else { - r = p.DstPorts() } - return fmt.Sprintf("%v, %v", ipString, aclPort(r)), nil + return fmt.Sprintf("%v, %v", ipString, printPorts(r)), nil case netp.AnyProtocol: return ipString, nil } diff --git a/pkg/io/csvio/sg.go b/pkg/io/commonSG.go similarity index 80% rename from pkg/io/csvio/sg.go rename to pkg/io/commonSG.go index 35c74f8b..d7ab5793 100644 --- a/pkg/io/csvio/sg.go +++ b/pkg/io/commonSG.go @@ -3,23 +3,19 @@ Copyright 2023- IBM Inc. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package csvio +package io import ( "errors" "fmt" - "github.com/np-guard/models/pkg/interval" "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 (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { - if err := w.w.WriteAll(sgHeader()); err != nil { - return err - } +func WriteSG(collection *ir.SGCollection, vpc string) ([][]string, error) { + res := make([][]string, 0) for _, vpcName := range collection.VpcNames() { if vpc != vpcName && vpc != "" { continue @@ -27,17 +23,15 @@ func (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { for _, sgName := range collection.SortedSGNames(vpcName) { sgTable, err := makeSGTable(collection.SGs[vpcName][sgName], sgName) if err != nil { - return err - } - if err := w.w.WriteAll(sgTable); err != nil { - return err + return nil, err } + res = append(res, sgTable...) } } - return nil + return res, nil } -func sgHeader() [][]string { +func SGHeader() [][]string { return [][]string{{ "SG", "Direction", @@ -49,6 +43,19 @@ func sgHeader() [][]string { }} } +func makeSGTable(t *ir.SG, sgName ir.SGName) ([][]string, error) { + rules := t.AllRules() + rows := make([][]string, len(rules)) + for i, rule := range rules { + sgRow, err := makeSGRow(rule, sgName) + if err != nil { + return nil, err + } + rows[i] = sgRow + } + return rows, nil +} + func makeSGRow(rule *ir.SGRule, sgName ir.SGName) ([]string, error) { remoteType, err1 := sgRemoteType(rule.Remote) remote, err2 := sgRemote(rule.Remote) @@ -68,28 +75,6 @@ func makeSGRow(rule *ir.SGRule, sgName ir.SGName) ([]string, error) { }, nil } -func makeSGTable(t *ir.SG, sgName ir.SGName) ([][]string, error) { - rules := t.AllRules() - rows := make([][]string, len(rules)) - for i, rule := range rules { - sgRow, err := makeSGRow(rule, sgName) - if err != nil { - return nil, err - } - rows[i] = sgRow - } - return rows, nil -} - -func sgPort(p interval.Interval) string { - switch { - case p.Start() == netp.MinPort && p.End() == netp.MaxPort: - return "any port" - default: - return fmt.Sprintf("ports %v-%v", p.Start(), p.End()) - } -} - func sgRemoteType(t ir.RemoteType) (string, error) { switch p := t.(type) { case *netset.IPBlock: @@ -122,7 +107,7 @@ func printProtocolParams(protocol netp.Protocol) (string, error) { case netp.ICMP: return printICMPTypeCode(protocol), nil case netp.TCPUDP: - return sgPort(p.DstPorts()), nil + return printPorts(p.DstPorts()), nil case netp.AnyProtocol: return "", nil } diff --git a/pkg/io/csvWriter.go b/pkg/io/csvWriter.go new file mode 100644 index 00000000..4c97b060 --- /dev/null +++ b/pkg/io/csvWriter.go @@ -0,0 +1,38 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package io + +import ( + "encoding/csv" + "io" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +// CSVWriter implements ir.Writer +type CSVWriter struct { + w *csv.Writer +} + +func NewCSVWriter(w io.Writer) *CSVWriter { + return &CSVWriter{w: csv.NewWriter(w)} +} + +func (w *CSVWriter) WriteSG(collection *ir.SGCollection, vpc string) error { + sgTable, err := WriteSG(collection, vpc) + if err != nil { + return err + } + return w.w.WriteAll(append(SGHeader(), sgTable...)) +} + +func (w *CSVWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { + aclTable, err := WriteACL(collection, vpc) + if err != nil { + return err + } + return w.w.WriteAll(append(ACLHeader(), aclTable...)) +} diff --git a/pkg/io/mdWriter.go b/pkg/io/mdWriter.go new file mode 100644 index 00000000..5da1d3ed --- /dev/null +++ b/pkg/io/mdWriter.go @@ -0,0 +1,71 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package io + +import ( + "bufio" + "io" + "strings" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +const ( + sgColsNum = 7 + aclColsNum = 10 + + leftAlign = " :--- " + separator = " | " +) + +// MDWriter implements ir.Writer +type MDWriter struct { + w *bufio.Writer +} + +func NewMDWriter(w io.Writer) *MDWriter { + return &MDWriter{w: bufio.NewWriter(w)} +} + +func (w *MDWriter) WriteSG(collection *ir.SGCollection, vpc string) error { + sgTable, err := WriteSG(collection, vpc) + if err != nil { + return err + } + return w.writeAll(append(append(SGHeader(), addAlighns(sgColsNum)...), sgTable...)) +} + +func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { + aclTable, err := WriteACL(collection, vpc) + if err != nil { + return err + } + return w.writeAll(append(append(ACLHeader(), addAlighns(aclColsNum)...), aclTable...)) +} + +func (w *MDWriter) writeAll(rows [][]string) error { + for _, row := range rows { + if _, err := w.w.WriteString(separator); err != nil { + return err + } + if _, err := w.w.WriteString(strings.Join(row, separator)); err != nil { + return err + } + if _, err := w.w.WriteString(separator + "\n"); err != nil { + return err + } + } + w.w.Flush() + return nil +} + +func addAlighns(n int) [][]string { + res := make([]string, n) + for i := range n { + res[i] = leftAlign + } + return [][]string{res} +} diff --git a/pkg/io/mdio/acl.go b/pkg/io/mdio/acl.go deleted file mode 100644 index 17f2b2ee..00000000 --- a/pkg/io/mdio/acl.go +++ /dev/null @@ -1,138 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package mdio - -import ( - "errors" - "fmt" - "strconv" - - "github.com/np-guard/models/pkg/interval" - "github.com/np-guard/models/pkg/netp" - "github.com/np-guard/models/pkg/netset" - - "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" -) - -// Write prints an entire collection of acls as a single MD table. -func (w *Writer) WriteACL(collection *ir.ACLCollection, vpc string) error { - if err := w.writeAll(aclHeader()); err != nil { - return err - } - for _, subnet := range collection.SortedACLSubnets(vpc) { - vpcName := ir.VpcFromScopedResource(subnet) - aclTable, err := makeACLTable(collection.ACLs[vpcName][subnet], subnet) - if err != nil { - return err - } - if err := w.writeAll(aclTable); err != nil { - return err - } - } - return nil -} - -func makeACLTable(t *ir.ACL, subnet string) ([][]string, error) { - rules := t.Rules() - rows := make([][]string, len(rules)) - for i, rule := range rules { - aclRow, err := makeACLRow(i+1, rule, t.Name(), subnet) - if err != nil { - return nil, err - } - rows[i] = aclRow - } - return rows, nil -} - -func aclPort(p interval.Interval) string { - if p.Equal(netp.AllPorts()) { - return "any port" //nolint:goconst // independent decision for SG and ACL - } - return fmt.Sprintf("ports %v-%v", p.Start(), p.End()) -} - -func action(a ir.Action) string { - if a == ir.Deny { - return "Deny" - } - return "Allow" -} - -func aclHeader() [][]string { - return [][]string{{ - "", - "Acl", - "Subnet", - "Direction", - "Rule priority", - "Allow or deny", - "Protocol", - "Source", - "Destination", - "Value", - "Description", - "", - }, { - "", - leftAlign, - leftAlign, - leftAlign, - leftAlign, - leftAlign, - leftAlign, - leftAlign, - leftAlign, - leftAlign, - leftAlign, - "", - }} -} - -func makeACLRow(priority int, rule *ir.ACLRule, aclName, subnet string) ([]string, error) { - srcProtocol, err1 := printIP(rule.Source, rule.Protocol, true) - dstProtocol, err2 := printIP(rule.Destination, rule.Protocol, false) - if err := errors.Join(err1, err2); err != nil { - return nil, err - } - - return []string{ - "", - aclName, - subnet, - direction(rule.Direction), - strconv.Itoa(priority), - action(rule.Action), - printProtocolName(rule.Protocol), - srcProtocol, - dstProtocol, - printICMPTypeCode(rule.Protocol), - rule.Explanation, - "", - }, nil -} - -func printIP(ip *netset.IPBlock, protocol netp.Protocol, isSource bool) (string, error) { - ipString := ip.String() - if ip.Equal(netset.GetCidrAll()) { - ipString = "Any IP" //nolint:goconst // independent decision for SG and ACL - } - switch p := protocol.(type) { - case netp.ICMP: - return ipString, nil - case netp.TCPUDP: - var r interval.Interval - if isSource { - r = p.SrcPorts() - } else { - r = p.DstPorts() - } - return fmt.Sprintf("%v, %v", ipString, aclPort(r)), nil - case netp.AnyProtocol: - return ipString, nil - } - return "", fmt.Errorf("impossible protocol %T", protocol) -} diff --git a/pkg/io/mdio/common.go b/pkg/io/mdio/common.go deleted file mode 100644 index abfb24a8..00000000 --- a/pkg/io/mdio/common.go +++ /dev/null @@ -1,82 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -// Package mdio implements output of ACLs and security groups in CSV format -package mdio - -import ( - "bufio" - "fmt" - "io" - "strconv" - "strings" - - "github.com/np-guard/models/pkg/netp" - - "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" -) - -const leftAlign = " :--- " - -// Writer implements ir.Writer -type Writer struct { - w *bufio.Writer -} - -func NewWriter(w io.Writer) *Writer { - return &Writer{w: bufio.NewWriter(w)} -} - -func (w *Writer) writeAll(rows [][]string) error { - for _, row := range rows { - _, err := w.w.WriteString(strings.Join(row, " | ") + "\n") - if err != nil { - return err - } - } - w.w.Flush() - return nil -} - -const ( - anyProtocol = "ALL" - nonIcmp = "-" - anyIcmpValue = "Any" -) - -func direction(d ir.Direction) string { - if d == ir.Inbound { - return "Inbound" - } - return "Outbound" -} - -func printICMPTypeCode(protocol netp.Protocol) string { - p, ok := protocol.(netp.ICMP) - if !ok { - return nonIcmp - } - icmpType := anyIcmpValue - icmpCode := anyIcmpValue - if typeCode := p.ICMPTypeCode(); typeCode != nil { - icmpType = strconv.Itoa(typeCode.Type) - if typeCode.Code != nil { - icmpCode = strconv.Itoa(*typeCode.Code) - } - } - return fmt.Sprintf("Type: %v, Code: %v", icmpType, icmpCode) -} - -func printProtocolName(protocol netp.Protocol) string { - switch p := protocol.(type) { - case netp.ICMP: - return "ICMP" - case netp.TCPUDP: - return strings.ToUpper(string(p.ProtocolString())) - case netp.AnyProtocol: - return anyProtocol - } - return "" -} diff --git a/pkg/io/mdio/sg.go b/pkg/io/mdio/sg.go deleted file mode 100644 index 0fcbf734..00000000 --- a/pkg/io/mdio/sg.go +++ /dev/null @@ -1,144 +0,0 @@ -/* -Copyright 2023- IBM Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package mdio - -import ( - "errors" - "fmt" - - "github.com/np-guard/models/pkg/interval" - "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 (w *Writer) WriteSG(collection *ir.SGCollection, vpc string) error { - if err := w.writeAll(sgHeader()); err != nil { - return err - } - for _, vpcName := range collection.VpcNames() { - if vpc != vpcName && vpc != "" { - continue - } - for _, sgName := range collection.SortedSGNames(vpcName) { - sgTable, err := makeSGTable(collection.SGs[vpcName][sgName], sgName) - if err != nil { - return err - } - if err := w.writeAll(sgTable); err != nil { - return err - } - } - } - return nil -} - -func sgHeader() [][]string { - return [][]string{{ - "", - "SG", - "Direction", - "Remote type", - "Remote", - "Protocol", - "Protocol params", - "Description", - "", - }, { - "", - leftAlign, - leftAlign, - leftAlign, - leftAlign, - leftAlign, - leftAlign, - leftAlign, - "", - }} -} - -func makeSGRow(rule *ir.SGRule, sgName ir.SGName) ([]string, error) { - remoteType, err1 := sgRemoteType(rule.Remote) - remote, err2 := sgRemote(rule.Remote) - protocolParams, err3 := printProtocolParams(rule.Protocol) - if err := errors.Join(err1, err2, err3); err != nil { - return nil, err - } - - return []string{ - "", - string(sgName), - direction(rule.Direction), - remoteType, - remote, - printProtocolName(rule.Protocol), - protocolParams, - rule.Explanation, - "", - }, nil -} - -func makeSGTable(t *ir.SG, sgName ir.SGName) ([][]string, error) { - rules := t.AllRules() - rows := make([][]string, len(rules)) - for i, rule := range rules { - sgRow, err := makeSGRow(rule, sgName) - if err != nil { - return nil, err - } - rows[i] = sgRow - } - return rows, nil -} - -func sgPort(p interval.Interval) string { - switch { - case p.Start() == netp.MinPort && p.End() == netp.MaxPort: - return "any port" - default: - return fmt.Sprintf("ports %v-%v", p.Start(), p.End()) - } -} - -func sgRemoteType(t ir.RemoteType) (string, error) { - switch r := t.(type) { - case *netset.IPBlock: - if ipString := r.ToIPAddressString(); ipString != "" { // single IP address - return "IP address", nil - } - return "CIDR block", nil - case ir.SGName: - return "Security group", nil - } - return "", fmt.Errorf("impossible remote type %T", t) -} - -func sgRemote(r ir.RemoteType) (string, error) { - switch tr := r.(type) { - case *netset.IPBlock: - s := tr.String() - if s == netset.CidrAll { - return "Any IP", nil - } - return s, nil - case ir.SGName: - return tr.String(), nil - } - return "", fmt.Errorf("impossible remote %v (%T)", r, r) -} - -func printProtocolParams(protocol netp.Protocol) (string, error) { - switch p := protocol.(type) { - case netp.ICMP: - return printICMPTypeCode(protocol), nil - case netp.TCPUDP: - return sgPort(p.DstPorts()), nil - case netp.AnyProtocol: - return "", nil - } - return "", fmt.Errorf("impossible protocol %v (type %T)", protocol, protocol) -} From fb59982440573bcca8bdb22e008dc0322698b5da Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Sun, 20 Oct 2024 15:39:28 +0300 Subject: [PATCH 084/131] added isSynth argument --- cmd/subcmds/output.go | 2 +- pkg/io/confio/acl.go | 2 +- pkg/io/confio/sg.go | 2 +- pkg/io/csvWriter.go | 4 ++-- pkg/io/mdWriter.go | 4 ++-- pkg/io/tfio/acl.go | 2 +- pkg/io/tfio/sg.go | 2 +- pkg/ir/acl.go | 6 +++--- pkg/ir/common.go | 2 +- pkg/ir/sg.go | 6 +++--- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cmd/subcmds/output.go b/cmd/subcmds/output.go index 66bf752a..97acf01a 100644 --- a/cmd/subcmds/output.go +++ b/cmd/subcmds/output.go @@ -64,7 +64,7 @@ func writeCollection(args *inArgs, collection ir.Collection, vpc string, isSynth if err != nil { return nil, err } - if err := collection.Write(writer, vpc); err != nil { + if err := collection.Write(writer, vpc, isSynth); err != nil { return nil, err } return &data, nil diff --git a/pkg/io/confio/acl.go b/pkg/io/confio/acl.go index ae5e7a7b..03059301 100644 --- a/pkg/io/confio/acl.go +++ b/pkg/io/confio/acl.go @@ -209,7 +209,7 @@ func subnetRef(subnet *configModel.Subnet) *vpcv1.SubnetReference { } } -func (w *Writer) WriteACL(collection *ir.ACLCollection, _ string) error { +func (w *Writer) WriteACL(collection *ir.ACLCollection, _ string, _ bool) error { if err := updateACLList(w.model, collection); err != nil { return err } diff --git a/pkg/io/confio/sg.go b/pkg/io/confio/sg.go index e4b74be7..90f1fd4f 100644 --- a/pkg/io/confio/sg.go +++ b/pkg/io/confio/sg.go @@ -258,7 +258,7 @@ func updateSG(model *configModel.ResourcesContainerModel, collection *ir.SGColle return errors.Join(err1, err2) } -func (w *Writer) WriteSG(collection *ir.SGCollection, _ string) error { +func (w *Writer) WriteSG(collection *ir.SGCollection, _ string, isSynth bool) error { if err := updateSG(w.model, collection); err != nil { return err } diff --git a/pkg/io/csvWriter.go b/pkg/io/csvWriter.go index 4c97b060..e583ca45 100644 --- a/pkg/io/csvWriter.go +++ b/pkg/io/csvWriter.go @@ -21,7 +21,7 @@ func NewCSVWriter(w io.Writer) *CSVWriter { return &CSVWriter{w: csv.NewWriter(w)} } -func (w *CSVWriter) WriteSG(collection *ir.SGCollection, vpc string) error { +func (w *CSVWriter) WriteSG(collection *ir.SGCollection, vpc string, _ bool) error { sgTable, err := WriteSG(collection, vpc) if err != nil { return err @@ -29,7 +29,7 @@ func (w *CSVWriter) WriteSG(collection *ir.SGCollection, vpc string) error { return w.w.WriteAll(append(SGHeader(), sgTable...)) } -func (w *CSVWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { +func (w *CSVWriter) WriteACL(collection *ir.ACLCollection, vpc string, _ bool) error { aclTable, err := WriteACL(collection, vpc) if err != nil { return err diff --git a/pkg/io/mdWriter.go b/pkg/io/mdWriter.go index 5da1d3ed..94b18553 100644 --- a/pkg/io/mdWriter.go +++ b/pkg/io/mdWriter.go @@ -30,7 +30,7 @@ func NewMDWriter(w io.Writer) *MDWriter { return &MDWriter{w: bufio.NewWriter(w)} } -func (w *MDWriter) WriteSG(collection *ir.SGCollection, vpc string) error { +func (w *MDWriter) WriteSG(collection *ir.SGCollection, vpc string, _ bool) error { sgTable, err := WriteSG(collection, vpc) if err != nil { return err @@ -38,7 +38,7 @@ func (w *MDWriter) WriteSG(collection *ir.SGCollection, vpc string) error { return w.writeAll(append(append(SGHeader(), addAlighns(sgColsNum)...), sgTable...)) } -func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { +func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string, _ bool) error { aclTable, err := WriteACL(collection, vpc) if err != nil { return err diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index d71b8d56..15b31afe 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -18,7 +18,7 @@ import ( ) // WriteACL prints an entire collection of acls as a sequence of terraform resources. -func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string) error { +func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string, _ bool) error { collection, err := aclCollection(c, vpc) if err != nil { return err diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index dafcaa6d..4d30de34 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -18,7 +18,7 @@ import ( ) // WriteSG prints an entire collection of Security Groups as a sequence of terraform resources. -func (w *Writer) WriteSG(c *ir.SGCollection, vpc string) error { +func (w *Writer) WriteSG(c *ir.SGCollection, vpc string, isSynth bool) error { collection, err := sgCollection(c, vpc) if err != nil { return err diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index e13b91bb..938a74e8 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -38,7 +38,7 @@ type ( } ACLWriter interface { - WriteACL(aclColl *ACLCollection, vpc string) error + WriteACL(aclColl *ACLCollection, vpc string, isSynth bool) error } ) @@ -128,8 +128,8 @@ func (c *ACLCollection) VpcNames() []string { return utils.SortedMapKeys(c.ACLs) } -func (c *ACLCollection) Write(w Writer, vpc string) error { - return w.WriteACL(c, vpc) +func (c *ACLCollection) Write(w Writer, vpc string, isSynth bool) error { + return w.WriteACL(c, vpc, isSynth) } func (c *ACLCollection) SortedACLSubnets(vpc string) []string { diff --git a/pkg/ir/common.go b/pkg/ir/common.go index a89aeae8..49d87bbc 100644 --- a/pkg/ir/common.go +++ b/pkg/ir/common.go @@ -9,7 +9,7 @@ type ( Direction string Collection interface { - Write(writer Writer, vpc string) error + Write(writer Writer, vpc string, isSynth bool) error VpcNames() []string } diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 286d683d..eb1737ec 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -54,7 +54,7 @@ type ( } SGWriter interface { - WriteSG(sgColl *SGCollection, vpc string) error + WriteSG(sgColl *SGCollection, vpc string, isSynth bool) error } ) @@ -122,8 +122,8 @@ func (c *SGCollection) VpcNames() []string { return utils.SortedMapKeys(c.SGs) } -func (c *SGCollection) Write(w Writer, vpc string) error { - return w.WriteSG(c, vpc) +func (c *SGCollection) Write(w Writer, vpc string, isSynth bool) error { + return w.WriteSG(c, vpc, isSynth) } func (c *SGCollection) SortedSGNames(vpc ID) []SGName { From 27bbf91796d2248a9ab5e64c90d8a035d835b594 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Sun, 20 Oct 2024 16:07:55 +0300 Subject: [PATCH 085/131] read sg targets, rename attached to targets --- pkg/io/confio/parse_sgs.go | 16 +++++++++++++++- pkg/ir/sg.go | 4 ++-- pkg/synth/sg.go | 4 ++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index e1528913..4ae37ecd 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -39,7 +39,10 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { if result.SGs[vpcName] == nil { result.SGs[vpcName] = make(map[ir.SGName]*ir.SG) } - result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, OutboundRules: outbound} + result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, + OutboundRules: outbound, + Targets: transalteTargets(sg.Targets), + } } return result, nil } @@ -170,6 +173,17 @@ func translateLocal(local vpcv1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, er return nil, fmt.Errorf("error parsing Local field") } +// translate SG targets +func transalteTargets(targets []vpcv1.SecurityGroupTargetReferenceIntf) []string { + res := make([]string, 0) + for i := range targets { + if t, ok := targets[i].(*vpcv1.SecurityGroupTargetReference); ok && t.Name != nil { + res = append(res, *t.Name) + } + } + return res +} + // temporary - first version of optimization requires local = 0.0.0.0/32 func verifyLocalValue(ipAddrs *netset.IPBlock) (*netset.IPBlock, error) { if !ipAddrs.Equal(netset.GetCidrAll()) { diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index eb1737ec..4ee2dd10 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -46,7 +46,7 @@ type ( SGName SGName InboundRules []*SGRule OutboundRules []*SGRule - Attached []ID + Targets []ID } SGCollection struct { @@ -85,7 +85,7 @@ func NewSGRule(direction Direction, remote RemoteType, p netp.Protocol, local *n } func NewSG(sgName SGName) *SG { - return &SG{SGName: sgName, InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Attached: []ID{}} + return &SG{SGName: sgName, InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Targets: []ID{}} } func NewSGCollection() *SGCollection { diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index c90b1783..4ffd887b 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -84,7 +84,7 @@ func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *n } localSGName := ir.SGName(localEndpoint.Name) localSG := s.result.LookupOrCreate(localSGName) - localSG.Attached = []ir.ID{ir.ID(localSGName)} + localSG.Targets = []ir.ID{ir.ID(localSGName)} rule := &ir.SGRule{ Remote: sgRemote(&s.spec.Defs, remoteEndpoint), Direction: direction, @@ -99,7 +99,7 @@ func (s *SGSynthesizer) generateSGsForBlockedResources() { blockedResources := s.spec.ComputeBlockedResources() for _, resource := range blockedResources { sg := s.result.LookupOrCreate(ir.SGName(resource)) // an empty SG allows no connections - sg.Attached = []ir.ID{resource} + sg.Targets = []ir.ID{resource} } } From 40e87d32a2aab56dcbe52560bd6281bec9674567 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Sun, 20 Oct 2024 16:33:41 +0300 Subject: [PATCH 086/131] tf comment, read targets --- pkg/io/commonACL.go | 1 + pkg/io/commonSG.go | 1 + pkg/io/confio/parse_sgs.go | 16 ++++++--- pkg/io/tfio/sg.go | 26 +++++++------- .../sg_expected.tf | 11 +++--- .../optimize_sg_redundant/sg_expected.tf | 11 +++--- test/expected/optimize_sg_t/sg_expected.tf | 11 +++--- .../expected/optimize_sg_t_all/sg_expected.tf | 11 +++--- test/expected/sg_protocols_tf/sg_expected.tf | 36 +++++++++---------- test/expected/sg_testing3_tf/sg_expected.tf | 12 +++---- .../sg_tg_multiple_tf_separate/test-vpc0.tf | 24 ++++++------- .../sg_tg_multiple_tf_separate/test-vpc1.tf | 4 +-- .../sg_tg_multiple_tf_separate/test-vpc2.tf | 6 ++-- .../sg_tg_multiple_tf_separate/test-vpc3.tf | 2 +- 14 files changed, 92 insertions(+), 80 deletions(-) diff --git a/pkg/io/commonACL.go b/pkg/io/commonACL.go index 99a1f0be..3dfe2537 100644 --- a/pkg/io/commonACL.go +++ b/pkg/io/commonACL.go @@ -12,6 +12,7 @@ import ( "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) diff --git a/pkg/io/commonSG.go b/pkg/io/commonSG.go index d7ab5793..021f5a57 100644 --- a/pkg/io/commonSG.go +++ b/pkg/io/commonSG.go @@ -11,6 +11,7 @@ import ( "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index 4ae37ecd..5b0cdc95 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -39,9 +39,10 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { if result.SGs[vpcName] == nil { result.SGs[vpcName] = make(map[ir.SGName]*ir.SG) } - result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, + result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{SGName: ir.SGName(*sg.Name), + InboundRules: inbound, OutboundRules: outbound, - Targets: transalteTargets(sg.Targets), + Targets: transalteTargets(&sg.SecurityGroup), } } return result, nil @@ -174,11 +175,16 @@ func translateLocal(local vpcv1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, er } // translate SG targets -func transalteTargets(targets []vpcv1.SecurityGroupTargetReferenceIntf) []string { +func transalteTargets(sg *vpcv1.SecurityGroup) []string { + if len(sg.Targets) == 0 { + log.Printf("Warning: Security Groups %s does not have attached resources", *sg.Name) + } res := make([]string, 0) - for i := range targets { - if t, ok := targets[i].(*vpcv1.SecurityGroupTargetReference); ok && t.Name != nil { + for i := range sg.Targets { + if t, ok := sg.Targets[i].(*vpcv1.SecurityGroupTargetReference); ok && t.Name != nil { res = append(res, *t.Name) + } else { + log.Printf("Warning: error translating target %d in %s Security Group", i, *sg.Name) } } return res diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 4d30de34..05d330a1 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -18,7 +18,7 @@ import ( ) // WriteSG prints an entire collection of Security Groups as a sequence of terraform resources. -func (w *Writer) WriteSG(c *ir.SGCollection, vpc string, isSynth bool) error { +func (w *Writer) WriteSG(c *ir.SGCollection, vpc string, _ bool) error { collection, err := sgCollection(c, vpc) if err != nil { return err @@ -79,7 +79,7 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { return tf.Block{ Name: "resource", - Labels: []string{quote("ibm_is_security_group_rule"), ir.ChangeScoping(quote(ruleName))}, + Labels: []string{quote("ibm_is_security_group_rule"), quote(ruleName)}, Comment: comment, Arguments: []tf.Argument{ {Name: "group", Value: group}, @@ -90,21 +90,21 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { }, nil } -func sg(sgName, vpcName string) (tf.Block, error) { - tfSGName := ir.ChangeScoping(sgName) - comment := fmt.Sprintf("\n### SG attached to %s", sgName) - if sgName == tfSGName { // optimization mode - comment = "\n" +func sg(sG *ir.SG, vpcName string) (tf.Block, error) { + sgName := ir.ChangeScoping(sG.SGName.String()) + comment := fmt.Sprintf("\n### SG %s is attached to %s", sgName, strings.Join(sG.Targets, ", ")) + if len(sG.Targets) == 0 { + comment = fmt.Sprintf("\n### SG %s is not attached to anything", sgName) } - if err := verifyName(tfSGName); err != nil { + if err := verifyName(sgName); err != nil { return tf.Block{}, err } return tf.Block{ Name: "resource", //nolint:revive // obvious false positive - Labels: []string{quote("ibm_is_security_group"), quote(tfSGName)}, + Labels: []string{quote("ibm_is_security_group"), quote(sgName)}, Comment: comment, Arguments: []tf.Argument{ - {Name: "name", Value: quote("sg-" + tfSGName)}, + {Name: "name", Value: quote("sg-" + sgName)}, {Name: "resource_group", Value: "local.sg_synth_resource_group_id"}, {Name: "vpc", Value: fmt.Sprintf("local.sg_synth_%s_id", vpcName)}, }, @@ -119,13 +119,13 @@ func sgCollection(collection *ir.SGCollection, vpc string) (*tf.ConfigFile, erro continue } for _, sgName := range collection.SortedSGNames(vpcName) { - rules := collection.SGs[vpcName][sgName].AllRules() - sg, err := sg(sgName.String(), vpcName) + sG := collection.SGs[vpcName][sgName] + sg, err := sg(sG, vpcName) if err != nil { return nil, err } resources = append(resources, sg) - for i, rule := range rules { + for i, rule := range sG.AllRules() { rule, err := sgRule(rule, sgName, i) if err != nil { return nil, err diff --git a/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf b/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf index 10f44116..3b2fc12f 100644 --- a/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf +++ b/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf @@ -1,3 +1,4 @@ +### SG sg1 is not attached to anything resource "ibm_is_security_group" "sg1" { name = "sg-sg1" resource_group = local.sg_synth_resource_group_id @@ -14,7 +15,7 @@ resource "ibm_is_security_group_rule" "sg1-1" { remote = "0.0.0.0/0" } - +### SG test-vpc1--vsi1 is attached to ni1 resource "ibm_is_security_group" "test-vpc1--vsi1" { name = "sg-test-vpc1--vsi1" resource_group = local.sg_synth_resource_group_id @@ -38,7 +39,7 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi1-2" { remote = "0.0.0.0/31" } - +### SG test-vpc1--vsi2 is attached to ni2 resource "ibm_is_security_group" "test-vpc1--vsi2" { name = "sg-test-vpc1--vsi2" resource_group = local.sg_synth_resource_group_id @@ -50,21 +51,21 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi2-0" { remote = ibm_is_security_group.test-vpc1--vsi1.id } - +### SG test-vpc1--vsi3a is attached to ni3a resource "ibm_is_security_group" "test-vpc1--vsi3a" { name = "sg-test-vpc1--vsi3a" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } - +### SG test-vpc1--vsi3b is attached to ni3b resource "ibm_is_security_group" "test-vpc1--vsi3b" { name = "sg-test-vpc1--vsi3b" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } - +### SG wombat-hesitate-scorn-subprime is not attached to anything resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { name = "sg-wombat-hesitate-scorn-subprime" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/optimize_sg_redundant/sg_expected.tf b/test/expected/optimize_sg_redundant/sg_expected.tf index 88239143..5ee3d54f 100644 --- a/test/expected/optimize_sg_redundant/sg_expected.tf +++ b/test/expected/optimize_sg_redundant/sg_expected.tf @@ -1,3 +1,4 @@ +### SG sg1 is not attached to anything resource "ibm_is_security_group" "sg1" { name = "sg-sg1" resource_group = local.sg_synth_resource_group_id @@ -14,7 +15,7 @@ resource "ibm_is_security_group_rule" "sg1-1" { remote = "0.0.0.0/0" } - +### SG test-vpc1--vsi1 is attached to ni1 resource "ibm_is_security_group" "test-vpc1--vsi1" { name = "sg-test-vpc1--vsi1" resource_group = local.sg_synth_resource_group_id @@ -31,7 +32,7 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { remote = "0.0.0.0/30" } - +### SG test-vpc1--vsi2 is attached to ni2 resource "ibm_is_security_group" "test-vpc1--vsi2" { name = "sg-test-vpc1--vsi2" resource_group = local.sg_synth_resource_group_id @@ -43,21 +44,21 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi2-0" { remote = ibm_is_security_group.test-vpc1--vsi1.id } - +### SG test-vpc1--vsi3a is attached to ni3a resource "ibm_is_security_group" "test-vpc1--vsi3a" { name = "sg-test-vpc1--vsi3a" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } - +### SG test-vpc1--vsi3b is attached to ni3b resource "ibm_is_security_group" "test-vpc1--vsi3b" { name = "sg-test-vpc1--vsi3b" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } - +### SG wombat-hesitate-scorn-subprime is not attached to anything resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { name = "sg-wombat-hesitate-scorn-subprime" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/optimize_sg_t/sg_expected.tf b/test/expected/optimize_sg_t/sg_expected.tf index 448d25d8..995e1b94 100644 --- a/test/expected/optimize_sg_t/sg_expected.tf +++ b/test/expected/optimize_sg_t/sg_expected.tf @@ -1,3 +1,4 @@ +### SG sg1 is not attached to anything resource "ibm_is_security_group" "sg1" { name = "sg-sg1" resource_group = local.sg_synth_resource_group_id @@ -14,7 +15,7 @@ resource "ibm_is_security_group_rule" "sg1-1" { remote = "0.0.0.0/0" } - +### SG test-vpc1--vsi1 is attached to ni1 resource "ibm_is_security_group" "test-vpc1--vsi1" { name = "sg-test-vpc1--vsi1" resource_group = local.sg_synth_resource_group_id @@ -37,28 +38,28 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { } } - +### SG test-vpc1--vsi2 is attached to ni2 resource "ibm_is_security_group" "test-vpc1--vsi2" { name = "sg-test-vpc1--vsi2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } - +### SG test-vpc1--vsi3a is attached to ni3a resource "ibm_is_security_group" "test-vpc1--vsi3a" { name = "sg-test-vpc1--vsi3a" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } - +### SG test-vpc1--vsi3b is attached to ni3b resource "ibm_is_security_group" "test-vpc1--vsi3b" { name = "sg-test-vpc1--vsi3b" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } - +### SG wombat-hesitate-scorn-subprime is not attached to anything resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { name = "sg-wombat-hesitate-scorn-subprime" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/optimize_sg_t_all/sg_expected.tf b/test/expected/optimize_sg_t_all/sg_expected.tf index 0f4d41e0..fd5b626f 100644 --- a/test/expected/optimize_sg_t_all/sg_expected.tf +++ b/test/expected/optimize_sg_t_all/sg_expected.tf @@ -1,3 +1,4 @@ +### SG sg1 is not attached to anything resource "ibm_is_security_group" "sg1" { name = "sg-sg1" resource_group = local.sg_synth_resource_group_id @@ -14,7 +15,7 @@ resource "ibm_is_security_group_rule" "sg1-1" { remote = "0.0.0.0/0" } - +### SG test-vpc1--vsi1 is attached to ni1 resource "ibm_is_security_group" "test-vpc1--vsi1" { name = "sg-test-vpc1--vsi1" resource_group = local.sg_synth_resource_group_id @@ -34,28 +35,28 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { remote = "0.0.0.2/31" } - +### SG test-vpc1--vsi2 is attached to ni2 resource "ibm_is_security_group" "test-vpc1--vsi2" { name = "sg-test-vpc1--vsi2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } - +### SG test-vpc1--vsi3a is attached to ni3a resource "ibm_is_security_group" "test-vpc1--vsi3a" { name = "sg-test-vpc1--vsi3a" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } - +### SG test-vpc1--vsi3b is attached to ni3b resource "ibm_is_security_group" "test-vpc1--vsi3b" { name = "sg-test-vpc1--vsi3b" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } - +### SG wombat-hesitate-scorn-subprime is not attached to anything resource "ibm_is_security_group" "wombat-hesitate-scorn-subprime" { name = "sg-wombat-hesitate-scorn-subprime" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/sg_protocols_tf/sg_expected.tf b/test/expected/sg_protocols_tf/sg_expected.tf index f7519b05..a85f889c 100644 --- a/test/expected/sg_protocols_tf/sg_expected.tf +++ b/test/expected/sg_protocols_tf/sg_expected.tf @@ -1,4 +1,4 @@ -### SG attached to test-vpc0/vsi0-subnet0 +### SG test-vpc0--vsi0-subnet0 is attached to test-vpc0/vsi0-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { name = "sg-test-vpc0--vsi0-subnet0" resource_group = local.sg_synth_resource_group_id @@ -21,7 +21,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-1" { } } -### SG attached to test-vpc0/vsi0-subnet1 +### SG test-vpc0--vsi0-subnet1 is attached to test-vpc0/vsi0-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { name = "sg-test-vpc0--vsi0-subnet1" resource_group = local.sg_synth_resource_group_id @@ -44,7 +44,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-1" { } } -### SG attached to test-vpc0/vsi0-subnet2 +### SG test-vpc0--vsi0-subnet2 is attached to test-vpc0/vsi0-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { name = "sg-test-vpc0--vsi0-subnet2" resource_group = local.sg_synth_resource_group_id @@ -69,7 +69,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet2-1" { } } -### SG attached to test-vpc0/vsi0-subnet3 +### SG test-vpc0--vsi0-subnet3 is attached to test-vpc0/vsi0-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { name = "sg-test-vpc0--vsi0-subnet3" resource_group = local.sg_synth_resource_group_id @@ -94,21 +94,21 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet3-1" { } } -### SG attached to test-vpc0/vsi0-subnet4 +### SG test-vpc0--vsi0-subnet4 is attached to test-vpc0/vsi0-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { name = "sg-test-vpc0--vsi0-subnet4" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet5 +### SG test-vpc0--vsi0-subnet5 is attached to test-vpc0/vsi0-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { name = "sg-test-vpc0--vsi0-subnet5" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet0 +### SG test-vpc0--vsi1-subnet0 is attached to test-vpc0/vsi1-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { name = "sg-test-vpc0--vsi1-subnet0" resource_group = local.sg_synth_resource_group_id @@ -144,7 +144,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-2" { } } -### SG attached to test-vpc0/vsi1-subnet1 +### SG test-vpc0--vsi1-subnet1 is attached to test-vpc0/vsi1-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { name = "sg-test-vpc0--vsi1-subnet1" resource_group = local.sg_synth_resource_group_id @@ -180,35 +180,35 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-2" { } } -### SG attached to test-vpc0/vsi1-subnet2 +### SG test-vpc0--vsi1-subnet2 is attached to test-vpc0/vsi1-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { name = "sg-test-vpc0--vsi1-subnet2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet3 +### SG test-vpc0--vsi1-subnet3 is attached to test-vpc0/vsi1-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { name = "sg-test-vpc0--vsi1-subnet3" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet4 +### SG test-vpc0--vsi1-subnet4 is attached to test-vpc0/vsi1-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { name = "sg-test-vpc0--vsi1-subnet4" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet5 +### SG test-vpc0--vsi1-subnet5 is attached to test-vpc0/vsi1-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { name = "sg-test-vpc0--vsi1-subnet5" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc1/vsi0-subnet10 +### SG test-vpc1--vsi0-subnet10 is attached to test-vpc1/vsi0-subnet10 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { name = "sg-test-vpc1--vsi0-subnet10" resource_group = local.sg_synth_resource_group_id @@ -223,21 +223,21 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet10-0" { } } -### SG attached to test-vpc1/vsi0-subnet11 +### SG test-vpc1--vsi0-subnet11 is attached to test-vpc1/vsi0-subnet11 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { name = "sg-test-vpc1--vsi0-subnet11" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } -### SG attached to test-vpc2/vsi0-subnet20 +### SG test-vpc2--vsi0-subnet20 is attached to test-vpc2/vsi0-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { name = "sg-test-vpc2--vsi0-subnet20" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc2_id } -### SG attached to test-vpc2/vsi1-subnet20 +### SG test-vpc2--vsi1-subnet20 is attached to test-vpc2/vsi1-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { name = "sg-test-vpc2--vsi1-subnet20" resource_group = local.sg_synth_resource_group_id @@ -250,14 +250,14 @@ resource "ibm_is_security_group_rule" "test-vpc2--vsi1-subnet20-0" { remote = "0.0.0.0/0" } -### SG attached to test-vpc2/vsi2-subnet20 +### SG test-vpc2--vsi2-subnet20 is attached to test-vpc2/vsi2-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { name = "sg-test-vpc2--vsi2-subnet20" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc2_id } -### SG attached to test-vpc3/vsi0-subnet30 +### SG test-vpc3--vsi0-subnet30 is attached to test-vpc3/vsi0-subnet30 resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { name = "sg-test-vpc3--vsi0-subnet30" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/sg_testing3_tf/sg_expected.tf b/test/expected/sg_testing3_tf/sg_expected.tf index 8bfb66a3..c7ced9bf 100644 --- a/test/expected/sg_testing3_tf/sg_expected.tf +++ b/test/expected/sg_testing3_tf/sg_expected.tf @@ -1,11 +1,11 @@ -### SG attached to test-vpc/appdata-endpoint-gateway +### SG test-vpc--appdata-endpoint-gateway is attached to test-vpc/appdata-endpoint-gateway resource "ibm_is_security_group" "test-vpc--appdata-endpoint-gateway" { name = "sg-test-vpc--appdata-endpoint-gateway" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc_id } -### SG attached to test-vpc/be +### SG test-vpc--be is attached to test-vpc/be resource "ibm_is_security_group" "test-vpc--be" { name = "sg-test-vpc--be" resource_group = local.sg_synth_resource_group_id @@ -32,7 +32,7 @@ resource "ibm_is_security_group_rule" "test-vpc--be-2" { remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id } -### SG attached to test-vpc/fe +### SG test-vpc--fe is attached to test-vpc/fe resource "ibm_is_security_group" "test-vpc--fe" { name = "sg-test-vpc--fe" resource_group = local.sg_synth_resource_group_id @@ -57,7 +57,7 @@ resource "ibm_is_security_group_rule" "test-vpc--fe-1" { } } -### SG attached to test-vpc/opa +### SG test-vpc--opa is attached to test-vpc/opa resource "ibm_is_security_group" "test-vpc--opa" { name = "sg-test-vpc--opa" resource_group = local.sg_synth_resource_group_id @@ -76,7 +76,7 @@ resource "ibm_is_security_group_rule" "test-vpc--opa-1" { remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id } -### SG attached to test-vpc/policydb-endpoint-gateway +### SG test-vpc--policydb-endpoint-gateway is attached to test-vpc/policydb-endpoint-gateway resource "ibm_is_security_group" "test-vpc--policydb-endpoint-gateway" { name = "sg-test-vpc--policydb-endpoint-gateway" resource_group = local.sg_synth_resource_group_id @@ -95,7 +95,7 @@ resource "ibm_is_security_group_rule" "test-vpc--policydb-endpoint-gateway-1" { remote = ibm_is_security_group.test-vpc--opa.id } -### SG attached to test-vpc/proxy +### SG test-vpc--proxy is attached to test-vpc/proxy resource "ibm_is_security_group" "test-vpc--proxy" { name = "sg-test-vpc--proxy" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf index 8f4979ba..1486e315 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc0.tf @@ -1,4 +1,4 @@ -### SG attached to test-vpc0/vsi0-subnet0 +### SG test-vpc0--vsi0-subnet0 is attached to test-vpc0/vsi0-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { name = "sg-test-vpc0--vsi0-subnet0" resource_group = local.sg_synth_resource_group_id @@ -11,70 +11,70 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-0" { remote = ibm_is_security_group.test-vpc0--vsi1-subnet4.id } -### SG attached to test-vpc0/vsi0-subnet1 +### SG test-vpc0--vsi0-subnet1 is attached to test-vpc0/vsi0-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { name = "sg-test-vpc0--vsi0-subnet1" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet2 +### SG test-vpc0--vsi0-subnet2 is attached to test-vpc0/vsi0-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { name = "sg-test-vpc0--vsi0-subnet2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet3 +### SG test-vpc0--vsi0-subnet3 is attached to test-vpc0/vsi0-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { name = "sg-test-vpc0--vsi0-subnet3" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet4 +### SG test-vpc0--vsi0-subnet4 is attached to test-vpc0/vsi0-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { name = "sg-test-vpc0--vsi0-subnet4" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet5 +### SG test-vpc0--vsi0-subnet5 is attached to test-vpc0/vsi0-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { name = "sg-test-vpc0--vsi0-subnet5" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet0 +### SG test-vpc0--vsi1-subnet0 is attached to test-vpc0/vsi1-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { name = "sg-test-vpc0--vsi1-subnet0" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet1 +### SG test-vpc0--vsi1-subnet1 is attached to test-vpc0/vsi1-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { name = "sg-test-vpc0--vsi1-subnet1" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet2 +### SG test-vpc0--vsi1-subnet2 is attached to test-vpc0/vsi1-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { name = "sg-test-vpc0--vsi1-subnet2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet3 +### SG test-vpc0--vsi1-subnet3 is attached to test-vpc0/vsi1-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { name = "sg-test-vpc0--vsi1-subnet3" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet4 +### SG test-vpc0--vsi1-subnet4 is attached to test-vpc0/vsi1-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { name = "sg-test-vpc0--vsi1-subnet4" resource_group = local.sg_synth_resource_group_id @@ -87,7 +87,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet4-0" { remote = ibm_is_security_group.test-vpc0--vsi0-subnet0.id } -### SG attached to test-vpc0/vsi1-subnet5 +### SG test-vpc0--vsi1-subnet5 is attached to test-vpc0/vsi1-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { name = "sg-test-vpc0--vsi1-subnet5" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf index 06e11954..9149e693 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc1.tf @@ -1,4 +1,4 @@ -### SG attached to test-vpc1/vsi0-subnet10 +### SG test-vpc1--vsi0-subnet10 is attached to test-vpc1/vsi0-subnet10 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { name = "sg-test-vpc1--vsi0-subnet10" resource_group = local.sg_synth_resource_group_id @@ -13,7 +13,7 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet10-0" { } } -### SG attached to test-vpc1/vsi0-subnet11 +### SG test-vpc1--vsi0-subnet11 is attached to test-vpc1/vsi0-subnet11 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { name = "sg-test-vpc1--vsi0-subnet11" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf index bf96f422..7adad885 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc2.tf @@ -1,4 +1,4 @@ -### SG attached to test-vpc2/vsi0-subnet20 +### SG test-vpc2--vsi0-subnet20 is attached to test-vpc2/vsi0-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { name = "sg-test-vpc2--vsi0-subnet20" resource_group = local.sg_synth_resource_group_id @@ -15,14 +15,14 @@ resource "ibm_is_security_group_rule" "test-vpc2--vsi0-subnet20-0" { } } -### SG attached to test-vpc2/vsi1-subnet20 +### SG test-vpc2--vsi1-subnet20 is attached to test-vpc2/vsi1-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { name = "sg-test-vpc2--vsi1-subnet20" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc2_id } -### SG attached to test-vpc2/vsi2-subnet20 +### SG test-vpc2--vsi2-subnet20 is attached to test-vpc2/vsi2-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { name = "sg-test-vpc2--vsi2-subnet20" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf b/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf index ef77175b..312dad54 100644 --- a/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf +++ b/test/expected/sg_tg_multiple_tf_separate/test-vpc3.tf @@ -1,4 +1,4 @@ -### SG attached to test-vpc3/vsi0-subnet30 +### SG test-vpc3--vsi0-subnet30 is attached to test-vpc3/vsi0-subnet30 resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { name = "sg-test-vpc3--vsi0-subnet30" resource_group = local.sg_synth_resource_group_id From 5616f9ed4a6e86baeaf87ac4702a08a6534f278e Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 21 Oct 2024 11:41:20 +0300 Subject: [PATCH 087/131] fixed --- cmd/subcmds/output.go | 8 ++---- pkg/io/confio/optimizeSG.go | 57 +++++++++++++++++++++++++++++++++++++ pkg/io/confio/sg.go | 29 +++++++++++++------ pkg/synth/sg.go | 11 ++----- 4 files changed, 84 insertions(+), 21 deletions(-) create mode 100644 pkg/io/confio/optimizeSG.go diff --git a/cmd/subcmds/output.go b/cmd/subcmds/output.go index 97acf01a..569d33e3 100644 --- a/cmd/subcmds/output.go +++ b/cmd/subcmds/output.go @@ -60,7 +60,7 @@ func writeOutput(args *inArgs, collection ir.Collection, vpcNames []string, isSy func writeCollection(args *inArgs, collection ir.Collection, vpc string, isSynth bool) (*bytes.Buffer, error) { var data bytes.Buffer - writer, err := pickWriter(args, &data, isSynth) + writer, err := pickWriter(args, &data) if err != nil { return nil, err } @@ -70,7 +70,7 @@ func writeCollection(args *inArgs, collection ir.Collection, vpc string, isSynth return &data, nil } -func pickWriter(args *inArgs, data *bytes.Buffer, isSynth bool) (ir.Writer, error) { +func pickWriter(args *inArgs, data *bytes.Buffer) (ir.Writer, error) { w := bufio.NewWriter(data) switch args.outputFmt { case tfOutputFormat: @@ -80,9 +80,7 @@ func pickWriter(args *inArgs, data *bytes.Buffer, isSynth bool) (ir.Writer, erro case mdOutputFormat: return io.NewMDWriter(w), nil case jsonOutputFormat: - if isSynth { - return confio.NewWriter(w, args.configFile) - } + return confio.NewWriter(w, args.configFile) } return nil, fmt.Errorf("bad output format: %q", args.outputFmt) } diff --git a/pkg/io/confio/optimizeSG.go b/pkg/io/confio/optimizeSG.go new file mode 100644 index 00000000..2c7f0851 --- /dev/null +++ b/pkg/io/confio/optimizeSG.go @@ -0,0 +1,57 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package confio + +import ( + "github.com/IBM/vpc-go-sdk/vpcv1" + + configModel "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +// updateSGs updates the config object file with the optimized SG rules +func updateSGs(model *configModel.ResourcesContainerModel, collection *ir.SGCollection) error { + sgRefMap := parseSGRefMap(model) + for _, sg := range model.SecurityGroupList { + if sg.Name == nil || sg.VPC == nil || sg.VPC.Name == nil { + continue + } + if err := updateSG(&sg.SecurityGroup, collection.SGs[*sg.VPC.Name][ir.SGName(*sg.Name)], sgRefMap); err != nil { + return err + } + } + return nil +} + +func updateSG(sg *vpcv1.SecurityGroup, optimizedSG *ir.SG, sgRefMap map[string]*vpcv1.SecurityGroupRuleRemoteSecurityGroupReference) error { + optimizedRules := optimizedSG.AllRules() + if len(optimizedRules) == len(sg.Rules) { + return nil + } + sg.Rules = make([]vpcv1.SecurityGroupRuleIntf, len(optimizedRules)) + for i, rule := range optimizedRules { + r, err := makeSGRuleItem(sgRefMap, rule, i) + if err != nil { + return err + } + sg.Rules[i] = r + } + return nil +} + +func parseSGRefMap(model *configModel.ResourcesContainerModel) map[string]*vpcv1.SecurityGroupRuleRemoteSecurityGroupReference { + res := make(map[string]*vpcv1.SecurityGroupRuleRemoteSecurityGroupReference) + for _, sg := range model.SecurityGroupList { + res[*sg.Name] = &vpcv1.SecurityGroupRuleRemoteSecurityGroupReference{ + ID: sg.ID, + CRN: sg.CRN, + Href: sg.Href, + Name: sg.Name, + } + } + return res +} diff --git a/pkg/io/confio/sg.go b/pkg/io/confio/sg.go index 90f1fd4f..fbbdd9f8 100644 --- a/pkg/io/confio/sg.go +++ b/pkg/io/confio/sg.go @@ -54,7 +54,7 @@ func sgRemote(nameToSGRemoteRef map[string]*vpcv1.SecurityGroupRuleRemoteSecurit st := rule.Remote.String() switch t := rule.Remote.(type) { case *netset.IPBlock: - if ipString := t.ToIPAddressString(); ipString != "" { // single IP address + if t.IsSingleIPAddress() { // single IP address return &vpcv1.SecurityGroupRuleRemoteIP{ Address: &st, } @@ -72,13 +72,20 @@ func makeSGRuleItem(nameToSGRemoteRef map[string]*vpcv1.SecurityGroupRuleRemoteS rule *ir.SGRule, i int) (vpcv1.SecurityGroupRuleIntf, error) { iPVersion := utils.Ptr(ipv4Const) direction := direction(rule.Direction) - cidrAll := netset.CidrAll - local := &vpcv1.SecurityGroupRuleLocal{ - CIDRBlock: &cidrAll, - } ref := allocateRef() remote := sgRemote(nameToSGRemoteRef, rule) + var local vpcv1.SecurityGroupRuleLocalIntf + if rule.Local.IsSingleIPAddress() { + local = &vpcv1.SecurityGroupRuleLocalIP{ + Address: utils.Ptr(rule.Local.FirstIPAddress()), + } + } else { + local = &vpcv1.SecurityGroupRuleLocalCIDR{ + CIDRBlock: utils.Ptr(rule.Local.ToCidrList()[0]), + } + } + switch p := rule.Protocol.(type) { case netp.TCPUDP: data := tcpudp(p) @@ -245,7 +252,7 @@ func updateSGEndpointGW(model *configModel.ResourcesContainerModel, collection * return nil } -func updateSG(model *configModel.ResourcesContainerModel, collection *ir.SGCollection) error { +func writeSGs(model *configModel.ResourcesContainerModel, collection *ir.SGCollection) error { nameToSGRemoteRef := make(map[string]*vpcv1.SecurityGroupRuleRemoteSecurityGroupReference) idToSGIndex := make(map[string]int, len(model.SecurityGroupList)) for i := range model.SecurityGroupList { @@ -254,13 +261,19 @@ func updateSG(model *configModel.ResourcesContainerModel, collection *ir.SGColle err1 := updateSGInstances(model, collection, nameToSGRemoteRef, idToSGIndex) err2 := updateSGEndpointGW(model, collection, nameToSGRemoteRef, idToSGIndex) - globalIndex = 0 // making test results more predictable return errors.Join(err1, err2) } func (w *Writer) WriteSG(collection *ir.SGCollection, _ string, isSynth bool) error { - if err := updateSG(w.model, collection); err != nil { + var err error + if isSynth { + err = writeSGs(w.model, collection) + } else { + err = updateSGs(w.model, collection) + } + if err != nil { return err } + globalIndex = 0 // making test results more predictable return w.writeModel() } diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 4ffd887b..732303a1 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -9,6 +9,7 @@ import ( "fmt" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -77,7 +78,7 @@ func (s *SGSynthesizer) generateSGRulesFromConnection(conn *ir.Connection) error } // if the endpoint in internal, a rule will be created to allow traffic. -func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *namedAddrs, protocol netp.Protocol, +func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *namedAddrs, p netp.Protocol, direction ir.Direction, internalEndpoint bool, ruleExplanation string) { if !internalEndpoint { return @@ -85,13 +86,7 @@ func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *n localSGName := ir.SGName(localEndpoint.Name) localSG := s.result.LookupOrCreate(localSGName) localSG.Targets = []ir.ID{ir.ID(localSGName)} - rule := &ir.SGRule{ - Remote: sgRemote(&s.spec.Defs, remoteEndpoint), - Direction: direction, - Protocol: protocol, - Explanation: ruleExplanation, - } - localSG.Add(rule) + localSG.Add(ir.NewSGRule(direction, sgRemote(&s.spec.Defs, remoteEndpoint), p, netset.GetCidrAll(), ruleExplanation)) } // generate SGs for blocked endpoints (endpoints that do not appear in Spec) From 93f805c26e3fe100c7b3c22b15849b1e04e34135 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 21 Oct 2024 11:52:58 +0300 Subject: [PATCH 088/131] added a test --- .../sg_expected.json | 2029 +++++++++++++++++ test/main_test_list.go | 9 + 2 files changed, 2038 insertions(+) create mode 100644 test/expected/optimize_sg_protocols_to_all_json/sg_expected.json diff --git a/test/expected/optimize_sg_protocols_to_all_json/sg_expected.json b/test/expected/optimize_sg_protocols_to_all_json/sg_expected.json new file mode 100644 index 00000000..34f2e08d --- /dev/null +++ b/test/expected/optimize_sg_protocols_to_all_json/sg_expected.json @@ -0,0 +1,2029 @@ +{ + "collector_version": "0.11.0", + "provider": "ibm", + "vpcs": [ + { + "classic_access": false, + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:1", + "cse_source_ips": [ + { + "ip": { + "address": "10.22.217.112" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "ip": { + "address": "10.12.160.153" + }, + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "ip": { + "address": "10.16.253.223" + }, + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "default_network_acl": { + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail" + }, + "default_routing_table": { + "crn": null, + "href": "href:11", + "id": "id:12", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "default_security_group": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "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": "test-vpc1", + "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-09-09T09:09:50.000Z", + "has_subnets": true, + "href": "href:18", + "id": "id:19", + "is_default": true, + "name": "filling-tasty-bacterium-parlor", + "zone": { + "href": "href:5", + "name": "us-south-1" + } + }, + { + "cidr": "10.240.64.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:20", + "id": "id:21", + "is_default": true, + "name": "relearn-ragweed-goon-feisty", + "zone": { + "href": "href:6", + "name": "us-south-2" + } + }, + { + "cidr": "10.240.128.0/18", + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, + "href": "href:22", + "id": "id:23", + "is_default": true, + "name": "unruffled-penknife-snowshoe-ninetieth", + "zone": { + "href": "href:7", + "name": "us-south-3" + } + } + ], + "tags": [] + } + ], + "subnets": [ + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:51.000Z", + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.20.0/24", + "name": "subnet2", + "network_acl": { + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "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": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.20.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:33", + "id": "id:34", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:35", + "id": "id:36", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:37", + "id": "id:38", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:39", + "id": "id:40", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.20.4", + "auto_delete": true, + "created_at": "2024-09-09T09:11:08.000Z", + "href": "href:41", + "id": "id:42", + "lifecycle_state": "stable", + "name": "startle-percent-embellish-squeegee", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.20.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:51.000Z", + "href": "href:45", + "id": "id:46", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 250, + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.10.0/24", + "name": "subnet1", + "network_acl": { + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1" + }, + "public_gateway": { + "crn": "crn:30", + "href": "href:31", + "id": "id:32", + "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": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.10.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:53", + "id": "id:54", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:55", + "id": "id:56", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:57", + "id": "id:58", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:59", + "id": "id:60", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.10.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:52.000Z", + "href": "href:61", + "id": "id:62", + "lifecycle_state": "stable", + "name": "tableware-sprawl-shrivel-popper", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.10.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:65", + "id": "id:66", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + }, + { + "available_ipv4_address_count": 249, + "created_at": "2024-09-09T09:10:18.000Z", + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "ip_version": "ipv4", + "ipv4_cidr_block": "10.240.30.0/24", + "name": "subnet3", + "network_acl": { + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3" + }, + "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": "fiscally-fresh-uncanny-ceramics", + "resource_type": "routing_table" + }, + "status": "available", + "total_ipv4_address_count": 256, + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "reserved_ips": [ + { + "address": "10.240.30.0", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:73", + "id": "id:74", + "lifecycle_state": "stable", + "name": "ibm-network-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.1", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:75", + "id": "id:76", + "lifecycle_state": "stable", + "name": "ibm-default-gateway", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.2", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:77", + "id": "id:78", + "lifecycle_state": "stable", + "name": "ibm-dns-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.3", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:79", + "id": "id:80", + "lifecycle_state": "stable", + "name": "ibm-reserved-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + }, + { + "address": "10.240.30.4", + "auto_delete": true, + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:81", + "id": "id:82", + "lifecycle_state": "stable", + "name": "disallow-oxidant-etching-selection", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.5", + "auto_delete": true, + "created_at": "2024-09-09T09:10:36.000Z", + "href": "href:85", + "id": "id:86", + "lifecycle_state": "stable", + "name": "reheat-joyride-little-overprice", + "owner": "user", + "resource_type": "subnet_reserved_ip", + "target": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + }, + { + "address": "10.240.30.255", + "auto_delete": false, + "created_at": "2024-09-09T09:10:18.000Z", + "href": "href:89", + "id": "id:90", + "lifecycle_state": "stable", + "name": "ibm-broadcast-address", + "owner": "provider", + "resource_type": "subnet_reserved_ip" + } + ], + "tags": [] + } + ], + "public_gateways": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:30", + "floating_ip": { + "address": "52.118.147.142", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1" + }, + "href": "href:31", + "id": "id:32", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "floating_ips": [ + { + "address": "52.116.129.168", + "created_at": "2024-09-09T09:11:31.000Z", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + }, + { + "address": "52.118.147.142", + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:91", + "href": "href:92", + "id": "id:93", + "name": "public-gw1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "status": "available", + "target": { + "href": "href:31", + "id": "id:32", + "name": "public-gw1", + "resource_type": "public_gateway", + "crn": "crn:30" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "tags": [] + } + ], + "network_acls": [ + { + "created_at": "2024-09-09T09:10:15.000Z", + "crn": "crn:27", + "href": "href:28", + "id": "id:29", + "name": "acl2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:99", + "id": "id:100", + "name": "acl2-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:97", + "id": "id:98", + "ip_version": "ipv4", + "name": "acl2-out-1", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:101", + "id": "id:102", + "name": "acl2-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:99", + "id": "id:100", + "ip_version": "ipv4", + "name": "acl2-out-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:103", + "id": "id:104", + "name": "acl2-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:101", + "id": "id:102", + "ip_version": "ipv4", + "name": "acl2-in-1", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.20.0/24", + "direction": "inbound", + "href": "href:103", + "id": "id:104", + "ip_version": "ipv4", + "name": "acl2-in-2", + "source": "10.240.10.0/24", + "protocol": "all" + } + ], + "subnets": [ + { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:50", + "href": "href:51", + "id": "id:52", + "name": "acl1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:107", + "id": "id:108", + "name": "acl1-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "172.217.22.46/32", + "direction": "outbound", + "href": "href:105", + "id": "id:106", + "ip_version": "ipv4", + "name": "acl1-out-1", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:109", + "id": "id:110", + "name": "acl1-out-3" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.20.0/24", + "direction": "outbound", + "href": "href:107", + "id": "id:108", + "ip_version": "ipv4", + "name": "acl1-out-2", + "source": "10.240.10.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:111", + "id": "id:112", + "name": "acl1-out-4" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:109", + "id": "id:110", + "ip_version": "ipv4", + "name": "acl1-out-3", + "source": "10.240.10.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:113", + "id": "id:114", + "name": "acl1-in-1" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "outbound", + "href": "href:111", + "id": "id:112", + "ip_version": "ipv4", + "name": "acl1-out-4", + "source": "10.240.10.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:115", + "id": "id:116", + "name": "acl1-in-2" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:113", + "id": "id:114", + "ip_version": "ipv4", + "name": "acl1-in-1", + "source": "172.217.22.46/32", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:117", + "id": "id:118", + "name": "acl1-in-3" + }, + "created_at": "2024-09-09T09:10:17.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:115", + "id": "id:116", + "ip_version": "ipv4", + "name": "acl1-in-2", + "source": "10.240.20.0/24", + "protocol": "all" + }, + { + "action": "allow", + "before": { + "href": "href:119", + "id": "id:120", + "name": "acl1-in-4" + }, + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:117", + "id": "id:118", + "ip_version": "ipv4", + "name": "acl1-in-3", + "source": "10.240.30.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + }, + { + "action": "allow", + "created_at": "2024-09-09T09:10:18.000Z", + "destination": "10.240.10.0/24", + "direction": "inbound", + "href": "href:119", + "id": "id:120", + "ip_version": "ipv4", + "name": "acl1-in-4", + "source": "10.240.30.0/24", + "destination_port_max": 443, + "destination_port_min": 443, + "protocol": "tcp", + "source_port_max": 65535, + "source_port_min": 1 + } + ], + "subnets": [ + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:123", + "id": "id:124", + "name": "acl3-out-2" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:121", + "id": "id:122", + "ip_version": "ipv4", + "name": "acl3-out-1", + "source": "10.240.30.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:125", + "id": "id:126", + "name": "acl3-in-1" + }, + "created_at": "2024-09-09T09:10:15.000Z", + "destination": "10.240.10.0/24", + "direction": "outbound", + "href": "href:123", + "id": "id:124", + "ip_version": "ipv4", + "name": "acl3-out-2", + "source": "10.240.30.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:127", + "id": "id:128", + "name": "acl3-in-2" + }, + "created_at": "2024-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:125", + "id": "id:126", + "ip_version": "ipv4", + "name": "acl3-in-1", + "source": "10.240.10.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-09-09T09:10:16.000Z", + "destination": "10.240.30.0/24", + "direction": "inbound", + "href": "href:127", + "id": "id:128", + "ip_version": "ipv4", + "name": "acl3-in-2", + "source": "10.240.10.0/24", + "destination_port_max": 65535, + "destination_port_min": 1, + "protocol": "tcp", + "source_port_max": 443, + "source_port_min": 443 + } + ], + "subnets": [ + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:8", + "href": "href:9", + "id": "id:10", + "name": "capitol-siren-chirpy-doornail", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "action": "allow", + "before": { + "href": "href:131", + "id": "id:132", + "name": "allow-outbound" + }, + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "inbound", + "href": "href:129", + "id": "id:130", + "ip_version": "ipv4", + "name": "allow-inbound", + "source": "0.0.0.0/0", + "protocol": "all" + }, + { + "action": "allow", + "created_at": "2024-09-09T09:09:50.000Z", + "destination": "0.0.0.0/0", + "direction": "outbound", + "href": "href:131", + "id": "id:132", + "ip_version": "ipv4", + "name": "allow-outbound", + "source": "0.0.0.0/0", + "protocol": "all" + } + ], + "subnets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "security_groups": [ + { + "created_at": "2024-09-09T09:10:14.000Z", + "crn": "crn:133", + "href": "href:134", + "id": "id:135", + "name": "sg1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "href:136", + "id": "id:137", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/0" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "href:138", + "id": "id:139", + "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": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": "2024-09-09T09:09:50.000Z", + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "href:140", + "id": "id:141", + "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:142", + "id": "id:143", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" + }, + "protocol": "all" + } + ], + "targets": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi2", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "inbound", + "href": "fake:href:1", + "id": "fake:id:1", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "all" + } + ], + "targets": [ + { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [ + { + "direction": "outbound", + "href": "fake:href:2", + "id": "fake:id:2", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi2" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "fake:href:3", + "id": "fake:id:3", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/30" + }, + "protocol": "icmp" + }, + { + "direction": "outbound", + "href": "fake:href:4", + "id": "fake:id:4", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "0.0.0.0/31" + }, + "protocol": "all" + } + ], + "targets": [ + { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:18", + "href": "fake:href:18", + "id": "fake:id:18", + "name": "test-vpc1--vsi3b", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + }, + { + "created_at": null, + "crn": "fake:crn:19", + "href": "fake:href:19", + "id": "fake:id:19", + "name": "test-vpc1--vsi3a", + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "rules": [], + "targets": [ + { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "tags": [] + } + ], + "endpoint_gateways": [], + "instances": [ + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:11:07.000Z", + "crn": "crn:144", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:145", + "id": "id:146", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi2", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:43", + "id": "id:44", + "name": "ni2", + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:149" + }, + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", + "volume": { + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:11:07.000Z", + "floating_ips": [], + "href": "href:43", + "id": "id:44", + "name": "ni2", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.20.4", + "href": "href:41", + "id": "id:42", + "name": "startle-percent-embellish-squeegee", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:7", + "href": "fake:href:7", + "id": "fake:id:7", + "name": "test-vpc1--vsi2" + } + ], + "status": "available", + "subnet": { + "crn": "crn:24", + "href": "href:25", + "id": "id:26", + "name": "subnet2", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:52.000Z", + "crn": "crn:157", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:158", + "id": "id:159", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi1", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:63", + "id": "id:64", + "name": "ni1", + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:162" + }, + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", + "volume": { + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:52.000Z", + "floating_ips": [ + { + "address": "52.116.129.168", + "crn": "crn:94", + "href": "href:95", + "id": "id:96", + "name": "vsi1-fip" + } + ], + "href": "href:63", + "id": "id:64", + "name": "ni1", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.10.4", + "href": "href:61", + "id": "id:62", + "name": "tableware-sprawl-shrivel-popper", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + } + ], + "status": "available", + "subnet": { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:166", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:167", + "id": "id:168", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3b", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:171" + }, + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", + "volume": { + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.5", + "href": "href:85", + "id": "id:86", + "name": "reheat-joyride-little-overprice", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:18", + "href": "fake:href:18", + "id": "fake:id:18", + "name": "test-vpc1--vsi3b" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + }, + { + "availability_policy": { + "host_failure": "restart" + }, + "bandwidth": 4000, + "boot_volume_attachment": { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + }, + "confidential_compute_mode": "disabled", + "created_at": "2024-09-09T09:10:34.000Z", + "crn": "crn:175", + "disks": [], + "enable_secure_boot": false, + "health_reasons": [], + "health_state": "ok", + "href": "href:176", + "id": "id:177", + "image": { + "crn": "crn:153", + "href": "href:154", + "id": "id:155", + "name": "server-9080", + "resource_type": "image" + }, + "lifecycle_reasons": [], + "lifecycle_state": "stable", + "memory": 4, + "metadata_service": { + "enabled": false, + "protocol": "http", + "response_hop_limit": 1 + }, + "name": "vsi3a", + "network_attachments": [], + "numa_count": 1, + "primary_network_interface": { + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + }, + "profile": { + "href": "href:156", + "name": "cx2-2x4", + "resource_type": "instance_profile" + }, + "reservation_affinity": { + "policy": "disabled", + "pool": [] + }, + "resource_group": { + "href": "href:16", + "id": "id:17", + "name": "name:4" + }, + "resource_type": "instance", + "startable": true, + "status": "running", + "status_reasons": [], + "total_network_bandwidth": 3000, + "total_volume_bandwidth": 1000, + "vcpu": { + "architecture": "amd64", + "count": 2, + "manufacturer": "intel" + }, + "volume_attachments": [ + { + "device": { + "id": "id:180" + }, + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", + "volume": { + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", + "resource_type": "volume" + } + } + ], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + }, + "zone": { + "href": "href:5", + "name": "us-south-1" + }, + "network_interfaces": [ + { + "allow_ip_spoofing": false, + "created_at": "2024-09-09T09:10:34.000Z", + "floating_ips": [], + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "port_speed": 3000, + "primary_ip": { + "address": "10.240.30.4", + "href": "href:81", + "id": "id:82", + "name": "disallow-oxidant-etching-selection", + "resource_type": "subnet_reserved_ip" + }, + "resource_type": "network_interface", + "security_groups": [ + { + "crn": "fake:crn:19", + "href": "fake:href:19", + "id": "fake:id:19", + "name": "test-vpc1--vsi3a" + } + ], + "status": "available", + "subnet": { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + }, + "type": "primary" + } + ], + "tags": [] + } + ], + "virtual_nis": null, + "routing_tables": [ + { + "accept_routes_from": [ + { + "resource_type": "vpn_gateway" + }, + { + "resource_type": "vpn_server" + } + ], + "advertise_routes_to": [], + "created_at": "2024-09-09T09:09:51.000Z", + "crn": null, + "href": "href:11", + "id": "id:12", + "is_default": true, + "lifecycle_state": "stable", + "name": "fiscally-fresh-uncanny-ceramics", + "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": "subnet2", + "resource_type": "subnet" + }, + { + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", + "resource_type": "subnet" + }, + { + "crn": "crn:67", + "href": "href:68", + "id": "id:69", + "name": "subnet3", + "resource_type": "subnet" + } + ], + "routes": [], + "vpc": { + "crn": "crn:1", + "href": "href:2", + "id": "id:3", + "name": "test-vpc1", + "resource_type": "vpc" + } + } + ], + "load_balancers": [], + "transit_connections": null, + "transit_gateways": null, + "iks_clusters": [] +} \ No newline at end of file diff --git a/test/main_test_list.go b/test/main_test_list.go index f9d63166..d6883aba 100644 --- a/test/main_test_list.go +++ b/test/main_test_list.go @@ -336,6 +336,15 @@ func optimizeSGTestsLists() []testCase { outputFile: "%s/optimize_sg_protocols_to_all_csv/sg_expected.csv", }, }, + { + testName: "optimize_sg_protocols_to_all_json", + args: &command{ + cmd: optimize, + subcmd: sg, + config: optimizeSGProtocolsToAllConfig, + outputFile: "%s/optimize_sg_protocols_to_all_json/sg_expected.json", + }, + }, { testName: "optimize_sg_protocols_to_all_md", args: &command{ From 3ec4c70810d4810d6b37d31ce5fab1e28623fee3 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 22 Oct 2024 13:13:00 +0300 Subject: [PATCH 089/131] fixed --- pkg/io/confio/parse_sgs.go | 35 ++++++++-------------- pkg/ir/sg.go | 29 +++++++++++++------ pkg/optimize/sg/ipCubesToRules.go | 30 ++++++++++--------- pkg/optimize/sg/sg.go | 48 +++++++++++++++++-------------- pkg/optimize/sg/sgCubesToRules.go | 12 ++++---- 5 files changed, 82 insertions(+), 72 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index 5b0cdc95..f39f890d 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -27,14 +27,14 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { result := ir.NewSGCollection() for i, sg := range config.SecurityGroupList { - inbound, outbound, err := translateSGRules(&sg.SecurityGroup) - if err != nil { - return nil, err - } if sg.Name == nil || sg.VPC == nil || sg.VPC.Name == nil { log.Printf("Warning: missing SG/VPC name in sg at index %d\n", i) continue } + inbound, outbound, err := translateSGRules(&sg.SecurityGroup) + if err != nil { + return nil, err + } vpcName := *sg.VPC.Name if result.SGs[vpcName] == nil { result.SGs[vpcName] = make(map[ir.SGName]*ir.SG) @@ -49,16 +49,19 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { } // parse security rules, splitted into ingress and egress rules -func translateSGRules(sg *vpcv1.SecurityGroup) (ingressRules, egressRules []*ir.SGRule, err error) { +func translateSGRules(sg *vpcv1.SecurityGroup) (ingressRules, egressRules map[string][]*ir.SGRule, err error) { + ingressRules = make(map[string][]*ir.SGRule) + egressRules = make(map[string][]*ir.SGRule) for index := range sg.Rules { rule, err := translateSGRule(sg, index) if err != nil { return nil, nil, err } + local := rule.Local.String() if rule.Direction == ir.Inbound { - ingressRules = append(ingressRules, rule) + ingressRules[local] = append(ingressRules[local], rule) } else { - egressRules = append(egressRules, rule) + egressRules[local] = append(egressRules[local], rule) } } return ingressRules, egressRules, nil @@ -157,19 +160,13 @@ func translateRemote(remote vpcv1.SecurityGroupRuleRemoteIntf) (ir.RemoteType, e } func translateLocal(local vpcv1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, error) { - var err error - var ipAddrs *netset.IPBlock if l, ok := local.(*vpcv1.SecurityGroupRuleLocal); ok { if l.CIDRBlock != nil { - ipAddrs, err = netset.IPBlockFromCidr(*l.CIDRBlock) + return netset.IPBlockFromCidr(*l.CIDRBlock) } if l.Address != nil { - ipAddrs, err = netset.IPBlockFromIPAddress(*l.CIDRBlock) - } - if err != nil { - return nil, err + return netset.IPBlockFromIPAddress(*l.Address) } - return verifyLocalValue(ipAddrs) } return nil, fmt.Errorf("error parsing Local field") } @@ -190,14 +187,6 @@ func transalteTargets(sg *vpcv1.SecurityGroup) []string { return res } -// temporary - first version of optimization requires local = 0.0.0.0/32 -func verifyLocalValue(ipAddrs *netset.IPBlock) (*netset.IPBlock, error) { - if !ipAddrs.Equal(netset.GetCidrAll()) { - return nil, fmt.Errorf("only 0.0.0.0/32 CIDR block is supported for local values") - } - return ipAddrs, nil -} - func translateProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (netp.Protocol, error) { isTCP := *rule.Protocol == vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudpProtocolTCPConst minDstPort := utils.GetProperty(rule.PortMin, netp.MinPort) diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 4ee2dd10..3a1957c3 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -44,8 +44,8 @@ type ( SG struct { SGName SGName - InboundRules []*SGRule - OutboundRules []*SGRule + InboundRules map[string][]*SGRule // the key is the locals value + OutboundRules map[string][]*SGRule // the key is the locals value Targets []ID } @@ -85,7 +85,11 @@ func NewSGRule(direction Direction, remote RemoteType, p netp.Protocol, local *n } func NewSG(sgName SGName) *SG { - return &SG{SGName: sgName, InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Targets: []ID{}} + return &SG{SGName: sgName, + InboundRules: make(map[string][]*SGRule), + OutboundRules: make(map[string][]*SGRule), + Targets: []ID{}, + } } func NewSGCollection() *SGCollection { @@ -106,16 +110,25 @@ func (c *SGCollection) LookupOrCreate(name SGName) *SG { } func (a *SG) Add(rule *SGRule) { - if rule.Direction == Outbound && !rule.isRedundant(a.OutboundRules) { - a.OutboundRules = append(a.OutboundRules, rule) + local := rule.Local.String() + if rule.Direction == Outbound && !rule.isRedundant(a.OutboundRules[local]) { + a.OutboundRules[local] = append(a.OutboundRules[local], rule) } - if rule.Direction == Inbound && !rule.isRedundant(a.InboundRules) { - a.InboundRules = append(a.InboundRules, rule) + + if rule.Direction == Inbound && !rule.isRedundant(a.InboundRules[local]) { + a.InboundRules[local] = append(a.InboundRules[local], rule) } } func (a *SG) AllRules() []*SGRule { - return append(a.InboundRules, a.OutboundRules...) + res := make([]*SGRule, 0) + for _, key := range utils.SortedMapKeys(a.InboundRules) { + res = append(res, a.InboundRules[key]...) + } + for _, key := range utils.SortedMapKeys(a.OutboundRules) { + res = append(res, a.OutboundRules[key]...) + } + return res } func (c *SGCollection) VpcNames() []string { diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go index f7b41bcf..40106f14 100644 --- a/pkg/optimize/sg/ipCubesToRules.go +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -17,17 +17,17 @@ import ( // all protocol cubes, represented by a single ipblock that will be decomposed // into cidrs. Each cidr will be the remote of a SG rule -func allProtocolIPCubesIPToRules(cubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { +func allProtocolIPCubesIPToRules(cubes *netset.IPBlock, direction ir.Direction, l *netset.IPBlock) []*ir.SGRule { result := make([]*ir.SGRule, 0) for _, cidr := range cubes.SplitToCidrs() { - result = append(result, ir.NewSGRule(direction, cidr, netp.AnyProtocol{}, netset.GetCidrAll(), "")) + result = append(result, ir.NewSGRule(direction, cidr, netp.AnyProtocol{}, l, "")) } return result } // tcpudpIPCubesToRules converts cubes representing tcp or udp protocol rules to SG rules func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], allCubes *netset.IPBlock, direction ir.Direction, - isTCP bool) []*ir.SGRule { + isTCP bool, l *netset.IPBlock) []*ir.SGRule { if len(cubes) == 0 { return []*ir.SGRule{} } @@ -38,7 +38,7 @@ func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], all for i := range cubes { // if it is not possible to continue the rule between the cubes, generate all the existing rules if i > 0 && !continuation(cubes[i-1], cubes[i], allCubes) { - result = append(result, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)...) + result = append(result, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction, l)...) activeRules = make(map[*netset.IPBlock]netp.Protocol) } @@ -48,7 +48,7 @@ func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], all for ipb, protocol := range activeRules { if tcpudp, ok := protocol.(netp.TCPUDP); ok { if !tcpudp.DstPorts().ToSet().IsSubset(cubes[i].Right) { - result = append(result, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction)...) + result = append(result, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction, l)...) } else { activePorts.AddInterval(tcpudp.DstPorts()) } @@ -64,11 +64,12 @@ func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], all } } // generate all the existing rules - return append(result, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction)...) + return append(result, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction, l)...) } // icmpIPCubesToRules converts cubes representing icmp protocol rules to SG rules -func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { +func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCubes *netset.IPBlock, direction ir.Direction, + l *netset.IPBlock) []*ir.SGRule { if len(cubes) == 0 { return []*ir.SGRule{} } @@ -79,7 +80,7 @@ func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCu for i := range cubes { // if it is not possible to continue the rule between the cubes, generate all the existing rules if i > 0 && !continuation(cubes[i-1], cubes[i], allCubes) { - result = append(result, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)...) + result = append(result, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction, l)...) activeRules = make(map[*netset.IPBlock]netp.Protocol) } @@ -90,7 +91,7 @@ func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCu if icmp, ok := protocol.(netp.ICMP); ok { ruleIcmpSet := optimize.IcmpRuleToIcmpSet(icmp) if !ruleIcmpSet.IsSubset(cubes[i].Right) { - result = append(result, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction)...) + result = append(result, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction, l)...) } else { activeICMP.Union(ruleIcmpSet) } @@ -106,7 +107,7 @@ func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCu } // generate all the existing rules - return append(result, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction)...) + return append(result, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction, l)...) } // continuation returns true if the rules can be continued between the two cubes @@ -124,20 +125,21 @@ func continuation[T ds.Set[T]](prevPair, currPair ds.Pair[*netset.IPBlock, T], a } // creates sgRules from SG active rules -func createActiveRules(activeRules map[*netset.IPBlock]netp.Protocol, endIP *netset.IPBlock, direction ir.Direction) []*ir.SGRule { +func createActiveRules(activeRules map[*netset.IPBlock]netp.Protocol, endIP *netset.IPBlock, direction ir.Direction, + l *netset.IPBlock) []*ir.SGRule { res := make([]*ir.SGRule, 0) for ipb, protocol := range activeRules { - res = append(res, createNewRules(protocol, ipb, endIP, direction)...) + res = append(res, createNewRules(protocol, ipb, endIP, direction, l)...) } return res } // 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) []*ir.SGRule { +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, netset.GetCidrAll(), "")) + res = append(res, ir.NewSGRule(direction, cidr, protocol, l, "")) } return res } diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index 0da688a2..f2f443d8 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -90,17 +90,23 @@ func (s *sgOptimizer) optimizeSG(vpcName string, sgName ir.SGName) { reducedRules := 0 // reduce inbound rules first - newInboundRules := s.reduceRules(sg.InboundRules, ir.Inbound) - if len(sg.InboundRules) > len(newInboundRules) { - reducedRules += len(sg.InboundRules) - len(newInboundRules) - s.sgCollection.SGs[vpcName][sgName].InboundRules = newInboundRules + for l, rules := range sg.InboundRules { + local, _ := netset.IPBlockFromCidr(l) + newInboundRules := s.reduceRules(rules, ir.Inbound, local) + if len(rules) > len(newInboundRules) { + reducedRules += len(rules) - len(newInboundRules) + sg.InboundRules[l] = newInboundRules + } } // reduce outbound rules second - newOutboundRules := s.reduceRules(sg.OutboundRules, ir.Outbound) - if len(sg.OutboundRules) > len(newOutboundRules) { - reducedRules += len(sg.OutboundRules) - len(newOutboundRules) - s.sgCollection.SGs[vpcName][sgName].OutboundRules = newOutboundRules + for l, rules := range sg.OutboundRules { + local, _ := netset.IPBlockFromCidr(l) + newOutboundRules := s.reduceRules(rules, ir.Outbound, local) + if len(rules) > len(newOutboundRules) { + reducedRules += len(rules) - len(newOutboundRules) + sg.OutboundRules[l] = newOutboundRules + } } // print a message to the log @@ -115,19 +121,19 @@ func (s *sgOptimizer) optimizeSG(vpcName string, sgName ir.SGName) { } // reduceSGRules attempts to reduce the number of rules with different remote types separately -func (s *sgOptimizer) reduceRules(rules []*ir.SGRule, direction ir.Direction) []*ir.SGRule { +func (s *sgOptimizer) reduceRules(rules []*ir.SGRule, direction ir.Direction, l *netset.IPBlock) []*ir.SGRule { // separate all rules to groups of protocol X remote ([tcp, udp, icmp, protocolAll] X [ip, sg]) ruleGroups := divideSGRules(rules) // rules with SG as a remote - optimizedRulesToSG := reduceRulesSGRemote(rulesToSGCubes(ruleGroups.sgRemoteRules), direction) + optimizedRulesToSG := reduceRulesSGRemote(rulesToSGCubes(ruleGroups.sgRemoteRules), direction, l) originlRulesToSG := ruleGroups.sgRemoteRules.allRules() if len(originlRulesToSG) < len(optimizedRulesToSG) { // failed to reduce number of rules optimizedRulesToSG = originlRulesToSG } // rules with IPBlock as a remote - optimizedRulesToIPAddrs := reduceRulesIPRemote(rulesToIPCubes(ruleGroups.ipRemoteRules), direction) + optimizedRulesToIPAddrs := reduceRulesIPRemote(rulesToIPCubes(ruleGroups.ipRemoteRules), direction, l) originalRulesToIPAddrs := ruleGroups.ipRemoteRules.allRules() if len(originalRulesToIPAddrs) < len(optimizedRulesToSG) { // failed to reduce number of rules optimizedRulesToIPAddrs = originalRulesToIPAddrs @@ -136,27 +142,27 @@ func (s *sgOptimizer) reduceRules(rules []*ir.SGRule, direction ir.Direction) [] return append(optimizedRulesToSG, optimizedRulesToIPAddrs...) } -func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*ir.SGRule { +func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction, l *netset.IPBlock) []*ir.SGRule { reduceSGCubes(cubes) // cubes to SG rules - tcpRules := tcpudpSGCubesToRules(cubes.tcp, direction, true) - udpRules := tcpudpSGCubesToRules(cubes.udp, direction, false) - icmpRules := icmpSGCubesToRules(cubes.icmp, direction) - allRules := protocolAllCubesToRules(cubes.all, direction) + tcpRules := tcpudpSGCubesToRules(cubes.tcp, direction, true, l) + udpRules := tcpudpSGCubesToRules(cubes.udp, direction, false, l) + icmpRules := icmpSGCubesToRules(cubes.icmp, direction, l) + allRules := protocolAllCubesToRules(cubes.all, direction, l) // return all rules return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) } -func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction) []*ir.SGRule { +func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction, l *netset.IPBlock) []*ir.SGRule { reduceIPCubes(cubes) // cubes to SG rules - tcpRules := tcpudpIPCubesToRules(cubes.tcp, cubes.all, direction, true) - udpRules := tcpudpIPCubesToRules(cubes.udp, cubes.all, direction, false) - icmpRules := icmpIPCubesToRules(cubes.icmp, cubes.all, direction) - allRules := allProtocolIPCubesIPToRules(cubes.all, direction) + tcpRules := tcpudpIPCubesToRules(cubes.tcp, cubes.all, direction, true, l) + udpRules := tcpudpIPCubesToRules(cubes.udp, cubes.all, direction, false, l) + icmpRules := icmpIPCubesToRules(cubes.icmp, cubes.all, direction, l) + allRules := allProtocolIPCubesIPToRules(cubes.all, direction, l) // return all rules return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) diff --git a/pkg/optimize/sg/sgCubesToRules.go b/pkg/optimize/sg/sgCubesToRules.go index 4ed229c7..03698f78 100644 --- a/pkg/optimize/sg/sgCubesToRules.go +++ b/pkg/optimize/sg/sgCubesToRules.go @@ -14,33 +14,33 @@ import ( ) // cubes (SGName X portSet) to SG rules -func tcpudpSGCubesToRules(span map[ir.SGName]*netset.PortSet, direction ir.Direction, isTCP bool) []*ir.SGRule { +func tcpudpSGCubesToRules(span map[ir.SGName]*netset.PortSet, direction ir.Direction, isTCP bool, l *netset.IPBlock) []*ir.SGRule { result := make([]*ir.SGRule, 0) for sgName, portSet := range span { for _, dstPorts := range portSet.Intervals() { p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) - result = append(result, ir.NewSGRule(direction, sgName, p, netset.GetCidrAll(), "")) + result = append(result, ir.NewSGRule(direction, sgName, p, l, "")) } } return result } // cubes (SGName X icmpset) to SG rules -func icmpSGCubesToRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Direction) []*ir.SGRule { +func icmpSGCubesToRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Direction, l *netset.IPBlock) []*ir.SGRule { result := make([]*ir.SGRule, 0) for sgName, icmpSet := range span { for _, icmp := range optimize.IcmpsetPartitions(icmpSet) { - result = append(result, ir.NewSGRule(direction, sgName, icmp, netset.GetCidrAll(), "")) + result = append(result, ir.NewSGRule(direction, sgName, icmp, l, "")) } } return result } // cubes (slice of SGs) to SG rules -func protocolAllCubesToRules(span []ir.SGName, direction ir.Direction) []*ir.SGRule { +func protocolAllCubesToRules(span []ir.SGName, direction ir.Direction, l *netset.IPBlock) []*ir.SGRule { result := make([]*ir.SGRule, len(span)) for i, sgName := range span { - result[i] = ir.NewSGRule(direction, sgName, netp.AnyProtocol{}, netset.GetCidrAll(), "") + result[i] = ir.NewSGRule(direction, sgName, netp.AnyProtocol{}, l, "") } return result } From 737b8030dc423745b62697f278695f42c148bd6d Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 28 Oct 2024 15:04:22 +0200 Subject: [PATCH 090/131] small fix --- pkg/ir/acl.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index b1de36c3..86c34171 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -79,7 +79,7 @@ func (a *ACL) Rules() []*ACLRule { } func (a *ACL) AppendInternal(rule *ACLRule) { - if a.External == nil { + if a.Internal == nil { panic("ACLs should be created with non-null Internal") } if !rule.isRedundant(a.Internal) { @@ -95,18 +95,17 @@ func (a *ACL) AppendExternal(rule *ACLRule) { if a.External == nil { panic("ACLs should be created with non-null External") } - if rule.isRedundant(a.External) { - return + if !rule.isRedundant(a.External) { + a.External = append(a.External, rule) } - a.External = append(a.External, rule) } func NewACLCollection() *ACLCollection { return &ACLCollection{ACLs: map[ID]map[string]*ACL{}} } -func NewACL() *ACL { - return &ACL{Internal: []*ACLRule{}, External: []*ACLRule{}} +func NewACL(subnet string) *ACL { + return &ACL{Subnet: subnet, Internal: []*ACLRule{}, External: []*ACLRule{}} } func (c *ACLCollection) LookupOrCreate(name string) *ACL { @@ -114,13 +113,11 @@ func (c *ACLCollection) LookupOrCreate(name string) *ACL { if acl, ok := c.ACLs[vpcName][name]; ok { return acl } - newACL := NewACL() - newACL.Subnet = name if c.ACLs[vpcName] == nil { c.ACLs[vpcName] = make(map[string]*ACL) } - c.ACLs[vpcName][name] = newACL - return newACL + c.ACLs[vpcName][name] = NewACL(name) + return c.ACLs[vpcName][name] } func (c *ACLCollection) Write(w Writer, vpc string) error { From 799cd737aff0e9d5fda7ad14f5c9b39115d98f8f Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 28 Oct 2024 15:06:20 +0200 Subject: [PATCH 091/131] small fix --- pkg/ir/packet.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/ir/packet.go b/pkg/ir/packet.go index a2d5f3a9..d6fbd1eb 100644 --- a/pkg/ir/packet.go +++ b/pkg/ir/packet.go @@ -41,7 +41,7 @@ func packetACLRule(packet *Packet, direction Direction, action Action) *ACLRule func makeDenyInternal() []*ACLRule { localCidrs := []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"} // https://datatracker.ietf.org/doc/html/rfc1918#section-3 localCidrsIPBlocks, _ := netset.IPBlockFromCidrList(localCidrs) - localCidrsList := localCidrsIPBlocks.Split() // should be splitted to CIDRs + localCidrsList := localCidrsIPBlocks.SplitToCidrs() var denyInternal []*ACLRule for i, localCidrSrc := range localCidrsList { for j, localCidrDst := range localCidrsList { From 6407b273617e7736607638fbb521b7309ad9443f Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 28 Oct 2024 16:04:50 +0200 Subject: [PATCH 092/131] rename1 --- pkg/io/jsonio/unmarshalConns.go | 9 +++++---- pkg/ir/lookupForACLSynth.go | 13 +++++++------ pkg/ir/lookupForSGSynth.go | 18 +++++++++--------- pkg/ir/spec.go | 14 +++++++------- pkg/synth/acl.go | 2 +- pkg/synth/sg.go | 2 +- 6 files changed, 30 insertions(+), 28 deletions(-) diff --git a/pkg/io/jsonio/unmarshalConns.go b/pkg/io/jsonio/unmarshalConns.go index e28f904a..4d0c59d6 100644 --- a/pkg/io/jsonio/unmarshalConns.go +++ b/pkg/io/jsonio/unmarshalConns.go @@ -55,12 +55,13 @@ func translateConnection(defs *ir.Definitions, conn *spec.SpecRequiredConnection return []*ir.Connection{out}, nil } -func transalteConnectionResource(defs *ir.Definitions, resource *spec.Resource, isSG bool) (r *ir.Resource, isExternal bool, err error) { +func transalteConnectionResource(defs *ir.Definitions, resource *spec.Resource, + isSG bool) (r *ir.FirewallResource, isExternal bool, err error) { resourceType, err := translateResourceType(defs, resource) if err != nil { return nil, false, err } - var res *ir.Resource + var res *ir.FirewallResource if isSG { res, err = defs.LookupForSGSynth(resourceType, resource.Name) updateBlockedResourcesSGSynth(defs, res) @@ -135,7 +136,7 @@ func translateResourceType(defs *ir.Definitions, resource *spec.Resource) (ir.Re return ir.ResourceTypeSubnet, fmt.Errorf("unsupported resource type %v (%v)", resource.Type, resource.Name) } -func updateBlockedResourcesSGSynth(defs *ir.Definitions, resource *ir.Resource) { +func updateBlockedResourcesSGSynth(defs *ir.Definitions, resource *ir.FirewallResource) { for _, namedAddrs := range resource.NamedAddrs { if _, ok := defs.BlockedInstances[*namedAddrs.Name]; ok { defs.BlockedInstances[*namedAddrs.Name] = false @@ -146,7 +147,7 @@ func updateBlockedResourcesSGSynth(defs *ir.Definitions, resource *ir.Resource) } } -func updateBlockedResourcesACLSynth(defs *ir.Definitions, resource *ir.Resource) { +func updateBlockedResourcesACLSynth(defs *ir.Definitions, resource *ir.FirewallResource) { for _, namedAddrs := range resource.NamedAddrs { if _, ok := defs.BlockedSubnets[*namedAddrs.Name]; ok { defs.BlockedSubnets[*namedAddrs.Name] = false diff --git a/pkg/ir/lookupForACLSynth.go b/pkg/ir/lookupForACLSynth.go index 8f207435..739f8f78 100644 --- a/pkg/ir/lookupForACLSynth.go +++ b/pkg/ir/lookupForACLSynth.go @@ -12,7 +12,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -func (s *Definitions) LookupForACLSynth(t ResourceType, name string) (*Resource, error) { +func (s *Definitions) LookupForACLSynth(t ResourceType, name string) (*FirewallResource, error) { switch t { case ResourceTypeExternal: return lookupSingle(s.Externals, name, t) @@ -38,7 +38,8 @@ func (s *Definitions) LookupForACLSynth(t ResourceType, name string) (*Resource, return nil, nil // should not get here } -func lookupSingleForACLSynth[T INWResource](m map[ID]T, subnets map[ID]*SubnetDetails, name string, t ResourceType) (*Resource, error) { +func lookupSingleForACLSynth[T INWResource](m map[ID]T, subnets map[ID]*SubnetDetails, name string, + t ResourceType) (*FirewallResource, error) { details, ok := m[name] if !ok { return nil, fmt.Errorf(resourceNotFound, name, t) @@ -52,13 +53,13 @@ func lookupSingleForACLSynth[T INWResource](m map[ID]T, subnets map[ID]*SubnetDe return res, nil } -func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definitions, name string, t ResourceType) (*Resource, error) { +func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definitions, name string, t ResourceType) (*FirewallResource, error) { containerDetails, ok := m[name] if !ok { return nil, fmt.Errorf(containerNotFound, name, t) } - res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + res := &FirewallResource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} endpointMap := containerDetails.endpointMap(defs) for _, endpointName := range containerDetails.endpointNames() { subnet, err := lookupSingleForACLSynth(endpointMap, defs.Subnets, endpointName, containerDetails.endpointType()) @@ -71,13 +72,13 @@ func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definition return res, nil } -func (s *Definitions) lookupCidrSegmentACL(name string) (*Resource, error) { +func (s *Definitions) lookupCidrSegmentACL(name string) (*FirewallResource, error) { segmentDetails, ok := s.CidrSegments[name] if !ok { return nil, fmt.Errorf(containerNotFound, name, ResourceTypeCidrSegment) } - res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + res := &FirewallResource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} for _, subnetName := range segmentDetails.ContainedSubnets { subnet, err := lookupSingle(s.Subnets, subnetName, ResourceTypeSubnet) if err != nil { diff --git a/pkg/ir/lookupForSGSynth.go b/pkg/ir/lookupForSGSynth.go index 177bfb9d..b0c62cf1 100644 --- a/pkg/ir/lookupForSGSynth.go +++ b/pkg/ir/lookupForSGSynth.go @@ -14,7 +14,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -func (s *Definitions) LookupForSGSynth(t ResourceType, name string) (*Resource, error) { +func (s *Definitions) LookupForSGSynth(t ResourceType, name string) (*FirewallResource, error) { switch t { case ResourceTypeExternal: return lookupSingle(s.Externals, name, t) @@ -40,9 +40,9 @@ func (s *Definitions) LookupForSGSynth(t ResourceType, name string) (*Resource, return nil, nil // should not get here } -func (s *Definitions) lookupNIFForSGSynth(name string) (*Resource, error) { +func (s *Definitions) lookupNIFForSGSynth(name string) (*FirewallResource, error) { if _, ok := s.NIFs[name]; ok { - return &Resource{ + return &FirewallResource{ Name: &name, NamedAddrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, Cidrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, @@ -52,9 +52,9 @@ func (s *Definitions) lookupNIFForSGSynth(name string) (*Resource, error) { return nil, fmt.Errorf(resourceNotFound, ResourceTypeNIF, name) } -func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, t ResourceType) (*Resource, error) { +func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, t ResourceType) (*FirewallResource, error) { if _, ok := m[name]; ok { - return &Resource{ + return &FirewallResource{ Name: &name, NamedAddrs: []*NamedAddrs{{Name: &name}}, Cidrs: []*NamedAddrs{{Name: &name}}, @@ -64,9 +64,9 @@ func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, return nil, fmt.Errorf(containerNotFound, t, name) } -func (s *Definitions) lookupSubnetForSGSynth(name string) (*Resource, error) { +func (s *Definitions) lookupSubnetForSGSynth(name string) (*FirewallResource, error) { if subnetDetails, ok := s.Subnets[name]; ok { - return &Resource{Name: &name, + return &FirewallResource{Name: &name, NamedAddrs: s.containedResourcesInCidr(subnetDetails.CIDR), Cidrs: []*NamedAddrs{{IPAddrs: subnetDetails.CIDR}}, Type: utils.Ptr(ResourceTypeSubnet), @@ -75,9 +75,9 @@ func (s *Definitions) lookupSubnetForSGSynth(name string) (*Resource, error) { return nil, fmt.Errorf(resourceNotFound, ResourceTypeSubnet, name) } -func (s *Definitions) lookupCidrSegmentForSGSynth(name string) (*Resource, error) { +func (s *Definitions) lookupCidrSegmentForSGSynth(name string) (*FirewallResource, error) { if segmentDetails, ok := s.CidrSegments[name]; ok { - return &Resource{Name: &name, + return &FirewallResource{Name: &name, NamedAddrs: s.containedResourcesInCidr(segmentDetails.Cidrs), Cidrs: cidrToNamedAddrs(segmentDetails.Cidrs), Type: utils.Ptr(ResourceTypeCidr), diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index 83258e3e..ceaf35a2 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -31,10 +31,10 @@ type ( Connection struct { // Egress resource - Src *Resource + Src *FirewallResource // Ingress resource - Dst *Resource + Dst *FirewallResource // Allowed protocols TrackedProtocols []*TrackedProtocol @@ -43,7 +43,7 @@ type ( Origin fmt.Stringer } - Resource struct { + FirewallResource struct { // Symbolic name of resource, if available Name *string @@ -264,9 +264,9 @@ func (v *VPEDetails) endpointType() ResourceType { return ResourceTypeVPE } -func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*Resource, error) { +func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*FirewallResource, error) { if details, ok := m[name]; ok { - return &Resource{ + return &FirewallResource{ Name: &name, NamedAddrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, Cidrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, @@ -277,13 +277,13 @@ func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*Resou } func (s *Definitions) lookupSegment(segment map[ID]*SegmentDetails, name string, t, elementType ResourceType, - lookup func(ResourceType, string) (*Resource, error)) (*Resource, error) { + lookup func(ResourceType, string) (*FirewallResource, error)) (*FirewallResource, error) { segmentDetails, ok := segment[name] if !ok { return nil, fmt.Errorf(containerNotFound, name, t) } - res := &Resource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(elementType)} + res := &FirewallResource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(elementType)} for _, elementName := range segmentDetails.Elements { subnet, err := lookup(elementType, elementName) if err != nil { diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index 9b4dc8f4..ffe5ebc1 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -45,7 +45,7 @@ func (a *ACLSynthesizer) makeACL() *ir.ACLCollection { return a.result } -func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection, thisResource, otherResource *ir.Resource, +func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection, thisResource, otherResource *ir.FirewallResource, allowConnection func(*ir.Connection, *ir.TrackedProtocol, *ir.NamedAddrs, *netset.IPBlock)) { for _, thisSubnet := range thisResource.NamedAddrs { for _, otherCidr := range otherResource.Cidrs { diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 1a1fd993..6bbaa839 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -79,7 +79,7 @@ func sgRemote(resource *ir.NamedAddrs, t *ir.ResourceType) ir.RemoteType { return resource.IPAddrs } -func connSettings(conn *ir.Connection, direction ir.Direction) (local, remote *ir.Resource, internalEndpoint, internalConn bool) { +func connSettings(conn *ir.Connection, direction ir.Direction) (local, remote *ir.FirewallResource, internalEndpoint, internalConn bool) { internalSrc, internalDst, internalConn := internalConnection(conn) local = conn.Src remote = conn.Dst From a9cb5ac8362b72b9016430ee1530e21a96e946f2 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 28 Oct 2024 16:12:22 +0200 Subject: [PATCH 093/131] rename2 --- pkg/io/jsonio/unmarshal.go | 2 +- pkg/io/jsonio/unmarshalConns.go | 14 +++++++------- pkg/ir/lookupForACLSynth.go | 8 ++++---- pkg/ir/lookupForSGSynth.go | 28 ++++++++++++++-------------- pkg/ir/spec.go | 15 +++++++-------- pkg/synth/acl.go | 2 +- pkg/synth/sg.go | 2 +- 7 files changed, 35 insertions(+), 36 deletions(-) diff --git a/pkg/io/jsonio/unmarshal.go b/pkg/io/jsonio/unmarshal.go index 6bf2b9ee..ad635f2e 100644 --- a/pkg/io/jsonio/unmarshal.go +++ b/pkg/io/jsonio/unmarshal.go @@ -41,7 +41,7 @@ func (r *Reader) ReadSpec(filename string, configDefs *ir.ConfigDefs, isSG bool) return nil, err } - connections, err := r.transalteConnections(jsonSpec.RequiredConnections, defs, isSG) + connections, err := r.translateConnections(jsonSpec.RequiredConnections, defs, isSG) if err != nil { return nil, err } diff --git a/pkg/io/jsonio/unmarshalConns.go b/pkg/io/jsonio/unmarshalConns.go index 4d0c59d6..a9b9a661 100644 --- a/pkg/io/jsonio/unmarshalConns.go +++ b/pkg/io/jsonio/unmarshalConns.go @@ -16,8 +16,8 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) -// transalteConnections translate requires connections from spec.Spec to []*ir.Connection -func (r *Reader) transalteConnections(conns []spec.SpecRequiredConnectionsElem, defs *ir.Definitions, isSG bool) ([]*ir.Connection, error) { +// translateConnections translate requires connections from spec.Spec to []*ir.Connection +func (r *Reader) translateConnections(conns []spec.SpecRequiredConnectionsElem, defs *ir.Definitions, isSG bool) ([]*ir.Connection, error) { var connections []*ir.Connection for i := range conns { conns, err := translateConnection(defs, &conns[i], i, isSG) @@ -31,8 +31,8 @@ func (r *Reader) transalteConnections(conns []spec.SpecRequiredConnectionsElem, func translateConnection(defs *ir.Definitions, conn *spec.SpecRequiredConnectionsElem, connIdx int, isSG bool) ([]*ir.Connection, error) { protocols, err1 := translateProtocols(conn.AllowedProtocols) - srcResource, isSrcExternal, err2 := transalteConnectionResource(defs, &conn.Src, isSG) - dstResource, isDstExternal, err3 := transalteConnectionResource(defs, &conn.Dst, isSG) + srcResource, isSrcExternal, err2 := translateConnectionResource(defs, &conn.Src, isSG) + dstResource, isDstExternal, err3 := translateConnectionResource(defs, &conn.Dst, isSG) if err := errors.Join(err1, err2, err3); err != nil { return nil, err } @@ -55,7 +55,7 @@ func translateConnection(defs *ir.Definitions, conn *spec.SpecRequiredConnection return []*ir.Connection{out}, nil } -func transalteConnectionResource(defs *ir.Definitions, resource *spec.Resource, +func translateConnectionResource(defs *ir.Definitions, resource *spec.Resource, isSG bool) (r *ir.FirewallResource, isExternal bool, err error) { resourceType, err := translateResourceType(defs, resource) if err != nil { @@ -137,7 +137,7 @@ func translateResourceType(defs *ir.Definitions, resource *spec.Resource) (ir.Re } func updateBlockedResourcesSGSynth(defs *ir.Definitions, resource *ir.FirewallResource) { - for _, namedAddrs := range resource.NamedAddrs { + for _, namedAddrs := range resource.AppliedTo { if _, ok := defs.BlockedInstances[*namedAddrs.Name]; ok { defs.BlockedInstances[*namedAddrs.Name] = false } @@ -148,7 +148,7 @@ func updateBlockedResourcesSGSynth(defs *ir.Definitions, resource *ir.FirewallRe } func updateBlockedResourcesACLSynth(defs *ir.Definitions, resource *ir.FirewallResource) { - for _, namedAddrs := range resource.NamedAddrs { + for _, namedAddrs := range resource.AppliedTo { if _, ok := defs.BlockedSubnets[*namedAddrs.Name]; ok { defs.BlockedSubnets[*namedAddrs.Name] = false } diff --git a/pkg/ir/lookupForACLSynth.go b/pkg/ir/lookupForACLSynth.go index 739f8f78..5119e7a6 100644 --- a/pkg/ir/lookupForACLSynth.go +++ b/pkg/ir/lookupForACLSynth.go @@ -59,7 +59,7 @@ func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definition return nil, fmt.Errorf(containerNotFound, name, t) } - res := &FirewallResource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} endpointMap := containerDetails.endpointMap(defs) for _, endpointName := range containerDetails.endpointNames() { subnet, err := lookupSingleForACLSynth(endpointMap, defs.Subnets, endpointName, containerDetails.endpointType()) @@ -67,7 +67,7 @@ func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definition return nil, err } res.Cidrs = append(res.Cidrs, subnet.Cidrs...) - res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) + res.AppliedTo = append(res.AppliedTo, subnet.AppliedTo...) } return res, nil } @@ -78,13 +78,13 @@ func (s *Definitions) lookupCidrSegmentACL(name string) (*FirewallResource, erro return nil, fmt.Errorf(containerNotFound, name, ResourceTypeCidrSegment) } - res := &FirewallResource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} for _, subnetName := range segmentDetails.ContainedSubnets { subnet, err := lookupSingle(s.Subnets, subnetName, ResourceTypeSubnet) if err != nil { return nil, fmt.Errorf("%w while looking up %v %v for cidr segment %v", err, ResourceTypeSubnet, subnetName, name) } - res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) + res.AppliedTo = append(res.AppliedTo, subnet.AppliedTo...) } for _, cidr := range segmentDetails.Cidrs.SplitToCidrs() { res.Cidrs = append(res.Cidrs, &NamedAddrs{Name: &name, IPAddrs: cidr}) diff --git a/pkg/ir/lookupForSGSynth.go b/pkg/ir/lookupForSGSynth.go index b0c62cf1..3f611c63 100644 --- a/pkg/ir/lookupForSGSynth.go +++ b/pkg/ir/lookupForSGSynth.go @@ -43,10 +43,10 @@ func (s *Definitions) LookupForSGSynth(t ResourceType, name string) (*FirewallRe func (s *Definitions) lookupNIFForSGSynth(name string) (*FirewallResource, error) { if _, ok := s.NIFs[name]; ok { return &FirewallResource{ - Name: &name, - NamedAddrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, - Cidrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, - Type: utils.Ptr(ResourceTypeNIF), + Name: &name, + AppliedTo: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, + Cidrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, + Type: utils.Ptr(ResourceTypeNIF), }, nil } return nil, fmt.Errorf(resourceNotFound, ResourceTypeNIF, name) @@ -55,10 +55,10 @@ func (s *Definitions) lookupNIFForSGSynth(name string) (*FirewallResource, error func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, t ResourceType) (*FirewallResource, error) { if _, ok := m[name]; ok { return &FirewallResource{ - Name: &name, - NamedAddrs: []*NamedAddrs{{Name: &name}}, - Cidrs: []*NamedAddrs{{Name: &name}}, - Type: utils.Ptr(t), + Name: &name, + AppliedTo: []*NamedAddrs{{Name: &name}}, + Cidrs: []*NamedAddrs{{Name: &name}}, + Type: utils.Ptr(t), }, nil } return nil, fmt.Errorf(containerNotFound, t, name) @@ -67,9 +67,9 @@ func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, func (s *Definitions) lookupSubnetForSGSynth(name string) (*FirewallResource, error) { if subnetDetails, ok := s.Subnets[name]; ok { return &FirewallResource{Name: &name, - NamedAddrs: s.containedResourcesInCidr(subnetDetails.CIDR), - Cidrs: []*NamedAddrs{{IPAddrs: subnetDetails.CIDR}}, - Type: utils.Ptr(ResourceTypeSubnet), + AppliedTo: s.containedResourcesInCidr(subnetDetails.CIDR), + Cidrs: []*NamedAddrs{{IPAddrs: subnetDetails.CIDR}}, + Type: utils.Ptr(ResourceTypeSubnet), }, nil } return nil, fmt.Errorf(resourceNotFound, ResourceTypeSubnet, name) @@ -78,9 +78,9 @@ func (s *Definitions) lookupSubnetForSGSynth(name string) (*FirewallResource, er func (s *Definitions) lookupCidrSegmentForSGSynth(name string) (*FirewallResource, error) { if segmentDetails, ok := s.CidrSegments[name]; ok { return &FirewallResource{Name: &name, - NamedAddrs: s.containedResourcesInCidr(segmentDetails.Cidrs), - Cidrs: cidrToNamedAddrs(segmentDetails.Cidrs), - Type: utils.Ptr(ResourceTypeCidr), + AppliedTo: s.containedResourcesInCidr(segmentDetails.Cidrs), + Cidrs: cidrToNamedAddrs(segmentDetails.Cidrs), + Type: utils.Ptr(ResourceTypeCidr), }, nil } return nil, fmt.Errorf(containerNotFound, ResourceTypeCidrSegment, name) diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index ceaf35a2..db2f5052 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -47,8 +47,7 @@ type ( // Symbolic name of resource, if available Name *string - // list of CIDR / Ip addresses. - NamedAddrs []*NamedAddrs + AppliedTo []*NamedAddrs // Cidr list Cidrs []*NamedAddrs @@ -267,10 +266,10 @@ func (v *VPEDetails) endpointType() ResourceType { func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*FirewallResource, error) { if details, ok := m[name]; ok { return &FirewallResource{ - Name: &name, - NamedAddrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, - Cidrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, - Type: utils.Ptr(t), + Name: &name, + AppliedTo: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, + Cidrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, + Type: utils.Ptr(t), }, nil } return nil, fmt.Errorf(resourceNotFound, name, t) @@ -283,13 +282,13 @@ func (s *Definitions) lookupSegment(segment map[ID]*SegmentDetails, name string, return nil, fmt.Errorf(containerNotFound, name, t) } - res := &FirewallResource{Name: &name, NamedAddrs: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(elementType)} + res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(elementType)} for _, elementName := range segmentDetails.Elements { subnet, err := lookup(elementType, elementName) if err != nil { return nil, err } - res.NamedAddrs = append(res.NamedAddrs, subnet.NamedAddrs...) + res.AppliedTo = append(res.AppliedTo, subnet.AppliedTo...) res.Cidrs = append(res.Cidrs, subnet.Cidrs...) } return res, nil diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index ffe5ebc1..aaace3b2 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -47,7 +47,7 @@ func (a *ACLSynthesizer) makeACL() *ir.ACLCollection { func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection, thisResource, otherResource *ir.FirewallResource, allowConnection func(*ir.Connection, *ir.TrackedProtocol, *ir.NamedAddrs, *netset.IPBlock)) { - for _, thisSubnet := range thisResource.NamedAddrs { + for _, thisSubnet := range thisResource.AppliedTo { for _, otherCidr := range otherResource.Cidrs { if thisSubnet.IPAddrs.Equal(otherCidr.IPAddrs) && *thisResource.Type != ir.ResourceTypeCidr && *otherResource.Type != ir.ResourceTypeCidr { diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 6bbaa839..05ae047f 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -43,7 +43,7 @@ func (s *SGSynthesizer) makeSG() *ir.SGCollection { func (s *SGSynthesizer) generateSGRulesFromConnection(conn *ir.Connection, direction ir.Direction) { localResource, remoteResource, internalEndpoint, internalConn := connSettings(conn, direction) - for _, localEndpoint := range localResource.NamedAddrs { + for _, localEndpoint := range localResource.AppliedTo { for _, remoteCidr := range remoteResource.Cidrs { for _, trackedProtocol := range conn.TrackedProtocols { ruleExplanation := explanation{internal: internalConn, connectionOrigin: conn.Origin, protocolOrigin: trackedProtocol.Origin}.String() From f4bca3b5e72e38d7fa36de9f9c8f0d2761664926 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 28 Oct 2024 16:16:25 +0200 Subject: [PATCH 094/131] rename3 --- pkg/ir/lookupForACLSynth.go | 8 ++++---- pkg/ir/lookupForSGSynth.go | 28 ++++++++++++++-------------- pkg/ir/sg.go | 11 ----------- pkg/ir/spec.go | 14 +++++++------- pkg/synth/acl.go | 2 +- pkg/synth/sg.go | 2 +- 6 files changed, 27 insertions(+), 38 deletions(-) diff --git a/pkg/ir/lookupForACLSynth.go b/pkg/ir/lookupForACLSynth.go index 5119e7a6..8181f043 100644 --- a/pkg/ir/lookupForACLSynth.go +++ b/pkg/ir/lookupForACLSynth.go @@ -59,14 +59,14 @@ func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definition return nil, fmt.Errorf(containerNotFound, name, t) } - res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, RemoteCidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} endpointMap := containerDetails.endpointMap(defs) for _, endpointName := range containerDetails.endpointNames() { subnet, err := lookupSingleForACLSynth(endpointMap, defs.Subnets, endpointName, containerDetails.endpointType()) if err != nil { return nil, err } - res.Cidrs = append(res.Cidrs, subnet.Cidrs...) + res.RemoteCidrs = append(res.RemoteCidrs, subnet.RemoteCidrs...) res.AppliedTo = append(res.AppliedTo, subnet.AppliedTo...) } return res, nil @@ -78,7 +78,7 @@ func (s *Definitions) lookupCidrSegmentACL(name string) (*FirewallResource, erro return nil, fmt.Errorf(containerNotFound, name, ResourceTypeCidrSegment) } - res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, RemoteCidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} for _, subnetName := range segmentDetails.ContainedSubnets { subnet, err := lookupSingle(s.Subnets, subnetName, ResourceTypeSubnet) if err != nil { @@ -87,7 +87,7 @@ func (s *Definitions) lookupCidrSegmentACL(name string) (*FirewallResource, erro res.AppliedTo = append(res.AppliedTo, subnet.AppliedTo...) } for _, cidr := range segmentDetails.Cidrs.SplitToCidrs() { - res.Cidrs = append(res.Cidrs, &NamedAddrs{Name: &name, IPAddrs: cidr}) + res.RemoteCidrs = append(res.RemoteCidrs, &NamedAddrs{Name: &name, IPAddrs: cidr}) } return res, nil } diff --git a/pkg/ir/lookupForSGSynth.go b/pkg/ir/lookupForSGSynth.go index 3f611c63..b7797539 100644 --- a/pkg/ir/lookupForSGSynth.go +++ b/pkg/ir/lookupForSGSynth.go @@ -43,10 +43,10 @@ func (s *Definitions) LookupForSGSynth(t ResourceType, name string) (*FirewallRe func (s *Definitions) lookupNIFForSGSynth(name string) (*FirewallResource, error) { if _, ok := s.NIFs[name]; ok { return &FirewallResource{ - Name: &name, - AppliedTo: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, - Cidrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, - Type: utils.Ptr(ResourceTypeNIF), + Name: &name, + AppliedTo: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, + RemoteCidrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, + Type: utils.Ptr(ResourceTypeNIF), }, nil } return nil, fmt.Errorf(resourceNotFound, ResourceTypeNIF, name) @@ -55,10 +55,10 @@ func (s *Definitions) lookupNIFForSGSynth(name string) (*FirewallResource, error func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, t ResourceType) (*FirewallResource, error) { if _, ok := m[name]; ok { return &FirewallResource{ - Name: &name, - AppliedTo: []*NamedAddrs{{Name: &name}}, - Cidrs: []*NamedAddrs{{Name: &name}}, - Type: utils.Ptr(t), + Name: &name, + AppliedTo: []*NamedAddrs{{Name: &name}}, + RemoteCidrs: []*NamedAddrs{{Name: &name}}, + Type: utils.Ptr(t), }, nil } return nil, fmt.Errorf(containerNotFound, t, name) @@ -67,9 +67,9 @@ func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, func (s *Definitions) lookupSubnetForSGSynth(name string) (*FirewallResource, error) { if subnetDetails, ok := s.Subnets[name]; ok { return &FirewallResource{Name: &name, - AppliedTo: s.containedResourcesInCidr(subnetDetails.CIDR), - Cidrs: []*NamedAddrs{{IPAddrs: subnetDetails.CIDR}}, - Type: utils.Ptr(ResourceTypeSubnet), + AppliedTo: s.containedResourcesInCidr(subnetDetails.CIDR), + RemoteCidrs: []*NamedAddrs{{IPAddrs: subnetDetails.CIDR}}, + Type: utils.Ptr(ResourceTypeSubnet), }, nil } return nil, fmt.Errorf(resourceNotFound, ResourceTypeSubnet, name) @@ -78,9 +78,9 @@ func (s *Definitions) lookupSubnetForSGSynth(name string) (*FirewallResource, er func (s *Definitions) lookupCidrSegmentForSGSynth(name string) (*FirewallResource, error) { if segmentDetails, ok := s.CidrSegments[name]; ok { return &FirewallResource{Name: &name, - AppliedTo: s.containedResourcesInCidr(segmentDetails.Cidrs), - Cidrs: cidrToNamedAddrs(segmentDetails.Cidrs), - Type: utils.Ptr(ResourceTypeCidr), + AppliedTo: s.containedResourcesInCidr(segmentDetails.Cidrs), + RemoteCidrs: cidrToNamedAddrs(segmentDetails.Cidrs), + Type: utils.Ptr(ResourceTypeCidr), }, nil } return nil, fmt.Errorf(containerNotFound, ResourceTypeCidrSegment, name) diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 0011b011..a8864141 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -14,17 +14,6 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -type SGResource string - -const ( - SGResourceNIF SGResource = "nif" - SGResourceBareMetalNIF SGResource = "bnif" - SGResourceLoadBalancer SGResource = "loadbalancer" - SGResourceVPE SGResource = "vpe" - SGResourceVPNServer SGResource = "vpn" - SGResourceFileShareMountTarget SGResource = "fsmt" -) - type SGName string func (s SGName) String() string { diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index db2f5052..94646b43 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -50,7 +50,7 @@ type ( AppliedTo []*NamedAddrs // Cidr list - Cidrs []*NamedAddrs + RemoteCidrs []*NamedAddrs // Type of resource Type *ResourceType @@ -266,10 +266,10 @@ func (v *VPEDetails) endpointType() ResourceType { func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*FirewallResource, error) { if details, ok := m[name]; ok { return &FirewallResource{ - Name: &name, - AppliedTo: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, - Cidrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, - Type: utils.Ptr(t), + Name: &name, + AppliedTo: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, + RemoteCidrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, + Type: utils.Ptr(t), }, nil } return nil, fmt.Errorf(resourceNotFound, name, t) @@ -282,14 +282,14 @@ func (s *Definitions) lookupSegment(segment map[ID]*SegmentDetails, name string, return nil, fmt.Errorf(containerNotFound, name, t) } - res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, Cidrs: []*NamedAddrs{}, Type: utils.Ptr(elementType)} + res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, RemoteCidrs: []*NamedAddrs{}, Type: utils.Ptr(elementType)} for _, elementName := range segmentDetails.Elements { subnet, err := lookup(elementType, elementName) if err != nil { return nil, err } res.AppliedTo = append(res.AppliedTo, subnet.AppliedTo...) - res.Cidrs = append(res.Cidrs, subnet.Cidrs...) + res.RemoteCidrs = append(res.RemoteCidrs, subnet.RemoteCidrs...) } return res, nil } diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index aaace3b2..f3c1b170 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -48,7 +48,7 @@ func (a *ACLSynthesizer) makeACL() *ir.ACLCollection { func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection, thisResource, otherResource *ir.FirewallResource, allowConnection func(*ir.Connection, *ir.TrackedProtocol, *ir.NamedAddrs, *netset.IPBlock)) { for _, thisSubnet := range thisResource.AppliedTo { - for _, otherCidr := range otherResource.Cidrs { + for _, otherCidr := range otherResource.RemoteCidrs { if thisSubnet.IPAddrs.Equal(otherCidr.IPAddrs) && *thisResource.Type != ir.ResourceTypeCidr && *otherResource.Type != ir.ResourceTypeCidr { continue diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 05ae047f..8dc2a60d 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -44,7 +44,7 @@ func (s *SGSynthesizer) generateSGRulesFromConnection(conn *ir.Connection, direc localResource, remoteResource, internalEndpoint, internalConn := connSettings(conn, direction) for _, localEndpoint := range localResource.AppliedTo { - for _, remoteCidr := range remoteResource.Cidrs { + for _, remoteCidr := range remoteResource.RemoteCidrs { for _, trackedProtocol := range conn.TrackedProtocols { ruleExplanation := explanation{internal: internalConn, connectionOrigin: conn.Origin, protocolOrigin: trackedProtocol.Origin}.String() s.allowConnectionEndpoint(localEndpoint, remoteCidr, remoteResource.Type, trackedProtocol.Protocol, direction, From 5ed05427ffa3275551bee33467c22acd25380449 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 29 Oct 2024 11:50:50 +0200 Subject: [PATCH 095/131] read acls --- pkg/io/confio/parse_acls.go | 135 +++++++++++++++++++++++++++++++++++- pkg/io/confio/parse_sgs.go | 67 ++++++------------ pkg/io/tfio/acl.go | 3 +- pkg/ir/acl.go | 2 + 4 files changed, 157 insertions(+), 50 deletions(-) diff --git a/pkg/io/confio/parse_acls.go b/pkg/io/confio/parse_acls.go index 13481978..09647519 100644 --- a/pkg/io/confio/parse_acls.go +++ b/pkg/io/confio/parse_acls.go @@ -5,8 +5,137 @@ SPDX-License-Identifier: Apache-2.0 package confio -import "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +import ( + "errors" + "fmt" + "log" -func ReadACLs(_ string) (*ir.ACLCollection, error) { - return nil, nil + "github.com/IBM/vpc-go-sdk/vpcv1" + + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +// ReadACLs translates ACLs from a config_object file to ir.ACLCollection +func ReadACLs(filename string) (*ir.ACLCollection, error) { + config, err := readModel(filename) + if err != nil { + return nil, err + } + + result := ir.NewACLCollection() + for i, acl := range config.NetworkACLList { + if acl.Name == nil || acl.VPC == nil || acl.VPC.Name == nil { + log.Printf("Warning: missing acl/VPC name in acl at index %d\n", i) + continue + } + inbound, outbound, err := translateACLRules(&acl.NetworkACL) + if err != nil { + return nil, err + } + vpcName := *acl.VPC.Name + if result.ACLs[vpcName] == nil { + result.ACLs[vpcName] = make(map[string]*ir.ACL) + } + result.ACLs[vpcName][*acl.Name] = &ir.ACL{Inbound: inbound, Outbound: outbound} + } + return result, nil +} + +func translateACLRules(acl *vpcv1.NetworkACL) (inbound, outbound []*ir.ACLRule, err error) { + inbound = make([]*ir.ACLRule, 0) + outbound = make([]*ir.ACLRule, 0) + for index := range acl.Rules { + rule, err := translateACLRule(acl, index) + if err != nil { + return nil, nil, err + } + if rule.Direction == ir.Inbound { + inbound = append(inbound, rule) + } else { + outbound = append(outbound, rule) + } + } + return inbound, outbound, nil +} + +func translateACLRule(acl *vpcv1.NetworkACL, i int) (*ir.ACLRule, error) { + switch r := acl.Rules[i].(type) { + case *vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolAll: + return translateACLRuleProtocolAll(r) + case *vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolTcpudp: + return translateACLRuleProtocolTCPUDP(r) + case *vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolIcmp: + return translateACLRuleProtocolIcmp(r) + } + return nil, fmt.Errorf("error parsing rule number %d in acl %s in VPC %s", i, *acl.Name, *acl.VPC.Name) +} + +func translateACLRuleProtocolAll(rule *vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolAll) (*ir.ACLRule, error) { + action, err1 := translateAction(rule.Action) + direction, err2 := translateDirection(*rule.Direction) + src, err3 := translateResource(rule.Source) + dst, err4 := translateResource(rule.Destination) + if err := errors.Join(err1, err2, err3, err4); err != nil { + return nil, err + } + return &ir.ACLRule{ + Action: action, + Direction: direction, + Source: src, + Destination: dst, + Protocol: netp.AnyProtocol{}, + }, nil +} + +func translateACLRuleProtocolTCPUDP(rule *vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolTcpudp) (*ir.ACLRule, error) { + action, err1 := translateAction(rule.Action) + direction, err2 := translateDirection(*rule.Direction) + src, err3 := translateResource(rule.Source) + dst, err4 := translateResource(rule.Destination) + protocol, err5 := translateProtocolTCPUDP(*rule.Protocol, rule.DestinationPortMin, rule.DestinationPortMax) + if err := errors.Join(err1, err2, err3, err4, err5); err != nil { + return nil, err + } + + return &ir.ACLRule{ + Action: action, + Direction: direction, + Source: src, + Destination: dst, + Protocol: protocol, + }, nil +} + +func translateACLRuleProtocolIcmp(rule *vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolIcmp) (*ir.ACLRule, error) { + action, err1 := translateAction(rule.Action) + direction, err2 := translateDirection(*rule.Direction) + src, err3 := translateResource(rule.Source) + dst, err4 := translateResource(rule.Destination) + protocol, err5 := netp.ICMPFromTypeAndCode64WithoutRFCValidation(rule.Type, rule.Code) + if err := errors.Join(err1, err2, err3, err4, err5); err != nil { + return nil, err + } + + return &ir.ACLRule{ + Action: action, + Direction: direction, + Source: src, + Destination: dst, + Protocol: protocol, + }, nil +} + +func translateAction(action *string) (ir.Action, error) { + if *action == vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolAllActionAllowConst { + return ir.Allow, nil + } else if *action == vpcv1.NetworkACLRuleItemNetworkACLRuleProtocolAllActionDenyConst { + return ir.Deny, nil + } + return ir.Deny, fmt.Errorf("an nACL rule action must be either allow or deny") +} + +func translateResource(ipAddrs *string) (*netset.IPBlock, error) { + return netset.IPBlockFromCidrOrAddress(*ipAddrs) } diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index f39f890d..840317dc 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -6,6 +6,7 @@ SPDX-License-Identifier: Apache-2.0 package confio import ( + "errors" "fmt" "log" @@ -42,7 +43,7 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{SGName: ir.SGName(*sg.Name), InboundRules: inbound, OutboundRules: outbound, - Targets: transalteTargets(&sg.SecurityGroup), + Targets: translateTargets(&sg.SecurityGroup), } } return result, nil @@ -81,56 +82,32 @@ func translateSGRule(sg *vpcv1.SecurityGroup, index int) (sgRule *ir.SGRule, err } func translateSGRuleProtocolAll(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll) (sgRule *ir.SGRule, err error) { - direction, err := translateDirection(*rule.Direction) - if err != nil { - return nil, err - } - remote, err := translateRemote(rule.Remote) - if err != nil { - return nil, err - } - local, err := translateLocal(rule.Local) - if err != nil { + direction, err1 := translateDirection(*rule.Direction) + remote, err2 := translateRemote(rule.Remote) + local, err3 := translateLocal(rule.Local) + if err := errors.Join(err1, err2, err3); err != nil { return nil, err } return &ir.SGRule{Direction: direction, Remote: remote, Protocol: netp.AnyProtocol{}, Local: local}, nil } func translateSGRuleProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (sgRule *ir.SGRule, err error) { - direction, err := translateDirection(*rule.Direction) - if err != nil { - return nil, err - } - remote, err := translateRemote(rule.Remote) - if err != nil { - return nil, err - } - local, err := translateLocal(rule.Local) - if err != nil { - return nil, err - } - protocol, err := translateProtocolTCPUDP(rule) - if err != nil { + direction, err1 := translateDirection(*rule.Direction) + remote, err2 := translateRemote(rule.Remote) + local, err3 := translateLocal(rule.Local) + protocol, err4 := translateProtocolTCPUDP(*rule.Protocol, rule.PortMin, rule.PortMax) + if err := errors.Join(err1, err2, err3, err4); err != nil { return nil, err } return &ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil } func translateSGRuleProtocolIcmp(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp) (sgRule *ir.SGRule, err error) { - direction, err := translateDirection(*rule.Direction) - if err != nil { - return nil, err - } - remote, err := translateRemote(rule.Remote) - if err != nil { - return nil, err - } - local, err := translateLocal(rule.Local) - if err != nil { - return nil, err - } - protocol, err := netp.ICMPFromTypeAndCode64WithoutRFCValidation(rule.Type, rule.Code) - if err != nil { + direction, err1 := translateDirection(*rule.Direction) + remote, err2 := translateRemote(rule.Remote) + local, err3 := translateLocal(rule.Local) + protocol, err4 := netp.ICMPFromTypeAndCode64WithoutRFCValidation(rule.Type, rule.Code) + if err := errors.Join(err1, err2, err3, err4); err != nil { return nil, err } return &ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil @@ -142,7 +119,7 @@ func translateDirection(direction string) (ir.Direction, error) { } else if direction == "outbound" { return ir.Outbound, nil } - return ir.Inbound, fmt.Errorf("SG rule direction must be either inbound or outbound") + return ir.Inbound, fmt.Errorf("a firewall rule direction must be either inbound or outbound") } func translateRemote(remote vpcv1.SecurityGroupRuleRemoteIntf) (ir.RemoteType, error) { @@ -172,7 +149,7 @@ func translateLocal(local vpcv1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, er } // translate SG targets -func transalteTargets(sg *vpcv1.SecurityGroup) []string { +func translateTargets(sg *vpcv1.SecurityGroup) []string { if len(sg.Targets) == 0 { log.Printf("Warning: Security Groups %s does not have attached resources", *sg.Name) } @@ -187,9 +164,9 @@ func transalteTargets(sg *vpcv1.SecurityGroup) []string { return res } -func translateProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (netp.Protocol, error) { - isTCP := *rule.Protocol == vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudpProtocolTCPConst - minDstPort := utils.GetProperty(rule.PortMin, netp.MinPort) - maxDstPort := utils.GetProperty(rule.PortMax, netp.MaxPort) +func translateProtocolTCPUDP(protocolName string, portMin, portMax *int64) (netp.Protocol, error) { + isTCP := protocolName == vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudpProtocolTCPConst + minDstPort := utils.GetProperty(portMin, netp.MinPort) + maxDstPort := utils.GetProperty(portMax, netp.MaxPort) return netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(minDstPort), int(maxDstPort)) } diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index 15b31afe..24f52ca6 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -28,8 +28,7 @@ func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string, _ bool) error { if err != nil { return err } - err = w.w.Flush() - return err + return w.w.Flush() } func aclProtocol(t netp.Protocol) []tf.Block { diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index 938a74e8..54e27a5f 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -31,6 +31,8 @@ type ( Subnet string Internal []*ACLRule External []*ACLRule + Inbound []*ACLRule + Outbound []*ACLRule } ACLCollection struct { From 9fbc33f6e198971d6efa3145d983d66cde00becc Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 29 Oct 2024 17:10:17 +0200 Subject: [PATCH 096/131] renaming --- pkg/io/jsonio/unmarshalConns.go | 12 +++++------ pkg/ir/lookupForACLSynth.go | 18 ++++++++--------- pkg/ir/lookupForSGSynth.go | 35 ++++++++++++++++----------------- pkg/ir/spec.go | 27 ++++++++++++------------- pkg/synth/acl.go | 8 ++++---- pkg/synth/common.go | 4 ++-- pkg/synth/sg.go | 12 +++++------ 7 files changed, 56 insertions(+), 60 deletions(-) diff --git a/pkg/io/jsonio/unmarshalConns.go b/pkg/io/jsonio/unmarshalConns.go index a9b9a661..fd194d43 100644 --- a/pkg/io/jsonio/unmarshalConns.go +++ b/pkg/io/jsonio/unmarshalConns.go @@ -56,12 +56,12 @@ func translateConnection(defs *ir.Definitions, conn *spec.SpecRequiredConnection } func translateConnectionResource(defs *ir.Definitions, resource *spec.Resource, - isSG bool) (r *ir.FirewallResource, isExternal bool, err error) { + isSG bool) (r *ir.LocalRemotePair, isExternal bool, err error) { resourceType, err := translateResourceType(defs, resource) if err != nil { return nil, false, err } - var res *ir.FirewallResource + var res *ir.LocalRemotePair if isSG { res, err = defs.LookupForSGSynth(resourceType, resource.Name) updateBlockedResourcesSGSynth(defs, res) @@ -136,8 +136,8 @@ func translateResourceType(defs *ir.Definitions, resource *spec.Resource) (ir.Re return ir.ResourceTypeSubnet, fmt.Errorf("unsupported resource type %v (%v)", resource.Type, resource.Name) } -func updateBlockedResourcesSGSynth(defs *ir.Definitions, resource *ir.FirewallResource) { - for _, namedAddrs := range resource.AppliedTo { +func updateBlockedResourcesSGSynth(defs *ir.Definitions, resource *ir.LocalRemotePair) { + for _, namedAddrs := range resource.LocalCidrs { if _, ok := defs.BlockedInstances[*namedAddrs.Name]; ok { defs.BlockedInstances[*namedAddrs.Name] = false } @@ -147,8 +147,8 @@ func updateBlockedResourcesSGSynth(defs *ir.Definitions, resource *ir.FirewallRe } } -func updateBlockedResourcesACLSynth(defs *ir.Definitions, resource *ir.FirewallResource) { - for _, namedAddrs := range resource.AppliedTo { +func updateBlockedResourcesACLSynth(defs *ir.Definitions, resource *ir.LocalRemotePair) { + for _, namedAddrs := range resource.LocalCidrs { if _, ok := defs.BlockedSubnets[*namedAddrs.Name]; ok { defs.BlockedSubnets[*namedAddrs.Name] = false } diff --git a/pkg/ir/lookupForACLSynth.go b/pkg/ir/lookupForACLSynth.go index 8181f043..8af15a5b 100644 --- a/pkg/ir/lookupForACLSynth.go +++ b/pkg/ir/lookupForACLSynth.go @@ -8,11 +8,9 @@ package ir import ( "fmt" - - "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -func (s *Definitions) LookupForACLSynth(t ResourceType, name string) (*FirewallResource, error) { +func (s *Definitions) LookupForACLSynth(t ResourceType, name string) (*LocalRemotePair, error) { switch t { case ResourceTypeExternal: return lookupSingle(s.Externals, name, t) @@ -39,7 +37,7 @@ func (s *Definitions) LookupForACLSynth(t ResourceType, name string) (*FirewallR } func lookupSingleForACLSynth[T INWResource](m map[ID]T, subnets map[ID]*SubnetDetails, name string, - t ResourceType) (*FirewallResource, error) { + t ResourceType) (*LocalRemotePair, error) { details, ok := m[name] if !ok { return nil, fmt.Errorf(resourceNotFound, name, t) @@ -53,13 +51,13 @@ func lookupSingleForACLSynth[T INWResource](m map[ID]T, subnets map[ID]*SubnetDe return res, nil } -func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definitions, name string, t ResourceType) (*FirewallResource, error) { +func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definitions, name string, t ResourceType) (*LocalRemotePair, error) { containerDetails, ok := m[name] if !ok { return nil, fmt.Errorf(containerNotFound, name, t) } - res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, RemoteCidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + res := &LocalRemotePair{Name: &name, LocalCidrs: []*NamedAddrs{}, RemoteCidrs: []*NamedAddrs{}, LocalType: ResourceTypeSubnet} endpointMap := containerDetails.endpointMap(defs) for _, endpointName := range containerDetails.endpointNames() { subnet, err := lookupSingleForACLSynth(endpointMap, defs.Subnets, endpointName, containerDetails.endpointType()) @@ -67,24 +65,24 @@ func lookupContainerForACLSynth[T EndpointProvider](m map[ID]T, defs *Definition return nil, err } res.RemoteCidrs = append(res.RemoteCidrs, subnet.RemoteCidrs...) - res.AppliedTo = append(res.AppliedTo, subnet.AppliedTo...) + res.LocalCidrs = append(res.LocalCidrs, subnet.LocalCidrs...) } return res, nil } -func (s *Definitions) lookupCidrSegmentACL(name string) (*FirewallResource, error) { +func (s *Definitions) lookupCidrSegmentACL(name string) (*LocalRemotePair, error) { segmentDetails, ok := s.CidrSegments[name] if !ok { return nil, fmt.Errorf(containerNotFound, name, ResourceTypeCidrSegment) } - res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, RemoteCidrs: []*NamedAddrs{}, Type: utils.Ptr(ResourceTypeSubnet)} + res := &LocalRemotePair{Name: &name, LocalCidrs: []*NamedAddrs{}, RemoteCidrs: []*NamedAddrs{}, LocalType: ResourceTypeSubnet} for _, subnetName := range segmentDetails.ContainedSubnets { subnet, err := lookupSingle(s.Subnets, subnetName, ResourceTypeSubnet) if err != nil { return nil, fmt.Errorf("%w while looking up %v %v for cidr segment %v", err, ResourceTypeSubnet, subnetName, name) } - res.AppliedTo = append(res.AppliedTo, subnet.AppliedTo...) + res.LocalCidrs = append(res.LocalCidrs, subnet.LocalCidrs...) } for _, cidr := range segmentDetails.Cidrs.SplitToCidrs() { res.RemoteCidrs = append(res.RemoteCidrs, &NamedAddrs{Name: &name, IPAddrs: cidr}) diff --git a/pkg/ir/lookupForSGSynth.go b/pkg/ir/lookupForSGSynth.go index b7797539..e55ad427 100644 --- a/pkg/ir/lookupForSGSynth.go +++ b/pkg/ir/lookupForSGSynth.go @@ -11,10 +11,9 @@ import ( "slices" "github.com/np-guard/models/pkg/netset" - "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -func (s *Definitions) LookupForSGSynth(t ResourceType, name string) (*FirewallResource, error) { +func (s *Definitions) LookupForSGSynth(t ResourceType, name string) (*LocalRemotePair, error) { switch t { case ResourceTypeExternal: return lookupSingle(s.Externals, name, t) @@ -40,47 +39,47 @@ func (s *Definitions) LookupForSGSynth(t ResourceType, name string) (*FirewallRe return nil, nil // should not get here } -func (s *Definitions) lookupNIFForSGSynth(name string) (*FirewallResource, error) { +func (s *Definitions) lookupNIFForSGSynth(name string) (*LocalRemotePair, error) { if _, ok := s.NIFs[name]; ok { - return &FirewallResource{ + return &LocalRemotePair{ Name: &name, - AppliedTo: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, + LocalCidrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, RemoteCidrs: []*NamedAddrs{{Name: &s.NIFs[name].Instance}}, - Type: utils.Ptr(ResourceTypeNIF), + LocalType: ResourceTypeNIF, }, nil } return nil, fmt.Errorf(resourceNotFound, ResourceTypeNIF, name) } -func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, t ResourceType) (*FirewallResource, error) { +func lookupContainerForSGSynth[T EndpointProvider](m map[string]T, name string, t ResourceType) (*LocalRemotePair, error) { if _, ok := m[name]; ok { - return &FirewallResource{ + return &LocalRemotePair{ Name: &name, - AppliedTo: []*NamedAddrs{{Name: &name}}, + LocalCidrs: []*NamedAddrs{{Name: &name}}, RemoteCidrs: []*NamedAddrs{{Name: &name}}, - Type: utils.Ptr(t), + LocalType: t, }, nil } return nil, fmt.Errorf(containerNotFound, t, name) } -func (s *Definitions) lookupSubnetForSGSynth(name string) (*FirewallResource, error) { +func (s *Definitions) lookupSubnetForSGSynth(name string) (*LocalRemotePair, error) { if subnetDetails, ok := s.Subnets[name]; ok { - return &FirewallResource{Name: &name, - AppliedTo: s.containedResourcesInCidr(subnetDetails.CIDR), + return &LocalRemotePair{Name: &name, + LocalCidrs: s.containedResourcesInCidr(subnetDetails.CIDR), RemoteCidrs: []*NamedAddrs{{IPAddrs: subnetDetails.CIDR}}, - Type: utils.Ptr(ResourceTypeSubnet), + LocalType: ResourceTypeSubnet, }, nil } return nil, fmt.Errorf(resourceNotFound, ResourceTypeSubnet, name) } -func (s *Definitions) lookupCidrSegmentForSGSynth(name string) (*FirewallResource, error) { +func (s *Definitions) lookupCidrSegmentForSGSynth(name string) (*LocalRemotePair, error) { if segmentDetails, ok := s.CidrSegments[name]; ok { - return &FirewallResource{Name: &name, - AppliedTo: s.containedResourcesInCidr(segmentDetails.Cidrs), + return &LocalRemotePair{Name: &name, + LocalCidrs: s.containedResourcesInCidr(segmentDetails.Cidrs), RemoteCidrs: cidrToNamedAddrs(segmentDetails.Cidrs), - Type: utils.Ptr(ResourceTypeCidr), + LocalType: ResourceTypeCidr, }, nil } return nil, fmt.Errorf(containerNotFound, ResourceTypeCidrSegment, name) diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index 94646b43..3a7bef5e 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -14,7 +14,6 @@ import ( "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" - "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) type ( @@ -31,10 +30,10 @@ type ( Connection struct { // Egress resource - Src *FirewallResource + Src *LocalRemotePair // Ingress resource - Dst *FirewallResource + Dst *LocalRemotePair // Allowed protocols TrackedProtocols []*TrackedProtocol @@ -43,17 +42,17 @@ type ( Origin fmt.Stringer } - FirewallResource struct { + LocalRemotePair struct { // Symbolic name of resource, if available Name *string - AppliedTo []*NamedAddrs + LocalCidrs []*NamedAddrs // Cidr list RemoteCidrs []*NamedAddrs - // Type of resource - Type *ResourceType + // LocalType of resource + LocalType ResourceType } NamedAddrs struct { @@ -263,32 +262,32 @@ func (v *VPEDetails) endpointType() ResourceType { return ResourceTypeVPE } -func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*FirewallResource, error) { +func lookupSingle[T NWResource](m map[ID]T, name string, t ResourceType) (*LocalRemotePair, error) { if details, ok := m[name]; ok { - return &FirewallResource{ + return &LocalRemotePair{ Name: &name, - AppliedTo: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, + LocalCidrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, RemoteCidrs: []*NamedAddrs{{Name: &name, IPAddrs: details.Address()}}, - Type: utils.Ptr(t), + LocalType: t, }, nil } return nil, fmt.Errorf(resourceNotFound, name, t) } func (s *Definitions) lookupSegment(segment map[ID]*SegmentDetails, name string, t, elementType ResourceType, - lookup func(ResourceType, string) (*FirewallResource, error)) (*FirewallResource, error) { + lookup func(ResourceType, string) (*LocalRemotePair, error)) (*LocalRemotePair, error) { segmentDetails, ok := segment[name] if !ok { return nil, fmt.Errorf(containerNotFound, name, t) } - res := &FirewallResource{Name: &name, AppliedTo: []*NamedAddrs{}, RemoteCidrs: []*NamedAddrs{}, Type: utils.Ptr(elementType)} + res := &LocalRemotePair{Name: &name, LocalCidrs: []*NamedAddrs{}, RemoteCidrs: []*NamedAddrs{}, LocalType: elementType} for _, elementName := range segmentDetails.Elements { subnet, err := lookup(elementType, elementName) if err != nil { return nil, err } - res.AppliedTo = append(res.AppliedTo, subnet.AppliedTo...) + res.LocalCidrs = append(res.LocalCidrs, subnet.LocalCidrs...) res.RemoteCidrs = append(res.RemoteCidrs, subnet.RemoteCidrs...) } return res, nil diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index f3c1b170..4b11d546 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -45,12 +45,12 @@ func (a *ACLSynthesizer) makeACL() *ir.ACLCollection { return a.result } -func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection, thisResource, otherResource *ir.FirewallResource, +func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection, thisResource, otherResource *ir.LocalRemotePair, allowConnection func(*ir.Connection, *ir.TrackedProtocol, *ir.NamedAddrs, *netset.IPBlock)) { - for _, thisSubnet := range thisResource.AppliedTo { + for _, thisSubnet := range thisResource.LocalCidrs { for _, otherCidr := range otherResource.RemoteCidrs { - if thisSubnet.IPAddrs.Equal(otherCidr.IPAddrs) && *thisResource.Type != ir.ResourceTypeCidr && - *otherResource.Type != ir.ResourceTypeCidr { + if thisSubnet.IPAddrs.Equal(otherCidr.IPAddrs) && thisResource.LocalType != ir.ResourceTypeCidr && + otherResource.LocalType != ir.ResourceTypeCidr { continue } for _, trackedProtocol := range conn.TrackedProtocols { diff --git a/pkg/synth/common.go b/pkg/synth/common.go index 101b01c9..fbfbcec5 100644 --- a/pkg/synth/common.go +++ b/pkg/synth/common.go @@ -43,8 +43,8 @@ func (e explanation) String() string { } func internalConnection(conn *ir.Connection) (internalSrc, internalDst, internal bool) { - internalSrc = *conn.Src.Type != ir.ResourceTypeExternal - internalDst = *conn.Dst.Type != ir.ResourceTypeExternal + internalSrc = conn.Src.LocalType != ir.ResourceTypeExternal + internalDst = conn.Dst.LocalType != ir.ResourceTypeExternal internal = internalSrc && internalDst return } diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 8dc2a60d..20323aba 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -43,11 +43,11 @@ func (s *SGSynthesizer) makeSG() *ir.SGCollection { func (s *SGSynthesizer) generateSGRulesFromConnection(conn *ir.Connection, direction ir.Direction) { localResource, remoteResource, internalEndpoint, internalConn := connSettings(conn, direction) - for _, localEndpoint := range localResource.AppliedTo { + for _, localEndpoint := range localResource.LocalCidrs { for _, remoteCidr := range remoteResource.RemoteCidrs { for _, trackedProtocol := range conn.TrackedProtocols { ruleExplanation := explanation{internal: internalConn, connectionOrigin: conn.Origin, protocolOrigin: trackedProtocol.Origin}.String() - s.allowConnectionEndpoint(localEndpoint, remoteCidr, remoteResource.Type, trackedProtocol.Protocol, direction, + s.allowConnectionEndpoint(localEndpoint, remoteCidr, remoteResource.LocalType, trackedProtocol.Protocol, direction, internalEndpoint, ruleExplanation) } } @@ -55,7 +55,7 @@ func (s *SGSynthesizer) generateSGRulesFromConnection(conn *ir.Connection, direc } // if the endpoint in internal, a rule will be created to allow traffic. -func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *ir.NamedAddrs, remoteType *ir.ResourceType, +func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *ir.NamedAddrs, remoteType ir.ResourceType, p netp.Protocol, direction ir.Direction, internalEndpoint bool, ruleExplanation string) { if !internalEndpoint { return @@ -72,14 +72,14 @@ func (s *SGSynthesizer) allowConnectionEndpoint(localEndpoint, remoteEndpoint *i localSG.Add(rule) } -func sgRemote(resource *ir.NamedAddrs, t *ir.ResourceType) ir.RemoteType { - if isSGRemote(*t) { +func sgRemote(resource *ir.NamedAddrs, t ir.ResourceType) ir.RemoteType { + if isSGRemote(t) { return ir.SGName(*resource.Name) } return resource.IPAddrs } -func connSettings(conn *ir.Connection, direction ir.Direction) (local, remote *ir.FirewallResource, internalEndpoint, internalConn bool) { +func connSettings(conn *ir.Connection, direction ir.Direction) (local, remote *ir.LocalRemotePair, internalEndpoint, internalConn bool) { internalSrc, internalDst, internalConn := internalConnection(conn) local = conn.Src remote = conn.Dst From 2eb5a5c5409cf52af220401372767bc4592c4121 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 29 Oct 2024 17:24:49 +0200 Subject: [PATCH 097/131] >= --- pkg/io/confio/optimizeSG.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/io/confio/optimizeSG.go b/pkg/io/confio/optimizeSG.go index 2c7f0851..b95d53f7 100644 --- a/pkg/io/confio/optimizeSG.go +++ b/pkg/io/confio/optimizeSG.go @@ -29,7 +29,7 @@ func updateSGs(model *configModel.ResourcesContainerModel, collection *ir.SGColl func updateSG(sg *vpcv1.SecurityGroup, optimizedSG *ir.SG, sgRefMap map[string]*vpcv1.SecurityGroupRuleRemoteSecurityGroupReference) error { optimizedRules := optimizedSG.AllRules() - if len(optimizedRules) == len(sg.Rules) { + if len(optimizedRules) >= len(sg.Rules) { return nil } sg.Rules = make([]vpcv1.SecurityGroupRuleIntf, len(optimizedRules)) From 7a62bc3b846505f90d3129449f181e127fa60179 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 29 Oct 2024 17:45:54 +0200 Subject: [PATCH 098/131] review comments --- README.md | 2 +- pkg/synth/acl.go | 12 ++++-------- pkg/synth/sg.go | 10 ++++------ 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 54a36496..48973bed 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Specifying the `--single` flag results in generating a single nACL for all subne ### Supported types The input supports subnets, subnet segments, CIDR segments, NIFs, NIF segments, instances (VSIs), instance segments, VPEs, VPE segments and externals. -**Note 1**: The segments are defined in the `conn_spec.json` file. +**Note**: Segments should be defined in the spec file. ### Output 1. If the `output-dir` flag is used, the specified folder will be created, containing one file per VPC. Each generated file will contain the network resources (Security Groups or Network ACLs) relevant to its VPC. File names are set as `prefix_vpc`, where prefix is ​​the value received in the `prefix` flag. If the `prefix` flag is omitted, file names will match VPC names. diff --git a/pkg/synth/acl.go b/pkg/synth/acl.go index 4b11d546..1f6e30ae 100644 --- a/pkg/synth/acl.go +++ b/pkg/synth/acl.go @@ -15,8 +15,6 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -const ACLTypeNotSupported = "ACL: src/dst of type %s is not supported" - type ACLSynthesizer struct { spec *ir.Spec singleACL bool @@ -36,8 +34,7 @@ func (a *ACLSynthesizer) Synth() ir.Collection { // 1. generate nACL rules for relevant subnets for each connection // 2. generate nACL rules for blocked subnets (subnets that do not appear in Spec) func (a *ACLSynthesizer) makeACL() *ir.ACLCollection { - for i := range a.spec.Connections { - conn := a.spec.Connections[i] + for _, conn := range a.spec.Connections { a.generateACLRulesFromConnection(conn, conn.Src, conn.Dst, a.allowConnectionSrc) a.generateACLRulesFromConnection(conn, conn.Dst, conn.Src, a.allowConnectionDst) } @@ -49,8 +46,7 @@ func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection, thi allowConnection func(*ir.Connection, *ir.TrackedProtocol, *ir.NamedAddrs, *netset.IPBlock)) { for _, thisSubnet := range thisResource.LocalCidrs { for _, otherCidr := range otherResource.RemoteCidrs { - if thisSubnet.IPAddrs.Equal(otherCidr.IPAddrs) && thisResource.LocalType != ir.ResourceTypeCidr && - otherResource.LocalType != ir.ResourceTypeCidr { + if thisSubnet.IPAddrs.Equal(otherCidr.IPAddrs) { continue } for _, trackedProtocol := range conn.TrackedProtocols { @@ -65,7 +61,7 @@ func (a *ACLSynthesizer) generateACLRulesFromConnection(conn *ir.Connection, thi func (a *ACLSynthesizer) allowConnectionSrc(conn *ir.Connection, p *ir.TrackedProtocol, srcSubnet *ir.NamedAddrs, dstCidr *netset.IPBlock) { internalSrc, _, internal := internalConnection(conn) - if !internalSrc || srcSubnet.IPAddrs.Equal(dstCidr) { + if !internalSrc { return } reason := explanation{internal: internal, connectionOrigin: conn.Origin, protocolOrigin: p.Origin} @@ -82,7 +78,7 @@ func (a *ACLSynthesizer) allowConnectionSrc(conn *ir.Connection, p *ir.TrackedPr func (a *ACLSynthesizer) allowConnectionDst(conn *ir.Connection, p *ir.TrackedProtocol, dstSubnet *ir.NamedAddrs, srcCidr *netset.IPBlock) { _, internalDst, internal := internalConnection(conn) - if !internalDst || dstSubnet.IPAddrs.Equal(srcCidr) { + if !internalDst { return } reason := explanation{internal: internal, connectionOrigin: conn.Origin, protocolOrigin: p.Origin} diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 20323aba..60b5ea5b 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -12,14 +12,12 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -const SGTypeNotSupported = "SG: src/dst of type %s is not supported" - type SGSynthesizer struct { spec *ir.Spec result *ir.SGCollection } -// NewSGSynthesizer creates and returns a new SGSynthesizer instances +// NewSGSynthesizer creates and returns a new SGSynthesizer instance func NewSGSynthesizer(s *ir.Spec, _ bool) Synthesizer { return &SGSynthesizer{spec: s, result: ir.NewSGCollection()} } @@ -32,9 +30,9 @@ func (s *SGSynthesizer) Synth() ir.Collection { // 1. generate SGs for relevant endpoints for each connection // 2. generate SGs for blocked endpoints (endpoints that do not appear in Spec) func (s *SGSynthesizer) makeSG() *ir.SGCollection { - for c := range s.spec.Connections { - s.generateSGRulesFromConnection(s.spec.Connections[c], ir.Outbound) - s.generateSGRulesFromConnection(s.spec.Connections[c], ir.Inbound) + for _, c := range s.spec.Connections { + s.generateSGRulesFromConnection(c, ir.Outbound) + s.generateSGRulesFromConnection(c, ir.Inbound) } s.generateSGsForBlockedResources() return s.result From aca7e73779b7b5f780d8cb9c671b0db329aa5fac Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 30 Oct 2024 11:17:57 +0200 Subject: [PATCH 099/131] update tests --- test/expected/sg_segments1_tf/sg_expected.tf | 36 ++++++++++---------- test/expected/sg_segments2_tf/sg_expected.tf | 36 ++++++++++---------- test/expected/sg_segments3_tf/sg_expected.tf | 36 ++++++++++---------- test/expected/sg_segments4_tf/sg_expected.tf | 12 +++---- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/test/expected/sg_segments1_tf/sg_expected.tf b/test/expected/sg_segments1_tf/sg_expected.tf index 7e8c7c2d..e32bb433 100644 --- a/test/expected/sg_segments1_tf/sg_expected.tf +++ b/test/expected/sg_segments1_tf/sg_expected.tf @@ -1,4 +1,4 @@ -### SG attached to test-vpc0/vsi0-subnet0 +### SG test-vpc0--vsi0-subnet0 is attached to test-vpc0/vsi0-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { name = "sg-test-vpc0--vsi0-subnet0" resource_group = local.sg_synth_resource_group_id @@ -17,7 +17,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-1" { remote = "10.240.0.0/23" } -### SG attached to test-vpc0/vsi0-subnet1 +### SG test-vpc0--vsi0-subnet1 is attached to test-vpc0/vsi0-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { name = "sg-test-vpc0--vsi0-subnet1" resource_group = local.sg_synth_resource_group_id @@ -36,35 +36,35 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-1" { remote = "10.240.0.0/23" } -### SG attached to test-vpc0/vsi0-subnet2 +### SG test-vpc0--vsi0-subnet2 is attached to test-vpc0/vsi0-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { name = "sg-test-vpc0--vsi0-subnet2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet3 +### SG test-vpc0--vsi0-subnet3 is attached to test-vpc0/vsi0-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { name = "sg-test-vpc0--vsi0-subnet3" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet4 +### SG test-vpc0--vsi0-subnet4 is attached to test-vpc0/vsi0-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { name = "sg-test-vpc0--vsi0-subnet4" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet5 +### SG test-vpc0--vsi0-subnet5 is attached to test-vpc0/vsi0-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { name = "sg-test-vpc0--vsi0-subnet5" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet0 +### SG test-vpc0--vsi1-subnet0 is attached to test-vpc0/vsi1-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { name = "sg-test-vpc0--vsi1-subnet0" resource_group = local.sg_synth_resource_group_id @@ -83,7 +83,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-1" { remote = "10.240.0.0/23" } -### SG attached to test-vpc0/vsi1-subnet1 +### SG test-vpc0--vsi1-subnet1 is attached to test-vpc0/vsi1-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { name = "sg-test-vpc0--vsi1-subnet1" resource_group = local.sg_synth_resource_group_id @@ -102,70 +102,70 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-1" { remote = "10.240.0.0/23" } -### SG attached to test-vpc0/vsi1-subnet2 +### SG test-vpc0--vsi1-subnet2 is attached to test-vpc0/vsi1-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { name = "sg-test-vpc0--vsi1-subnet2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet3 +### SG test-vpc0--vsi1-subnet3 is attached to test-vpc0/vsi1-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { name = "sg-test-vpc0--vsi1-subnet3" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet4 +### SG test-vpc0--vsi1-subnet4 is attached to test-vpc0/vsi1-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { name = "sg-test-vpc0--vsi1-subnet4" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet5 +### SG test-vpc0--vsi1-subnet5 is attached to test-vpc0/vsi1-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { name = "sg-test-vpc0--vsi1-subnet5" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc1/vsi0-subnet10 +### SG test-vpc1--vsi0-subnet10 is attached to test-vpc1/vsi0-subnet10 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { name = "sg-test-vpc1--vsi0-subnet10" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } -### SG attached to test-vpc1/vsi0-subnet11 +### SG test-vpc1--vsi0-subnet11 is attached to test-vpc1/vsi0-subnet11 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { name = "sg-test-vpc1--vsi0-subnet11" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } -### SG attached to test-vpc2/vsi0-subnet20 +### SG test-vpc2--vsi0-subnet20 is attached to test-vpc2/vsi0-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { name = "sg-test-vpc2--vsi0-subnet20" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc2_id } -### SG attached to test-vpc2/vsi1-subnet20 +### SG test-vpc2--vsi1-subnet20 is attached to test-vpc2/vsi1-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { name = "sg-test-vpc2--vsi1-subnet20" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc2_id } -### SG attached to test-vpc2/vsi2-subnet20 +### SG test-vpc2--vsi2-subnet20 is attached to test-vpc2/vsi2-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { name = "sg-test-vpc2--vsi2-subnet20" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc2_id } -### SG attached to test-vpc3/vsi0-subnet30 +### SG test-vpc3--vsi0-subnet30 is attached to test-vpc3/vsi0-subnet30 resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { name = "sg-test-vpc3--vsi0-subnet30" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/sg_segments2_tf/sg_expected.tf b/test/expected/sg_segments2_tf/sg_expected.tf index 0ecc69d1..3db420a0 100644 --- a/test/expected/sg_segments2_tf/sg_expected.tf +++ b/test/expected/sg_segments2_tf/sg_expected.tf @@ -1,4 +1,4 @@ -### SG attached to test-vpc0/vsi0-subnet0 +### SG test-vpc0--vsi0-subnet0 is attached to test-vpc0/vsi0-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { name = "sg-test-vpc0--vsi0-subnet0" resource_group = local.sg_synth_resource_group_id @@ -17,7 +17,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet0-1" { remote = ibm_is_security_group.test-vpc0--vsi0-subnet5.id } -### SG attached to test-vpc0/vsi0-subnet1 +### SG test-vpc0--vsi0-subnet1 is attached to test-vpc0/vsi0-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { name = "sg-test-vpc0--vsi0-subnet1" resource_group = local.sg_synth_resource_group_id @@ -36,28 +36,28 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet1-1" { remote = ibm_is_security_group.test-vpc0--vsi0-subnet5.id } -### SG attached to test-vpc0/vsi0-subnet2 +### SG test-vpc0--vsi0-subnet2 is attached to test-vpc0/vsi0-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { name = "sg-test-vpc0--vsi0-subnet2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet3 +### SG test-vpc0--vsi0-subnet3 is attached to test-vpc0/vsi0-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { name = "sg-test-vpc0--vsi0-subnet3" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet4 +### SG test-vpc0--vsi0-subnet4 is attached to test-vpc0/vsi0-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { name = "sg-test-vpc0--vsi0-subnet4" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet5 +### SG test-vpc0--vsi0-subnet5 is attached to test-vpc0/vsi0-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { name = "sg-test-vpc0--vsi0-subnet5" resource_group = local.sg_synth_resource_group_id @@ -70,7 +70,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet5-0" { remote = "10.240.0.0/23" } -### SG attached to test-vpc0/vsi1-subnet0 +### SG test-vpc0--vsi1-subnet0 is attached to test-vpc0/vsi1-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { name = "sg-test-vpc0--vsi1-subnet0" resource_group = local.sg_synth_resource_group_id @@ -89,7 +89,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet0-1" { remote = ibm_is_security_group.test-vpc0--vsi0-subnet5.id } -### SG attached to test-vpc0/vsi1-subnet1 +### SG test-vpc0--vsi1-subnet1 is attached to test-vpc0/vsi1-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { name = "sg-test-vpc0--vsi1-subnet1" resource_group = local.sg_synth_resource_group_id @@ -108,42 +108,42 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet1-1" { remote = ibm_is_security_group.test-vpc0--vsi0-subnet5.id } -### SG attached to test-vpc0/vsi1-subnet2 +### SG test-vpc0--vsi1-subnet2 is attached to test-vpc0/vsi1-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { name = "sg-test-vpc0--vsi1-subnet2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet3 +### SG test-vpc0--vsi1-subnet3 is attached to test-vpc0/vsi1-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { name = "sg-test-vpc0--vsi1-subnet3" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet4 +### SG test-vpc0--vsi1-subnet4 is attached to test-vpc0/vsi1-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { name = "sg-test-vpc0--vsi1-subnet4" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet5 +### SG test-vpc0--vsi1-subnet5 is attached to test-vpc0/vsi1-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { name = "sg-test-vpc0--vsi1-subnet5" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc1/vsi0-subnet10 +### SG test-vpc1--vsi0-subnet10 is attached to test-vpc1/vsi0-subnet10 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { name = "sg-test-vpc1--vsi0-subnet10" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } -### SG attached to test-vpc1/vsi0-subnet11 +### SG test-vpc1--vsi0-subnet11 is attached to test-vpc1/vsi0-subnet11 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { name = "sg-test-vpc1--vsi0-subnet11" resource_group = local.sg_synth_resource_group_id @@ -156,28 +156,28 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet11-0" { remote = "10.240.0.0/23" } -### SG attached to test-vpc2/vsi0-subnet20 +### SG test-vpc2--vsi0-subnet20 is attached to test-vpc2/vsi0-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { name = "sg-test-vpc2--vsi0-subnet20" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc2_id } -### SG attached to test-vpc2/vsi1-subnet20 +### SG test-vpc2--vsi1-subnet20 is attached to test-vpc2/vsi1-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { name = "sg-test-vpc2--vsi1-subnet20" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc2_id } -### SG attached to test-vpc2/vsi2-subnet20 +### SG test-vpc2--vsi2-subnet20 is attached to test-vpc2/vsi2-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { name = "sg-test-vpc2--vsi2-subnet20" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc2_id } -### SG attached to test-vpc3/vsi0-subnet30 +### SG test-vpc3--vsi0-subnet30 is attached to test-vpc3/vsi0-subnet30 resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { name = "sg-test-vpc3--vsi0-subnet30" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/sg_segments3_tf/sg_expected.tf b/test/expected/sg_segments3_tf/sg_expected.tf index a14bcf10..82443b46 100644 --- a/test/expected/sg_segments3_tf/sg_expected.tf +++ b/test/expected/sg_segments3_tf/sg_expected.tf @@ -1,32 +1,32 @@ -### SG attached to test-vpc0/vsi0-subnet0 +### SG test-vpc0--vsi0-subnet0 is attached to test-vpc0/vsi0-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet0" { name = "sg-test-vpc0--vsi0-subnet0" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet1 +### SG test-vpc0--vsi0-subnet1 is attached to test-vpc0/vsi0-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet1" { name = "sg-test-vpc0--vsi0-subnet1" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet2 +### SG test-vpc0--vsi0-subnet2 is attached to test-vpc0/vsi0-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet2" { name = "sg-test-vpc0--vsi0-subnet2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet3 +### SG test-vpc0--vsi0-subnet3 is attached to test-vpc0/vsi0-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet3" { name = "sg-test-vpc0--vsi0-subnet3" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi0-subnet4 +### SG test-vpc0--vsi0-subnet4 is attached to test-vpc0/vsi0-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet4" { name = "sg-test-vpc0--vsi0-subnet4" resource_group = local.sg_synth_resource_group_id @@ -45,49 +45,49 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi0-subnet4-1" { remote = "10.240.128.0/24" } -### SG attached to test-vpc0/vsi0-subnet5 +### SG test-vpc0--vsi0-subnet5 is attached to test-vpc0/vsi0-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi0-subnet5" { name = "sg-test-vpc0--vsi0-subnet5" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet0 +### SG test-vpc0--vsi1-subnet0 is attached to test-vpc0/vsi1-subnet0 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet0" { name = "sg-test-vpc0--vsi1-subnet0" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet1 +### SG test-vpc0--vsi1-subnet1 is attached to test-vpc0/vsi1-subnet1 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet1" { name = "sg-test-vpc0--vsi1-subnet1" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet2 +### SG test-vpc0--vsi1-subnet2 is attached to test-vpc0/vsi1-subnet2 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet2" { name = "sg-test-vpc0--vsi1-subnet2" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet3 +### SG test-vpc0--vsi1-subnet3 is attached to test-vpc0/vsi1-subnet3 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet3" { name = "sg-test-vpc0--vsi1-subnet3" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet4 +### SG test-vpc0--vsi1-subnet4 is attached to test-vpc0/vsi1-subnet4 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet4" { name = "sg-test-vpc0--vsi1-subnet4" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc0_id } -### SG attached to test-vpc0/vsi1-subnet5 +### SG test-vpc0--vsi1-subnet5 is attached to test-vpc0/vsi1-subnet5 resource "ibm_is_security_group" "test-vpc0--vsi1-subnet5" { name = "sg-test-vpc0--vsi1-subnet5" resource_group = local.sg_synth_resource_group_id @@ -106,7 +106,7 @@ resource "ibm_is_security_group_rule" "test-vpc0--vsi1-subnet5-1" { remote = "10.240.128.0/24" } -### SG attached to test-vpc1/vsi0-subnet10 +### SG test-vpc1--vsi0-subnet10 is attached to test-vpc1/vsi0-subnet10 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet10" { name = "sg-test-vpc1--vsi0-subnet10" resource_group = local.sg_synth_resource_group_id @@ -125,14 +125,14 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi0-subnet10-1" { remote = ibm_is_security_group.test-vpc0--vsi1-subnet5.id } -### SG attached to test-vpc1/vsi0-subnet11 +### SG test-vpc1--vsi0-subnet11 is attached to test-vpc1/vsi0-subnet11 resource "ibm_is_security_group" "test-vpc1--vsi0-subnet11" { name = "sg-test-vpc1--vsi0-subnet11" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } -### SG attached to test-vpc2/vsi0-subnet20 +### SG test-vpc2--vsi0-subnet20 is attached to test-vpc2/vsi0-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi0-subnet20" { name = "sg-test-vpc2--vsi0-subnet20" resource_group = local.sg_synth_resource_group_id @@ -151,7 +151,7 @@ resource "ibm_is_security_group_rule" "test-vpc2--vsi0-subnet20-1" { remote = ibm_is_security_group.test-vpc0--vsi1-subnet5.id } -### SG attached to test-vpc2/vsi1-subnet20 +### SG test-vpc2--vsi1-subnet20 is attached to test-vpc2/vsi1-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi1-subnet20" { name = "sg-test-vpc2--vsi1-subnet20" resource_group = local.sg_synth_resource_group_id @@ -170,7 +170,7 @@ resource "ibm_is_security_group_rule" "test-vpc2--vsi1-subnet20-1" { remote = ibm_is_security_group.test-vpc0--vsi1-subnet5.id } -### SG attached to test-vpc2/vsi2-subnet20 +### SG test-vpc2--vsi2-subnet20 is attached to test-vpc2/vsi2-subnet20 resource "ibm_is_security_group" "test-vpc2--vsi2-subnet20" { name = "sg-test-vpc2--vsi2-subnet20" resource_group = local.sg_synth_resource_group_id @@ -189,7 +189,7 @@ resource "ibm_is_security_group_rule" "test-vpc2--vsi2-subnet20-1" { remote = ibm_is_security_group.test-vpc0--vsi1-subnet5.id } -### SG attached to test-vpc3/vsi0-subnet30 +### SG test-vpc3--vsi0-subnet30 is attached to test-vpc3/vsi0-subnet30 resource "ibm_is_security_group" "test-vpc3--vsi0-subnet30" { name = "sg-test-vpc3--vsi0-subnet30" resource_group = local.sg_synth_resource_group_id diff --git a/test/expected/sg_segments4_tf/sg_expected.tf b/test/expected/sg_segments4_tf/sg_expected.tf index 07166fff..fde97298 100644 --- a/test/expected/sg_segments4_tf/sg_expected.tf +++ b/test/expected/sg_segments4_tf/sg_expected.tf @@ -1,4 +1,4 @@ -### SG attached to test-vpc/appdata-endpoint-gateway +### SG test-vpc--appdata-endpoint-gateway is attached to test-vpc/appdata-endpoint-gateway resource "ibm_is_security_group" "test-vpc--appdata-endpoint-gateway" { name = "sg-test-vpc--appdata-endpoint-gateway" resource_group = local.sg_synth_resource_group_id @@ -17,7 +17,7 @@ resource "ibm_is_security_group_rule" "test-vpc--appdata-endpoint-gateway-1" { remote = ibm_is_security_group.test-vpc--be.id } -### SG attached to test-vpc/be +### SG test-vpc--be is attached to test-vpc/be resource "ibm_is_security_group" "test-vpc--be" { name = "sg-test-vpc--be" resource_group = local.sg_synth_resource_group_id @@ -36,7 +36,7 @@ resource "ibm_is_security_group_rule" "test-vpc--be-1" { remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id } -### SG attached to test-vpc/fe +### SG test-vpc--fe is attached to test-vpc/fe resource "ibm_is_security_group" "test-vpc--fe" { name = "sg-test-vpc--fe" resource_group = local.sg_synth_resource_group_id @@ -55,14 +55,14 @@ resource "ibm_is_security_group_rule" "test-vpc--fe-1" { remote = ibm_is_security_group.test-vpc--policydb-endpoint-gateway.id } -### SG attached to test-vpc/opa +### SG test-vpc--opa is attached to test-vpc/opa resource "ibm_is_security_group" "test-vpc--opa" { name = "sg-test-vpc--opa" resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc_id } -### SG attached to test-vpc/policydb-endpoint-gateway +### SG test-vpc--policydb-endpoint-gateway is attached to test-vpc/policydb-endpoint-gateway resource "ibm_is_security_group" "test-vpc--policydb-endpoint-gateway" { name = "sg-test-vpc--policydb-endpoint-gateway" resource_group = local.sg_synth_resource_group_id @@ -81,7 +81,7 @@ resource "ibm_is_security_group_rule" "test-vpc--policydb-endpoint-gateway-1" { remote = ibm_is_security_group.test-vpc--be.id } -### SG attached to test-vpc/proxy +### SG test-vpc--proxy is attached to test-vpc/proxy resource "ibm_is_security_group" "test-vpc--proxy" { name = "sg-test-vpc--proxy" resource_group = local.sg_synth_resource_group_id From 51d04a24dc339ce64011ec3dc1d5666daaadd283 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 4 Nov 2024 11:10:09 +0200 Subject: [PATCH 100/131] check vpc --- pkg/optimize/sg/sg.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index 0da688a2..7e0373d7 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -66,6 +66,9 @@ func NewSGOptimizer(collection ir.Collection, sgName string) optimize.Optimizer func (s *sgOptimizer) Optimize() (ir.Collection, error) { if s.sgName != "" { for _, vpcName := range utils.SortedMapKeys(s.sgCollection.SGs) { + if s.sgVPC != nil && s.sgVPC != &vpcName { + continue + } if _, ok := s.sgCollection.SGs[vpcName][s.sgName]; ok { s.optimizeSG(vpcName, s.sgName) return s.sgCollection, nil From 191c996227af253bd12917a6fe0cafb3250c6e14 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 4 Nov 2024 11:16:53 +0200 Subject: [PATCH 101/131] typo --- pkg/optimize/sg/sg.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index 7e0373d7..d65eb9d1 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -74,7 +74,7 @@ func (s *sgOptimizer) Optimize() (ir.Collection, error) { return s.sgCollection, nil } } - return nil, fmt.Errorf("could no find %s sg", s.sgName) + return nil, fmt.Errorf("could not find %s sg", s.sgName) } for _, vpcName := range utils.SortedMapKeys(s.sgCollection.SGs) { From a72b4b7b8748ec3e33d956a3d46f36a409959af4 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 5 Nov 2024 13:52:14 +0200 Subject: [PATCH 102/131] small fix --- pkg/io/mdWriter.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/io/mdWriter.go b/pkg/io/mdWriter.go index 5da1d3ed..082bc3ee 100644 --- a/pkg/io/mdWriter.go +++ b/pkg/io/mdWriter.go @@ -35,7 +35,7 @@ func (w *MDWriter) WriteSG(collection *ir.SGCollection, vpc string) error { if err != nil { return err } - return w.writeAll(append(append(SGHeader(), addAlighns(sgColsNum)...), sgTable...)) + return w.writeAll(append(append(SGHeader(), addAlighns(sgColsNum)), sgTable...)) } func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { @@ -43,7 +43,7 @@ func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { if err != nil { return err } - return w.writeAll(append(append(ACLHeader(), addAlighns(aclColsNum)...), aclTable...)) + return w.writeAll(append(append(ACLHeader(), addAlighns(aclColsNum)), aclTable...)) } func (w *MDWriter) writeAll(rows [][]string) error { @@ -62,10 +62,10 @@ func (w *MDWriter) writeAll(rows [][]string) error { return nil } -func addAlighns(n int) [][]string { +func addAlighns(n int) []string { res := make([]string, n) for i := range n { res[i] = leftAlign } - return [][]string{res} + return res } From ecbb4aa4a95e1013f862004b2d3d22ea411cdae9 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 9 Dec 2024 14:09:31 +0200 Subject: [PATCH 103/131] small fixed --- cmd/subcmds/optimize.go | 2 +- cmd/subcmds/optimizeACL.go | 2 +- cmd/subcmds/output.go | 6 +++--- cmd/subcmds/root.go | 11 +++-------- cmd/subcmds/synth.go | 8 ++++++-- cmd/subcmds/synthACL.go | 2 ++ pkg/ir/spec.go | 5 ----- 7 files changed, 16 insertions(+), 20 deletions(-) diff --git a/cmd/subcmds/optimize.go b/cmd/subcmds/optimize.go index 896b61d2..447be8ee 100644 --- a/cmd/subcmds/optimize.go +++ b/cmd/subcmds/optimize.go @@ -14,7 +14,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" ) -func NewOptimizeCommand(args *inArgs) *cobra.Command { +func newOptimizeCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "optimize", Short: "optimization of existing SG (nACLS are not supported yet)", diff --git a/cmd/subcmds/optimizeACL.go b/cmd/subcmds/optimizeACL.go index 5b8c4c3a..60327bd2 100644 --- a/cmd/subcmds/optimizeACL.go +++ b/cmd/subcmds/optimizeACL.go @@ -7,6 +7,7 @@ package subcmds import "github.com/spf13/cobra" +// temporarily exported and currently unused func NewOptimizeACLCommand(_ *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "acl", @@ -17,6 +18,5 @@ func NewOptimizeACLCommand(_ *inArgs) *cobra.Command { return nil }, } - return cmd } diff --git a/cmd/subcmds/output.go b/cmd/subcmds/output.go index b3f71013..339b06b1 100644 --- a/cmd/subcmds/output.go +++ b/cmd/subcmds/output.go @@ -110,11 +110,11 @@ func writeLocals(args *inArgs, vpcNames []ir.ID, collection ir.Collection) error } outputFile := "" - suffix := "/locals.tf" + pathSuffix := "/locals.tf" if args.outputDir != "" { - outputFile = args.outputDir + suffix + outputFile = args.outputDir + pathSuffix } else if args.outputFile != "" { - outputFile = filepath.Dir(args.outputFile) + suffix + outputFile = filepath.Dir(args.outputFile) + pathSuffix } return writeToFile(outputFile, data) } diff --git a/cmd/subcmds/root.go b/cmd/subcmds/root.go index 2c347f48..f84b958b 100644 --- a/cmd/subcmds/root.go +++ b/cmd/subcmds/root.go @@ -16,9 +16,6 @@ const ( configFlag = "config" outputFmtFlag = "format" outputFileFlag = "output-file" - outputDirFlag = "output-dir" - prefixFlag = "prefix" - singleACLFlag = "single" localsFlag = "locals" ) @@ -36,9 +33,7 @@ type inArgs struct { func newRootCommand() *cobra.Command { args := &inArgs{} - - // allow PersistentPreRunE - cobra.EnableTraverseRunHooks = true + cobra.EnableTraverseRunHooks = true // allow PersistentPreRunE rootCmd := &cobra.Command{ Use: "vpcgen", @@ -62,8 +57,8 @@ func newRootCommand() *cobra.Command { _ = rootCmd.MarkPersistentFlagRequired(configFlag) // sub cmds - rootCmd.AddCommand(NewSynthCommand(args)) - rootCmd.AddCommand(NewOptimizeCommand(args)) + rootCmd.AddCommand(newSynthCommand(args)) + rootCmd.AddCommand(newOptimizeCommand(args)) // prevent Cobra from creating a default 'completion' command rootCmd.CompletionOptions.DisableDefaultCmd = true diff --git a/cmd/subcmds/synth.go b/cmd/subcmds/synth.go index 7fd497a9..aab12f66 100644 --- a/cmd/subcmds/synth.go +++ b/cmd/subcmds/synth.go @@ -13,9 +13,13 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -const specFlag = "spec" +const ( + specFlag = "spec" + outputDirFlag = "output-dir" + prefixFlag = "prefix" +) -func NewSynthCommand(args *inArgs) *cobra.Command { +func newSynthCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "synth", Short: "generate a SG/nACL collection", diff --git a/cmd/subcmds/synthACL.go b/cmd/subcmds/synthACL.go index ea556e3f..0d2d5d4c 100644 --- a/cmd/subcmds/synthACL.go +++ b/cmd/subcmds/synthACL.go @@ -11,6 +11,8 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/synth" ) +const singleACLFlag = "single" + func newSynthACLCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "acl", diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index fbdee5e4..ca70b0fd 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -178,11 +178,6 @@ type ( getConnectedResource() *ConnectedResource setConnectedResource(r *ConnectedResource) } - - INWResource interface { - NWResource - SubnetName() ID - } ) const ( From 75a7f7dcdf40be5685a71fee321025221fb8aa48 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 9 Dec 2024 15:25:36 +0200 Subject: [PATCH 104/131] minor fixes --- pkg/io/confio/parse_sgs.go | 3 ++- pkg/optimize/common.go | 4 ++++ pkg/optimize/sg/reduceCubes.go | 10 ++++------ pkg/optimize/sg/rulesToCubes.go | 19 ++++++++++--------- pkg/optimize/sg/sg.go | 21 ++++++++++----------- 5 files changed, 30 insertions(+), 27 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index e1528913..3dcf1bf8 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -35,11 +35,12 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { log.Printf("Warning: missing SG/VPC name in sg at index %d\n", i) continue } + sgName := ir.SGName(*sg.Name) vpcName := *sg.VPC.Name if result.SGs[vpcName] == nil { result.SGs[vpcName] = make(map[ir.SGName]*ir.SG) } - result.SGs[vpcName][ir.SGName(*sg.Name)] = &ir.SG{InboundRules: inbound, OutboundRules: outbound} + result.SGs[vpcName][sgName] = &ir.SG{SGName: sgName, InboundRules: inbound, OutboundRules: outbound} } return result, nil } diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index 9d62a104..58486c9f 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -78,3 +78,7 @@ func IcmpRuleToIcmpSet(icmp netp.ICMP) *netset.ICMPSet { icmpCode := int64(*icmp.TypeCode.Code) return netset.NewICMPSet(icmpType, icmpType, icmpCode, icmpCode) } + +func AllPorts(tcpudpPorts *netset.PortSet) bool { + return tcpudpPorts.Equal(netset.AllPorts()) +} diff --git a/pkg/optimize/sg/reduceCubes.go b/pkg/optimize/sg/reduceCubes.go index 44d9a9d7..b7829852 100644 --- a/pkg/optimize/sg/reduceCubes.go +++ b/pkg/optimize/sg/reduceCubes.go @@ -8,8 +8,6 @@ package sgoptimizer import ( "slices" - "github.com/np-guard/models/pkg/netset" - "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" ) @@ -32,7 +30,7 @@ func compressThreeProtocolsToAllProtocol(spans *sgCubesPerProtocol) { for sgName, tcpPorts := range spans.tcp { if udpPorts, ok := spans.udp[sgName]; ok { if ic, ok := spans.icmp[sgName]; ok { - if ic.IsAll() && tcpPorts.Equal(netset.AllPorts()) && udpPorts.Equal(netset.AllPorts()) { + if ic.IsAll() && optimize.AllPorts(tcpPorts) && optimize.AllPorts(udpPorts) { delete(spans.tcp, sgName) delete(spans.udp, sgName) delete(spans.icmp, sgName) @@ -53,15 +51,15 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) { icmpPtr := 0 for tcpPtr < len(cubes.tcp) && udpPtr < len(cubes.udp) && icmpPtr < len(cubes.icmp) { - if !cubes.tcp[tcpPtr].Right.Equal(netset.AllPorts()) { + if !optimize.AllPorts(cubes.tcp[tcpPtr].Right) { // not all tcp ports tcpPtr++ continue } - if !cubes.udp[udpPtr].Right.Equal(netset.AllPorts()) { + if !optimize.AllPorts(cubes.udp[udpPtr].Right) { // not all udp ports udpPtr++ continue } - if !cubes.icmp[icmpPtr].Right.IsAll() { + if !cubes.icmp[icmpPtr].Right.IsAll() { // not all icmp types & codes icmpPtr++ continue } diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go index f3802ef1..351390e6 100644 --- a/pkg/optimize/sg/rulesToCubes.go +++ b/pkg/optimize/sg/rulesToCubes.go @@ -6,6 +6,8 @@ SPDX-License-Identifier: Apache-2.0 package sgoptimizer import ( + "slices" + "github.com/np-guard/models/pkg/ds" "github.com/np-guard/models/pkg/interval" "github.com/np-guard/models/pkg/netp" @@ -13,7 +15,6 @@ import ( "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" ) // SG remote @@ -27,26 +28,26 @@ func rulesToSGCubes(rules *rulesPerProtocol) *sgCubesPerProtocol { // all protocol rules to cubes func allProtocolRulesToSGCubes(rules []*ir.SGRule) []ir.SGName { - result := make(map[ir.SGName]struct{}) + res := make([]ir.SGName, len(rules)) for i := range rules { remote := rules[i].Remote.(ir.SGName) // already checked - result[remote] = struct{}{} + res[i] = remote } - return utils.SortedMapKeys(result) + return slices.Compact(slices.Sorted(slices.Values(res))) } // tcp/udp rules to cubes -- map where the key is the SG name and the value is the protocol ports func tcpudpRulesSGCubes(rules []*ir.SGRule) map[ir.SGName]*netset.PortSet { - result := make(map[ir.SGName]*netset.PortSet) + res := make(map[ir.SGName]*netset.PortSet) for _, rule := range rules { p := rule.Protocol.(netp.TCPUDP) // already checked remote := rule.Remote.(ir.SGName) // already checked - if result[remote] == nil { - result[remote] = interval.NewCanonicalSet() + if res[remote] == nil { + res[remote] = interval.NewCanonicalSet() } - result[remote].AddInterval(p.DstPorts()) + res[remote].AddInterval(p.DstPorts()) } - return result + return res } // icmp rules to cubes -- map where the key is the SG name and the value is icmpset diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index d65eb9d1..1f147de1 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -70,7 +70,7 @@ func (s *sgOptimizer) Optimize() (ir.Collection, error) { continue } if _, ok := s.sgCollection.SGs[vpcName][s.sgName]; ok { - s.optimizeSG(vpcName, s.sgName) + s.optimizeSG(s.sgCollection.SGs[vpcName][s.sgName]) return s.sgCollection, nil } } @@ -79,7 +79,7 @@ func (s *sgOptimizer) Optimize() (ir.Collection, error) { for _, vpcName := range utils.SortedMapKeys(s.sgCollection.SGs) { for _, sgName := range utils.SortedMapKeys(s.sgCollection.SGs[vpcName]) { - s.optimizeSG(vpcName, sgName) + s.optimizeSG(s.sgCollection.SGs[vpcName][sgName]) } } return s.sgCollection, nil @@ -88,32 +88,31 @@ func (s *sgOptimizer) Optimize() (ir.Collection, error) { // optimizeSG attempts to reduce the number of SG rules // the algorithm attempts to reduce both inbound and outbound rules separately // A message is printed to the log at the end of the algorithm -func (s *sgOptimizer) optimizeSG(vpcName string, sgName ir.SGName) { - sg := s.sgCollection.SGs[vpcName][sgName] +func (s *sgOptimizer) optimizeSG(sg *ir.SG) { reducedRules := 0 // reduce inbound rules first newInboundRules := s.reduceRules(sg.InboundRules, ir.Inbound) if len(sg.InboundRules) > len(newInboundRules) { reducedRules += len(sg.InboundRules) - len(newInboundRules) - s.sgCollection.SGs[vpcName][sgName].InboundRules = newInboundRules + sg.InboundRules = newInboundRules } // reduce outbound rules second newOutboundRules := s.reduceRules(sg.OutboundRules, ir.Outbound) if len(sg.OutboundRules) > len(newOutboundRules) { reducedRules += len(sg.OutboundRules) - len(newOutboundRules) - s.sgCollection.SGs[vpcName][sgName].OutboundRules = newOutboundRules + sg.OutboundRules = newOutboundRules } // print a message to the log switch { case reducedRules == 0: - log.Printf("no rules were reduced in sg %s\n", string(sgName)) + log.Printf("no rules were reduced in sg %s\n", string(sg.SGName)) case reducedRules == 1: - log.Printf("1 rule was reduced in sg %s\n", string(sgName)) + log.Printf("1 rule was reduced in sg %s\n", string(sg.SGName)) default: - log.Printf("%d rules were reduced in sg %s\n", reducedRules, string(sgName)) + log.Printf("%d rules were reduced in sg %s\n", reducedRules, string(sg.SGName)) } } @@ -125,14 +124,14 @@ func (s *sgOptimizer) reduceRules(rules []*ir.SGRule, direction ir.Direction) [] // rules with SG as a remote optimizedRulesToSG := reduceRulesSGRemote(rulesToSGCubes(ruleGroups.sgRemoteRules), direction) originlRulesToSG := ruleGroups.sgRemoteRules.allRules() - if len(originlRulesToSG) < len(optimizedRulesToSG) { // failed to reduce number of rules + if len(originlRulesToSG) <= len(optimizedRulesToSG) { // failed to reduce number of rules optimizedRulesToSG = originlRulesToSG } // rules with IPBlock as a remote optimizedRulesToIPAddrs := reduceRulesIPRemote(rulesToIPCubes(ruleGroups.ipRemoteRules), direction) originalRulesToIPAddrs := ruleGroups.ipRemoteRules.allRules() - if len(originalRulesToIPAddrs) < len(optimizedRulesToSG) { // failed to reduce number of rules + if len(originalRulesToIPAddrs) <= len(optimizedRulesToSG) { // failed to reduce number of rules optimizedRulesToIPAddrs = originalRulesToIPAddrs } From 43dbf82930e4ba3007bbac1ca2f4937b5e82175a Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 9 Dec 2024 15:41:56 +0200 Subject: [PATCH 105/131] renaming, docs --- pkg/optimize/sg/ipCubesToRules.go | 6 +++--- pkg/optimize/sg/reduceCubes.go | 34 ++++++++++++++++++------------- pkg/optimize/sg/rulesToCubes.go | 10 ++++----- pkg/optimize/sg/sg.go | 26 +++++++++++------------ pkg/optimize/sg/sgCubesToRules.go | 2 +- 5 files changed, 42 insertions(+), 36 deletions(-) diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go index f7b41bcf..016fb670 100644 --- a/pkg/optimize/sg/ipCubesToRules.go +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -15,9 +15,9 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" ) -// all protocol cubes, represented by a single ipblock that will be decomposed -// into cidrs. Each cidr will be the remote of a SG rule -func allProtocolIPCubesIPToRules(cubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { +// any protocol cubes, represented by a single ipblock that will be decomposed +// into cidrs. Each cidr will be a remote of a single SG rule +func anyProtocolIPCubesToRules(cubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { result := make([]*ir.SGRule, 0) for _, cidr := range cubes.SplitToCidrs() { result = append(result, ir.NewSGRule(direction, cidr, netp.AnyProtocol{}, netset.GetCidrAll(), "")) diff --git a/pkg/optimize/sg/reduceCubes.go b/pkg/optimize/sg/reduceCubes.go index b7829852..9f82fa9d 100644 --- a/pkg/optimize/sg/reduceCubes.go +++ b/pkg/optimize/sg/reduceCubes.go @@ -12,13 +12,13 @@ import ( ) func reduceSGCubes(spans *sgCubesPerProtocol) { - deleteOtherProtocolIfAllProtocolExists(spans) - compressThreeProtocolsToAllProtocol(spans) + deleteOtherProtocolIfAnyProtocolExists(spans) + compressThreeProtocolsToAnyProtocol(spans) } -// delete other protocols rules if all protocol rule exists -func deleteOtherProtocolIfAllProtocolExists(spans *sgCubesPerProtocol) { - for _, sgName := range spans.all { +// delete other protocols rules if any protocol rule exists +func deleteOtherProtocolIfAnyProtocolExists(spans *sgCubesPerProtocol) { + for _, sgName := range spans.anyP { delete(spans.tcp, sgName) delete(spans.udp, sgName) delete(spans.icmp, sgName) @@ -26,7 +26,7 @@ func deleteOtherProtocolIfAllProtocolExists(spans *sgCubesPerProtocol) { } // merge tcp, udp and icmp rules into all protocol rule -func compressThreeProtocolsToAllProtocol(spans *sgCubesPerProtocol) { +func compressThreeProtocolsToAnyProtocol(spans *sgCubesPerProtocol) { for sgName, tcpPorts := range spans.tcp { if udpPorts, ok := spans.udp[sgName]; ok { if ic, ok := spans.icmp[sgName]; ok { @@ -34,7 +34,7 @@ func compressThreeProtocolsToAllProtocol(spans *sgCubesPerProtocol) { delete(spans.tcp, sgName) delete(spans.udp, sgName) delete(spans.icmp, sgName) - spans.all = append(spans.all, sgName) + spans.anyP = append(spans.anyP, sgName) } } } @@ -64,16 +64,21 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) { continue } - if compressedToAllCube(cubes, tcpPtr, udpPtr, icmpPtr) { + // all three protocols include all ports and types & codes + // attempt to convert to any protocol rule + if compressedToAnyProtocolCube(cubes, tcpPtr, udpPtr, icmpPtr) { // converted to any protocol rule continue } + // could not compress to all protocol rule -- advance one ipblock + // case 1: one protocol ipb contains two other ipbs ==> advance the smaller one + // case 2: advance the smaller ipb tcpIP := cubes.tcp[tcpPtr].Left udpIP := cubes.udp[udpPtr].Left icmpIP := cubes.icmp[icmpPtr].Left switch { - // one protocol ipb contains two other ipbs ==> advance the smaller ipb + // case 1 case udpIP.IsSubset(tcpIP) && icmpIP.IsSubset(tcpIP) && optimize.LessIPBlock(udpIP, icmpIP): udpPtr++ case udpIP.IsSubset(tcpIP) && icmpIP.IsSubset(tcpIP) && optimize.LessIPBlock(icmpIP, udpIP): @@ -87,7 +92,7 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) { case tcpIP.IsSubset(icmpIP) && udpIP.IsSubset(icmpIP) && optimize.LessIPBlock(udpIP, tcpIP): udpPtr++ - // advance the smaller ipb + // case 2 case optimize.LessIPBlock(tcpIP, udpIP) && optimize.LessIPBlock(tcpIP, icmpIP): tcpPtr++ case optimize.LessIPBlock(udpIP, tcpIP) && optimize.LessIPBlock(udpIP, icmpIP): @@ -99,7 +104,8 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) { } // compress three protocol rules to all protocol rule (and maybe another protocol rule) -func compressedToAllCube(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) bool { +// returns true if the compression was successful +func compressedToAnyProtocolCube(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) bool { tcpIP := cubes.tcp[tcpPtr].Left udpIP := cubes.udp[udpPtr].Left icmpIP := cubes.icmp[icmpPtr].Left @@ -111,17 +117,17 @@ func compressedToAllCube(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) case udpIP.IsSubset(tcpIP) && udpIP.Equal(icmpIP): cubes.udp = slices.Delete(cubes.udp, udpPtr, udpPtr+1) cubes.icmp = slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) - cubes.all = cubes.all.Union(udpIP) + cubes.anyP = cubes.anyP.Union(udpIP) return true case tcpIP.IsSubset(udpIP) && tcpIP.Equal(icmpIP): cubes.tcp = slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) cubes.icmp = slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) - cubes.all = cubes.all.Union(tcpIP) + cubes.anyP = cubes.anyP.Union(tcpIP) return true case tcpIP.IsSubset(icmpIP) && tcpIP.Equal(udpIP): cubes.tcp = slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) cubes.udp = slices.Delete(cubes.udp, udpPtr, udpPtr+1) - cubes.all = cubes.all.Union(tcpIP) + cubes.anyP = cubes.anyP.Union(tcpIP) return true } return false diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go index 351390e6..f268c660 100644 --- a/pkg/optimize/sg/rulesToCubes.go +++ b/pkg/optimize/sg/rulesToCubes.go @@ -22,12 +22,12 @@ func rulesToSGCubes(rules *rulesPerProtocol) *sgCubesPerProtocol { return &sgCubesPerProtocol{tcp: tcpudpRulesSGCubes(rules.tcp), udp: tcpudpRulesSGCubes(rules.udp), icmp: icmpRulesSGCubes(rules.icmp), - all: allProtocolRulesToSGCubes(rules.all), + anyP: anyProtocolRulesToSGCubes(rules.anyP), } } // all protocol rules to cubes -func allProtocolRulesToSGCubes(rules []*ir.SGRule) []ir.SGName { +func anyProtocolRulesToSGCubes(rules []*ir.SGRule) []ir.SGName { res := make([]ir.SGName, len(rules)) for i := range rules { remote := rules[i].Remote.(ir.SGName) // already checked @@ -70,12 +70,12 @@ func rulesToIPCubes(rules *rulesPerProtocol) *ipCubesPerProtocol { return &ipCubesPerProtocol{tcp: tcpudpRulesToIPCubes(rules.tcp), udp: tcpudpRulesToIPCubes(rules.udp), icmp: icmpRulesToIPCubes(rules.icmp), - all: allProtocolRulesToIPCubes(rules.all), + anyP: anyProtocolRulesToIPCubes(rules.anyP), } } -// all protocol rules to cubes -func allProtocolRulesToIPCubes(rules []*ir.SGRule) *netset.IPBlock { +// any protocol rules to cubes +func anyProtocolRulesToIPCubes(rules []*ir.SGRule) *netset.IPBlock { res := netset.NewIPBlock() for i := range rules { res = res.Union(rules[i].Remote.(*netset.IPBlock)) diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index 1f147de1..1c1f4b71 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -34,21 +34,21 @@ type ( tcp []*ir.SGRule udp []*ir.SGRule icmp []*ir.SGRule - all []*ir.SGRule + anyP []*ir.SGRule } sgCubesPerProtocol struct { tcp map[ir.SGName]*netset.PortSet udp map[ir.SGName]*netset.PortSet icmp map[ir.SGName]*netset.ICMPSet - all []ir.SGName + anyP []ir.SGName } ipCubesPerProtocol struct { tcp []ds.Pair[*netset.IPBlock, *netset.PortSet] udp []ds.Pair[*netset.IPBlock, *netset.PortSet] icmp []ds.Pair[*netset.IPBlock, *netset.ICMPSet] - all *netset.IPBlock + anyP *netset.IPBlock } ) @@ -145,7 +145,7 @@ func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*i tcpRules := tcpudpSGCubesToRules(cubes.tcp, direction, true) udpRules := tcpudpSGCubesToRules(cubes.udp, direction, false) icmpRules := icmpSGCubesToRules(cubes.icmp, direction) - allRules := protocolAllCubesToRules(cubes.all, direction) + allRules := anyPotocolCubesToRules(cubes.anyP, direction) // return all rules return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) @@ -155,10 +155,10 @@ func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction) []*i reduceIPCubes(cubes) // cubes to SG rules - tcpRules := tcpudpIPCubesToRules(cubes.tcp, cubes.all, direction, true) - udpRules := tcpudpIPCubesToRules(cubes.udp, cubes.all, direction, false) - icmpRules := icmpIPCubesToRules(cubes.icmp, cubes.all, direction) - allRules := allProtocolIPCubesIPToRules(cubes.all, direction) + tcpRules := tcpudpIPCubesToRules(cubes.tcp, cubes.anyP, direction, true) + udpRules := tcpudpIPCubesToRules(cubes.udp, cubes.anyP, direction, false) + icmpRules := icmpIPCubesToRules(cubes.icmp, cubes.anyP, direction) + allRules := anyProtocolIPCubesToRules(cubes.anyP, direction) // return all rules return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) @@ -167,9 +167,9 @@ func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction) []*i // divide SGCollection to TCP/UDP/ICMP/ProtocolALL X SGRemote/IPAddrs rules func divideSGRules(rules []*ir.SGRule) *ruleGroups { rulesToSG := &rulesPerProtocol{tcp: make([]*ir.SGRule, 0), udp: make([]*ir.SGRule, 0), - icmp: make([]*ir.SGRule, 0), all: make([]*ir.SGRule, 0)} + icmp: make([]*ir.SGRule, 0), anyP: make([]*ir.SGRule, 0)} rulesToIPAddrs := &rulesPerProtocol{tcp: make([]*ir.SGRule, 0), udp: make([]*ir.SGRule, 0), - icmp: make([]*ir.SGRule, 0), all: make([]*ir.SGRule, 0)} + icmp: make([]*ir.SGRule, 0), anyP: make([]*ir.SGRule, 0)} for _, rule := range rules { // TCP rule @@ -202,9 +202,9 @@ func divideSGRules(rules []*ir.SGRule) *ruleGroups { // all protocol rules if _, ok := rule.Protocol.(netp.AnyProtocol); ok { if _, ok := rule.Remote.(*netset.IPBlock); ok { - rulesToIPAddrs.all = append(rulesToIPAddrs.all, rule) + rulesToIPAddrs.anyP = append(rulesToIPAddrs.anyP, rule) } else { - rulesToSG.all = append(rulesToSG.all, rule) + rulesToSG.anyP = append(rulesToSG.anyP, rule) } } } @@ -212,5 +212,5 @@ func divideSGRules(rules []*ir.SGRule) *ruleGroups { } func (s *rulesPerProtocol) allRules() []*ir.SGRule { - return append(s.tcp, append(s.udp, append(s.icmp, s.all...)...)...) + return append(s.tcp, append(s.udp, append(s.icmp, s.anyP...)...)...) } diff --git a/pkg/optimize/sg/sgCubesToRules.go b/pkg/optimize/sg/sgCubesToRules.go index 4ed229c7..8932e591 100644 --- a/pkg/optimize/sg/sgCubesToRules.go +++ b/pkg/optimize/sg/sgCubesToRules.go @@ -37,7 +37,7 @@ func icmpSGCubesToRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Directi } // cubes (slice of SGs) to SG rules -func protocolAllCubesToRules(span []ir.SGName, direction ir.Direction) []*ir.SGRule { +func anyPotocolCubesToRules(span []ir.SGName, direction ir.Direction) []*ir.SGRule { result := make([]*ir.SGRule, len(span)) for i, sgName := range span { result[i] = ir.NewSGRule(direction, sgName, netp.AnyProtocol{}, netset.GetCidrAll(), "") From 0dbae7ea0a537aba5bcac9daea741fda7bb54162 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Mon, 9 Dec 2024 16:16:34 +0200 Subject: [PATCH 106/131] docs --- pkg/optimize/sg/ipCubesToRules.go | 63 ++++++++++++++++--------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go index 016fb670..dc746a7d 100644 --- a/pkg/optimize/sg/ipCubesToRules.go +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -26,36 +26,36 @@ func anyProtocolIPCubesToRules(cubes *netset.IPBlock, direction ir.Direction) [] } // tcpudpIPCubesToRules converts cubes representing tcp or udp protocol rules to SG rules -func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], allCubes *netset.IPBlock, direction ir.Direction, +func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], anyProtoclCubes *netset.IPBlock, direction ir.Direction, isTCP bool) []*ir.SGRule { if len(cubes) == 0 { return []*ir.SGRule{} } + res := make([]*ir.SGRule, 0) activeRules := make(map[*netset.IPBlock]netp.Protocol) // the key is the first IP - result := make([]*ir.SGRule, 0) for i := range cubes { - // if it is not possible to continue the rule between the cubes, generate all the existing rules - if i > 0 && !continuation(cubes[i-1], cubes[i], allCubes) { - result = append(result, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)...) + // if it is not possible to continue the rule between the cubes, generate all existing rules + if i > 0 && uncoveredHole(cubes[i-1], cubes[i], anyProtoclCubes) { + res = append(res, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)...) activeRules = make(map[*netset.IPBlock]netp.Protocol) } - // if the proctol is not contained in the current cube, we will generate SG rules - // calculate active ports = active rules covers these ports + // if there are active rules whose ports are not fully included in the current cube, they will be created + // also activePorts will be calculated, which is the ports that are still included in the active rules activePorts := interval.NewCanonicalSet() for ipb, protocol := range activeRules { if tcpudp, ok := protocol.(netp.TCPUDP); ok { if !tcpudp.DstPorts().ToSet().IsSubset(cubes[i].Right) { - result = append(result, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction)...) + res = append(res, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction)...) } else { activePorts.AddInterval(tcpudp.DstPorts()) } } } - // if the cube contains ports that are not contained in the active rules, new rules will be created + // if the current cube contains ports that are not contained in active rules, new rules will be created for _, ports := range cubes[i].Right.Intervals() { if !ports.ToSet().IsSubset(activePorts) { p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(ports.Start()), int(ports.End())) @@ -63,8 +63,8 @@ func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], all } } } - // generate all the existing rules - return append(result, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction)...) + // generate all existing rules + return append(res, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction)...) } // icmpIPCubesToRules converts cubes representing icmp protocol rules to SG rules @@ -73,31 +73,31 @@ func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCu return []*ir.SGRule{} } + res := make([]*ir.SGRule, 0) activeRules := make(map[*netset.IPBlock]netp.Protocol) // the key is the first IP - result := make([]*ir.SGRule, 0) for i := range cubes { - // if it is not possible to continue the rule between the cubes, generate all the existing rules - if i > 0 && !continuation(cubes[i-1], cubes[i], allCubes) { - result = append(result, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)...) + // if it is not possible to continue the rule between the cubes, generate all existing rules + if i > 0 && uncoveredHole(cubes[i-1], cubes[i], allCubes) { + res = append(res, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)...) activeRules = make(map[*netset.IPBlock]netp.Protocol) } - // if the proctol is not contained in the current cube, we will generate SG rules - // calculate activeICMP = active rules covers these icmp values + // if there are active rules whose icmp values are not fully included in the current cube, they will be created + // also activeICMP will be calculated, which is the icmp values that are still included in the active rules activeICMP := netset.EmptyICMPSet() for ipb, protocol := range activeRules { if icmp, ok := protocol.(netp.ICMP); ok { ruleIcmpSet := optimize.IcmpRuleToIcmpSet(icmp) if !ruleIcmpSet.IsSubset(cubes[i].Right) { - result = append(result, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction)...) + res = append(res, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction)...) } else { activeICMP.Union(ruleIcmpSet) } } } - // if the cube contains icmp values that are not contained in the active rules, new rules will be created + // if the cube contains icmp values that are not contained in active rules, new rules will be created for _, p := range optimize.IcmpsetPartitions(cubes[i].Right) { if !optimize.IcmpRuleToIcmpSet(p).IsSubset(activeICMP) { activeRules[cubes[i].Left.FirstIPAddressObject()] = p @@ -105,29 +105,30 @@ func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCu } } - // generate all the existing rules - return append(result, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction)...) + // generate all existing rules + return append(res, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction)...) } -// continuation returns true if the rules can be continued between the two cubes -func continuation[T ds.Set[T]](prevPair, currPair ds.Pair[*netset.IPBlock, T], allProtocolCubes *netset.IPBlock) bool { +// uncoveredHole returns true if the rules can not be continued between the two cubes +// i.e there is a hole between two ipblocks that is not a subset of anyProtocol cubes +func uncoveredHole[T ds.Set[T]](prevPair, currPair ds.Pair[*netset.IPBlock, T], allProtocolCubes *netset.IPBlock) bool { prevIPBlock := prevPair.Left currIPBlock := currPair.Left touching, _ := prevIPBlock.TouchingIPRanges(currIPBlock) if touching { - return true + return false } - startH, _ := prevIPBlock.NextIP() - endH, _ := currIPBlock.PreviousIP() - hole, _ := netset.IPBlockFromIPRange(startH, endH) - return hole.IsSubset(allProtocolCubes) + holeFirstIP, _ := prevIPBlock.NextIP() + holeEndIP, _ := currIPBlock.PreviousIP() + hole, _ := netset.IPBlockFromIPRange(holeFirstIP, holeEndIP) + return !hole.IsSubset(allProtocolCubes) } // creates sgRules from SG active rules -func createActiveRules(activeRules map[*netset.IPBlock]netp.Protocol, endIP *netset.IPBlock, direction ir.Direction) []*ir.SGRule { +func createActiveRules(activeRules map[*netset.IPBlock]netp.Protocol, lastIP *netset.IPBlock, direction ir.Direction) []*ir.SGRule { res := make([]*ir.SGRule, 0) - for ipb, protocol := range activeRules { - res = append(res, createNewRules(protocol, ipb, endIP, direction)...) + for firstIP, protocol := range activeRules { + res = append(res, createNewRules(protocol, firstIP, lastIP, direction)...) } return res } From 1b2861fcab61e237a43badcb4e0a25b633015496 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 10 Dec 2024 10:00:31 +0200 Subject: [PATCH 107/131] reorder tf functions --- pkg/io/commonACL.go | 14 ++--- pkg/io/tfio/acl.go | 122 ++++++++++++++++++++-------------------- pkg/io/tfio/sg.go | 132 ++++++++++++++++++++++---------------------- 3 files changed, 134 insertions(+), 134 deletions(-) diff --git a/pkg/io/commonACL.go b/pkg/io/commonACL.go index 99a1f0be..12959280 100644 --- a/pkg/io/commonACL.go +++ b/pkg/io/commonACL.go @@ -56,13 +56,6 @@ func makeACLTable(t *ir.ACL, subnet string) ([][]string, error) { return rows, nil } -func action(a ir.Action) string { - if a == ir.Deny { - return "Deny" - } - return "Allow" -} - func makeACLRow(priority int, rule *ir.ACLRule, aclName, subnet string) ([]string, error) { src, err1 := printIP(rule.Source, rule.Protocol, true) dst, err2 := printIP(rule.Destination, rule.Protocol, false) @@ -84,6 +77,13 @@ func makeACLRow(priority int, rule *ir.ACLRule, aclName, subnet string) ([]strin }, nil } +func action(a ir.Action) string { + if a == ir.Deny { + return "Deny" + } + return "Allow" +} + func printIP(ip *netset.IPBlock, protocol netp.Protocol, isSource bool) (string, error) { ipString := ip.String() if ip.Equal(netset.GetCidrAll()) { diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index d71b8d56..93fce635 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -32,48 +32,26 @@ func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string) error { return err } -func aclProtocol(t netp.Protocol) []tf.Block { - switch p := t.(type) { - case netp.TCPUDP: - return []tf.Block{{ - Name: strings.ToLower(string(p.ProtocolString())), - Arguments: append( - portRange(p.DstPorts(), "port"), - portRange(p.SrcPorts(), "source_port")..., - ), - }} - case netp.ICMP: - return []tf.Block{{ - Name: "icmp", - Arguments: codeTypeArguments(p.ICMPTypeCode()), - }} - case netp.AnyProtocol: - return []tf.Block{} - } - return nil -} - -func aclRule(rule *ir.ACLRule, name string) (tf.Block, error) { - if err := verifyName(name); err != nil { - return tf.Block{}, err - } - arguments := []tf.Argument{ - {Name: "name", Value: quote(name)}, - {Name: "action", Value: quote(action(rule.Action))}, - {Name: "direction", Value: quote(direction(rule.Direction))}, - {Name: "source", Value: quote(rule.Source.String())}, - {Name: "destination", Value: quote(rule.Destination.String())}, - } - - comment := "\n" - if rule.Explanation != "" { - comment = fmt.Sprintf("# %v", rule.Explanation) +func aclCollection(t *ir.ACLCollection, vpc string) (*tf.ConfigFile, error) { + sortedACLs := t.SortedACLSubnets(vpc) + var acls = make([]tf.Block, len(sortedACLs)) + i := 0 + for _, subnet := range sortedACLs { + comment := "\n" + vpcName := ir.VpcFromScopedResource(subnet) + acl := t.ACLs[vpcName][subnet] + if len(sortedACLs) > 1 { // not a single nacl + comment = fmt.Sprintf("\n# %v [%v]", subnet, subnetCidr(acl)) + } + singleACL, err := singleACL(acl, comment) + if err != nil { + return nil, err + } + acls[i] = singleACL + i += 1 } - - return tf.Block{Name: "rules", - Comment: comment, - Arguments: arguments, - Blocks: aclProtocol(rule.Protocol), + return &tf.ConfigFile{ + Resources: acls, }, nil } @@ -96,7 +74,7 @@ func singleACL(t *ir.ACL, comment string) (tf.Block, error) { Name: "resource", Labels: []string{quote("ibm_is_network_acl"), quote(aclName)}, Arguments: []tf.Argument{ - {Name: "name", Value: quote(aclName)}, //nolint:revive // obvious false positive + {Name: "name", Value: quote(aclName)}, {Name: "resource_group", Value: "local.acl_synth_resource_group_id"}, {Name: "vpc", Value: fmt.Sprintf("local.acl_synth_%s_id", ir.VpcFromScopedResource(t.Subnet))}, }, @@ -104,29 +82,51 @@ func singleACL(t *ir.ACL, comment string) (tf.Block, error) { }, nil } -func aclCollection(t *ir.ACLCollection, vpc string) (*tf.ConfigFile, error) { - sortedACLs := t.SortedACLSubnets(vpc) - var acls = make([]tf.Block, len(sortedACLs)) - i := 0 - for _, subnet := range sortedACLs { - comment := "\n" - vpcName := ir.VpcFromScopedResource(subnet) - acl := t.ACLs[vpcName][subnet] - if len(sortedACLs) > 1 { // not a single nacl - comment = fmt.Sprintf("\n# %v [%v]", subnet, subnetCidr(acl)) - } - singleACL, err := singleACL(acl, comment) - if err != nil { - return nil, err - } - acls[i] = singleACL - i += 1 +func aclRule(rule *ir.ACLRule, name string) (tf.Block, error) { + if err := verifyName(name); err != nil { + return tf.Block{}, err } - return &tf.ConfigFile{ - Resources: acls, + arguments := []tf.Argument{ + {Name: "name", Value: quote(name)}, //nolint:revive // obvious false positive + {Name: "action", Value: quote(action(rule.Action))}, + {Name: "direction", Value: quote(direction(rule.Direction))}, + {Name: "source", Value: quote(rule.Source.String())}, + {Name: "destination", Value: quote(rule.Destination.String())}, + } + + comment := "\n" + if rule.Explanation != "" { + comment = fmt.Sprintf("# %v", rule.Explanation) + } + + return tf.Block{Name: "rules", + Comment: comment, + Arguments: arguments, + Blocks: aclProtocol(rule.Protocol), }, nil } +func aclProtocol(t netp.Protocol) []tf.Block { + switch p := t.(type) { + case netp.TCPUDP: + return []tf.Block{{ + Name: strings.ToLower(string(p.ProtocolString())), + Arguments: append( + portRange(p.DstPorts(), "port"), + portRange(p.SrcPorts(), "source_port")..., + ), + }} + case netp.ICMP: + return []tf.Block{{ + Name: "icmp", + Arguments: codeTypeArguments(p.ICMPTypeCode()), + }} + case netp.AnyProtocol: + return []tf.Block{} + } + return nil +} + func subnetCidr(acl *ir.ACL) *netset.IPBlock { if len(acl.Internal) > 0 { return acl.Internal[0].Target() diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index dafcaa6d..2d027f01 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -32,32 +32,53 @@ func (w *Writer) WriteSG(c *ir.SGCollection, vpc string) error { return err } -func value(x interface{}) (string, error) { - switch v := x.(type) { - case *netset.IPBlock: - return quote(v.String()), nil - case ir.SGName: - return ir.ChangeScoping(fmt.Sprintf("ibm_is_security_group.%v.id", v)), nil +func sgCollection(collection *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { + var resources []tf.Block + + for _, vpcName := range collection.VpcNames() { + if vpc != vpcName && vpc != "" { + continue + } + for _, sgName := range collection.SortedSGNames(vpcName) { + rules := collection.SGs[vpcName][sgName].AllRules() + sg, err := sg(sgName.String(), vpcName) + if err != nil { + return nil, err + } + resources = append(resources, sg) + for i, rule := range rules { + rule, err := sgRule(rule, sgName, i) + if err != nil { + return nil, err + } + resources = append(resources, rule) + } + } } - return "", fmt.Errorf("invalid terraform value %v (type %T)", x, x) + return &tf.ConfigFile{ + Resources: resources, + }, nil } -func sgProtocol(t netp.Protocol) []tf.Block { - switch p := t.(type) { - case netp.TCPUDP: - return []tf.Block{{ - Name: strings.ToLower(string(p.ProtocolString())), - Arguments: portRange(p.DstPorts(), "port"), - }} - case netp.ICMP: - return []tf.Block{{ - Name: "icmp", - Arguments: codeTypeArguments(p.ICMPTypeCode()), - }} - case netp.AnyProtocol: - return []tf.Block{} +func sg(sgName, vpcName string) (tf.Block, error) { + tfSGName := ir.ChangeScoping(sgName) + comment := fmt.Sprintf("\n### SG attached to %s", sgName) + if sgName == tfSGName { // optimization mode + comment = "\n" } - return nil + if err := verifyName(tfSGName); err != nil { + return tf.Block{}, err + } + return tf.Block{ + Name: "resource", + Labels: []string{quote("ibm_is_security_group"), quote(tfSGName)}, + Comment: comment, + Arguments: []tf.Argument{ + {Name: "name", Value: quote("sg-" + tfSGName)}, + {Name: "resource_group", Value: "local.sg_synth_resource_group_id"}, + {Name: "vpc", Value: fmt.Sprintf("local.sg_synth_%s_id", vpcName)}, + }, + }, nil } func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { @@ -78,7 +99,7 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { } return tf.Block{ - Name: "resource", + Name: "resource", //nolint:revive // obvious false positive Labels: []string{quote("ibm_is_security_group_rule"), ir.ChangeScoping(quote(ruleName))}, Comment: comment, Arguments: []tf.Argument{ @@ -90,51 +111,30 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { }, nil } -func sg(sgName, vpcName string) (tf.Block, error) { - tfSGName := ir.ChangeScoping(sgName) - comment := fmt.Sprintf("\n### SG attached to %s", sgName) - if sgName == tfSGName { // optimization mode - comment = "\n" - } - if err := verifyName(tfSGName); err != nil { - return tf.Block{}, err +func sgProtocol(t netp.Protocol) []tf.Block { + switch p := t.(type) { + case netp.TCPUDP: + return []tf.Block{{ + Name: strings.ToLower(string(p.ProtocolString())), + Arguments: portRange(p.DstPorts(), "port"), + }} + case netp.ICMP: + return []tf.Block{{ + Name: "icmp", + Arguments: codeTypeArguments(p.ICMPTypeCode()), + }} + case netp.AnyProtocol: + return []tf.Block{} } - return tf.Block{ - Name: "resource", //nolint:revive // obvious false positive - Labels: []string{quote("ibm_is_security_group"), quote(tfSGName)}, - Comment: comment, - Arguments: []tf.Argument{ - {Name: "name", Value: quote("sg-" + tfSGName)}, - {Name: "resource_group", Value: "local.sg_synth_resource_group_id"}, - {Name: "vpc", Value: fmt.Sprintf("local.sg_synth_%s_id", vpcName)}, - }, - }, nil + return nil } -func sgCollection(collection *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { - var resources []tf.Block - - for _, vpcName := range collection.VpcNames() { - if vpc != vpcName && vpc != "" { - continue - } - for _, sgName := range collection.SortedSGNames(vpcName) { - rules := collection.SGs[vpcName][sgName].AllRules() - sg, err := sg(sgName.String(), vpcName) - if err != nil { - return nil, err - } - resources = append(resources, sg) - for i, rule := range rules { - rule, err := sgRule(rule, sgName, i) - if err != nil { - return nil, err - } - resources = append(resources, rule) - } - } +func value(x interface{}) (string, error) { + switch v := x.(type) { + case *netset.IPBlock: + return quote(v.String()), nil + case ir.SGName: + return ir.ChangeScoping(fmt.Sprintf("ibm_is_security_group.%v.id", v)), nil } - return &tf.ConfigFile{ - Resources: resources, - }, nil + return "", fmt.Errorf("invalid terraform value %v (type %T)", x, x) } From f39fe6ee9008a51706fd092eb5482dd8bcdfbcca Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 10 Dec 2024 11:48:30 +0200 Subject: [PATCH 108/131] renaming --- pkg/optimize/sg/sg.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index 1c1f4b71..2b0353d8 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -145,10 +145,10 @@ func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*i tcpRules := tcpudpSGCubesToRules(cubes.tcp, direction, true) udpRules := tcpudpSGCubesToRules(cubes.udp, direction, false) icmpRules := icmpSGCubesToRules(cubes.icmp, direction) - allRules := anyPotocolCubesToRules(cubes.anyP, direction) + anyProtocolRules := anyPotocolCubesToRules(cubes.anyP, direction) // return all rules - return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) + return append(tcpRules, append(udpRules, append(icmpRules, anyProtocolRules...)...)...) } func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction) []*ir.SGRule { @@ -158,10 +158,10 @@ func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction) []*i tcpRules := tcpudpIPCubesToRules(cubes.tcp, cubes.anyP, direction, true) udpRules := tcpudpIPCubesToRules(cubes.udp, cubes.anyP, direction, false) icmpRules := icmpIPCubesToRules(cubes.icmp, cubes.anyP, direction) - allRules := anyProtocolIPCubesToRules(cubes.anyP, direction) + anyProtocolRules := anyProtocolIPCubesToRules(cubes.anyP, direction) // return all rules - return append(tcpRules, append(udpRules, append(icmpRules, allRules...)...)...) + return append(tcpRules, append(udpRules, append(icmpRules, anyProtocolRules...)...)...) } // divide SGCollection to TCP/UDP/ICMP/ProtocolALL X SGRemote/IPAddrs rules From aa83ea834d6dbdd712a4c418ff82e4773824ebc2 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 10 Dec 2024 11:51:29 +0200 Subject: [PATCH 109/131] errors.Join --- pkg/io/confio/parse_sgs.go | 53 +++++++++++--------------------------- 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index 91853903..abca1995 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -6,6 +6,7 @@ SPDX-License-Identifier: Apache-2.0 package confio import ( + "errors" "fmt" "log" @@ -74,56 +75,32 @@ func translateSGRule(sg *vpcv1.SecurityGroup, index int) (sgRule *ir.SGRule, err } func translateSGRuleProtocolAll(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll) (sgRule *ir.SGRule, err error) { - direction, err := translateDirection(*rule.Direction) - if err != nil { - return nil, err - } - remote, err := translateRemote(rule.Remote) - if err != nil { - return nil, err - } - local, err := translateLocal(rule.Local) - if err != nil { + direction, err1 := translateDirection(*rule.Direction) + remote, err2 := translateRemote(rule.Remote) + local, err3 := translateLocal(rule.Local) + if err := errors.Join(err1, err2, err3); err != nil { return nil, err } return &ir.SGRule{Direction: direction, Remote: remote, Protocol: netp.AnyProtocol{}, Local: local}, nil } func translateSGRuleProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) (sgRule *ir.SGRule, err error) { - direction, err := translateDirection(*rule.Direction) - if err != nil { - return nil, err - } - remote, err := translateRemote(rule.Remote) - if err != nil { - return nil, err - } - local, err := translateLocal(rule.Local) - if err != nil { - return nil, err - } - protocol, err := translateProtocolTCPUDP(rule) - if err != nil { + direction, err1 := translateDirection(*rule.Direction) + remote, err2 := translateRemote(rule.Remote) + local, err3 := translateLocal(rule.Local) + protocol, err4 := translateProtocolTCPUDP(rule) + if err := errors.Join(err1, err2, err3, err4); err != nil { return nil, err } return &ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil } func translateSGRuleProtocolIcmp(rule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp) (sgRule *ir.SGRule, err error) { - direction, err := translateDirection(*rule.Direction) - if err != nil { - return nil, err - } - remote, err := translateRemote(rule.Remote) - if err != nil { - return nil, err - } - local, err := translateLocal(rule.Local) - if err != nil { - return nil, err - } - protocol, err := netp.ICMPFromTypeAndCode64(rule.Type, rule.Code) - if err != nil { + direction, err1 := translateDirection(*rule.Direction) + remote, err2 := translateRemote(rule.Remote) + local, err3 := translateLocal(rule.Local) + protocol, err4 := netp.ICMPFromTypeAndCode64(rule.Type, rule.Code) + if err := errors.Join(err1, err2, err3, err4); err != nil { return nil, err } return &ir.SGRule{Direction: direction, Remote: remote, Protocol: protocol, Local: local}, nil From 4a506889d4e473d60ddf4a684f1c08c4c9360f9b Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 10 Dec 2024 14:29:46 +0200 Subject: [PATCH 110/131] renaming --- pkg/optimize/sg/ipCubesToRules.go | 9 +++++---- pkg/optimize/sg/reduceCubes.go | 16 ++++++++-------- pkg/optimize/sg/rulesToCubes.go | 12 ++++++------ pkg/optimize/sg/sg.go | 30 +++++++++++++++--------------- 4 files changed, 34 insertions(+), 33 deletions(-) diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go index dc746a7d..8b04c70b 100644 --- a/pkg/optimize/sg/ipCubesToRules.go +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -68,7 +68,8 @@ func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], any } // icmpIPCubesToRules converts cubes representing icmp protocol rules to SG rules -func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCubes *netset.IPBlock, direction ir.Direction) []*ir.SGRule { +func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], anyProtocolCubes *netset.IPBlock, + direction ir.Direction) []*ir.SGRule { if len(cubes) == 0 { return []*ir.SGRule{} } @@ -78,7 +79,7 @@ func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCu for i := range cubes { // if it is not possible to continue the rule between the cubes, generate all existing rules - if i > 0 && uncoveredHole(cubes[i-1], cubes[i], allCubes) { + if i > 0 && uncoveredHole(cubes[i-1], cubes[i], anyProtocolCubes) { res = append(res, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)...) activeRules = make(map[*netset.IPBlock]netp.Protocol) } @@ -111,7 +112,7 @@ func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], allCu // uncoveredHole returns true if the rules can not be continued between the two cubes // i.e there is a hole between two ipblocks that is not a subset of anyProtocol cubes -func uncoveredHole[T ds.Set[T]](prevPair, currPair ds.Pair[*netset.IPBlock, T], allProtocolCubes *netset.IPBlock) bool { +func uncoveredHole[T ds.Set[T]](prevPair, currPair ds.Pair[*netset.IPBlock, T], anyProtocolCubes *netset.IPBlock) bool { prevIPBlock := prevPair.Left currIPBlock := currPair.Left touching, _ := prevIPBlock.TouchingIPRanges(currIPBlock) @@ -121,7 +122,7 @@ func uncoveredHole[T ds.Set[T]](prevPair, currPair ds.Pair[*netset.IPBlock, T], holeFirstIP, _ := prevIPBlock.NextIP() holeEndIP, _ := currIPBlock.PreviousIP() hole, _ := netset.IPBlockFromIPRange(holeFirstIP, holeEndIP) - return !hole.IsSubset(allProtocolCubes) + return !hole.IsSubset(anyProtocolCubes) } // creates sgRules from SG active rules diff --git a/pkg/optimize/sg/reduceCubes.go b/pkg/optimize/sg/reduceCubes.go index 9f82fa9d..fa5e851c 100644 --- a/pkg/optimize/sg/reduceCubes.go +++ b/pkg/optimize/sg/reduceCubes.go @@ -18,14 +18,14 @@ func reduceSGCubes(spans *sgCubesPerProtocol) { // delete other protocols rules if any protocol rule exists func deleteOtherProtocolIfAnyProtocolExists(spans *sgCubesPerProtocol) { - for _, sgName := range spans.anyP { + for _, sgName := range spans.anyProtocol { delete(spans.tcp, sgName) delete(spans.udp, sgName) delete(spans.icmp, sgName) } } -// merge tcp, udp and icmp rules into all protocol rule +// merge tcp, udp and icmp rules into any protocol rule func compressThreeProtocolsToAnyProtocol(spans *sgCubesPerProtocol) { for sgName, tcpPorts := range spans.tcp { if udpPorts, ok := spans.udp[sgName]; ok { @@ -34,7 +34,7 @@ func compressThreeProtocolsToAnyProtocol(spans *sgCubesPerProtocol) { delete(spans.tcp, sgName) delete(spans.udp, sgName) delete(spans.icmp, sgName) - spans.anyP = append(spans.anyP, sgName) + spans.anyProtocol = append(spans.anyProtocol, sgName) } } } @@ -70,7 +70,7 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) { continue } - // could not compress to all protocol rule -- advance one ipblock + // could not compress to any protocol rule -- advance one ipblock // case 1: one protocol ipb contains two other ipbs ==> advance the smaller one // case 2: advance the smaller ipb tcpIP := cubes.tcp[tcpPtr].Left @@ -103,7 +103,7 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) { } } -// compress three protocol rules to all protocol rule (and maybe another protocol rule) +// compress three protocol rules to any protocol rule (and maybe another protocol rule) // returns true if the compression was successful func compressedToAnyProtocolCube(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) bool { tcpIP := cubes.tcp[tcpPtr].Left @@ -117,17 +117,17 @@ func compressedToAnyProtocolCube(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmp case udpIP.IsSubset(tcpIP) && udpIP.Equal(icmpIP): cubes.udp = slices.Delete(cubes.udp, udpPtr, udpPtr+1) cubes.icmp = slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) - cubes.anyP = cubes.anyP.Union(udpIP) + cubes.anyProtocol = cubes.anyProtocol.Union(udpIP) return true case tcpIP.IsSubset(udpIP) && tcpIP.Equal(icmpIP): cubes.tcp = slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) cubes.icmp = slices.Delete(cubes.icmp, icmpPtr, icmpPtr+1) - cubes.anyP = cubes.anyP.Union(tcpIP) + cubes.anyProtocol = cubes.anyProtocol.Union(tcpIP) return true case tcpIP.IsSubset(icmpIP) && tcpIP.Equal(udpIP): cubes.tcp = slices.Delete(cubes.tcp, tcpPtr, tcpPtr+1) cubes.udp = slices.Delete(cubes.udp, udpPtr, udpPtr+1) - cubes.anyP = cubes.anyP.Union(tcpIP) + cubes.anyProtocol = cubes.anyProtocol.Union(tcpIP) return true } return false diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go index f268c660..651b9e88 100644 --- a/pkg/optimize/sg/rulesToCubes.go +++ b/pkg/optimize/sg/rulesToCubes.go @@ -20,9 +20,9 @@ import ( // SG remote func rulesToSGCubes(rules *rulesPerProtocol) *sgCubesPerProtocol { return &sgCubesPerProtocol{tcp: tcpudpRulesSGCubes(rules.tcp), - udp: tcpudpRulesSGCubes(rules.udp), - icmp: icmpRulesSGCubes(rules.icmp), - anyP: anyProtocolRulesToSGCubes(rules.anyP), + udp: tcpudpRulesSGCubes(rules.udp), + icmp: icmpRulesSGCubes(rules.icmp), + anyProtocol: anyProtocolRulesToSGCubes(rules.anyP), } } @@ -68,9 +68,9 @@ func icmpRulesSGCubes(rules []*ir.SGRule) map[ir.SGName]*netset.ICMPSet { // IP remote func rulesToIPCubes(rules *rulesPerProtocol) *ipCubesPerProtocol { return &ipCubesPerProtocol{tcp: tcpudpRulesToIPCubes(rules.tcp), - udp: tcpudpRulesToIPCubes(rules.udp), - icmp: icmpRulesToIPCubes(rules.icmp), - anyP: anyProtocolRulesToIPCubes(rules.anyP), + udp: tcpudpRulesToIPCubes(rules.udp), + icmp: icmpRulesToIPCubes(rules.icmp), + anyProtocol: anyProtocolRulesToIPCubes(rules.anyP), } } diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index 2b0353d8..72ad6fca 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -38,17 +38,17 @@ type ( } sgCubesPerProtocol struct { - tcp map[ir.SGName]*netset.PortSet - udp map[ir.SGName]*netset.PortSet - icmp map[ir.SGName]*netset.ICMPSet - anyP []ir.SGName + tcp map[ir.SGName]*netset.PortSet + udp map[ir.SGName]*netset.PortSet + icmp map[ir.SGName]*netset.ICMPSet + anyProtocol []ir.SGName } ipCubesPerProtocol struct { - tcp []ds.Pair[*netset.IPBlock, *netset.PortSet] - udp []ds.Pair[*netset.IPBlock, *netset.PortSet] - icmp []ds.Pair[*netset.IPBlock, *netset.ICMPSet] - anyP *netset.IPBlock + tcp []ds.Pair[*netset.IPBlock, *netset.PortSet] + udp []ds.Pair[*netset.IPBlock, *netset.PortSet] + icmp []ds.Pair[*netset.IPBlock, *netset.ICMPSet] + anyProtocol *netset.IPBlock } ) @@ -145,7 +145,7 @@ func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*i tcpRules := tcpudpSGCubesToRules(cubes.tcp, direction, true) udpRules := tcpudpSGCubesToRules(cubes.udp, direction, false) icmpRules := icmpSGCubesToRules(cubes.icmp, direction) - anyProtocolRules := anyPotocolCubesToRules(cubes.anyP, direction) + anyProtocolRules := anyPotocolCubesToRules(cubes.anyProtocol, direction) // return all rules return append(tcpRules, append(udpRules, append(icmpRules, anyProtocolRules...)...)...) @@ -155,16 +155,16 @@ func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction) []*i reduceIPCubes(cubes) // cubes to SG rules - tcpRules := tcpudpIPCubesToRules(cubes.tcp, cubes.anyP, direction, true) - udpRules := tcpudpIPCubesToRules(cubes.udp, cubes.anyP, direction, false) - icmpRules := icmpIPCubesToRules(cubes.icmp, cubes.anyP, direction) - anyProtocolRules := anyProtocolIPCubesToRules(cubes.anyP, direction) + tcpRules := tcpudpIPCubesToRules(cubes.tcp, cubes.anyProtocol, direction, true) + udpRules := tcpudpIPCubesToRules(cubes.udp, cubes.anyProtocol, direction, false) + icmpRules := icmpIPCubesToRules(cubes.icmp, cubes.anyProtocol, direction) + anyProtocolRules := anyProtocolIPCubesToRules(cubes.anyProtocol, direction) // return all rules return append(tcpRules, append(udpRules, append(icmpRules, anyProtocolRules...)...)...) } -// divide SGCollection to TCP/UDP/ICMP/ProtocolALL X SGRemote/IPAddrs rules +// divide SGCollection to TCP/UDP/ICMP/anyProtocols X SGRemote/IPAddrs rules func divideSGRules(rules []*ir.SGRule) *ruleGroups { rulesToSG := &rulesPerProtocol{tcp: make([]*ir.SGRule, 0), udp: make([]*ir.SGRule, 0), icmp: make([]*ir.SGRule, 0), anyP: make([]*ir.SGRule, 0)} @@ -199,7 +199,7 @@ func divideSGRules(rules []*ir.SGRule) *ruleGroups { } } - // all protocol rules + // any protocol rules if _, ok := rule.Protocol.(netp.AnyProtocol); ok { if _, ok := rule.Remote.(*netset.IPBlock); ok { rulesToIPAddrs.anyP = append(rulesToIPAddrs.anyP, rule) From 5009f2580f2404a812448e7513bff3042964355a Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 10 Dec 2024 15:54:45 +0200 Subject: [PATCH 111/131] minor changes --- pkg/optimize/common.go | 2 +- pkg/optimize/sg/reduceCubes.go | 32 ++++++++-------- pkg/optimize/sg/rulesToCubes.go | 8 ++-- pkg/optimize/sg/sg.go | 37 +++++++++---------- pkg/optimize/sg/sgCubesToRules.go | 8 ++-- .../optimize_sg_protocols_to_all/details.txt | 6 ++- test/data/optimize_sg_redundant/details.txt | 6 ++- test/data/optimize_sg_t/details.txt | 5 ++- test/data/optimize_sg_t_all/details.txt | 5 ++- 9 files changed, 61 insertions(+), 48 deletions(-) diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index 58486c9f..fe6bcea0 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -21,7 +21,7 @@ type Optimizer interface { } // each IPBlock is a single CIDR. The CIDRs are disjoint. -func SortPartitionsByIPAddrs[T any](p []ds.Pair[*netset.IPBlock, T]) []ds.Pair[*netset.IPBlock, T] { +func SortPartitionsByIPAddrs[T ds.Set[T]](p []ds.Pair[*netset.IPBlock, T]) []ds.Pair[*netset.IPBlock, T] { cmp := func(i, j int) bool { if p[i].Left.FirstIPAddress() == p[j].Left.FirstIPAddress() { return p[i].Left.LastIPAddress() < p[j].Left.LastIPAddress() diff --git a/pkg/optimize/sg/reduceCubes.go b/pkg/optimize/sg/reduceCubes.go index fa5e851c..e4f1eb9a 100644 --- a/pkg/optimize/sg/reduceCubes.go +++ b/pkg/optimize/sg/reduceCubes.go @@ -11,30 +11,30 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" ) -func reduceSGCubes(spans *sgCubesPerProtocol) { - deleteOtherProtocolIfAnyProtocolExists(spans) - compressThreeProtocolsToAnyProtocol(spans) +func reduceCubesWithSGRemote(cubes *sgCubesPerProtocol) { + deleteOtherProtocolIfAnyProtocolExists(cubes) + compressThreeProtocolsToAnyProtocol(cubes) } // delete other protocols rules if any protocol rule exists -func deleteOtherProtocolIfAnyProtocolExists(spans *sgCubesPerProtocol) { - for _, sgName := range spans.anyProtocol { - delete(spans.tcp, sgName) - delete(spans.udp, sgName) - delete(spans.icmp, sgName) +func deleteOtherProtocolIfAnyProtocolExists(cubes *sgCubesPerProtocol) { + for _, sgName := range cubes.anyProtocol { + delete(cubes.tcp, sgName) + delete(cubes.udp, sgName) + delete(cubes.icmp, sgName) } } // merge tcp, udp and icmp rules into any protocol rule -func compressThreeProtocolsToAnyProtocol(spans *sgCubesPerProtocol) { - for sgName, tcpPorts := range spans.tcp { - if udpPorts, ok := spans.udp[sgName]; ok { - if ic, ok := spans.icmp[sgName]; ok { +func compressThreeProtocolsToAnyProtocol(cubes *sgCubesPerProtocol) { + for sgName, tcpPorts := range cubes.tcp { + if udpPorts, ok := cubes.udp[sgName]; ok { + if ic, ok := cubes.icmp[sgName]; ok { if ic.IsAll() && optimize.AllPorts(tcpPorts) && optimize.AllPorts(udpPorts) { - delete(spans.tcp, sgName) - delete(spans.udp, sgName) - delete(spans.icmp, sgName) - spans.anyProtocol = append(spans.anyProtocol, sgName) + delete(cubes.tcp, sgName) + delete(cubes.udp, sgName) + delete(cubes.icmp, sgName) + cubes.anyProtocol = append(cubes.anyProtocol, sgName) } } } diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go index 651b9e88..c878a19b 100644 --- a/pkg/optimize/sg/rulesToCubes.go +++ b/pkg/optimize/sg/rulesToCubes.go @@ -22,11 +22,11 @@ func rulesToSGCubes(rules *rulesPerProtocol) *sgCubesPerProtocol { return &sgCubesPerProtocol{tcp: tcpudpRulesSGCubes(rules.tcp), udp: tcpudpRulesSGCubes(rules.udp), icmp: icmpRulesSGCubes(rules.icmp), - anyProtocol: anyProtocolRulesToSGCubes(rules.anyP), + anyProtocol: anyProtocolRulesToSGCubes(rules.anyProtocol), } } -// all protocol rules to cubes +// any protocol rules to cubes func anyProtocolRulesToSGCubes(rules []*ir.SGRule) []ir.SGName { res := make([]ir.SGName, len(rules)) for i := range rules { @@ -70,7 +70,7 @@ func rulesToIPCubes(rules *rulesPerProtocol) *ipCubesPerProtocol { return &ipCubesPerProtocol{tcp: tcpudpRulesToIPCubes(rules.tcp), udp: tcpudpRulesToIPCubes(rules.udp), icmp: icmpRulesToIPCubes(rules.icmp), - anyProtocol: anyProtocolRulesToIPCubes(rules.anyP), + anyProtocol: anyProtocolRulesToIPCubes(rules.anyProtocol), } } @@ -83,7 +83,7 @@ func anyProtocolRulesToIPCubes(rules []*ir.SGRule) *netset.IPBlock { return res } -// tcp/udp rules (separately) to cubes (IPBlock X portset). +// tcp/udp rules (separately) to cubes (IPBlock X portset) func tcpudpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.PortSet] { cubes := ds.NewProductLeft[*netset.IPBlock, *netset.PortSet]() for _, rule := range rules { diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index 72ad6fca..95231803 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -31,12 +31,13 @@ type ( } rulesPerProtocol struct { - tcp []*ir.SGRule - udp []*ir.SGRule - icmp []*ir.SGRule - anyP []*ir.SGRule + tcp []*ir.SGRule + udp []*ir.SGRule + icmp []*ir.SGRule + anyProtocol []*ir.SGRule } + // ir.SGName refers to the remote SG sgCubesPerProtocol struct { tcp map[ir.SGName]*netset.PortSet udp map[ir.SGName]*netset.PortSet @@ -44,6 +45,7 @@ type ( anyProtocol []ir.SGName } + // ipblocks refers to remote IPs ipCubesPerProtocol struct { tcp []ds.Pair[*netset.IPBlock, *netset.PortSet] udp []ds.Pair[*netset.IPBlock, *netset.PortSet] @@ -92,32 +94,29 @@ func (s *sgOptimizer) optimizeSG(sg *ir.SG) { reducedRules := 0 // reduce inbound rules first - newInboundRules := s.reduceRules(sg.InboundRules, ir.Inbound) + newInboundRules := s.reduceSGRules(sg.InboundRules, ir.Inbound) if len(sg.InboundRules) > len(newInboundRules) { reducedRules += len(sg.InboundRules) - len(newInboundRules) sg.InboundRules = newInboundRules } // reduce outbound rules second - newOutboundRules := s.reduceRules(sg.OutboundRules, ir.Outbound) + newOutboundRules := s.reduceSGRules(sg.OutboundRules, ir.Outbound) if len(sg.OutboundRules) > len(newOutboundRules) { reducedRules += len(sg.OutboundRules) - len(newOutboundRules) sg.OutboundRules = newOutboundRules } // print a message to the log - switch { - case reducedRules == 0: + if reducedRules == 0 { log.Printf("no rules were reduced in sg %s\n", string(sg.SGName)) - case reducedRules == 1: - log.Printf("1 rule was reduced in sg %s\n", string(sg.SGName)) - default: - log.Printf("%d rules were reduced in sg %s\n", reducedRules, string(sg.SGName)) + } else { + log.Printf("the number of rules in sg %s was reduced by %d\n", string(sg.SGName), reducedRules) } } // reduceSGRules attempts to reduce the number of rules with different remote types separately -func (s *sgOptimizer) reduceRules(rules []*ir.SGRule, direction ir.Direction) []*ir.SGRule { +func (s *sgOptimizer) reduceSGRules(rules []*ir.SGRule, direction ir.Direction) []*ir.SGRule { // separate all rules to groups of protocol X remote ([tcp, udp, icmp, protocolAll] X [ip, sg]) ruleGroups := divideSGRules(rules) @@ -139,7 +138,7 @@ func (s *sgOptimizer) reduceRules(rules []*ir.SGRule, direction ir.Direction) [] } func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*ir.SGRule { - reduceSGCubes(cubes) + reduceCubesWithSGRemote(cubes) // cubes to SG rules tcpRules := tcpudpSGCubesToRules(cubes.tcp, direction, true) @@ -167,9 +166,9 @@ func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction) []*i // divide SGCollection to TCP/UDP/ICMP/anyProtocols X SGRemote/IPAddrs rules func divideSGRules(rules []*ir.SGRule) *ruleGroups { rulesToSG := &rulesPerProtocol{tcp: make([]*ir.SGRule, 0), udp: make([]*ir.SGRule, 0), - icmp: make([]*ir.SGRule, 0), anyP: make([]*ir.SGRule, 0)} + icmp: make([]*ir.SGRule, 0), anyProtocol: make([]*ir.SGRule, 0)} rulesToIPAddrs := &rulesPerProtocol{tcp: make([]*ir.SGRule, 0), udp: make([]*ir.SGRule, 0), - icmp: make([]*ir.SGRule, 0), anyP: make([]*ir.SGRule, 0)} + icmp: make([]*ir.SGRule, 0), anyProtocol: make([]*ir.SGRule, 0)} for _, rule := range rules { // TCP rule @@ -202,9 +201,9 @@ func divideSGRules(rules []*ir.SGRule) *ruleGroups { // any protocol rules if _, ok := rule.Protocol.(netp.AnyProtocol); ok { if _, ok := rule.Remote.(*netset.IPBlock); ok { - rulesToIPAddrs.anyP = append(rulesToIPAddrs.anyP, rule) + rulesToIPAddrs.anyProtocol = append(rulesToIPAddrs.anyProtocol, rule) } else { - rulesToSG.anyP = append(rulesToSG.anyP, rule) + rulesToSG.anyProtocol = append(rulesToSG.anyProtocol, rule) } } } @@ -212,5 +211,5 @@ func divideSGRules(rules []*ir.SGRule) *ruleGroups { } func (s *rulesPerProtocol) allRules() []*ir.SGRule { - return append(s.tcp, append(s.udp, append(s.icmp, s.anyP...)...)...) + return append(s.tcp, append(s.udp, append(s.icmp, s.anyProtocol...)...)...) } diff --git a/pkg/optimize/sg/sgCubesToRules.go b/pkg/optimize/sg/sgCubesToRules.go index 8932e591..b0d3bfd8 100644 --- a/pkg/optimize/sg/sgCubesToRules.go +++ b/pkg/optimize/sg/sgCubesToRules.go @@ -14,9 +14,9 @@ import ( ) // cubes (SGName X portSet) to SG rules -func tcpudpSGCubesToRules(span map[ir.SGName]*netset.PortSet, direction ir.Direction, isTCP bool) []*ir.SGRule { +func tcpudpSGCubesToRules(cubes map[ir.SGName]*netset.PortSet, direction ir.Direction, isTCP bool) []*ir.SGRule { result := make([]*ir.SGRule, 0) - for sgName, portSet := range span { + for sgName, portSet := range cubes { for _, dstPorts := range portSet.Intervals() { p, _ := netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(dstPorts.Start()), int(dstPorts.End())) result = append(result, ir.NewSGRule(direction, sgName, p, netset.GetCidrAll(), "")) @@ -26,9 +26,9 @@ func tcpudpSGCubesToRules(span map[ir.SGName]*netset.PortSet, direction ir.Direc } // cubes (SGName X icmpset) to SG rules -func icmpSGCubesToRules(span map[ir.SGName]*netset.ICMPSet, direction ir.Direction) []*ir.SGRule { +func icmpSGCubesToRules(cubes map[ir.SGName]*netset.ICMPSet, direction ir.Direction) []*ir.SGRule { result := make([]*ir.SGRule, 0) - for sgName, icmpSet := range span { + for sgName, icmpSet := range cubes { for _, icmp := range optimize.IcmpsetPartitions(icmpSet) { result = append(result, ir.NewSGRule(direction, sgName, icmp, netset.GetCidrAll(), "")) } diff --git a/test/data/optimize_sg_protocols_to_all/details.txt b/test/data/optimize_sg_protocols_to_all/details.txt index 09b14960..09cf8da5 100644 --- a/test/data/optimize_sg_protocols_to_all/details.txt +++ b/test/data/optimize_sg_protocols_to_all/details.txt @@ -1,3 +1,5 @@ +######## BEFORE ######## + vsi1 --> 0.0.0.0/30 (icmp) vsi1 --> 0.0.0.0/31 (tcp) vsi1 --> 0.0.0.0/31 (udp ports 1-100) @@ -10,7 +12,9 @@ vsi1 --> vsi2 (udp ports 1-100) vsi1 --> vsi2 (udp ports 50-150) vsi1 --> vsi2 (udp ports 151-65535) -==================================== + + +######## AFTER ######## vsi1 --> 0.0.0.0/31 (all protocol) vsi1 --> 0.0.0.0/30 (icmp) diff --git a/test/data/optimize_sg_redundant/details.txt b/test/data/optimize_sg_redundant/details.txt index 70573b2d..24f206ae 100644 --- a/test/data/optimize_sg_redundant/details.txt +++ b/test/data/optimize_sg_redundant/details.txt @@ -1,10 +1,14 @@ +######## BEFORE ######## + vsi1 --> 0.0.0.0/30 (protocol all) vsi1 --> 0.0.0.0/31 (protocol all) vsi1 --> vsi2 (protocol all) vsi1 --> vsi2 (protocol all) -==================================== + + +######## AFTER ######## vsi1 --> 0.0.0.0/30 (all protocol) vsi1 --> vsi2 (all protocol) \ No newline at end of file diff --git a/test/data/optimize_sg_t/details.txt b/test/data/optimize_sg_t/details.txt index f0569c96..36385a73 100644 --- a/test/data/optimize_sg_t/details.txt +++ b/test/data/optimize_sg_t/details.txt @@ -1,8 +1,11 @@ +######## BEFORE ######## + vsi1 --> 0.0.0.0/31 (tcp ports 1-10) vsi1 --> 0.0.0.2/31 (tcp ports 1-20) vsi1 --> 0.0.0.4/30 (tcp ports 1-10) -==================================== + +######## AFTER ######## vsi1 --> 0.0.0.0/29 (tcp ports 1-10) vsi1 --> 0.0.0.2/31 (tcp ports 1-20) \ No newline at end of file diff --git a/test/data/optimize_sg_t_all/details.txt b/test/data/optimize_sg_t_all/details.txt index 0de517d7..57a9a7a6 100644 --- a/test/data/optimize_sg_t_all/details.txt +++ b/test/data/optimize_sg_t_all/details.txt @@ -1,8 +1,11 @@ +######## BEFORE ######## + vsi1 --> 0.0.0.0/31 (tcp ports 1-10) vsi1 --> 0.0.0.2/31 (all protocols) vsi1 --> 0.0.0.4/30 (tcp ports 1-10) -==================================== + +######## AFTER ######## vsi1 --> 0.0.0.0/29 (tcp ports 1-10) vsi1 --> 0.0.0.2/31 (all protocols) \ No newline at end of file From 5538d7eb1931b5cbe32521c63edfcd415897fff4 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 11 Dec 2024 15:32:10 +0200 Subject: [PATCH 112/131] any protocol replaces other protocols ip cubes --- pkg/optimize/sg/ipCubesToRules.go | 4 ++-- pkg/optimize/sg/rulesToCubes.go | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go index 8b04c70b..121f4491 100644 --- a/pkg/optimize/sg/ipCubesToRules.go +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -26,7 +26,7 @@ func anyProtocolIPCubesToRules(cubes *netset.IPBlock, direction ir.Direction) [] } // tcpudpIPCubesToRules converts cubes representing tcp or udp protocol rules to SG rules -func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], anyProtoclCubes *netset.IPBlock, direction ir.Direction, +func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], anyProtocolCubes *netset.IPBlock, direction ir.Direction, isTCP bool) []*ir.SGRule { if len(cubes) == 0 { return []*ir.SGRule{} @@ -37,7 +37,7 @@ func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], any for i := range cubes { // if it is not possible to continue the rule between the cubes, generate all existing rules - if i > 0 && uncoveredHole(cubes[i-1], cubes[i], anyProtoclCubes) { + if i > 0 && uncoveredHole(cubes[i-1], cubes[i], anyProtocolCubes) { res = append(res, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)...) activeRules = make(map[*netset.IPBlock]netp.Protocol) } diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go index c878a19b..986f166d 100644 --- a/pkg/optimize/sg/rulesToCubes.go +++ b/pkg/optimize/sg/rulesToCubes.go @@ -67,10 +67,11 @@ func icmpRulesSGCubes(rules []*ir.SGRule) map[ir.SGName]*netset.ICMPSet { // IP remote func rulesToIPCubes(rules *rulesPerProtocol) *ipCubesPerProtocol { - return &ipCubesPerProtocol{tcp: tcpudpRulesToIPCubes(rules.tcp), - udp: tcpudpRulesToIPCubes(rules.udp), - icmp: icmpRulesToIPCubes(rules.icmp), - anyProtocol: anyProtocolRulesToIPCubes(rules.anyProtocol), + anyProtocolCubes := anyProtocolRulesToIPCubes(rules.anyProtocol) + return &ipCubesPerProtocol{tcp: tcpudpRulesToIPCubes(rules.tcp, anyProtocolCubes), + udp: tcpudpRulesToIPCubes(rules.udp, anyProtocolCubes), + icmp: icmpRulesToIPCubes(rules.icmp, anyProtocolCubes), + anyProtocol: anyProtocolCubes, } } @@ -84,7 +85,7 @@ func anyProtocolRulesToIPCubes(rules []*ir.SGRule) *netset.IPBlock { } // tcp/udp rules (separately) to cubes (IPBlock X portset) -func tcpudpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.PortSet] { +func tcpudpRulesToIPCubes(rules []*ir.SGRule, anyProtocolCubes *netset.IPBlock) []ds.Pair[*netset.IPBlock, *netset.PortSet] { cubes := ds.NewProductLeft[*netset.IPBlock, *netset.PortSet]() for _, rule := range rules { ipb := rule.Remote.(*netset.IPBlock) // already checked @@ -92,11 +93,13 @@ func tcpudpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset r := ds.CartesianPairLeft(ipb, p.DstPorts().ToSet()) cubes = cubes.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.PortSet]) } + anyProtocolPair := ds.CartesianPairLeft(anyProtocolCubes, netset.AllPorts()) + cubes = cubes.Subtract(anyProtocolPair).(*ds.ProductLeft[*netset.IPBlock, *netset.PortSet]) // subtruct any protocol cubes return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) } // icmp rules to cubes (IPBlock X icmp set). -func icmpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.ICMPSet] { +func icmpRulesToIPCubes(rules []*ir.SGRule, anyProtocolCubes *netset.IPBlock) []ds.Pair[*netset.IPBlock, *netset.ICMPSet] { cubes := ds.NewProductLeft[*netset.IPBlock, *netset.ICMPSet]() for _, rule := range rules { ipb := rule.Remote.(*netset.IPBlock) // already checked @@ -104,5 +107,7 @@ func icmpRulesToIPCubes(rules []*ir.SGRule) []ds.Pair[*netset.IPBlock, *netset.I r := ds.CartesianPairLeft(ipb, optimize.IcmpRuleToIcmpSet(p)) cubes = cubes.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.ICMPSet]) } + anyProtocolPair := ds.CartesianPairLeft(anyProtocolCubes, netset.AllICMPSet()) + cubes = cubes.Subtract(anyProtocolPair).(*ds.ProductLeft[*netset.IPBlock, *netset.ICMPSet]) // subtruct any protocol cubes return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) } From 298bc6f1793b8209bb4ccdb3f9020f6484d05363 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 11 Dec 2024 16:15:03 +0200 Subject: [PATCH 113/131] upgrade models version --- go.mod | 2 +- go.sum | 4 +-- pkg/optimize/common.go | 8 ------ pkg/optimize/sg/reduceCubes.go | 46 ++++++++++++++++++++-------------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index eff546f4..76af26f6 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.0 require ( github.com/IBM/vpc-go-sdk v0.63.1 github.com/np-guard/cloud-resource-collector v0.17.0 - github.com/np-guard/models v0.5.2 + github.com/np-guard/models v0.5.3-0.20241211135034-007a252c72b2 github.com/spf13/cobra v1.8.1 ) diff --git a/go.sum b/go.sum index 9e08ccd1..5eb5136a 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.2 h1:lty+shExffJpMQyu36a/NBYEky/rjEddQid4GOVHnhs= -github.com/np-guard/models v0.5.2/go.mod h1:dqRdt5EQID1GmHuYsMOJzg4sS104om6NwEZ6sVO55z8= +github.com/np-guard/models v0.5.3-0.20241211135034-007a252c72b2 h1:ONAWOdxDCr3SrzarIPJFRdDTGH9+KKJvDyUsb6id9ws= +github.com/np-guard/models v0.5.3-0.20241211135034-007a252c72b2/go.mod h1:dqRdt5EQID1GmHuYsMOJzg4sS104om6NwEZ6sVO55z8= 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= diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index fe6bcea0..3551b22f 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -32,14 +32,6 @@ func SortPartitionsByIPAddrs[T ds.Set[T]](p []ds.Pair[*netset.IPBlock, T]) []ds. return p } -// returns true if this advance the smaller one // case 2: advance the smaller ipb - tcpIP := cubes.tcp[tcpPtr].Left - udpIP := cubes.udp[udpPtr].Left - icmpIP := cubes.icmp[icmpPtr].Left + tcpIPblock := cubes.tcp[tcpPtr].Left + udpIPblock := cubes.udp[udpPtr].Left + icmpIPblock := cubes.icmp[icmpPtr].Left + + udpSmallerThanICMP := udpIPblock.Smaller(icmpIPblock) + tcpSmallerThanUDP := tcpIPblock.Smaller(udpIPblock) + tcpSmallerThanICMP := tcpIPblock.Smaller(icmpIPblock) + + udpAndICMPSubsetOfTCP := udpIPblock.IsSubset(tcpIPblock) && icmpIPblock.IsSubset(tcpIPblock) + tcpAndICMPSubsetOfUDP := icmpIPblock.IsSubset(udpIPblock) && tcpIPblock.IsSubset(udpIPblock) + tcpAndUDPSubsetOfICMP := tcpIPblock.IsSubset(icmpIPblock) && udpIPblock.IsSubset(icmpIPblock) switch { // case 1 - case udpIP.IsSubset(tcpIP) && icmpIP.IsSubset(tcpIP) && optimize.LessIPBlock(udpIP, icmpIP): + case udpAndICMPSubsetOfTCP && udpSmallerThanICMP: udpPtr++ - case udpIP.IsSubset(tcpIP) && icmpIP.IsSubset(tcpIP) && optimize.LessIPBlock(icmpIP, udpIP): + case udpAndICMPSubsetOfTCP && !udpSmallerThanICMP: icmpPtr++ - case tcpIP.IsSubset(udpIP) && icmpIP.IsSubset(udpIP) && optimize.LessIPBlock(tcpIP, icmpIP): + case tcpAndICMPSubsetOfUDP && tcpSmallerThanICMP: tcpPtr++ - case tcpIP.IsSubset(udpIP) && icmpIP.IsSubset(udpIP) && optimize.LessIPBlock(icmpIP, tcpIP): + case tcpAndICMPSubsetOfUDP && !tcpSmallerThanICMP: icmpPtr++ - case tcpIP.IsSubset(icmpIP) && udpIP.IsSubset(icmpIP) && optimize.LessIPBlock(tcpIP, udpIP): + case tcpAndUDPSubsetOfICMP && tcpSmallerThanUDP: tcpPtr++ - case tcpIP.IsSubset(icmpIP) && udpIP.IsSubset(icmpIP) && optimize.LessIPBlock(udpIP, tcpIP): + case tcpAndUDPSubsetOfICMP && !tcpSmallerThanUDP: udpPtr++ // case 2 - case optimize.LessIPBlock(tcpIP, udpIP) && optimize.LessIPBlock(tcpIP, icmpIP): + case tcpSmallerThanUDP && tcpSmallerThanICMP: tcpPtr++ - case optimize.LessIPBlock(udpIP, tcpIP) && optimize.LessIPBlock(udpIP, icmpIP): + case !tcpSmallerThanUDP && udpSmallerThanICMP: udpPtr++ - case optimize.LessIPBlock(icmpIP, tcpIP) && optimize.LessIPBlock(icmpIP, udpIP): + case !tcpSmallerThanICMP && !udpSmallerThanICMP: icmpPtr++ } } @@ -105,7 +113,7 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) { // compress three protocol rules to any protocol rule (and maybe another protocol rule) // returns true if the compression was successful -func compressedToAnyProtocolCube(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) bool { +func compressedToAnyProtocolCubeIPCubes(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) bool { tcpIP := cubes.tcp[tcpPtr].Left udpIP := cubes.udp[udpPtr].Left icmpIP := cubes.icmp[icmpPtr].Left From c6452e40059dd0f980a7f951e556bd822451a2b6 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 11 Dec 2024 17:56:06 +0200 Subject: [PATCH 114/131] typos, models --- go.mod | 2 +- go.sum | 4 ++-- pkg/optimize/sg/ipCubesToRules.go | 10 ++++++---- pkg/optimize/sg/reduceCubes.go | 24 ++++++++++++------------ pkg/optimize/sg/rulesToCubes.go | 4 ++-- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 76af26f6..6aabf93f 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.0 require ( github.com/IBM/vpc-go-sdk v0.63.1 github.com/np-guard/cloud-resource-collector v0.17.0 - github.com/np-guard/models v0.5.3-0.20241211135034-007a252c72b2 + github.com/np-guard/models v0.5.3 github.com/spf13/cobra v1.8.1 ) diff --git a/go.sum b/go.sum index 5eb5136a..01b9286e 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-0.20241211135034-007a252c72b2 h1:ONAWOdxDCr3SrzarIPJFRdDTGH9+KKJvDyUsb6id9ws= -github.com/np-guard/models v0.5.3-0.20241211135034-007a252c72b2/go.mod h1:dqRdt5EQID1GmHuYsMOJzg4sS104om6NwEZ6sVO55z8= +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/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= diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go index 121f4491..e1dc3729 100644 --- a/pkg/optimize/sg/ipCubesToRules.go +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -45,10 +45,11 @@ func tcpudpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.PortSet], any // if there are active rules whose ports are not fully included in the current cube, they will be created // also activePorts will be calculated, which is the ports that are still included in the active rules activePorts := interval.NewCanonicalSet() - for ipb, protocol := range activeRules { + for startIP, protocol := range activeRules { if tcpudp, ok := protocol.(netp.TCPUDP); ok { if !tcpudp.DstPorts().ToSet().IsSubset(cubes[i].Right) { - res = append(res, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction)...) + res = append(res, createNewRules(protocol, startIP, cubes[i-1].Left.LastIPAddressObject(), direction)...) + delete(activeRules, startIP) } else { activePorts.AddInterval(tcpudp.DstPorts()) } @@ -87,11 +88,12 @@ func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], anyPr // if there are active rules whose icmp values are not fully included in the current cube, they will be created // also activeICMP will be calculated, which is the icmp values that are still included in the active rules activeICMP := netset.EmptyICMPSet() - for ipb, protocol := range activeRules { + for startIP, protocol := range activeRules { if icmp, ok := protocol.(netp.ICMP); ok { ruleIcmpSet := optimize.IcmpRuleToIcmpSet(icmp) if !ruleIcmpSet.IsSubset(cubes[i].Right) { - res = append(res, createNewRules(protocol, ipb, cubes[i-1].Left.LastIPAddressObject(), direction)...) + res = append(res, createNewRules(protocol, startIP, cubes[i-1].Left.LastIPAddressObject(), direction)...) + delete(activeRules, startIP) } else { activeICMP.Union(ruleIcmpSet) } diff --git a/pkg/optimize/sg/reduceCubes.go b/pkg/optimize/sg/reduceCubes.go index e2509d8e..e18c2e76 100644 --- a/pkg/optimize/sg/reduceCubes.go +++ b/pkg/optimize/sg/reduceCubes.go @@ -77,9 +77,9 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) { udpIPblock := cubes.udp[udpPtr].Left icmpIPblock := cubes.icmp[icmpPtr].Left - udpSmallerThanICMP := udpIPblock.Smaller(icmpIPblock) - tcpSmallerThanUDP := tcpIPblock.Smaller(udpIPblock) - tcpSmallerThanICMP := tcpIPblock.Smaller(icmpIPblock) + udpComparedToICMP := udpIPblock.Compare(icmpIPblock) + tcpComparedToUDP := tcpIPblock.Compare(udpIPblock) + tcpComparedToICMP := tcpIPblock.Compare(icmpIPblock) udpAndICMPSubsetOfTCP := udpIPblock.IsSubset(tcpIPblock) && icmpIPblock.IsSubset(tcpIPblock) tcpAndICMPSubsetOfUDP := icmpIPblock.IsSubset(udpIPblock) && tcpIPblock.IsSubset(udpIPblock) @@ -87,25 +87,25 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) { switch { // case 1 - case udpAndICMPSubsetOfTCP && udpSmallerThanICMP: + case udpAndICMPSubsetOfTCP && udpComparedToICMP == -1: udpPtr++ - case udpAndICMPSubsetOfTCP && !udpSmallerThanICMP: + case udpAndICMPSubsetOfTCP && udpComparedToICMP == 1: icmpPtr++ - case tcpAndICMPSubsetOfUDP && tcpSmallerThanICMP: + case tcpAndICMPSubsetOfUDP && tcpComparedToICMP == -1: tcpPtr++ - case tcpAndICMPSubsetOfUDP && !tcpSmallerThanICMP: + case tcpAndICMPSubsetOfUDP && tcpComparedToICMP == 1: icmpPtr++ - case tcpAndUDPSubsetOfICMP && tcpSmallerThanUDP: + case tcpAndUDPSubsetOfICMP && tcpComparedToUDP == -1: tcpPtr++ - case tcpAndUDPSubsetOfICMP && !tcpSmallerThanUDP: + case tcpAndUDPSubsetOfICMP && tcpComparedToUDP == 1: udpPtr++ // case 2 - case tcpSmallerThanUDP && tcpSmallerThanICMP: + case tcpComparedToUDP == -1 && tcpComparedToICMP == -1: tcpPtr++ - case !tcpSmallerThanUDP && udpSmallerThanICMP: + case tcpComparedToUDP == 1 && udpComparedToICMP == -1: udpPtr++ - case !tcpSmallerThanICMP && !udpSmallerThanICMP: + case tcpComparedToICMP == 1 && udpComparedToICMP == 1: icmpPtr++ } } diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go index 986f166d..5763641a 100644 --- a/pkg/optimize/sg/rulesToCubes.go +++ b/pkg/optimize/sg/rulesToCubes.go @@ -94,7 +94,7 @@ func tcpudpRulesToIPCubes(rules []*ir.SGRule, anyProtocolCubes *netset.IPBlock) cubes = cubes.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.PortSet]) } anyProtocolPair := ds.CartesianPairLeft(anyProtocolCubes, netset.AllPorts()) - cubes = cubes.Subtract(anyProtocolPair).(*ds.ProductLeft[*netset.IPBlock, *netset.PortSet]) // subtruct any protocol cubes + cubes = cubes.Subtract(anyProtocolPair).(*ds.ProductLeft[*netset.IPBlock, *netset.PortSet]) // subtract any protocol cubes return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) } @@ -108,6 +108,6 @@ func icmpRulesToIPCubes(rules []*ir.SGRule, anyProtocolCubes *netset.IPBlock) [] cubes = cubes.Union(r).(*ds.ProductLeft[*netset.IPBlock, *netset.ICMPSet]) } anyProtocolPair := ds.CartesianPairLeft(anyProtocolCubes, netset.AllICMPSet()) - cubes = cubes.Subtract(anyProtocolPair).(*ds.ProductLeft[*netset.IPBlock, *netset.ICMPSet]) // subtruct any protocol cubes + cubes = cubes.Subtract(anyProtocolPair).(*ds.ProductLeft[*netset.IPBlock, *netset.ICMPSet]) // subtract any protocol cubes return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) } From b236fade49140a92d75345ff44ac5d4ca6ddcbbc Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Thu, 12 Dec 2024 15:23:36 +0200 Subject: [PATCH 115/131] update test --- .../optimize_sg_protocols_to_all_json/sg_expected.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/expected/optimize_sg_protocols_to_all_json/sg_expected.json b/test/expected/optimize_sg_protocols_to_all_json/sg_expected.json index 34f2e08d..7c8093aa 100644 --- a/test/expected/optimize_sg_protocols_to_all_json/sg_expected.json +++ b/test/expected/optimize_sg_protocols_to_all_json/sg_expected.json @@ -1343,6 +1343,7 @@ "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", "created_at": "2024-09-09T09:11:07.000Z", "crn": "crn:144", @@ -1501,6 +1502,7 @@ "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", "created_at": "2024-09-09T09:10:52.000Z", "crn": "crn:157", @@ -1667,6 +1669,7 @@ "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", "created_at": "2024-09-09T09:10:35.000Z", "crn": "crn:166", @@ -1825,6 +1828,7 @@ "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", "created_at": "2024-09-09T09:10:34.000Z", "crn": "crn:175", From 22d30f29751c32f89973d8015ea7d91b4754fec7 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 17 Dec 2024 12:28:46 +0200 Subject: [PATCH 116/131] wip --- pkg/optimize/common.go | 16 +++++++--------- pkg/optimize/sg/reduceCubes.go | 6 +++--- pkg/optimize/sg/sg.go | 10 +++++----- pkg/optimize/sg/sgCubesToRules.go | 8 ++++---- test/main_test_list.go | 3 ++- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/pkg/optimize/common.go b/pkg/optimize/common.go index 3551b22f..70b3be01 100644 --- a/pkg/optimize/common.go +++ b/pkg/optimize/common.go @@ -6,7 +6,7 @@ SPDX-License-Identifier: Apache-2.0 package optimize import ( - "sort" + "slices" "github.com/np-guard/models/pkg/ds" "github.com/np-guard/models/pkg/netp" @@ -22,23 +22,21 @@ type Optimizer interface { // each IPBlock is a single CIDR. The CIDRs are disjoint. func SortPartitionsByIPAddrs[T ds.Set[T]](p []ds.Pair[*netset.IPBlock, T]) []ds.Pair[*netset.IPBlock, T] { - cmp := func(i, j int) bool { - if p[i].Left.FirstIPAddress() == p[j].Left.FirstIPAddress() { - return p[i].Left.LastIPAddress() < p[j].Left.LastIPAddress() - } - return p[i].Left.FirstIPAddress() < p[j].Left.FirstIPAddress() + cmp := func(i, j ds.Pair[*netset.IPBlock, T]) int { + return i.Left.Compare(j.Left) } - sort.Slice(p, cmp) + slices.SortFunc(p, cmp) return p } +// IcmpsetPartitions breaks the set into ICMP slice, where each element defined as legal in nACL, SG rules func IcmpsetPartitions(icmpset *netset.ICMPSet) []netp.ICMP { - result := make([]netp.ICMP, 0) if icmpset.IsAll() { icmp, _ := netp.ICMPFromTypeAndCode64WithoutRFCValidation(nil, nil) return []netp.ICMP{icmp} } + result := make([]netp.ICMP, 0) for _, cube := range icmpset.Partitions() { for _, typeInterval := range cube.Left.Intervals() { for _, icmpType := range typeInterval.Elements() { @@ -71,6 +69,6 @@ func IcmpRuleToIcmpSet(icmp netp.ICMP) *netset.ICMPSet { return netset.NewICMPSet(icmpType, icmpType, icmpCode, icmpCode) } -func AllPorts(tcpudpPorts *netset.PortSet) bool { +func IsAllPorts(tcpudpPorts *netset.PortSet) bool { return tcpudpPorts.Equal(netset.AllPorts()) } diff --git a/pkg/optimize/sg/reduceCubes.go b/pkg/optimize/sg/reduceCubes.go index e18c2e76..fd303114 100644 --- a/pkg/optimize/sg/reduceCubes.go +++ b/pkg/optimize/sg/reduceCubes.go @@ -30,7 +30,7 @@ func compressThreeProtocolsToAnyProtocolSGRemote(cubes *sgCubesPerProtocol) { for sgName, tcpPorts := range cubes.tcp { if udpPorts, ok := cubes.udp[sgName]; ok { if ic, ok := cubes.icmp[sgName]; ok { - if ic.IsAll() && optimize.AllPorts(tcpPorts) && optimize.AllPorts(udpPorts) { + if ic.IsAll() && optimize.IsAllPorts(tcpPorts) && optimize.IsAllPorts(udpPorts) { delete(cubes.tcp, sgName) delete(cubes.udp, sgName) delete(cubes.icmp, sgName) @@ -51,11 +51,11 @@ func reduceIPCubes(cubes *ipCubesPerProtocol) { icmpPtr := 0 for tcpPtr < len(cubes.tcp) && udpPtr < len(cubes.udp) && icmpPtr < len(cubes.icmp) { - if !optimize.AllPorts(cubes.tcp[tcpPtr].Right) { // not all tcp ports + if !optimize.IsAllPorts(cubes.tcp[tcpPtr].Right) { // not all tcp ports tcpPtr++ continue } - if !optimize.AllPorts(cubes.udp[udpPtr].Right) { // not all udp ports + if !optimize.IsAllPorts(cubes.udp[udpPtr].Right) { // not all udp ports udpPtr++ continue } diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index 95231803..0bac3289 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -22,7 +22,7 @@ type ( sgOptimizer struct { sgCollection *ir.SGCollection sgName ir.SGName - sgVPC *string + sgVPC string } ruleGroups struct { @@ -57,9 +57,9 @@ type ( func NewSGOptimizer(collection ir.Collection, sgName string) optimize.Optimizer { components := ir.ScopingComponents(sgName) if len(components) == 1 { - return &sgOptimizer{sgCollection: collection.(*ir.SGCollection), sgName: ir.SGName(sgName), sgVPC: nil} + return &sgOptimizer{sgCollection: collection.(*ir.SGCollection), sgName: ir.SGName(sgName), sgVPC: ""} } - return &sgOptimizer{sgCollection: collection.(*ir.SGCollection), sgName: ir.SGName(components[1]), sgVPC: &components[0]} + return &sgOptimizer{sgCollection: collection.(*ir.SGCollection), sgName: ir.SGName(components[1]), sgVPC: components[0]} } // Optimize attempts to reduce the number of SG rules @@ -68,7 +68,7 @@ func NewSGOptimizer(collection ir.Collection, sgName string) optimize.Optimizer func (s *sgOptimizer) Optimize() (ir.Collection, error) { if s.sgName != "" { for _, vpcName := range utils.SortedMapKeys(s.sgCollection.SGs) { - if s.sgVPC != nil && s.sgVPC != &vpcName { + if s.sgVPC != "" && s.sgVPC != vpcName { continue } if _, ok := s.sgCollection.SGs[vpcName][s.sgName]; ok { @@ -144,7 +144,7 @@ func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*i tcpRules := tcpudpSGCubesToRules(cubes.tcp, direction, true) udpRules := tcpudpSGCubesToRules(cubes.udp, direction, false) icmpRules := icmpSGCubesToRules(cubes.icmp, direction) - anyProtocolRules := anyPotocolCubesToRules(cubes.anyProtocol, direction) + anyProtocolRules := anyProtocolCubesToRules(cubes.anyProtocol, direction) // return all rules return append(tcpRules, append(udpRules, append(icmpRules, anyProtocolRules...)...)...) diff --git a/pkg/optimize/sg/sgCubesToRules.go b/pkg/optimize/sg/sgCubesToRules.go index b0d3bfd8..94904c5d 100644 --- a/pkg/optimize/sg/sgCubesToRules.go +++ b/pkg/optimize/sg/sgCubesToRules.go @@ -36,10 +36,10 @@ func icmpSGCubesToRules(cubes map[ir.SGName]*netset.ICMPSet, direction ir.Direct return result } -// cubes (slice of SGs) to SG rules -func anyPotocolCubesToRules(span []ir.SGName, direction ir.Direction) []*ir.SGRule { - result := make([]*ir.SGRule, len(span)) - for i, sgName := range span { +// slice of remote SGs to SG rules +func anyProtocolCubesToRules(remoteSG []ir.SGName, direction ir.Direction) []*ir.SGRule { + result := make([]*ir.SGRule, len(remoteSG)) + for i, sgName := range remoteSG { result[i] = ir.NewSGRule(direction, sgName, netp.AnyProtocol{}, netset.GetCidrAll(), "") } return result diff --git a/test/main_test_list.go b/test/main_test_list.go index 6012d200..709e0ae6 100644 --- a/test/main_test_list.go +++ b/test/main_test_list.go @@ -7,6 +7,7 @@ package test import ( "fmt" + "slices" "github.com/np-guard/vpc-network-config-synthesis/pkg/synth" "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" @@ -40,7 +41,7 @@ const ( ) func allMainTests() []testCase { - return append(synthACLTestsList(), append(synthSGTestsList(), optimizeSGTestsLists()...)...) + return slices.Concat(synthACLTestsList(), synthSGTestsList(), optimizeSGTestsLists()) } //nolint:funlen //all acl synthesis tests From 1fa61624b90165aeb7f5a12b4e89afc92584cf4c Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 17 Dec 2024 12:41:47 +0200 Subject: [PATCH 117/131] typo --- pkg/io/mdWriter.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/io/mdWriter.go b/pkg/io/mdWriter.go index 082bc3ee..cd1a5b8c 100644 --- a/pkg/io/mdWriter.go +++ b/pkg/io/mdWriter.go @@ -35,7 +35,7 @@ func (w *MDWriter) WriteSG(collection *ir.SGCollection, vpc string) error { if err != nil { return err } - return w.writeAll(append(append(SGHeader(), addAlighns(sgColsNum)), sgTable...)) + return w.writeAll(append(append(SGHeader(), addAligns(sgColsNum)), sgTable...)) } func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { @@ -43,7 +43,7 @@ func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { if err != nil { return err } - return w.writeAll(append(append(ACLHeader(), addAlighns(aclColsNum)), aclTable...)) + return w.writeAll(append(append(ACLHeader(), addAligns(aclColsNum)), aclTable...)) } func (w *MDWriter) writeAll(rows [][]string) error { @@ -62,7 +62,7 @@ func (w *MDWriter) writeAll(rows [][]string) error { return nil } -func addAlighns(n int) []string { +func addAligns(n int) []string { res := make([]string, n) for i := range n { res[i] = leftAlign From 668996746cad0c561d434f42a14667b23c326bde Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 17 Dec 2024 13:54:42 +0200 Subject: [PATCH 118/131] update test --- .../optimize_sg_protocols_to_all/details.txt | 6 +- .../optimize_sg_redundant/config_object.json | 133 ++++++++++++++++-- .../data/optimize_sg_redundant/conn_spec.json | 54 ++++++- test/data/optimize_sg_redundant/details.txt | 22 +-- test/data/optimize_sg_t/details.txt | 2 + test/data/optimize_sg_t_all/details.txt | 6 +- .../optimize_sg_redundant/sg_expected.tf | 15 ++ 7 files changed, 212 insertions(+), 26 deletions(-) diff --git a/test/data/optimize_sg_protocols_to_all/details.txt b/test/data/optimize_sg_protocols_to_all/details.txt index 09cf8da5..dcd70519 100644 --- a/test/data/optimize_sg_protocols_to_all/details.txt +++ b/test/data/optimize_sg_protocols_to_all/details.txt @@ -1,3 +1,5 @@ +original config object: acl_testing4 config + ######## BEFORE ######## vsi1 --> 0.0.0.0/30 (icmp) @@ -16,6 +18,6 @@ vsi1 --> vsi2 (udp ports 151-65535) ######## AFTER ######## -vsi1 --> 0.0.0.0/31 (all protocol) +vsi1 --> 0.0.0.0/31 (any protocol) vsi1 --> 0.0.0.0/30 (icmp) -vsi1 --> vsi2 (all protocol) \ No newline at end of file +vsi1 --> vsi2 (any protocol) \ No newline at end of file diff --git a/test/data/optimize_sg_redundant/config_object.json b/test/data/optimize_sg_redundant/config_object.json index e9dd5c87..bc4c61c5 100644 --- a/test/data/optimize_sg_redundant/config_object.json +++ b/test/data/optimize_sg_redundant/config_object.json @@ -42,6 +42,7 @@ "name": "capitol-siren-chirpy-doornail" }, "default_routing_table": { + "crn": null, "href": "href:11", "id": "id:12", "name": "fiscally-fresh-uncanny-ceramics", @@ -156,6 +157,7 @@ }, "resource_type": "subnet", "routing_table": { + "crn": null, "href": "href:11", "id": "id:12", "name": "fiscally-fresh-uncanny-ceramics", @@ -279,6 +281,7 @@ }, "resource_type": "subnet", "routing_table": { + "crn": null, "href": "href:11", "id": "id:12", "name": "fiscally-fresh-uncanny-ceramics", @@ -395,6 +398,7 @@ }, "resource_type": "subnet", "routing_table": { + "crn": null, "href": "href:11", "id": "id:12", "name": "fiscally-fresh-uncanny-ceramics", @@ -1232,6 +1236,34 @@ "local": { "cidr_block": "0.0.0.0/0" }, + "remote": { + "cidr_block": "1.0.0.0/30" + }, + "protocol": "all" + }, + { + "direction": "outbound", + "href": "fake:href:7", + "id": "fake:id:7", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "cidr_block": "1.0.0.0/31" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "outbound", + "href": "fake:href:8", + "id": "fake:id:8", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, "remote": { "crn": "fake:crn:3", "href": "fake:href:3", @@ -1239,6 +1271,40 @@ "name": "test-vpc1--vsi2" }, "protocol": "all" + }, + { + "direction": "outbound", + "href": "fake:href:9", + "id": "fake:id:9", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:10", + "href": "fake:href:10", + "id": "fake:id:10", + "name": "test-vpc1--vsi3a" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "outbound", + "href": "fake:href:11", + "id": "fake:id:11", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:10", + "href": "fake:href:10", + "id": "fake:id:10", + "name": "test-vpc1--vsi3a" + }, + "protocol": "all" } ], "targets": [ @@ -1260,9 +1326,9 @@ }, { "created_at": null, - "crn": "fake:crn:7", - "href": "fake:href:7", - "id": "fake:id:7", + "crn": "fake:crn:12", + "href": "fake:href:12", + "id": "fake:id:12", "name": "test-vpc1--vsi3b", "resource_group": { "href": "href:16", @@ -1289,16 +1355,51 @@ }, { "created_at": null, - "crn": "fake:crn:8", - "href": "fake:href:8", - "id": "fake:id:8", + "crn": "fake:crn:10", + "href": "fake:href:10", + "id": "fake:id:10", "name": "test-vpc1--vsi3a", "resource_group": { "href": "href:16", "id": "id:17", "name": "name:4" }, - "rules": [], + "rules": [ + { + "direction": "inbound", + "href": "fake:href:13", + "id": "fake:id:13", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" + }, + { + "direction": "inbound", + "href": "fake:href:14", + "id": "fake:id:14", + "ip_version": "ipv4", + "local": { + "cidr_block": "0.0.0.0/0" + }, + "remote": { + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" + }, + "protocol": "all" + } + ], "targets": [ { "href": "href:83", @@ -1339,6 +1440,7 @@ "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", "created_at": "2024-09-09T09:11:07.000Z", "crn": "crn:144", @@ -1497,6 +1599,7 @@ "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", "created_at": "2024-09-09T09:10:52.000Z", "crn": "crn:157", @@ -1663,6 +1766,7 @@ "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", "created_at": "2024-09-09T09:10:35.000Z", "crn": "crn:166", @@ -1782,9 +1886,9 @@ "resource_type": "network_interface", "security_groups": [ { - "crn": "fake:crn:7", - "href": "fake:href:7", - "id": "fake:id:7", + "crn": "fake:crn:12", + "href": "fake:href:12", + "id": "fake:id:12", "name": "test-vpc1--vsi3b" } ], @@ -1821,6 +1925,7 @@ "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", "created_at": "2024-09-09T09:10:34.000Z", "crn": "crn:175", @@ -1940,9 +2045,9 @@ "resource_type": "network_interface", "security_groups": [ { - "crn": "fake:crn:8", - "href": "fake:href:8", - "id": "fake:id:8", + "crn": "fake:crn:10", + "href": "fake:href:10", + "id": "fake:id:10", "name": "test-vpc1--vsi3a" } ], @@ -1973,11 +2078,13 @@ ], "advertise_routes_to": [], "created_at": "2024-09-09T09:09:51.000Z", + "crn": null, "href": "href:11", "id": "id:12", "is_default": true, "lifecycle_state": "stable", "name": "fiscally-fresh-uncanny-ceramics", + "resource_group": null, "resource_type": "routing_table", "route_direct_link_ingress": false, "route_internet_ingress": false, diff --git a/test/data/optimize_sg_redundant/conn_spec.json b/test/data/optimize_sg_redundant/conn_spec.json index ef2331cd..f9db31d6 100644 --- a/test/data/optimize_sg_redundant/conn_spec.json +++ b/test/data/optimize_sg_redundant/conn_spec.json @@ -1,7 +1,9 @@ { "externals": { "e1": "0.0.0.0/30", - "e2": "0.0.0.0/31" + "e2": "0.0.0.0/31", + "e3": "1.0.0.0/30", + "e4": "1.0.0.0/31" }, "required-connections": [ { @@ -24,6 +26,31 @@ "type": "external" } }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e3", + "type": "external" + } + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e4", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "TCP" + } + ] + }, { "src": { "name": "vsi1", @@ -43,6 +70,31 @@ "name": "vsi2", "type": "instance" } + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi3a", + "type": "instance" + }, + "allowed-protocols": [ + { + "protocol": "TCP" + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi3a", + "type": "instance" + } } ] } diff --git a/test/data/optimize_sg_redundant/details.txt b/test/data/optimize_sg_redundant/details.txt index 24f206ae..814b59c2 100644 --- a/test/data/optimize_sg_redundant/details.txt +++ b/test/data/optimize_sg_redundant/details.txt @@ -1,14 +1,20 @@ -######## BEFORE ######## - -vsi1 --> 0.0.0.0/30 (protocol all) -vsi1 --> 0.0.0.0/31 (protocol all) +original config object: acl_testing4 config -vsi1 --> vsi2 (protocol all) -vsi1 --> vsi2 (protocol all) +######## BEFORE ######## +vsi1 --> 0.0.0.0/30 (any protocol) +vsi1 --> 0.0.0.0/31 (any protocol) +vsi1 --> 1.0.0.0/30 (TCP) +vsi1 --> 1.0.0.0/31 (any protocol) +vsi1 --> vsi2 (any protocol) +vsi1 --> vsi2 (any protocol) +vsi1 --> vsi3a (TCP) +vsi1 --> vsi3a (any protocol) ######## AFTER ######## -vsi1 --> 0.0.0.0/30 (all protocol) -vsi1 --> vsi2 (all protocol) \ No newline at end of file +vsi1 --> 0.0.0.0/30 (any protocol) +vsi1 --> 1.0.0.0/30 (any protocol) +vsi1 --> vsi2 (any protocol) +vsi1 --> vsi3a (any protocol) \ No newline at end of file diff --git a/test/data/optimize_sg_t/details.txt b/test/data/optimize_sg_t/details.txt index 36385a73..30e6764b 100644 --- a/test/data/optimize_sg_t/details.txt +++ b/test/data/optimize_sg_t/details.txt @@ -1,3 +1,5 @@ +original config object: acl_testing4 config + ######## BEFORE ######## vsi1 --> 0.0.0.0/31 (tcp ports 1-10) diff --git a/test/data/optimize_sg_t_all/details.txt b/test/data/optimize_sg_t_all/details.txt index 57a9a7a6..9d84988b 100644 --- a/test/data/optimize_sg_t_all/details.txt +++ b/test/data/optimize_sg_t_all/details.txt @@ -1,11 +1,13 @@ +original config object: acl_testing4 config + ######## BEFORE ######## vsi1 --> 0.0.0.0/31 (tcp ports 1-10) -vsi1 --> 0.0.0.2/31 (all protocols) +vsi1 --> 0.0.0.2/31 (any protocol) vsi1 --> 0.0.0.4/30 (tcp ports 1-10) ######## AFTER ######## vsi1 --> 0.0.0.0/29 (tcp ports 1-10) -vsi1 --> 0.0.0.2/31 (all protocols) \ No newline at end of file +vsi1 --> 0.0.0.2/31 (any protocol) \ No newline at end of file diff --git a/test/expected/optimize_sg_redundant/sg_expected.tf b/test/expected/optimize_sg_redundant/sg_expected.tf index 88239143..7319be9e 100644 --- a/test/expected/optimize_sg_redundant/sg_expected.tf +++ b/test/expected/optimize_sg_redundant/sg_expected.tf @@ -26,10 +26,20 @@ resource "ibm_is_security_group_rule" "test-vpc1--vsi1-0" { remote = ibm_is_security_group.test-vpc1--vsi2.id } resource "ibm_is_security_group_rule" "test-vpc1--vsi1-1" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = ibm_is_security_group.test-vpc1--vsi3a.id +} +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-2" { group = ibm_is_security_group.test-vpc1--vsi1.id direction = "outbound" remote = "0.0.0.0/30" } +resource "ibm_is_security_group_rule" "test-vpc1--vsi1-3" { + group = ibm_is_security_group.test-vpc1--vsi1.id + direction = "outbound" + remote = "1.0.0.0/30" +} resource "ibm_is_security_group" "test-vpc1--vsi2" { @@ -49,6 +59,11 @@ resource "ibm_is_security_group" "test-vpc1--vsi3a" { resource_group = local.sg_synth_resource_group_id vpc = local.sg_synth_test-vpc1_id } +resource "ibm_is_security_group_rule" "test-vpc1--vsi3a-0" { + group = ibm_is_security_group.test-vpc1--vsi3a.id + direction = "inbound" + remote = ibm_is_security_group.test-vpc1--vsi1.id +} resource "ibm_is_security_group" "test-vpc1--vsi3b" { From f1e93a4933734fda2e0c6e8f4c7ebf627e950489 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 17 Dec 2024 14:27:30 +0200 Subject: [PATCH 119/131] -d optimization --- README.md | 59 ++++++++++++++++++++++++++++++-------------- cmd/subcmds/root.go | 7 +++++- cmd/subcmds/synth.go | 9 +------ 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index aba49ca9..f4617bb1 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,66 @@ # vpc-network-config-synthesis ## About vpc-network-config-synthesis -Tool for automatic synthesis of VPC network configurations, namely Network ACLs and Security Groups. +Tool for automatic synthesis and optimization of VPC network configurations, namely Network ACLs and Security Groups. ## Usage -Use the `vpcgen` CLI tool with one of the following commands to specify the type of network resources to generate. +Use the `vpcgen` CLI tool with one of the following commands: * `vpcgen synth sg` - generate Security Groups. * `vpcgen synth acl` - generate an nACL for each subnet separately. * `vpcgen synth acl --single` - generate a single nACL for all subnets in the same VPC. +* `vpcgen optimize sg` - optimize SGs. +* `vpcgen optimize acl` - optimize nACLs (In progress). -### nACLs Generation -Specifying the `--single` flag results in generating a single nACL for all subnets in the same VPC. Otherwise, an nACL is generated for each subnet separately. -**Note**: A required connection between NIFs/VSIs/VPEs implies connectivity will be allowed between the subnets they are contained in. +## Synthesis +#### nACLs Generation +a required connection between NIFs/VSIs/VPEs implies connectivity will be allowed between the subnets they are contained in. -### SGs Generation -**Note**: A Security Group, generated for a specific VSI (or for one of its NIFs), will be applied to all the NIFs of the VSI. The same goes for Reserved IPs of a VPE. +#### SGs Generation +A Security Group, generated for a specific VSI (or for one of its NIFs), will be applied to all the NIFs of the VSI. The same goes for Reserved IPs of a VPE. -### Supported types +#### Supported types The input supports subnets, subnet segments, CIDR segments, NIFs, NIF segments, instances (VSIs), instance segments, VPEs, VPE segments and externals. **Note**: Segments should be defined in the spec file. -### Output -1. If the `output-dir` flag is used, the specified folder will be created, containing one file per VPC. Each generated file will contain the network resources (Security Groups or Network ACLs) relevant to its VPC. File names are set as `prefix_vpc`, where prefix is ​​the value received in the `prefix` flag. If the `prefix` flag is omitted, file names will match VPC names. -2. If the `output-file` flag is used, all generated resources will be written to the specified file. -3. if both `output-file` and `output-dir` flags are not used, the collection will be written to stdout. +#### Options +```commandline +Flags: + -h, --help help for synth + -s, --spec string JSON file containing spec file +``` + +## Optimization +#### SG optimization +Specifying the `-n` flag results in optimizing only one given SG. Otherwise, all SGs will be optimized. +``` +Flags: + -n, --sg-name string which security group to optimize +``` -### Global options +#### nACL optimization (in progress) +Specifying the `-n` flag results in optimizing only one given nACL. Otherwise, all nACLs will be optimized. +``` +Flags: + -n, --acl-name string which nACL to optimize +``` + + +## Global options ```commandline Flags: -c, --config string JSON file containing a configuration object of existing resources -f, --format string Output format; must be one of [tf, csv, md, json] - -h, --help help for vpc-synthesis + -h, --help help for vpcgen -l, --locals whether to generate a locals.tf file (only possible when the output format is tf) - -d, --output-dir string Write generated resources to files in the specified directory, one file per VPC. -o, --output-file string Write all generated resources to the specified file. - -p, --prefix string The prefix of the files that will be created. - -s, --spec string JSON file containing spec file ``` -**Note 1**: The infrastructure configuration must always be provided using the `--config` flag. -**Note 2**: Multi-vpc input is supported. +**Note**: The infrastructure configuration must always be provided using the `--config` flag. + +## Output +1. If the `output-dir` flag is used, the specified folder will be created, containing one file per VPC. Each generated file will contain the network resources (Security Groups or Network ACLs) relevant to its VPC. File names are set as `prefix_vpc`, where prefix is ​​the value received in the `prefix` flag. If the `prefix` flag is omitted, file names will match VPC names. +2. If the `output-file` flag is used, all generated resources will be written to the specified file. +3. if both `output-file` and `output-dir` flags are not used, the collection will be written to stdout. ## Build the project Make sure you have golang 1.23+ on your platform. diff --git a/cmd/subcmds/root.go b/cmd/subcmds/root.go index f84b958b..ddbfd979 100644 --- a/cmd/subcmds/root.go +++ b/cmd/subcmds/root.go @@ -17,6 +17,8 @@ const ( outputFmtFlag = "format" outputFileFlag = "output-file" localsFlag = "locals" + outputDirFlag = "output-dir" + prefixFlag = "prefix" ) type inArgs struct { @@ -48,7 +50,10 @@ func newRootCommand() *cobra.Command { rootCmd.PersistentFlags().StringVarP(&args.configFile, configFlag, "c", "", "JSON file containing a configuration object of existing resources") rootCmd.PersistentFlags().StringVarP(&args.outputFmt, outputFmtFlag, "f", "", "Output format; "+mustBeOneOf(outputFormats)) - rootCmd.PersistentFlags().StringVarP(&args.outputFile, outputFileFlag, "o", "", "Write all generated resources to the specified file.") + rootCmd.PersistentFlags().StringVarP(&args.outputFile, outputFileFlag, "o", "", "Write all generated resources to the specified file") + rootCmd.PersistentFlags().StringVarP(&args.outputDir, outputDirFlag, "d", "", + "Write generated resources to files in the specified directory, one file per VPC.") + rootCmd.PersistentFlags().StringVarP(&args.prefix, prefixFlag, "p", "", "The prefix of the files that will be created.") rootCmd.PersistentFlags().BoolVarP(&args.locals, localsFlag, "l", false, "whether to generate a locals.tf file (only possible when the output format is tf)") diff --git a/cmd/subcmds/synth.go b/cmd/subcmds/synth.go index aab12f66..491306c8 100644 --- a/cmd/subcmds/synth.go +++ b/cmd/subcmds/synth.go @@ -13,11 +13,7 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -const ( - specFlag = "spec" - outputDirFlag = "output-dir" - prefixFlag = "prefix" -) +const specFlag = "spec" func newSynthCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ @@ -29,9 +25,6 @@ func newSynthCommand(args *inArgs) *cobra.Command { // flags cmd.PersistentFlags().StringVarP(&args.specFile, specFlag, "s", "", "JSON file containing spec file") - cmd.PersistentFlags().StringVarP(&args.outputDir, outputDirFlag, "d", "", - "Write generated resources to files in the specified directory, one file per VPC.") - cmd.PersistentFlags().StringVarP(&args.prefix, prefixFlag, "p", "", "The prefix of the files that will be created.") // flags settings _ = cmd.MarkPersistentFlagRequired(specFlag) From bc8133fb9814aef45d2e8bcb2bb1db3f649a2ef1 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 17 Dec 2024 14:30:49 +0200 Subject: [PATCH 120/131] readme --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f4617bb1..c6b80a7b 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Flags: ## Optimization #### SG optimization +SG optimizatin attempts to reduce the number of security group rules in a SG without changing the semantic. Specifying the `-n` flag results in optimizing only one given SG. Otherwise, all SGs will be optimized. ``` Flags: @@ -39,6 +40,7 @@ Flags: ``` #### nACL optimization (in progress) +nACL optimizatin attempts to reduce the number of nACL rules in an nACL without changing the semantic. Specifying the `-n` flag results in optimizing only one given nACL. Otherwise, all nACLs will be optimized. ``` Flags: @@ -53,7 +55,9 @@ Flags: -f, --format string Output format; must be one of [tf, csv, md, json] -h, --help help for vpcgen -l, --locals whether to generate a locals.tf file (only possible when the output format is tf) - -o, --output-file string Write all generated resources to the specified file. + -d, --output-dir string Write generated resources to files in the specified directory, one file per VPC. + -o, --output-file string Write all generated resources to the specified file + -p, --prefix string The prefix of the files that will be created. ``` **Note**: The infrastructure configuration must always be provided using the `--config` flag. From d5edbe439ebfa753a3e67592c0a10cdfd27bc6c5 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Tue, 17 Dec 2024 15:02:00 +0200 Subject: [PATCH 121/131] minor change --- pkg/io/csvWriter.go | 5 +++-- pkg/io/mdWriter.go | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pkg/io/csvWriter.go b/pkg/io/csvWriter.go index 4c97b060..9a001286 100644 --- a/pkg/io/csvWriter.go +++ b/pkg/io/csvWriter.go @@ -8,6 +8,7 @@ package io import ( "encoding/csv" "io" + "slices" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) @@ -26,7 +27,7 @@ func (w *CSVWriter) WriteSG(collection *ir.SGCollection, vpc string) error { if err != nil { return err } - return w.w.WriteAll(append(SGHeader(), sgTable...)) + return w.w.WriteAll(slices.Concat(SGHeader(), sgTable)) } func (w *CSVWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { @@ -34,5 +35,5 @@ func (w *CSVWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { if err != nil { return err } - return w.w.WriteAll(append(ACLHeader(), aclTable...)) + return w.w.WriteAll(slices.Concat(ACLHeader(), aclTable)) } diff --git a/pkg/io/mdWriter.go b/pkg/io/mdWriter.go index cd1a5b8c..be47134e 100644 --- a/pkg/io/mdWriter.go +++ b/pkg/io/mdWriter.go @@ -8,6 +8,7 @@ package io import ( "bufio" "io" + "slices" "strings" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" @@ -35,7 +36,7 @@ func (w *MDWriter) WriteSG(collection *ir.SGCollection, vpc string) error { if err != nil { return err } - return w.writeAll(append(append(SGHeader(), addAligns(sgColsNum)), sgTable...)) + return w.writeAll(slices.Concat(SGHeader(), addAligns(sgColsNum), sgTable)) } func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { @@ -43,7 +44,7 @@ func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { if err != nil { return err } - return w.writeAll(append(append(ACLHeader(), addAligns(aclColsNum)), aclTable...)) + return w.writeAll(slices.Concat(ACLHeader(), addAligns(aclColsNum), aclTable)) } func (w *MDWriter) writeAll(rows [][]string) error { @@ -62,10 +63,10 @@ func (w *MDWriter) writeAll(rows [][]string) error { return nil } -func addAligns(n int) []string { +func addAligns(n int) [][]string { res := make([]string, n) for i := range n { res[i] = leftAlign } - return res + return [][]string{res} } From abad158ca7cff69714b818011b30154834c37fd0 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 18 Dec 2024 12:32:51 +0200 Subject: [PATCH 122/131] make fmt --- pkg/io/commonACL.go | 1 + pkg/io/commonSG.go | 1 + pkg/io/jsonio/unmarshalConns.go | 1 + pkg/io/jsonio/unmarshalDefinitions.go | 1 + 4 files changed, 4 insertions(+) diff --git a/pkg/io/commonACL.go b/pkg/io/commonACL.go index 12959280..5eb2878a 100644 --- a/pkg/io/commonACL.go +++ b/pkg/io/commonACL.go @@ -12,6 +12,7 @@ import ( "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) diff --git a/pkg/io/commonSG.go b/pkg/io/commonSG.go index d7ab5793..021f5a57 100644 --- a/pkg/io/commonSG.go +++ b/pkg/io/commonSG.go @@ -11,6 +11,7 @@ import ( "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) diff --git a/pkg/io/jsonio/unmarshalConns.go b/pkg/io/jsonio/unmarshalConns.go index c6fc06bc..7dcd002d 100644 --- a/pkg/io/jsonio/unmarshalConns.go +++ b/pkg/io/jsonio/unmarshalConns.go @@ -13,6 +13,7 @@ import ( "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/spec" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) diff --git a/pkg/io/jsonio/unmarshalDefinitions.go b/pkg/io/jsonio/unmarshalDefinitions.go index 20dae58d..b675c564 100644 --- a/pkg/io/jsonio/unmarshalDefinitions.go +++ b/pkg/io/jsonio/unmarshalDefinitions.go @@ -11,6 +11,7 @@ import ( "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) From 4ac6d7a7011e390bf6d77103c9d53a1cf43685f0 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 18 Dec 2024 12:35:22 +0200 Subject: [PATCH 123/131] slices.Concat --- pkg/ir/acl.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/ir/acl.go b/pkg/ir/acl.go index 9274c48e..5fd79c7e 100644 --- a/pkg/ir/acl.go +++ b/pkg/ir/acl.go @@ -8,6 +8,7 @@ package ir import ( "fmt" "reflect" + "slices" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" @@ -74,8 +75,7 @@ func (r *ACLRule) Target() *netset.IPBlock { func (a *ACL) Rules() []*ACLRule { rules := a.Internal if len(a.External) != 0 { - rules = append(rules, makeDenyInternal()...) - rules = append(rules, a.External...) + rules = slices.Concat(rules, makeDenyInternal(), a.External) } return rules } From 97def7abdf783eb9e0a71e9d5ca0348ae0b38f10 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 18 Dec 2024 13:04:45 +0200 Subject: [PATCH 124/131] minor changes --- pkg/io/commonACL.go | 3 ++- pkg/io/commonSG.go | 3 ++- pkg/io/tfio/acl.go | 16 ++++++---------- pkg/io/tfio/sg.go | 6 ++---- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/pkg/io/commonACL.go b/pkg/io/commonACL.go index 5eb2878a..4adfe77e 100644 --- a/pkg/io/commonACL.go +++ b/pkg/io/commonACL.go @@ -8,6 +8,7 @@ package io import ( "errors" "fmt" + "slices" "strconv" "github.com/np-guard/models/pkg/netp" @@ -24,7 +25,7 @@ func WriteACL(collection *ir.ACLCollection, vpc string) ([][]string, error) { if err != nil { return nil, err } - res = append(res, aclTable...) + res = slices.Concat(res, aclTable) } return res, nil } diff --git a/pkg/io/commonSG.go b/pkg/io/commonSG.go index 021f5a57..b2868225 100644 --- a/pkg/io/commonSG.go +++ b/pkg/io/commonSG.go @@ -8,6 +8,7 @@ package io import ( "errors" "fmt" + "slices" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" @@ -26,7 +27,7 @@ func WriteSG(collection *ir.SGCollection, vpc string) ([][]string, error) { if err != nil { return nil, err } - res = append(res, sgTable...) + res = slices.Concat(res, sgTable) } } return res, nil diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index bda9d019..bf316b5e 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -8,6 +8,7 @@ package tfio import ( "fmt" + "slices" "strings" "github.com/np-guard/models/pkg/netp" @@ -23,13 +24,11 @@ func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string, _ bool) error { if err != nil { return err } - output := collection.Print() - _, err = w.w.WriteString(output) + _, err = w.w.WriteString(collection.Print()) if err != nil { return err } - err = w.w.Flush() - return err + return w.w.Flush() } func aclCollection(t *ir.ACLCollection, vpc string) (*tf.ConfigFile, error) { @@ -37,9 +36,9 @@ func aclCollection(t *ir.ACLCollection, vpc string) (*tf.ConfigFile, error) { var acls = make([]tf.Block, len(sortedACLs)) i := 0 for _, subnet := range sortedACLs { - comment := "\n" vpcName := ir.VpcFromScopedResource(subnet) acl := t.ACLs[vpcName][subnet] + comment := "\n" if len(sortedACLs) > 1 { // not a single nacl comment = fmt.Sprintf("\n# %v [%v]", subnet, subnetCidr(acl)) } @@ -110,11 +109,8 @@ func aclProtocol(t netp.Protocol) []tf.Block { switch p := t.(type) { case netp.TCPUDP: return []tf.Block{{ - Name: strings.ToLower(string(p.ProtocolString())), - Arguments: append( - portRange(p.DstPorts(), "port"), - portRange(p.SrcPorts(), "source_port")..., - ), + Name: strings.ToLower(string(p.ProtocolString())), + Arguments: slices.Concat(portRange(p.DstPorts(), "port"), portRange(p.SrcPorts(), "source_port")), }} case netp.ICMP: return []tf.Block{{ diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index bec41c31..d3ea1007 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -23,13 +23,11 @@ func (w *Writer) WriteSG(c *ir.SGCollection, vpc string, _ bool) error { if err != nil { return err } - output := collection.Print() - _, err = w.w.WriteString(output) + _, err = w.w.WriteString(collection.Print()) if err != nil { return err } - err = w.w.Flush() - return err + return w.w.Flush() } func sgCollection(collection *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { From 9cef23a24859e382617ebc218086447af1f3d97d Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 18 Dec 2024 13:13:11 +0200 Subject: [PATCH 125/131] munir changes --- pkg/io/commonACL.go | 3 ++- pkg/io/commonSG.go | 3 ++- pkg/io/jsonio/unmarshalConns.go | 3 ++- pkg/io/tfio/acl.go | 17 ++++++----------- pkg/io/tfio/sg.go | 7 ++----- pkg/ir/sg.go | 3 ++- pkg/ir/spec.go | 5 +++-- pkg/optimize/sg/sg.go | 2 +- pkg/synth/sg.go | 4 +++- pkg/utils/utils.go | 2 +- 10 files changed, 24 insertions(+), 25 deletions(-) diff --git a/pkg/io/commonACL.go b/pkg/io/commonACL.go index 5eb2878a..4adfe77e 100644 --- a/pkg/io/commonACL.go +++ b/pkg/io/commonACL.go @@ -8,6 +8,7 @@ package io import ( "errors" "fmt" + "slices" "strconv" "github.com/np-guard/models/pkg/netp" @@ -24,7 +25,7 @@ func WriteACL(collection *ir.ACLCollection, vpc string) ([][]string, error) { if err != nil { return nil, err } - res = append(res, aclTable...) + res = slices.Concat(res, aclTable) } return res, nil } diff --git a/pkg/io/commonSG.go b/pkg/io/commonSG.go index 021f5a57..b2868225 100644 --- a/pkg/io/commonSG.go +++ b/pkg/io/commonSG.go @@ -8,6 +8,7 @@ package io import ( "errors" "fmt" + "slices" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" @@ -26,7 +27,7 @@ func WriteSG(collection *ir.SGCollection, vpc string) ([][]string, error) { if err != nil { return nil, err } - res = append(res, sgTable...) + res = slices.Concat(res, sgTable) } } return res, nil diff --git a/pkg/io/jsonio/unmarshalConns.go b/pkg/io/jsonio/unmarshalConns.go index 7dcd002d..8f4a5145 100644 --- a/pkg/io/jsonio/unmarshalConns.go +++ b/pkg/io/jsonio/unmarshalConns.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "log" + "slices" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/spec" @@ -26,7 +27,7 @@ func (r *Reader) translateConnections(conns []spec.SpecRequiredConnectionsElem, if err != nil { return nil, err } - res = append(res, connections...) + res = slices.Concat(res, connections) } return res, nil } diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index 93fce635..2bbde487 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -8,6 +8,7 @@ package tfio import ( "fmt" + "slices" "strings" "github.com/np-guard/models/pkg/netp" @@ -23,13 +24,10 @@ func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string) error { if err != nil { return err } - output := collection.Print() - _, err = w.w.WriteString(output) - if err != nil { + if _, err := w.w.WriteString(collection.Print()); err != nil { return err } - err = w.w.Flush() - return err + return w.w.Flush() } func aclCollection(t *ir.ACLCollection, vpc string) (*tf.ConfigFile, error) { @@ -37,9 +35,9 @@ func aclCollection(t *ir.ACLCollection, vpc string) (*tf.ConfigFile, error) { var acls = make([]tf.Block, len(sortedACLs)) i := 0 for _, subnet := range sortedACLs { - comment := "\n" vpcName := ir.VpcFromScopedResource(subnet) acl := t.ACLs[vpcName][subnet] + comment := "\n" if len(sortedACLs) > 1 { // not a single nacl comment = fmt.Sprintf("\n# %v [%v]", subnet, subnetCidr(acl)) } @@ -110,11 +108,8 @@ func aclProtocol(t netp.Protocol) []tf.Block { switch p := t.(type) { case netp.TCPUDP: return []tf.Block{{ - Name: strings.ToLower(string(p.ProtocolString())), - Arguments: append( - portRange(p.DstPorts(), "port"), - portRange(p.SrcPorts(), "source_port")..., - ), + Name: strings.ToLower(string(p.ProtocolString())), + Arguments: slices.Concat(portRange(p.DstPorts(), "port"), portRange(p.SrcPorts(), "source_port")), }} case netp.ICMP: return []tf.Block{{ diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index 2d027f01..e710dc46 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -23,13 +23,10 @@ func (w *Writer) WriteSG(c *ir.SGCollection, vpc string) error { if err != nil { return err } - output := collection.Print() - _, err = w.w.WriteString(output) - if err != nil { + if _, err := w.w.WriteString(collection.Print()); err != nil { return err } - err = w.w.Flush() - return err + return w.w.Flush() } func sgCollection(collection *ir.SGCollection, vpc string) (*tf.ConfigFile, error) { diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 3b877809..7cb6242c 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -8,6 +8,7 @@ package ir import ( "fmt" "reflect" + "slices" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" @@ -104,7 +105,7 @@ func (a *SG) Add(rule *SGRule) { } func (a *SG) AllRules() []*SGRule { - return append(a.InboundRules, a.OutboundRules...) + return slices.Concat(a.InboundRules, a.OutboundRules) } func (c *SGCollection) VpcNames() []string { diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index ca70b0fd..a8a723e5 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -8,6 +8,7 @@ package ir import ( "fmt" + "slices" "strings" "github.com/np-guard/models/pkg/netp" @@ -312,8 +313,8 @@ func (s *Definitions) lookupSegment(segment map[ID]*SegmentDetails, name string, if err != nil { return nil, err } - res.CidrsWhenLocal = append(res.CidrsWhenLocal, element.CidrsWhenLocal...) - res.CidrsWhenRemote = append(res.CidrsWhenRemote, element.CidrsWhenRemote...) + res.CidrsWhenLocal = slices.Concat(res.CidrsWhenLocal, element.CidrsWhenLocal) + res.CidrsWhenRemote = slices.Concat(res.CidrsWhenRemote, element.CidrsWhenRemote) } segmentDetails.ConnectedResource = res return res, nil diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index dc49400c..fed45079 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -135,7 +135,7 @@ func (s *sgOptimizer) reduceSGRules(rules []*ir.SGRule, direction ir.Direction) optimizedRulesToIPAddrs = originalRulesToIPAddrs } - return append(optimizedRulesToSG, optimizedRulesToIPAddrs...) + return slices.Concat(optimizedRulesToSG, optimizedRulesToIPAddrs) } func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*ir.SGRule { diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 0caec383..54190b1a 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -6,6 +6,8 @@ SPDX-License-Identifier: Apache-2.0 package synth import ( + "slices" + "github.com/np-guard/models/pkg/netp" "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" @@ -98,7 +100,7 @@ func isSGRemote(t ir.ResourceType) bool { // generate SGs for blocked endpoints (endpoints that do not appear in Spec) func (s *SGSynthesizer) generateSGsForBlockedResources() string { - blockedResources := append(utils.TrueKeyValues(s.spec.BlockedInstances), utils.TrueKeyValues(s.spec.BlockedVPEs)...) + blockedResources := slices.Concat(utils.TrueKeyValues(s.spec.BlockedInstances), utils.TrueKeyValues(s.spec.BlockedVPEs)) for _, resource := range blockedResources { sg := s.result.LookupOrCreate(ir.SGName(resource)) // an empty SG allows no connections sg.Attached = []ir.ID{resource} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index e5f14e28..d919189c 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -26,7 +26,7 @@ func SortedMapKeys[T cmp.Ordered, V any](m map[T]V) []T { func SortedAllInnerMapsKeys[T, K cmp.Ordered, V any](m map[K]map[T]V) []T { keys := make([]T, 0) for _, vpc := range m { - keys = append(keys, MapKeys(vpc)...) + keys = slices.Concat(keys, MapKeys(vpc)) } slices.Sort(keys) return keys From 4018372ffc58bf50dad55aacac060daaea153085 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 18 Dec 2024 13:44:30 +0200 Subject: [PATCH 126/131] merge --- pkg/io/jsonio/unmarshalConns.go | 3 ++- pkg/io/tfio/acl.go | 3 +-- pkg/io/tfio/sg.go | 3 +-- pkg/ir/spec.go | 5 +++-- pkg/optimize/sg/sg.go | 2 +- pkg/synth/sg.go | 4 +++- pkg/utils/utils.go | 2 +- 7 files changed, 12 insertions(+), 10 deletions(-) diff --git a/pkg/io/jsonio/unmarshalConns.go b/pkg/io/jsonio/unmarshalConns.go index 7dcd002d..8f4a5145 100644 --- a/pkg/io/jsonio/unmarshalConns.go +++ b/pkg/io/jsonio/unmarshalConns.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "log" + "slices" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/spec" @@ -26,7 +27,7 @@ func (r *Reader) translateConnections(conns []spec.SpecRequiredConnectionsElem, if err != nil { return nil, err } - res = append(res, connections...) + res = slices.Concat(res, connections) } return res, nil } diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index bf316b5e..dffe4c55 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -24,8 +24,7 @@ func (w *Writer) WriteACL(c *ir.ACLCollection, vpc string, _ bool) error { if err != nil { return err } - _, err = w.w.WriteString(collection.Print()) - if err != nil { + if _, err := w.w.WriteString(collection.Print()); err != nil { return err } return w.w.Flush() diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index d3ea1007..c008ef5d 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -23,8 +23,7 @@ func (w *Writer) WriteSG(c *ir.SGCollection, vpc string, _ bool) error { if err != nil { return err } - _, err = w.w.WriteString(collection.Print()) - if err != nil { + if _, err := w.w.WriteString(collection.Print()); err != nil { return err } return w.w.Flush() diff --git a/pkg/ir/spec.go b/pkg/ir/spec.go index ca70b0fd..a8a723e5 100644 --- a/pkg/ir/spec.go +++ b/pkg/ir/spec.go @@ -8,6 +8,7 @@ package ir import ( "fmt" + "slices" "strings" "github.com/np-guard/models/pkg/netp" @@ -312,8 +313,8 @@ func (s *Definitions) lookupSegment(segment map[ID]*SegmentDetails, name string, if err != nil { return nil, err } - res.CidrsWhenLocal = append(res.CidrsWhenLocal, element.CidrsWhenLocal...) - res.CidrsWhenRemote = append(res.CidrsWhenRemote, element.CidrsWhenRemote...) + res.CidrsWhenLocal = slices.Concat(res.CidrsWhenLocal, element.CidrsWhenLocal) + res.CidrsWhenRemote = slices.Concat(res.CidrsWhenRemote, element.CidrsWhenRemote) } segmentDetails.ConnectedResource = res return res, nil diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go index fdf6ba90..06feaacc 100644 --- a/pkg/optimize/sg/sg.go +++ b/pkg/optimize/sg/sg.go @@ -141,7 +141,7 @@ func (s *sgOptimizer) reduceSGRules(rules []*ir.SGRule, direction ir.Direction, optimizedRulesToIPAddrs = originalRulesToIPAddrs } - return append(optimizedRulesToSG, optimizedRulesToIPAddrs...) + return slices.Concat(optimizedRulesToSG, optimizedRulesToIPAddrs) } func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction, l *netset.IPBlock) []*ir.SGRule { diff --git a/pkg/synth/sg.go b/pkg/synth/sg.go index 388c4eb6..7bf1262c 100644 --- a/pkg/synth/sg.go +++ b/pkg/synth/sg.go @@ -6,6 +6,8 @@ SPDX-License-Identifier: Apache-2.0 package synth import ( + "slices" + "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" @@ -93,7 +95,7 @@ func isSGRemote(t ir.ResourceType) bool { // generate SGs for blocked endpoints (endpoints that do not appear in Spec) func (s *SGSynthesizer) generateSGsForBlockedResources() string { - blockedResources := append(utils.TrueKeyValues(s.spec.BlockedInstances), utils.TrueKeyValues(s.spec.BlockedVPEs)...) + blockedResources := slices.Concat(utils.TrueKeyValues(s.spec.BlockedInstances), utils.TrueKeyValues(s.spec.BlockedVPEs)) for _, resource := range blockedResources { sg := s.result.LookupOrCreate(ir.SGName(resource)) // an empty SG allows no connections sg.Targets = []ir.ID{resource} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index e5f14e28..d919189c 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -26,7 +26,7 @@ func SortedMapKeys[T cmp.Ordered, V any](m map[T]V) []T { func SortedAllInnerMapsKeys[T, K cmp.Ordered, V any](m map[K]map[T]V) []T { keys := make([]T, 0) for _, vpc := range m { - keys = append(keys, MapKeys(vpc)...) + keys = slices.Concat(keys, MapKeys(vpc)) } slices.Sort(keys) return keys From 92d379b98c1abf42a19d3cb4a25491330187eda6 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 18 Dec 2024 13:51:57 +0200 Subject: [PATCH 127/131] minor change --- pkg/ir/sg.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/ir/sg.go b/pkg/ir/sg.go index 254b4ae7..3f9fa27d 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -8,6 +8,7 @@ package ir import ( "fmt" "reflect" + "slices" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/models/pkg/netset" @@ -77,7 +78,6 @@ func NewSG(sgName SGName) *SG { return &SG{SGName: sgName, InboundRules: make(map[string][]*SGRule), OutboundRules: make(map[string][]*SGRule), - Targets: []ID{}, } } @@ -112,10 +112,10 @@ func (a *SG) Add(rule *SGRule) { func (a *SG) AllRules() []*SGRule { res := make([]*SGRule, 0) for _, key := range utils.SortedMapKeys(a.InboundRules) { - res = append(res, a.InboundRules[key]...) + res = slices.Concat(res, a.InboundRules[key]) } for _, key := range utils.SortedMapKeys(a.OutboundRules) { - res = append(res, a.OutboundRules[key]...) + res = slices.Concat(res, a.OutboundRules[key]) } return res } From 927d85b1e232ffdb3e231ac56778178a9e2cc04c Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 18 Dec 2024 14:20:19 +0200 Subject: [PATCH 128/131] fix --- pkg/io/common.go | 2 +- pkg/io/commonACL.go | 2 +- pkg/io/commonSG.go | 2 +- pkg/io/csvWriter.go | 4 ++-- pkg/io/mdWriter.go | 21 +++++++-------------- pkg/io/tfio/acl.go | 6 +++--- pkg/io/tfio/common.go | 5 +++++ pkg/io/tfio/sg.go | 4 ++-- 8 files changed, 22 insertions(+), 24 deletions(-) diff --git a/pkg/io/common.go b/pkg/io/common.go index 4e4f9e33..1a0eb695 100644 --- a/pkg/io/common.go +++ b/pkg/io/common.go @@ -32,7 +32,7 @@ func direction(d ir.Direction) string { func printProtocolName(protocol netp.Protocol) string { switch p := protocol.(type) { case netp.ICMP: - return "ICMP" + return string(netp.ProtocolStringICMP) case netp.TCPUDP: return strings.ToUpper(string(p.ProtocolString())) case netp.AnyProtocol: diff --git a/pkg/io/commonACL.go b/pkg/io/commonACL.go index 4adfe77e..865e3251 100644 --- a/pkg/io/commonACL.go +++ b/pkg/io/commonACL.go @@ -30,7 +30,7 @@ func WriteACL(collection *ir.ACLCollection, vpc string) ([][]string, error) { return res, nil } -func ACLHeader() [][]string { +func makeACLHeader() [][]string { return [][]string{{ "Acl", "Subnet", diff --git a/pkg/io/commonSG.go b/pkg/io/commonSG.go index b2868225..3a05a5ec 100644 --- a/pkg/io/commonSG.go +++ b/pkg/io/commonSG.go @@ -33,7 +33,7 @@ func WriteSG(collection *ir.SGCollection, vpc string) ([][]string, error) { return res, nil } -func SGHeader() [][]string { +func makeSGHeader() [][]string { return [][]string{{ "SG", "Direction", diff --git a/pkg/io/csvWriter.go b/pkg/io/csvWriter.go index 9a001286..4a31e67a 100644 --- a/pkg/io/csvWriter.go +++ b/pkg/io/csvWriter.go @@ -27,7 +27,7 @@ func (w *CSVWriter) WriteSG(collection *ir.SGCollection, vpc string) error { if err != nil { return err } - return w.w.WriteAll(slices.Concat(SGHeader(), sgTable)) + return w.w.WriteAll(slices.Concat(makeSGHeader(), sgTable)) } func (w *CSVWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { @@ -35,5 +35,5 @@ func (w *CSVWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { if err != nil { return err } - return w.w.WriteAll(slices.Concat(ACLHeader(), aclTable)) + return w.w.WriteAll(slices.Concat(makeACLHeader(), aclTable)) } diff --git a/pkg/io/mdWriter.go b/pkg/io/mdWriter.go index be47134e..3b102b49 100644 --- a/pkg/io/mdWriter.go +++ b/pkg/io/mdWriter.go @@ -15,9 +15,6 @@ import ( ) const ( - sgColsNum = 7 - aclColsNum = 10 - leftAlign = " :--- " separator = " | " ) @@ -36,7 +33,8 @@ func (w *MDWriter) WriteSG(collection *ir.SGCollection, vpc string) error { if err != nil { return err } - return w.writeAll(slices.Concat(SGHeader(), addAligns(sgColsNum), sgTable)) + sgHeader := makeSGHeader() + return w.writeAll(slices.Concat(sgHeader, addAligns(len(sgHeader[0])), sgTable)) } func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { @@ -44,23 +42,18 @@ func (w *MDWriter) WriteACL(collection *ir.ACLCollection, vpc string) error { if err != nil { return err } - return w.writeAll(slices.Concat(ACLHeader(), addAligns(aclColsNum), aclTable)) + aclHeader := makeACLHeader() + return w.writeAll(slices.Concat(aclHeader, addAligns(len(aclHeader[0])), aclTable)) } func (w *MDWriter) writeAll(rows [][]string) error { for _, row := range rows { - if _, err := w.w.WriteString(separator); err != nil { - return err - } - if _, err := w.w.WriteString(strings.Join(row, separator)); err != nil { - return err - } - if _, err := w.w.WriteString(separator + "\n"); err != nil { + finalString := separator + strings.Join(row, separator) + separator + "\n" + if _, err := w.w.WriteString(finalString); err != nil { return err } } - w.w.Flush() - return nil + return w.w.Flush() } func addAligns(n int) [][]string { diff --git a/pkg/io/tfio/acl.go b/pkg/io/tfio/acl.go index 2bbde487..90a1fdfe 100644 --- a/pkg/io/tfio/acl.go +++ b/pkg/io/tfio/acl.go @@ -69,10 +69,10 @@ func singleACL(t *ir.ACL, comment string) (tf.Block, error) { } return tf.Block{ Comment: comment, - Name: "resource", + Name: resourceConst, Labels: []string{quote("ibm_is_network_acl"), quote(aclName)}, Arguments: []tf.Argument{ - {Name: "name", Value: quote(aclName)}, + {Name: nameConst, Value: quote(aclName)}, {Name: "resource_group", Value: "local.acl_synth_resource_group_id"}, {Name: "vpc", Value: fmt.Sprintf("local.acl_synth_%s_id", ir.VpcFromScopedResource(t.Subnet))}, }, @@ -85,7 +85,7 @@ func aclRule(rule *ir.ACLRule, name string) (tf.Block, error) { return tf.Block{}, err } arguments := []tf.Argument{ - {Name: "name", Value: quote(name)}, //nolint:revive // obvious false positive + {Name: nameConst, Value: quote(name)}, {Name: "action", Value: quote(action(rule.Action))}, {Name: "direction", Value: quote(direction(rule.Direction))}, {Name: "source", Value: quote(rule.Source.String())}, diff --git a/pkg/io/tfio/common.go b/pkg/io/tfio/common.go index 96611c65..2cfe0057 100644 --- a/pkg/io/tfio/common.go +++ b/pkg/io/tfio/common.go @@ -20,6 +20,11 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" ) +const ( + resourceConst = "resource" + nameConst = "name" +) + // Writer implements ir.Writer type Writer struct { w *bufio.Writer diff --git a/pkg/io/tfio/sg.go b/pkg/io/tfio/sg.go index e710dc46..e41fd9d0 100644 --- a/pkg/io/tfio/sg.go +++ b/pkg/io/tfio/sg.go @@ -71,7 +71,7 @@ func sg(sgName, vpcName string) (tf.Block, error) { Labels: []string{quote("ibm_is_security_group"), quote(tfSGName)}, Comment: comment, Arguments: []tf.Argument{ - {Name: "name", Value: quote("sg-" + tfSGName)}, + {Name: nameConst, Value: quote("sg-" + tfSGName)}, {Name: "resource_group", Value: "local.sg_synth_resource_group_id"}, {Name: "vpc", Value: fmt.Sprintf("local.sg_synth_%s_id", vpcName)}, }, @@ -96,7 +96,7 @@ func sgRule(rule *ir.SGRule, sgName ir.SGName, i int) (tf.Block, error) { } return tf.Block{ - Name: "resource", //nolint:revive // obvious false positive + Name: resourceConst, Labels: []string{quote("ibm_is_security_group_rule"), ir.ChangeScoping(quote(ruleName))}, Comment: comment, Arguments: []tf.Argument{ From e6f45cd39121d4b9c87959f5cac9d94dff38722d Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 18 Dec 2024 14:55:36 +0200 Subject: [PATCH 129/131] typo --- pkg/io/confio/parse_sgs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index 2931b627..31d7c9bf 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -45,7 +45,7 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { SGName: sgName, InboundRules: inbound, OutboundRules: outbound, - Targets: transalteTargets(&sg.SecurityGroup), + Targets: transalateTargets(&sg.SecurityGroup), } } return result, nil @@ -154,7 +154,7 @@ func translateLocal(local vpcv1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, er } // translate SG targets -func transalteTargets(sg *vpcv1.SecurityGroup) []string { +func transalateTargets(sg *vpcv1.SecurityGroup) []string { if len(sg.Targets) == 0 { log.Printf("Warning: Security Groups %s does not have attached resources", *sg.Name) } From 2ddde89484c68a4d87ed74d127eae49bb3f24585 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Wed, 18 Dec 2024 14:58:20 +0200 Subject: [PATCH 130/131] another typo --- pkg/io/confio/parse_sgs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index 31d7c9bf..9d06f7b5 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -45,7 +45,7 @@ func ReadSGs(filename string) (*ir.SGCollection, error) { SGName: sgName, InboundRules: inbound, OutboundRules: outbound, - Targets: transalateTargets(&sg.SecurityGroup), + Targets: translateTargets(&sg.SecurityGroup), } } return result, nil @@ -154,7 +154,7 @@ func translateLocal(local vpcv1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, er } // translate SG targets -func transalateTargets(sg *vpcv1.SecurityGroup) []string { +func translateTargets(sg *vpcv1.SecurityGroup) []string { if len(sg.Targets) == 0 { log.Printf("Warning: Security Groups %s does not have attached resources", *sg.Name) } From 9b275788a4530fdf28b5858046d4f0a996dbc3a2 Mon Sep 17 00:00:00 2001 From: Yair Slobodin Date: Thu, 19 Dec 2024 10:36:05 +0200 Subject: [PATCH 131/131] src ports --- pkg/io/confio/parse_acls.go | 3 ++- pkg/io/confio/parse_sgs.go | 12 +++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pkg/io/confio/parse_acls.go b/pkg/io/confio/parse_acls.go index 09647519..567fbc00 100644 --- a/pkg/io/confio/parse_acls.go +++ b/pkg/io/confio/parse_acls.go @@ -94,7 +94,8 @@ func translateACLRuleProtocolTCPUDP(rule *vpcv1.NetworkACLRuleItemNetworkACLRule direction, err2 := translateDirection(*rule.Direction) src, err3 := translateResource(rule.Source) dst, err4 := translateResource(rule.Destination) - protocol, err5 := translateProtocolTCPUDP(*rule.Protocol, rule.DestinationPortMin, rule.DestinationPortMax) + protocol, err5 := translateProtocolTCPUDP(*rule.Protocol, rule.SourcePortMin, rule.SourcePortMax, + rule.DestinationPortMin, rule.DestinationPortMax) if err := errors.Join(err1, err2, err3, err4, err5); err != nil { return nil, err } diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go index dd325772..25904ca9 100644 --- a/pkg/io/confio/parse_sgs.go +++ b/pkg/io/confio/parse_sgs.go @@ -97,7 +97,7 @@ func translateSGRuleProtocolTCPUDP(rule *vpcv1.SecurityGroupRuleSecurityGroupRul direction, err1 := translateDirection(*rule.Direction) remote, err2 := translateRemote(rule.Remote) local, err3 := translateLocal(rule.Local) - protocol, err4 := translateProtocolTCPUDP(*rule.Protocol, rule.PortMin, rule.PortMax) + protocol, err4 := translateProtocolTCPUDP(*rule.Protocol, nil, nil, rule.PortMin, rule.PortMax) if err := errors.Join(err1, err2, err3, err4); err != nil { return nil, err } @@ -166,9 +166,11 @@ func translateTargets(sg *vpcv1.SecurityGroup) []string { return res } -func translateProtocolTCPUDP(protocolName string, portMin, portMax *int64) (netp.Protocol, error) { +func translateProtocolTCPUDP(protocolName string, srcPortMin, srcPortMax, dstPortMin, dstPortMax *int64) (netp.Protocol, error) { isTCP := protocolName == vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudpProtocolTCPConst - minDstPort := utils.GetProperty(portMin, netp.MinPort) - maxDstPort := utils.GetProperty(portMax, netp.MaxPort) - return netp.NewTCPUDP(isTCP, netp.MinPort, netp.MaxPort, int(minDstPort), int(maxDstPort)) + minSrcPort := utils.GetProperty(srcPortMin, netp.MinPort) + maxSrcPort := utils.GetProperty(srcPortMax, netp.MaxPort) + minDstPort := utils.GetProperty(dstPortMin, netp.MinPort) + maxDstPort := utils.GetProperty(dstPortMax, netp.MaxPort) + return netp.NewTCPUDP(isTCP, int(minSrcPort), int(maxSrcPort), int(minDstPort), int(maxDstPort)) }