diff --git a/README.md b/README.md index aba49ca9..c814ce26 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,69 @@ # 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: + -s, --spec string JSON file containing spec file +``` + +## 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: + -n, --sg-name string which security group to optimize +``` -### Global options +#### 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: + -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. + -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. @@ -60,6 +84,8 @@ make build bin/vpcgen synth acl -c test/data/acl_testing5/config_object.json -s test/data/acl_testing5/conn_spec.json bin/vpcgen synth sg -c test/data/sg_testing3/config_object.json -s test/data/sg_testing3/conn_spec.json + +bin/vpcgen optimize sg -c test/data/optimize_sg_redundant/config_object.json ``` **Note**: Windows environment users should replace all `/` with `\`. \ No newline at end of file diff --git a/cmd/subcmds/optimize.go b/cmd/subcmds/optimize.go index c3d9da24..447be8ee 100644 --- a/cmd/subcmds/optimize.go +++ b/cmd/subcmds/optimize.go @@ -5,17 +5,38 @@ SPDX-License-Identifier: Apache-2.0 package subcmds -import "github.com/spf13/cobra" +import ( + "fmt" -func NewOptimizeCommand(args *inArgs) *cobra.Command { + "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{ 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)) + // 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/optimizeACL.go b/cmd/subcmds/optimizeACL.go index d6bd46ea..60327bd2 100644 --- a/cmd/subcmds/optimizeACL.go +++ b/cmd/subcmds/optimizeACL.go @@ -7,7 +7,8 @@ package subcmds import "github.com/spf13/cobra" -func newOptimizeACLCommand(_ *inArgs) *cobra.Command { +// temporarily exported and currently unused +func NewOptimizeACLCommand(_ *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "acl", Short: "OptimizeACL is not supported yet", @@ -17,6 +18,5 @@ func newOptimizeACLCommand(_ *inArgs) *cobra.Command { return nil }, } - return cmd } diff --git a/cmd/subcmds/optimizeSG.go b/cmd/subcmds/optimizeSG.go index 4f2a80fd..94e27389 100644 --- a/cmd/subcmds/optimizeSG.go +++ b/cmd/subcmds/optimizeSG.go @@ -5,18 +5,27 @@ SPDX-License-Identifier: Apache-2.0 package subcmds -import "github.com/spf13/cobra" +import ( + "github.com/spf13/cobra" -func newOptimizeSGCommand(_ *inArgs) *cobra.Command { + sgoptimizer "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize/sg" +) + +const sgNameFlag = "sg-name" + +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 + return optimization(cmd, args, sgoptimizer.NewSGOptimizer, true) }, } + // flags + cmd.PersistentFlags().StringVarP(&args.firewallName, sgNameFlag, "n", "", "which security group to optimize") + return cmd } diff --git a/cmd/subcmds/output.go b/cmd/subcmds/output.go index aa817b7e..339b06b1 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,34 +80,41 @@ 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 } 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/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 a0074d1e..ddbfd979 100644 --- a/cmd/subcmds/root.go +++ b/cmd/subcmds/root.go @@ -14,54 +14,62 @@ import ( const ( configFlag = "config" - specFlag = "spec" outputFmtFlag = "format" outputFileFlag = "output-file" + localsFlag = "locals" outputDirFlag = "output-dir" prefixFlag = "prefix" - singleACLFlag = "single" - localsFlag = "locals" ) type inArgs struct { - configFile string - specFile string - outputFmt string - outputFile string - outputDir string - prefix 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{} + cobra.EnableTraverseRunHooks = true // allow PersistentPreRunE 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.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) - rootCmd.AddCommand(NewSynthCommand(args)) - // Todo: add optimize command + // sub cmds + rootCmd.AddCommand(newSynthCommand(args)) + rootCmd.AddCommand(newOptimizeCommand(args)) + + // prevent Cobra from creating a default 'completion' command + rootCmd.CompletionOptions.DisableDefaultCmd = true - rootCmd.CompletionOptions.HiddenDefaultCmd = true - rootCmd.SetHelpCommand(&cobra.Command{Hidden: true}) // disable help command. should use --help flag instead + // 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 506d9ff6..491306c8 100644 --- a/cmd/subcmds/synth.go +++ b/cmd/subcmds/synth.go @@ -13,7 +13,9 @@ import ( "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" ) -func NewSynthCommand(args *inArgs) *cobra.Command { +const specFlag = "spec" + +func newSynthCommand(args *inArgs) *cobra.Command { cmd := &cobra.Command{ Use: "synth", Short: "generate a SG/nACL collection", @@ -21,9 +23,13 @@ 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") + + // flags settings _ = cmd.MarkPersistentFlagRequired(specFlag) + // subcmds cmd.AddCommand(newSynthACLCommand(args)) cmd.AddCommand(newSynthSGCommand(args)) @@ -39,5 +45,5 @@ func synthesis(cmd *cobra.Command, args *inArgs, newSynthesizer func(*ir.Spec, b synthesizer := newSynthesizer(spec, singleacl) collection, warning := synthesizer.Synth() cmd.Print(warning) - 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 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/cmd/subcmds/unmarshal.go b/cmd/subcmds/unmarshal.go index c1321f97..62780810 100644 --- a/cmd/subcmds/unmarshal.go +++ b/cmd/subcmds/unmarshal.go @@ -26,3 +26,10 @@ func unmarshal(args *inArgs, isSG bool) (*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/go.mod b/go.mod index eff546f4..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.2 + github.com/np-guard/models v0.5.3 github.com/spf13/cobra v1.8.1 ) diff --git a/go.sum b/go.sum index 9e08ccd1..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.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 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/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/confio/parse_defs.go b/pkg/io/confio/parse_defs.go index 8e94750d..0d250e32 100644 --- a/pkg/io/confio/parse_defs.go +++ b/pkg/io/confio/parse_defs.go @@ -46,7 +46,7 @@ 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)) + res := make(map[ir.ID]*ir.VPCDetails, len(config.VpcList)) for _, vpc := range config.VpcList { addressPrefixes := netset.NewIPBlock() for _, addressPrefix := range vpc.AddressPrefixes { @@ -56,9 +56,9 @@ func parseVPCs(config *configModel.ResourcesContainerModel) (map[ir.ID]*ir.VPCDe } addressPrefixes = addressPrefixes.Union(address) } - VPCs[*vpc.Name] = &ir.VPCDetails{AddressPrefixes: addressPrefixes} + res[*vpc.Name] = &ir.VPCDetails{AddressPrefixes: addressPrefixes} } - return VPCs, nil + return res, nil } func parseSubnets(config *configModel.ResourcesContainerModel) (map[ir.ID]*ir.SubnetDetails, error) { @@ -148,6 +148,9 @@ func parseVPEs(config *configModel.ResourcesContainerModel) (vpes map[ir.ID]*ir. } func validateVpcs(vpcs map[ir.ID]*ir.VPCDetails) error { + if vpcs == nil { + return nil + } for vpcName1, vpcDetails1 := range vpcs { for vpcName2, vpcDetails2 := range vpcs { if vpcName1 >= vpcName2 { diff --git a/pkg/io/confio/parse_sgs.go b/pkg/io/confio/parse_sgs.go new file mode 100644 index 00000000..6285e8ee --- /dev/null +++ b/pkg/io/confio/parse_sgs.go @@ -0,0 +1,164 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package confio + +import ( + "errors" + "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) { + 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 + } + 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][sgName] = &ir.SG{SGName: sgName, 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, 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, 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, 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 +} + +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/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/jsonio/unmarshalDefinitions.go b/pkg/io/jsonio/unmarshalDefinitions.go index 40c90ab2..20dae58d 100644 --- a/pkg/io/jsonio/unmarshalDefinitions.go +++ b/pkg/io/jsonio/unmarshalDefinitions.go @@ -78,7 +78,6 @@ func parseCidrSegments(cidrSegments map[string][]string, configDefs *ir.ConfigDe result := make(map[ir.ID]*ir.CidrSegmentDetails) for segmentName, segment := range cidrSegments { cidrs := netset.NewIPBlock() - for _, cidr := range segment { c, err := netset.IPBlockFromCidr(cidr) if err != 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..d71b8d56 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 := "\n" + 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 @@ -103,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 747be97d..dafcaa6d 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 { // optimization mode + comment = "\n" + } + 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 86c34171..9274c48e 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) { @@ -120,6 +122,10 @@ func (c *ACLCollection) LookupOrCreate(name string) *ACL { return c.ACLs[vpcName][name] } +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 a8864141..3b877809 100644 --- a/pkg/ir/sg.go +++ b/pkg/ir/sg.go @@ -10,40 +10,45 @@ 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" ) -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 - 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 { @@ -63,8 +68,13 @@ func (r *SGRule) mustSupersede(other *SGRule) bool { return res } -func NewSG() *SG { - return &SG{InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Attached: []ID{}} +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(sgName SGName) *SG { + return &SG{SGName: sgName, InboundRules: []*SGRule{}, OutboundRules: []*SGRule{}, Attached: []ID{}} } func NewSGCollection() *SGCollection { @@ -76,7 +86,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) } @@ -97,6 +107,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..70b3be01 --- /dev/null +++ b/pkg/optimize/common.go @@ -0,0 +1,74 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package optimize + +import ( + "slices" + + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" +) + +type Optimizer interface { + // attempts to reduce number of SG/nACL rules + Optimize() (ir.Collection, error) +} + +// 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 ds.Pair[*netset.IPBlock, T]) int { + return i.Left.Compare(j.Left) + } + 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 { + 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() { + 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) +} + +func IsAllPorts(tcpudpPorts *netset.PortSet) bool { + return tcpudpPorts.Equal(netset.AllPorts()) +} diff --git a/pkg/optimize/sg/ipCubesToRules.go b/pkg/optimize/sg/ipCubesToRules.go new file mode 100644 index 00000000..1e46873c --- /dev/null +++ b/pkg/optimize/sg/ipCubesToRules.go @@ -0,0 +1,147 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +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" + "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" +) + +// any protocol IP-segments, 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(), "")) + } + return result +} + +// tcpudpIPCubesToRules converts cubes representing tcp or udp protocol rules to SG rules +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{} + } + + res := make([]*ir.SGRule, 0) + activeRules := make(map[*netset.IPBlock]netp.Protocol) // the key is the first IP + + 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], anyProtocolCubes) { + res = slices.Concat(res, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)) + activeRules = make(map[*netset.IPBlock]netp.Protocol) + } + + // 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 startIP, protocol := range activeRules { + tcpudp, _ := protocol.(netp.TCPUDP) // already checked + if !tcpudp.DstPorts().ToSet().IsSubset(cubes[i].Right) { + res = slices.Concat(res, createNewRules(protocol, startIP, cubes[i-1].Left.LastIPAddressObject(), direction)) + delete(activeRules, startIP) + } else { + activePorts.AddInterval(tcpudp.DstPorts()) + } + } + + // 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())) + activeRules[cubes[i].Left.FirstIPAddressObject()] = p + } + } + } + // generate all existing rules + return slices.Concat(res, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction)) +} + +// icmpIPCubesToRules converts cubes representing icmp protocol rules to SG rules +func icmpIPCubesToRules(cubes []ds.Pair[*netset.IPBlock, *netset.ICMPSet], anyProtocolCubes *netset.IPBlock, + direction ir.Direction) []*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 + + 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], anyProtocolCubes) { + res = slices.Concat(res, createActiveRules(activeRules, cubes[i-1].Left.LastIPAddressObject(), direction)) + activeRules = make(map[*netset.IPBlock]netp.Protocol) + } + + // 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 startIP, protocol := range activeRules { + icmp, _ := protocol.(netp.ICMP) + ruleIcmpSet := optimize.IcmpRuleToIcmpSet(icmp) + if !ruleIcmpSet.IsSubset(cubes[i].Right) { + res = slices.Concat(res, createNewRules(protocol, startIP, cubes[i-1].Left.LastIPAddressObject(), direction)) + delete(activeRules, startIP) + } else { + activeICMP.Union(ruleIcmpSet) + } + } + + // 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 + } + } + } + + // generate all existing rules + return slices.Concat(res, createActiveRules(activeRules, cubes[len(cubes)-1].Left.LastIPAddressObject(), direction)) +} + +// 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], anyProtocolCubes *netset.IPBlock) bool { + prevIPBlock := prevPair.Left + currIPBlock := currPair.Left + touching, _ := prevIPBlock.TouchingIPRanges(currIPBlock) + if touching { + return false + } + holeFirstIP, _ := prevIPBlock.NextIP() + holeEndIP, _ := currIPBlock.PreviousIP() + hole, _ := netset.IPBlockFromIPRange(holeFirstIP, holeEndIP) + return !hole.IsSubset(anyProtocolCubes) +} + +// creates sgRules from SG active rules +func createActiveRules(activeRules map[*netset.IPBlock]netp.Protocol, lastIP *netset.IPBlock, direction ir.Direction) []*ir.SGRule { + res := make([]*ir.SGRule, 0) + for firstIP, protocol := range activeRules { + res = slices.Concat(res, createNewRules(protocol, firstIP, lastIP, 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/reduceCubes.go b/pkg/optimize/sg/reduceCubes.go new file mode 100644 index 00000000..c8b9994b --- /dev/null +++ b/pkg/optimize/sg/reduceCubes.go @@ -0,0 +1,142 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package sgoptimizer + +import ( + "slices" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" +) + +func reduceCubesWithSGRemote(cubes *sgCubesPerProtocol) { + deleteOtherProtocolIfAnyProtocolExistsSGRemote(cubes) + compressThreeProtocolsToAnyProtocolSGRemote(cubes) +} + +// delete other protocols rules if any protocol rule exists +func deleteOtherProtocolIfAnyProtocolExistsSGRemote(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 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.IsAllPorts(tcpPorts) && optimize.IsAllPorts(udpPorts) { + delete(cubes.tcp, sgName) + delete(cubes.udp, sgName) + delete(cubes.icmp, sgName) + cubes.anyProtocol = append(cubes.anyProtocol, sgName) + } + } + } + } +} + +// 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 checks +func reduceIPCubes(cubes *ipCubesPerProtocol) { + tcpPtr := 0 + udpPtr := 0 + icmpPtr := 0 + + for tcpPtr < len(cubes.tcp) && udpPtr < len(cubes.udp) && icmpPtr < len(cubes.icmp) { + if !optimize.IsAllPorts(cubes.tcp[tcpPtr].Right) { // not all tcp ports + tcpPtr++ + continue + } + if !optimize.IsAllPorts(cubes.udp[udpPtr].Right) { // not all udp ports + udpPtr++ + continue + } + if !cubes.icmp[icmpPtr].Right.IsAll() { // not all icmp types & codes + icmpPtr++ + continue + } + + // all three protocols include all ports and types & codes + // attempt to convert to any protocol rule + if compressedToAnyProtocolCubeIPCubes(cubes, tcpPtr, udpPtr, icmpPtr) { // converted to any protocol rule + continue + } + + // 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 + tcpIPblock := cubes.tcp[tcpPtr].Left + udpIPblock := cubes.udp[udpPtr].Left + icmpIPblock := cubes.icmp[icmpPtr].Left + + 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) + tcpAndUDPSubsetOfICMP := tcpIPblock.IsSubset(icmpIPblock) && udpIPblock.IsSubset(icmpIPblock) + + switch { + // case 1 + case udpAndICMPSubsetOfTCP && udpComparedToICMP == -1: + udpPtr++ + case udpAndICMPSubsetOfTCP: + icmpPtr++ + case tcpAndICMPSubsetOfUDP && tcpComparedToICMP == -1: + tcpPtr++ + case tcpAndICMPSubsetOfUDP: + icmpPtr++ + case tcpAndUDPSubsetOfICMP && tcpComparedToUDP == -1: + tcpPtr++ + case tcpAndUDPSubsetOfICMP: + udpPtr++ + + // case 2 + case tcpComparedToUDP < 1 && tcpComparedToICMP < 1: + tcpPtr++ + case tcpComparedToUDP >= 0 && udpComparedToICMP < 1: + udpPtr++ + case tcpComparedToICMP >= 0 && udpComparedToICMP >= 0: + icmpPtr++ + } + } +} + +// compress three protocol rules to any protocol rule (and maybe another protocol rule) +// returns true if the compression was successful +func compressedToAnyProtocolCubeIPCubes(cubes *ipCubesPerProtocol, tcpPtr, udpPtr, icmpPtr int) bool { + tcpIP := cubes.tcp[tcpPtr].Left + udpIP := cubes.udp[udpPtr].Left + icmpIP := cubes.icmp[icmpPtr].Left + + 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.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.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.anyProtocol = cubes.anyProtocol.Union(tcpIP) + return true + } + return false +} diff --git a/pkg/optimize/sg/rulesToCubes.go b/pkg/optimize/sg/rulesToCubes.go new file mode 100644 index 00000000..5763641a --- /dev/null +++ b/pkg/optimize/sg/rulesToCubes.go @@ -0,0 +1,113 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +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" + "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" +) + +// SG remote +func rulesToSGCubes(rules *rulesPerProtocol) *sgCubesPerProtocol { + return &sgCubesPerProtocol{tcp: tcpudpRulesSGCubes(rules.tcp), + udp: tcpudpRulesSGCubes(rules.udp), + icmp: icmpRulesSGCubes(rules.icmp), + anyProtocol: anyProtocolRulesToSGCubes(rules.anyProtocol), + } +} + +// any protocol rules to cubes +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 + res[i] = remote + } + 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 { + 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 res[remote] == nil { + res[remote] = interval.NewCanonicalSet() + } + res[remote].AddInterval(p.DstPorts()) + } + return res +} + +// 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 { + anyProtocolCubes := anyProtocolRulesToIPCubes(rules.anyProtocol) + return &ipCubesPerProtocol{tcp: tcpudpRulesToIPCubes(rules.tcp, anyProtocolCubes), + udp: tcpudpRulesToIPCubes(rules.udp, anyProtocolCubes), + icmp: icmpRulesToIPCubes(rules.icmp, anyProtocolCubes), + anyProtocol: anyProtocolCubes, + } +} + +// 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)) + } + return res +} + +// tcp/udp rules (separately) to cubes (IPBlock X 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 + p := rule.Protocol.(netp.TCPUDP) // already checked + 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]) // subtract any protocol cubes + return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) +} + +// icmp rules to cubes (IPBlock X icmp set). +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 + p := rule.Protocol.(netp.ICMP) // already checked + 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]) // subtract any protocol cubes + return optimize.SortPartitionsByIPAddrs(cubes.Partitions()) +} diff --git a/pkg/optimize/sg/sg.go b/pkg/optimize/sg/sg.go new file mode 100644 index 00000000..dc49400c --- /dev/null +++ b/pkg/optimize/sg/sg.go @@ -0,0 +1,213 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package sgoptimizer + +import ( + "fmt" + "log" + "slices" + + "github.com/np-guard/models/pkg/ds" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + + "github.com/np-guard/vpc-network-config-synthesis/pkg/ir" + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" + "github.com/np-guard/vpc-network-config-synthesis/pkg/utils" +) + +type ( + sgOptimizer struct { + sgCollection *ir.SGCollection + sgName ir.SGName + sgVPC string + } + + ruleGroups struct { + sgRemoteRules *rulesPerProtocol + ipRemoteRules *rulesPerProtocol + } + + rulesPerProtocol struct { + 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 + icmp map[ir.SGName]*netset.ICMPSet + anyProtocol []ir.SGName + } + + // ipblocks refers to remote IPs + ipCubesPerProtocol struct { + tcp []ds.Pair[*netset.IPBlock, *netset.PortSet] + udp []ds.Pair[*netset.IPBlock, *netset.PortSet] + icmp []ds.Pair[*netset.IPBlock, *netset.ICMPSet] + anyProtocol *netset.IPBlock + } +) + +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: ""} + } + 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 the requested SG +// otherwise, it will attempt to reduce the number of rules in all SGs +func (s *sgOptimizer) Optimize() (ir.Collection, error) { + if s.sgName != "" { + for _, vpcName := range utils.SortedMapKeys(s.sgCollection.SGs) { + if s.sgVPC != "" && s.sgVPC != vpcName { + continue + } + if _, ok := s.sgCollection.SGs[vpcName][s.sgName]; ok { + s.optimizeSG(s.sgCollection.SGs[vpcName][s.sgName]) + return s.sgCollection, nil + } + } + return nil, fmt.Errorf("could not find %s sg", s.sgName) + } + + for _, vpcName := range utils.SortedMapKeys(s.sgCollection.SGs) { + for _, sgName := range utils.SortedMapKeys(s.sgCollection.SGs[vpcName]) { + s.optimizeSG(s.sgCollection.SGs[vpcName][sgName]) + } + } + return s.sgCollection, nil +} + +// 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(sg *ir.SG) { + 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) + sg.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) + sg.OutboundRules = newOutboundRules + } + + // print a message to the log + if reducedRules == 0 { + log.Printf("no rules were reduced in sg %s\n", 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) 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) + + // rules with SG as a remote + optimizedRulesToSG := reduceRulesSGRemote(rulesToSGCubes(ruleGroups.sgRemoteRules), direction) + originalRulesToSG := ruleGroups.sgRemoteRules.allRules() + if len(originalRulesToSG) <= len(optimizedRulesToSG) { // failed to reduce number of rules + optimizedRulesToSG = originalRulesToSG + } + + // 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 + optimizedRulesToIPAddrs = originalRulesToIPAddrs + } + + return append(optimizedRulesToSG, optimizedRulesToIPAddrs...) +} + +func reduceRulesSGRemote(cubes *sgCubesPerProtocol, direction ir.Direction) []*ir.SGRule { + reduceCubesWithSGRemote(cubes) + + // cubes to SG rules + tcpRules := tcpudpSGCubesToRules(cubes.tcp, direction, true) + udpRules := tcpudpSGCubesToRules(cubes.udp, direction, false) + icmpRules := icmpSGCubesToRules(cubes.icmp, direction) + anyProtocolRules := anyProtocolCubesToRules(cubes.anyProtocol, direction) + + // return all rules + return slices.Concat(tcpRules, udpRules, icmpRules, anyProtocolRules) +} + +func reduceRulesIPRemote(cubes *ipCubesPerProtocol, direction ir.Direction) []*ir.SGRule { + reduceIPCubes(cubes) + + // cubes to SG rules + 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 slices.Concat(tcpRules, udpRules, icmpRules, anyProtocolRules) +} + +// divide SGCollection to TCP/UDP/ICMP/anyProtocols X SGRemote/IPAddrs rules +func divideSGRules(rules []*ir.SGRule) *ruleGroups { + rulesToSG := &rulesPerProtocol{} + rulesToIPAddrs := &rulesPerProtocol{} + + for _, rule := range rules { + switch p := rule.Protocol.(type) { + case netp.TCPUDP: + //nolint:nestif // if statements + if p.ProtocolString() == "TCP" { + if isRemoteIPBlock(rule) { + rulesToIPAddrs.tcp = append(rulesToIPAddrs.tcp, rule) + } else { + rulesToSG.tcp = append(rulesToSG.tcp, rule) + } + } else { + if isRemoteIPBlock(rule) { + rulesToIPAddrs.udp = append(rulesToIPAddrs.udp, rule) + } else { + rulesToSG.udp = append(rulesToSG.udp, rule) + } + } + case netp.ICMP: + if isRemoteIPBlock(rule) { + rulesToIPAddrs.icmp = append(rulesToIPAddrs.icmp, rule) + } else { + rulesToSG.icmp = append(rulesToSG.icmp, rule) + } + case netp.AnyProtocol: + if isRemoteIPBlock(rule) { + rulesToIPAddrs.anyProtocol = append(rulesToIPAddrs.anyProtocol, rule) + } else { + rulesToSG.anyProtocol = append(rulesToSG.anyProtocol, rule) + } + } + } + return &ruleGroups{sgRemoteRules: rulesToSG, ipRemoteRules: rulesToIPAddrs} +} + +func isRemoteIPBlock(rule *ir.SGRule) bool { + _, ok := rule.Remote.(*netset.IPBlock) + return ok +} + +func (s *rulesPerProtocol) allRules() []*ir.SGRule { + return slices.Concat(s.tcp, s.udp, s.icmp, s.anyProtocol) +} diff --git a/pkg/optimize/sg/sgCubesToRules.go b/pkg/optimize/sg/sgCubesToRules.go new file mode 100644 index 00000000..94904c5d --- /dev/null +++ b/pkg/optimize/sg/sgCubesToRules.go @@ -0,0 +1,46 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package sgoptimizer + +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" + "github.com/np-guard/vpc-network-config-synthesis/pkg/optimize" +) + +// cubes (SGName X portSet) to SG rules +func tcpudpSGCubesToRules(cubes map[ir.SGName]*netset.PortSet, direction ir.Direction, isTCP bool) []*ir.SGRule { + result := make([]*ir.SGRule, 0) + 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(), "")) + } + } + return result +} + +// cubes (SGName X icmpset) to SG rules +func icmpSGCubesToRules(cubes map[ir.SGName]*netset.ICMPSet, direction ir.Direction) []*ir.SGRule { + result := make([]*ir.SGRule, 0) + for sgName, icmpSet := range cubes { + for _, icmp := range optimize.IcmpsetPartitions(icmpSet) { + result = append(result, ir.NewSGRule(direction, sgName, icmp, netset.GetCidrAll(), "")) + } + } + return result +} + +// 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/pkg/utils/utils.go b/pkg/utils/utils.go index 746fcd44..e5f14e28 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -32,6 +32,22 @@ func SortedAllInnerMapsKeys[T, K cmp.Ordered, V any](m map[K]map[T]V) []T { 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)) +} + func TrueKeyValues[T cmp.Ordered](m map[T]bool) []T { keys := make([]T, 0) for _, k := range SortedMapKeys(m) { 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..e4d7662a --- /dev/null +++ b/test/data/optimize_sg_protocols_to_all/config_object.json @@ -0,0 +1,2220 @@ +{ + "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": "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/30" + }, + "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", + "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/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..4b184550 --- /dev/null +++ b/test/data/optimize_sg_protocols_to_all/conn_spec.json @@ -0,0 +1,170 @@ +{ + "externals": { + "e1": "0.0.0.0/31", + "e2": "0.0.0.0/30" + }, + "required-connections": [ + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e2", + "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..dcd70519 --- /dev/null +++ b/test/data/optimize_sg_protocols_to_all/details.txt @@ -0,0 +1,23 @@ +original config object: acl_testing4 config + +######## 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) +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) + + + +######## AFTER ######## + +vsi1 --> 0.0.0.0/31 (any protocol) +vsi1 --> 0.0.0.0/30 (icmp) +vsi1 --> vsi2 (any protocol) \ No newline at end of file diff --git a/test/data_for_testing_errors/vpe_acl/config_object.json b/test/data/optimize_sg_redundant/config_object.json similarity index 55% rename from test/data_for_testing_errors/vpe_acl/config_object.json rename to test/data/optimize_sg_redundant/config_object.json index 75620661..bc4c61c5 100644 --- a/test/data_for_testing_errors/vpe_acl/config_object.json +++ b/test/data/optimize_sg_redundant/config_object.json @@ -4,12 +4,12 @@ "vpcs": [ { "classic_access": false, - "created_at": "2024-06-19T07:11:56.000Z", + "created_at": "2024-09-09T09:09:50.000Z", "crn": "crn:1", "cse_source_ips": [ { "ip": { - "address": "10.16.239.119" + "address": "10.22.217.112" }, "zone": { "href": "href:5", @@ -18,7 +18,7 @@ }, { "ip": { - "address": "10.22.28.206" + "address": "10.12.160.153" }, "zone": { "href": "href:6", @@ -27,7 +27,7 @@ }, { "ip": { - "address": "10.16.253.77" + "address": "10.16.253.223" }, "zone": { "href": "href:7", @@ -39,19 +39,20 @@ "crn": "crn:8", "href": "href:9", "id": "id:10", - "name": "premises-eleven-nursery-coveted" + "name": "capitol-siren-chirpy-doornail" }, "default_routing_table": { + "crn": null, "href": "href:11", "id": "id:12", - "name": "unguarded-corncob-unaired-corner", + "name": "fiscally-fresh-uncanny-ceramics", "resource_type": "routing_table" }, "default_security_group": { "crn": "crn:13", "href": "href:14", "id": "id:15", - "name": "impart-oxidize-chive-escapade" + "name": "wombat-hesitate-scorn-subprime" }, "dns": { "enable_hub": false, @@ -59,21 +60,21 @@ "resolver": { "servers": [ { - "address": "161.26.0.7" + "address": "161.26.0.10" }, { - "address": "161.26.0.8" + "address": "161.26.0.11" } ], "type": "system", - "configuration": "private_resolver" + "configuration": "default" } }, "health_reasons": null, "health_state": "ok", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_group": { "href": "href:16", "id": "id:17", @@ -85,12 +86,12 @@ "address_prefixes": [ { "cidr": "10.240.0.0/18", - "created_at": "2024-06-19T07:11:56.000Z", + "created_at": "2024-09-09T09:09:50.000Z", "has_subnets": true, "href": "href:18", "id": "id:19", "is_default": true, - "name": "seismic-phosphate-subtext-unleash", + "name": "filling-tasty-bacterium-parlor", "zone": { "href": "href:5", "name": "us-south-1" @@ -98,12 +99,12 @@ }, { "cidr": "10.240.64.0/18", - "created_at": "2024-06-19T07:11:56.000Z", - "has_subnets": true, + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, "href": "href:20", "id": "id:21", "is_default": true, - "name": "shaded-tribute-glazing-explains", + "name": "relearn-ragweed-goon-feisty", "zone": { "href": "href:6", "name": "us-south-2" @@ -111,12 +112,12 @@ }, { "cidr": "10.240.128.0/18", - "created_at": "2024-06-19T07:11:56.000Z", - "has_subnets": true, + "created_at": "2024-09-09T09:09:50.000Z", + "has_subnets": false, "href": "href:22", "id": "id:23", "is_default": true, - "name": "overlabor-spiffy-economist-clanking", + "name": "unruffled-penknife-snowshoe-ninetieth", "zone": { "href": "href:7", "name": "us-south-3" @@ -128,19 +129,26 @@ ], "subnets": [ { - "available_ipv4_address_count": 249, - "created_at": "2024-06-19T07:12:21.000Z", + "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.0.0/24", - "name": "sub1", + "ipv4_cidr_block": "10.240.20.0/24", + "name": "subnet2", "network_acl": { "crn": "crn:27", "href": "href:28", "id": "id:29", - "name": "acl1" + "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", @@ -149,9 +157,10 @@ }, "resource_type": "subnet", "routing_table": { + "crn": null, "href": "href:11", "id": "id:12", - "name": "unguarded-corncob-unaired-corner", + "name": "fiscally-fresh-uncanny-ceramics", "resource_type": "routing_table" }, "status": "available", @@ -160,7 +169,7 @@ "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "zone": { @@ -169,115 +178,102 @@ }, "reserved_ips": [ { - "address": "10.240.0.0", + "address": "10.240.20.0", "auto_delete": false, - "created_at": "2024-06-19T07:12:21.000Z", - "href": "href:30", - "id": "id:31", + "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.0.1", + "address": "10.240.20.1", "auto_delete": false, - "created_at": "2024-06-19T07:12:21.000Z", - "href": "href:32", - "id": "id:33", + "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.0.2", + "address": "10.240.20.2", "auto_delete": false, - "created_at": "2024-06-19T07:12:21.000Z", - "href": "href:34", - "id": "id:35", + "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.0.3", + "address": "10.240.20.3", "auto_delete": false, - "created_at": "2024-06-19T07:12:21.000Z", - "href": "href:36", - "id": "id:37", + "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.0.4", + "address": "10.240.20.4", "auto_delete": true, - "created_at": "2024-06-19T07:12:47.000Z", - "href": "href:38", - "id": "id:39", + "created_at": "2024-09-09T09:11:08.000Z", + "href": "href:41", + "id": "id:42", "lifecycle_state": "stable", - "name": "portion-send-snout-magazine", + "name": "startle-percent-embellish-squeegee", "owner": "user", "resource_type": "subnet_reserved_ip", "target": { - "href": "href:40", - "id": "id:41", - "name": "bouncing-serpent-graffiti-evasion", + "href": "href:43", + "id": "id:44", + "name": "ni2", "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", + "address": "10.240.20.255", "auto_delete": false, - "created_at": "2024-06-19T07:12:21.000Z", - "href": "href:47", - "id": "id:48", + "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": [ - "trust-zone:edge" - ] + "tags": [] }, { "available_ipv4_address_count": 250, - "created_at": "2024-06-19T07:12:20.000Z", - "crn": "crn:49", - "href": "href:50", - "id": "id:51", + "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.64.0/24", - "name": "sub3", + "ipv4_cidr_block": "10.240.10.0/24", + "name": "subnet1", "network_acl": { - "crn": "crn:27", - "href": "href:28", - "id": "id:29", + "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", @@ -285,9 +281,10 @@ }, "resource_type": "subnet", "routing_table": { + "crn": null, "href": "href:11", "id": "id:12", - "name": "unguarded-corncob-unaired-corner", + "name": "fiscally-fresh-uncanny-ceramics", "resource_type": "routing_table" }, "status": "available", @@ -296,80 +293,79 @@ "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "zone": { - "href": "href:6", - "name": "us-south-2" + "href": "href:5", + "name": "us-south-1" }, "reserved_ips": [ { - "address": "10.240.64.0", + "address": "10.240.10.0", "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:52", - "id": "id:53", + "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.64.1", + "address": "10.240.10.1", "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:54", - "id": "id:55", + "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.64.2", + "address": "10.240.10.2", "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:56", - "id": "id:57", + "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.64.3", + "address": "10.240.10.3", "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:58", - "id": "id:59", + "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.64.4", + "address": "10.240.10.4", "auto_delete": true, - "created_at": "2024-06-19T11:03:34.000Z", - "href": "href:60", - "id": "id:61", + "created_at": "2024-09-09T09:10:52.000Z", + "href": "href:61", + "id": "id:62", "lifecycle_state": "stable", - "name": "policydb-vpe3", + "name": "tableware-sprawl-shrivel-popper", "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" + "name": "ni1", + "resource_type": "network_interface" } }, { - "address": "10.240.64.255", + "address": "10.240.10.255", "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", + "created_at": "2024-09-09T09:10:35.000Z", "href": "href:65", "id": "id:66", "lifecycle_state": "stable", @@ -378,24 +374,22 @@ "resource_type": "subnet_reserved_ip" } ], - "tags": [ - "trust-zone:transit" - ] + "tags": [] }, { - "available_ipv4_address_count": 246, - "created_at": "2024-06-19T07:12:20.000Z", + "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.128.0/24", - "name": "sub2", + "ipv4_cidr_block": "10.240.30.0/24", + "name": "subnet3", "network_acl": { - "crn": "crn:27", - "href": "href:28", - "id": "id:29", - "name": "acl1" + "crn": "crn:70", + "href": "href:71", + "id": "id:72", + "name": "acl3" }, "resource_group": { "href": "href:16", @@ -404,9 +398,10 @@ }, "resource_type": "subnet", "routing_table": { + "crn": null, "href": "href:11", "id": "id:12", - "name": "unguarded-corncob-unaired-corner", + "name": "fiscally-fresh-uncanny-ceramics", "resource_type": "routing_table" }, "status": "available", @@ -415,171 +410,150 @@ "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "zone": { - "href": "href:7", - "name": "us-south-3" + "href": "href:5", + "name": "us-south-1" }, "reserved_ips": [ { - "address": "10.240.128.0", + "address": "10.240.30.0", "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:70", - "id": "id:71", + "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.128.1", + "address": "10.240.30.1", "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:72", - "id": "id:73", + "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.128.2", + "address": "10.240.30.2", "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:74", - "id": "id:75", + "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.128.3", + "address": "10.240.30.3", "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:76", - "id": "id:77", + "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.128.4", + "address": "10.240.30.4", "auto_delete": true, - "created_at": "2024-06-19T07:12:46.000Z", - "href": "href:78", - "id": "id:79", + "created_at": "2024-09-09T09:10:35.000Z", + "href": "href:81", + "id": "id:82", "lifecycle_state": "stable", - "name": "magnetism-steersman-botany-hurled", + "name": "disallow-oxidant-etching-selection", "owner": "user", "resource_type": "subnet_reserved_ip", "target": { - "href": "href:80", - "id": "id:81", - "name": "captain-captivity-shorty-crown", + "href": "href:83", + "id": "id:84", + "name": "ni3a", "resource_type": "network_interface" } }, { - "address": "10.240.128.5", + "address": "10.240.30.5", "auto_delete": true, - "created_at": "2024-06-19T07:12:47.000Z", - "href": "href:82", - "id": "id:83", + "created_at": "2024-09-09T09:10:36.000Z", + "href": "href:85", + "id": "id:86", "lifecycle_state": "stable", - "name": "kilt-snipping-yen-unmanaged", + "name": "reheat-joyride-little-overprice", "owner": "user", "resource_type": "subnet_reserved_ip", "target": { - "href": "href:84", - "id": "id:85", - "name": "left-pebble-agonizing-wharf", + "href": "href:87", + "id": "id:88", + "name": "ni3b", "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", + "address": "10.240.30.255", "auto_delete": false, - "created_at": "2024-06-19T07:12:20.000Z", - "href": "href:94", - "id": "id:95", + "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": [ - "trust-zone:private" - ] + "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": [] } ], - "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", + "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", @@ -587,14 +561,14 @@ }, "status": "available", "target": { - "href": "href:40", - "id": "id:41", - "name": "bouncing-serpent-graffiti-evasion", + "href": "href:63", + "id": "id:64", + "name": "ni1", "primary_ip": { - "address": "10.240.0.4", - "href": "href:38", - "id": "id:39", - "name": "portion-send-snout-magazine", + "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" @@ -604,15 +578,41 @@ "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-06-19T07:12:16.000Z", + "created_at": "2024-09-09T09:10:15.000Z", "crn": "crn:27", "href": "href:28", "id": "id:29", - "name": "acl1", + "name": "acl2", "resource_group": { "href": "href:16", "id": "id:17", @@ -620,20 +620,37 @@ }, "rules": [ { - "action": "deny", + "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": "acl1-out3" + "name": "acl2-in-1" }, - "created_at": "2024-06-19T07:12:17.000Z", - "destination": "10.240.0.0/24", + "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": "acl1-out2", - "source": "10.240.128.0/24", + "name": "acl2-out-2", + "source": "10.240.20.0/24", "protocol": "all" }, { @@ -641,28 +658,28 @@ "before": { "href": "href:103", "id": "id:104", - "name": "acl1-in2" + "name": "acl2-in-2" }, - "created_at": "2024-06-19T07:12:18.000Z", - "destination": "0.0.0.0/0", - "direction": "outbound", + "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": "acl1-out3", + "name": "acl2-in-1", "source": "0.0.0.0/0", "protocol": "all" }, { "action": "allow", - "created_at": "2024-06-19T07:12:18.000Z", - "destination": "0.0.0.0/0", + "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": "acl1-in2", - "source": "0.0.0.0/0", + "name": "acl2-in-2", + "source": "10.240.10.0/24", "protocol": "all" } ], @@ -671,21 +688,7 @@ "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", + "name": "subnet2", "resource_type": "subnet" } ], @@ -693,17 +696,17 @@ "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "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", + "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", @@ -715,49 +718,173 @@ "before": { "href": "href:107", "id": "id:108", - "name": "allow-outbound" + "name": "acl1-out-2" }, - "created_at": "2024-06-19T07:11:57.000Z", - "destination": "0.0.0.0/0", - "direction": "inbound", + "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": "allow-inbound", - "source": "0.0.0.0/0", + "name": "acl1-out-1", + "source": "10.240.10.0/24", "protocol": "all" }, { "action": "allow", - "created_at": "2024-06-19T07:11:57.000Z", - "destination": "0.0.0.0/0", + "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": "allow-outbound", - "source": "0.0.0.0/0", + "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" } ], - "subnets": [], "vpc": { "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "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", + "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", @@ -765,47 +892,109 @@ }, "rules": [ { - "direction": "inbound", - "href": "href:112", - "id": "id:113", + "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", - "local": { - "cidr_block": "0.0.0.0/0" + "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" }, - "remote": { - "crn": "crn:114", - "href": "href:115", - "id": "id:116", - "name": "be-sg" + "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" }, - "port_max": 8181, - "port_min": 8181, - "protocol": "tcp" + "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 } ], - "targets": [ + "subnets": [ { - "href": "href:84", - "id": "id:85", - "name": "left-pebble-agonizing-wharf", - "resource_type": "network_interface" + "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-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "tags": [] }, { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:114", - "href": "href:115", - "id": "id:116", - "name": "be-sg", + "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", @@ -813,65 +1002,53 @@ }, "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:117", - "id": "id:118", + "href": "href:129", + "id": "id:130", "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" + "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:122", - "id": "id:123", + "href": "href:131", + "id": "id:132", "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" + "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", + "name": "test-vpc1", "resource_type": "vpc" }, "tags": [] - }, + } + ], + "security_groups": [ { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:124", - "href": "href:125", - "id": "id:126", - "name": "policydb-vpe", + "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", @@ -879,59 +1056,48 @@ }, "rules": [ { - "direction": "outbound", - "href": "href:127", - "id": "id:128", + "direction": "inbound", + "href": "href:136", + "id": "id:137", "ip_version": "ipv4", "local": { "cidr_block": "0.0.0.0/0" }, "remote": { - "address": "10.240.128.7" + "cidr_block": "0.0.0.0/0" }, - "port_max": 65535, - "port_min": 1, - "protocol": "tcp" + "protocol": "all" }, { "direction": "outbound", - "href": "href:129", - "id": "id:130", + "href": "href:138", + "id": "id:139", "ip_version": "ipv4", "local": { "cidr_block": "0.0.0.0/0" }, "remote": { - "address": "10.240.64.4" + "cidr_block": "0.0.0.0/0" }, - "port_max": 65535, - "port_min": 1, - "protocol": "tcp" - } - ], - "targets": [ - { - "href": "href:80", - "id": "id:81", - "name": "captain-captivity-shorty-crown", - "resource_type": "network_interface" + "protocol": "all" } ], + "targets": [], "vpc": { "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "tags": [] }, { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:131", - "href": "href:132", - "id": "id:133", - "name": "proxy-sg", + "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", @@ -939,9 +1105,9 @@ }, "rules": [ { - "direction": "inbound", - "href": "href:134", - "id": "id:135", + "direction": "outbound", + "href": "href:140", + "id": "id:141", "ip_version": "ipv4", "local": { "cidr_block": "0.0.0.0/0" @@ -952,47 +1118,38 @@ "protocol": "all" }, { - "direction": "outbound", - "href": "href:136", - "id": "id:137", + "direction": "inbound", + "href": "href:142", + "id": "id:143", "ip_version": "ipv4", "local": { "cidr_block": "0.0.0.0/0" }, "remote": { - "crn": "crn:119", - "href": "href:120", - "id": "id:121", - "name": "fe-sg" + "crn": "crn:13", + "href": "href:14", + "id": "id:15", + "name": "wombat-hesitate-scorn-subprime" }, - "port_max": 9000, - "port_min": 9000, - "protocol": "udp" - } - ], - "targets": [ - { - "href": "href:40", - "id": "id:41", - "name": "bouncing-serpent-graffiti-evasion", - "resource_type": "network_interface" + "protocol": "all" } ], + "targets": [], "vpc": { "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "tags": [] }, { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:138", - "href": "href:139", - "id": "id:140", - "name": "appdata-sg", + "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", @@ -1001,44 +1158,44 @@ "rules": [ { "direction": "inbound", - "href": "href:141", - "id": "id:142", + "href": "fake:href:1", + "id": "fake:id:1", "ip_version": "ipv4", "local": { "cidr_block": "0.0.0.0/0" }, "remote": { - "cidr_block": "0.0.0.0/0" + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" }, - "port_max": 65535, - "port_min": 1, - "protocol": "tcp" + "protocol": "all" } ], "targets": [ { - "href": "href:45", - "id": "id:46", - "name": "appdata-endpoint-gateway", - "resource_type": "endpoint_gateway", - "crn": "crn:44" + "href": "href:43", + "id": "id:44", + "name": "ni2", + "resource_type": "network_interface" } ], "vpc": { "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "tags": [] }, { - "created_at": "2024-06-19T07:12:17.000Z", - "crn": "crn:143", - "href": "href:144", - "id": "id:145", - "name": "appdata-vpe", + "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", @@ -1047,91 +1204,114 @@ "rules": [ { "direction": "outbound", - "href": "href:146", - "id": "id:147", + "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": { - "address": "10.240.128.8" + "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" - } - ], - "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": "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", + "id": "fake:id:3", + "name": "test-vpc1--vsi2" + }, + "protocol": "all" + }, { "direction": "outbound", - "href": "href:148", - "id": "id:149", + "href": "fake:href:9", + "id": "fake:id:9", "ip_version": "ipv4", "local": { "cidr_block": "0.0.0.0/0" }, "remote": { - "crn": "crn:114", - "href": "href:115", - "id": "id:116", - "name": "be-sg" + "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": "inbound", - "href": "href:150", - "id": "id:151", + "direction": "outbound", + "href": "fake:href:11", + "id": "fake:id:11", "ip_version": "ipv4", "local": { "cidr_block": "0.0.0.0/0" }, "remote": { - "crn": "crn:131", - "href": "href:132", - "id": "id:133", - "name": "proxy-sg" + "crn": "fake:crn:10", + "href": "fake:href:10", + "id": "fake:id:10", + "name": "test-vpc1--vsi3a" }, - "port_max": 9000, - "port_min": 9000, - "protocol": "udp" + "protocol": "all" } ], "targets": [ { - "href": "href:88", - "id": "id:89", - "name": "litigate-bullfrog-improve-shandy", + "href": "href:63", + "id": "id:64", + "name": "ni1", "resource_type": "network_interface" } ], @@ -1139,63 +1319,46 @@ "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "tags": [] }, { - "created_at": "2024-06-19T07:12:16.000Z", - "crn": "crn:152", - "href": "href:153", - "id": "id:154", - "name": "policydb-sg", + "created_at": null, + "crn": "fake:crn:12", + "href": "fake:href:12", + "id": "fake:id:12", + "name": "test-vpc1--vsi3b", "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" - } - ], + "rules": [], "targets": [ { - "href": "href:63", - "id": "id:64", - "name": "policydb-endpoint-gateway", - "resource_type": "endpoint_gateway", - "crn": "crn:62" + "href": "href:87", + "id": "id:88", + "name": "ni3b", + "resource_type": "network_interface" } ], "vpc": { "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "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", + "created_at": null, + "crn": "fake:crn:10", + "href": "fake:href:10", + "id": "fake:id:10", + "name": "test-vpc1--vsi3a", "resource_group": { "href": "href:16", "id": "id:17", @@ -1203,164 +1366,59 @@ }, "rules": [ { - "direction": "outbound", - "href": "href:157", - "id": "id:158", + "direction": "inbound", + "href": "fake:href:13", + "id": "fake:id:13", "ip_version": "ipv4", "local": { "cidr_block": "0.0.0.0/0" }, "remote": { - "cidr_block": "0.0.0.0/0" + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" }, - "protocol": "all" + "port_max": 65535, + "port_min": 1, + "protocol": "tcp" }, { "direction": "inbound", - "href": "href:159", - "id": "id:160", + "href": "fake:href:14", + "id": "fake:id:14", "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" + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" }, "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": [ + "targets": [ { - "crn": "crn:138", - "href": "href:139", - "id": "id:140", - "name": "appdata-sg" + "href": "href:83", + "id": "id:84", + "name": "ni3a", + "resource_type": "network_interface" } ], - "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", + "name": "test-vpc1", "resource_type": "vpc" }, "tags": [] } ], + "endpoint_gateways": [], "instances": [ { "availability_policy": { @@ -1369,32 +1427,33 @@ "bandwidth": 4000, "boot_volume_attachment": { "device": { - "id": "id:168" + "id": "id:149" }, - "href": "href:166", - "id": "id:167", - "name": "magnitude-aloe-wildlife-vacancy", + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", "volume": { - "crn": "crn:169", - "href": "href:170", - "id": "id:171", - "name": "catbrier-onto-grapple-fastball", + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", - "created_at": "2024-06-19T07:12:47.000Z", - "crn": "crn:163", + "created_at": "2024-09-09T09:11:07.000Z", + "crn": "crn:144", "disks": [], "enable_secure_boot": false, "health_reasons": [], "health_state": "ok", - "href": "href:164", - "id": "id:165", + "href": "href:145", + "id": "id:146", "image": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", + "crn": "crn:153", + "href": "href:154", + "id": "id:155", "name": "server-9080", "resource_type": "image" }, @@ -1406,18 +1465,18 @@ "protocol": "http", "response_hop_limit": 1 }, - "name": "proxy", + "name": "vsi2", "network_attachments": [], "numa_count": 1, "primary_network_interface": { - "href": "href:40", - "id": "id:41", - "name": "bouncing-serpent-graffiti-evasion", + "href": "href:43", + "id": "id:44", + "name": "ni2", "primary_ip": { - "address": "10.240.0.4", - "href": "href:38", - "id": "id:39", - "name": "portion-send-snout-magazine", + "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", @@ -1425,12 +1484,12 @@ "crn": "crn:24", "href": "href:25", "id": "id:26", - "name": "sub1", + "name": "subnet2", "resource_type": "subnet" } }, "profile": { - "href": "href:175", + "href": "href:156", "name": "cx2-2x4", "resource_type": "instance_profile" }, @@ -1457,16 +1516,16 @@ "volume_attachments": [ { "device": { - "id": "id:168" + "id": "id:149" }, - "href": "href:166", - "id": "id:167", - "name": "magnitude-aloe-wildlife-vacancy", + "href": "href:147", + "id": "id:148", + "name": "falsetto-snowstorm-bankbook-agreement", "volume": { - "crn": "crn:169", - "href": "href:170", - "id": "id:171", - "name": "catbrier-onto-grapple-fastball", + "crn": "crn:150", + "href": "href:151", + "id": "id:152", + "name": "prawn-trusting-pasty-dental", "resource_type": "volume" } } @@ -1475,7 +1534,7 @@ "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "zone": { @@ -1485,34 +1544,26 @@ "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", + "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.0.4", - "href": "href:38", - "id": "id:39", - "name": "portion-send-snout-magazine", + "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": "crn:131", - "href": "href:132", - "id": "id:133", - "name": "proxy-sg" + "crn": "fake:crn:3", + "href": "fake:href:3", + "id": "fake:id:3", + "name": "test-vpc1--vsi2" } ], "status": "available", @@ -1520,7 +1571,7 @@ "crn": "crn:24", "href": "href:25", "id": "id:26", - "name": "sub1", + "name": "subnet2", "resource_type": "subnet" }, "type": "primary" @@ -1535,32 +1586,33 @@ "bandwidth": 4000, "boot_volume_attachment": { "device": { - "id": "id:181" + "id": "id:162" }, - "href": "href:179", - "id": "id:180", - "name": "folk-mousy-collar-kleenex", + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", "volume": { - "crn": "crn:182", - "href": "href:183", - "id": "id:184", - "name": "regalia-pavestone-ramble-stretch", + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", - "created_at": "2024-06-19T07:12:46.000Z", - "crn": "crn:176", + "created_at": "2024-09-09T09:10:52.000Z", + "crn": "crn:157", "disks": [], "enable_secure_boot": false, "health_reasons": [], "health_state": "ok", - "href": "href:177", - "id": "id:178", + "href": "href:158", + "id": "id:159", "image": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", + "crn": "crn:153", + "href": "href:154", + "id": "id:155", "name": "server-9080", "resource_type": "image" }, @@ -1572,31 +1624,31 @@ "protocol": "http", "response_hop_limit": 1 }, - "name": "opa", + "name": "vsi1", "network_attachments": [], "numa_count": 1, "primary_network_interface": { - "href": "href:84", - "id": "id:85", - "name": "left-pebble-agonizing-wharf", + "href": "href:63", + "id": "id:64", + "name": "ni1", "primary_ip": { - "address": "10.240.128.5", - "href": "href:82", - "id": "id:83", - "name": "kilt-snipping-yen-unmanaged", + "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:67", - "href": "href:68", - "id": "id:69", - "name": "sub2", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", "resource_type": "subnet" } }, "profile": { - "href": "href:175", + "href": "href:156", "name": "cx2-2x4", "resource_type": "instance_profile" }, @@ -1623,16 +1675,16 @@ "volume_attachments": [ { "device": { - "id": "id:181" + "id": "id:162" }, - "href": "href:179", - "id": "id:180", - "name": "folk-mousy-collar-kleenex", + "href": "href:160", + "id": "id:161", + "name": "outskirts-oversized-roundish-ludicrous", "volume": { - "crn": "crn:182", - "href": "href:183", - "id": "id:184", - "name": "regalia-pavestone-ramble-stretch", + "crn": "crn:163", + "href": "href:164", + "id": "id:165", + "name": "family-tackling-foothold-train", "resource_type": "volume" } } @@ -1641,44 +1693,52 @@ "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "zone": { - "href": "href:7", - "name": "us-south-3" + "href": "href:5", + "name": "us-south-1" }, "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", + "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.128.5", - "href": "href:82", - "id": "id:83", - "name": "kilt-snipping-yen-unmanaged", + "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": "crn:109", - "href": "href:110", - "id": "id:111", - "name": "opa-sg" + "crn": "fake:crn:2", + "href": "fake:href:2", + "id": "fake:id:2", + "name": "test-vpc1--vsi1" } ], "status": "available", "subnet": { - "crn": "crn:67", - "href": "href:68", - "id": "id:69", - "name": "sub2", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", "resource_type": "subnet" }, "type": "primary" @@ -1693,32 +1753,33 @@ "bandwidth": 4000, "boot_volume_attachment": { "device": { - "id": "id:190" + "id": "id:171" }, - "href": "href:188", - "id": "id:189", - "name": "scarily-reapprove-ecologist-gosling", + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", "volume": { - "crn": "crn:191", - "href": "href:192", - "id": "id:193", - "name": "flattered-laboring-reusable-comic", + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", - "created_at": "2024-06-19T07:12:46.000Z", - "crn": "crn:185", + "created_at": "2024-09-09T09:10:35.000Z", + "crn": "crn:166", "disks": [], "enable_secure_boot": false, "health_reasons": [], "health_state": "ok", - "href": "href:186", - "id": "id:187", + "href": "href:167", + "id": "id:168", "image": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", + "crn": "crn:153", + "href": "href:154", + "id": "id:155", "name": "server-9080", "resource_type": "image" }, @@ -1730,18 +1791,18 @@ "protocol": "http", "response_hop_limit": 1 }, - "name": "fe", + "name": "vsi3b", "network_attachments": [], "numa_count": 1, "primary_network_interface": { - "href": "href:88", - "id": "id:89", - "name": "litigate-bullfrog-improve-shandy", + "href": "href:87", + "id": "id:88", + "name": "ni3b", "primary_ip": { - "address": "10.240.128.6", - "href": "href:86", - "id": "id:87", - "name": "manic-nerve-surfboard-cofounder", + "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", @@ -1749,12 +1810,12 @@ "crn": "crn:67", "href": "href:68", "id": "id:69", - "name": "sub2", + "name": "subnet3", "resource_type": "subnet" } }, "profile": { - "href": "href:175", + "href": "href:156", "name": "cx2-2x4", "resource_type": "instance_profile" }, @@ -1781,16 +1842,16 @@ "volume_attachments": [ { "device": { - "id": "id:190" + "id": "id:171" }, - "href": "href:188", - "id": "id:189", - "name": "scarily-reapprove-ecologist-gosling", + "href": "href:169", + "id": "id:170", + "name": "camera-yam-headfirst-scabiosa", "volume": { - "crn": "crn:191", - "href": "href:192", - "id": "id:193", - "name": "flattered-laboring-reusable-comic", + "crn": "crn:172", + "href": "href:173", + "id": "id:174", + "name": "sprinkler-avenue-playset-dislodge", "resource_type": "volume" } } @@ -1799,36 +1860,36 @@ "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "zone": { - "href": "href:7", - "name": "us-south-3" + "href": "href:5", + "name": "us-south-1" }, "network_interfaces": [ { "allow_ip_spoofing": false, - "created_at": "2024-06-19T07:12:46.000Z", + "created_at": "2024-09-09T09:10:34.000Z", "floating_ips": [], - "href": "href:88", - "id": "id:89", - "name": "litigate-bullfrog-improve-shandy", + "href": "href:87", + "id": "id:88", + "name": "ni3b", "port_speed": 3000, "primary_ip": { - "address": "10.240.128.6", - "href": "href:86", - "id": "id:87", - "name": "manic-nerve-surfboard-cofounder", + "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": "crn:119", - "href": "href:120", - "id": "id:121", - "name": "fe-sg" + "crn": "fake:crn:12", + "href": "fake:href:12", + "id": "fake:id:12", + "name": "test-vpc1--vsi3b" } ], "status": "available", @@ -1836,7 +1897,7 @@ "crn": "crn:67", "href": "href:68", "id": "id:69", - "name": "sub2", + "name": "subnet3", "resource_type": "subnet" }, "type": "primary" @@ -1851,32 +1912,33 @@ "bandwidth": 4000, "boot_volume_attachment": { "device": { - "id": "id:199" + "id": "id:180" }, - "href": "href:197", - "id": "id:198", - "name": "carnival-grimace-mannequin-lumping", + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", "volume": { - "crn": "crn:200", - "href": "href:201", - "id": "id:202", - "name": "wands-niece-whole-cocoa", + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", "resource_type": "volume" } }, + "cluster_network_attachments": null, "confidential_compute_mode": "disabled", - "created_at": "2024-06-19T07:12:46.000Z", - "crn": "crn:194", + "created_at": "2024-09-09T09:10:34.000Z", + "crn": "crn:175", "disks": [], "enable_secure_boot": false, "health_reasons": [], "health_state": "ok", - "href": "href:195", - "id": "id:196", + "href": "href:176", + "id": "id:177", "image": { - "crn": "crn:172", - "href": "href:173", - "id": "id:174", + "crn": "crn:153", + "href": "href:154", + "id": "id:155", "name": "server-9080", "resource_type": "image" }, @@ -1888,18 +1950,18 @@ "protocol": "http", "response_hop_limit": 1 }, - "name": "be", + "name": "vsi3a", "network_attachments": [], "numa_count": 1, "primary_network_interface": { - "href": "href:80", - "id": "id:81", - "name": "captain-captivity-shorty-crown", + "href": "href:83", + "id": "id:84", + "name": "ni3a", "primary_ip": { - "address": "10.240.128.4", - "href": "href:78", - "id": "id:79", - "name": "magnetism-steersman-botany-hurled", + "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", @@ -1907,12 +1969,12 @@ "crn": "crn:67", "href": "href:68", "id": "id:69", - "name": "sub2", + "name": "subnet3", "resource_type": "subnet" } }, "profile": { - "href": "href:175", + "href": "href:156", "name": "cx2-2x4", "resource_type": "instance_profile" }, @@ -1939,16 +2001,16 @@ "volume_attachments": [ { "device": { - "id": "id:199" + "id": "id:180" }, - "href": "href:197", - "id": "id:198", - "name": "carnival-grimace-mannequin-lumping", + "href": "href:178", + "id": "id:179", + "name": "cryptic-cork-saponify-lively", "volume": { - "crn": "crn:200", - "href": "href:201", - "id": "id:202", - "name": "wands-niece-whole-cocoa", + "crn": "crn:181", + "href": "href:182", + "id": "id:183", + "name": "appraisal-mountains-itinerary-twine", "resource_type": "volume" } } @@ -1957,48 +2019,36 @@ "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" }, "zone": { - "href": "href:7", - "name": "us-south-3" + "href": "href:5", + "name": "us-south-1" }, "network_interfaces": [ { "allow_ip_spoofing": false, - "created_at": "2024-06-19T07:12:46.000Z", + "created_at": "2024-09-09T09:10:34.000Z", "floating_ips": [], - "href": "href:80", - "id": "id:81", - "name": "captain-captivity-shorty-crown", + "href": "href:83", + "id": "id:84", + "name": "ni3a", "port_speed": 3000, "primary_ip": { - "address": "10.240.128.4", - "href": "href:78", - "id": "id:79", - "name": "magnetism-steersman-botany-hurled", + "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": "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" + "crn": "fake:crn:10", + "href": "fake:href:10", + "id": "fake:id:10", + "name": "test-vpc1--vsi3a" } ], "status": "available", @@ -2006,7 +2056,7 @@ "crn": "crn:67", "href": "href:68", "id": "id:69", - "name": "sub2", + "name": "subnet3", "resource_type": "subnet" }, "type": "primary" @@ -2015,6 +2065,7 @@ "tags": [] } ], + "virtual_nis": null, "routing_tables": [ { "accept_routes_from": [ @@ -2026,12 +2077,14 @@ } ], "advertise_routes_to": [], - "created_at": "2024-06-19T07:11:57.000Z", + "created_at": "2024-09-09T09:09:51.000Z", + "crn": null, "href": "href:11", "id": "id:12", "is_default": true, "lifecycle_state": "stable", - "name": "unguarded-corncob-unaired-corner", + "name": "fiscally-fresh-uncanny-ceramics", + "resource_group": null, "resource_type": "routing_table", "route_direct_link_ingress": false, "route_internet_ingress": false, @@ -2042,21 +2095,21 @@ "crn": "crn:24", "href": "href:25", "id": "id:26", - "name": "sub1", + "name": "subnet2", "resource_type": "subnet" }, { - "crn": "crn:49", - "href": "href:50", - "id": "id:51", - "name": "sub3", + "crn": "crn:47", + "href": "href:48", + "id": "id:49", + "name": "subnet1", "resource_type": "subnet" }, { "crn": "crn:67", "href": "href:68", "id": "id:69", - "name": "sub2", + "name": "subnet3", "resource_type": "subnet" } ], @@ -2065,7 +2118,7 @@ "crn": "crn:1", "href": "href:2", "id": "id:3", - "name": "test-vpc", + "name": "test-vpc1", "resource_type": "vpc" } } @@ -2074,4 +2127,4 @@ "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..f9db31d6 --- /dev/null +++ b/test/data/optimize_sg_redundant/conn_spec.json @@ -0,0 +1,100 @@ +{ + "externals": { + "e1": "0.0.0.0/30", + "e2": "0.0.0.0/31", + "e3": "1.0.0.0/30", + "e4": "1.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": "e3", + "type": "external" + } + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "e4", + "type": "external" + }, + "allowed-protocols": [ + { + "protocol": "TCP" + } + ] + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "name": "vsi2", + "type": "instance" + } + }, + { + "src": { + "name": "vsi1", + "type": "instance" + }, + "dst": { + "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 new file mode 100644 index 00000000..c07d18d8 --- /dev/null +++ b/test/data/optimize_sg_redundant/details.txt @@ -0,0 +1,20 @@ +original config object: acl_testing4 config + +######## BEFORE ######## + +vsi1 --> 0.0.0.0/30 (any protocol) +vsi1 --> 0.0.0.0/31 (any protocol) +vsi1 --> 1.0.0.0/30 (any protocol) +vsi1 --> 1.0.0.0/31 (TCP) + +vsi1 --> vsi2 (any protocol) +vsi1 --> vsi2 (any protocol) +vsi1 --> vsi3a (TCP) +vsi1 --> vsi3a (any protocol) + +######## AFTER ######## + +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/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..30e6764b --- /dev/null +++ b/test/data/optimize_sg_t/details.txt @@ -0,0 +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 (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/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..9d84988b --- /dev/null +++ b/test/data/optimize_sg_t_all/details.txt @@ -0,0 +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 (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 (any protocol) \ No newline at end of file diff --git a/test/data_for_testing_errors/vpe_acl/conn_spec.json b/test/data_for_testing_errors/vpe_acl/conn_spec.json deleted file mode 100644 index 1d6e39eb..00000000 --- a/test/data_for_testing_errors/vpe_acl/conn_spec.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "required-connections": [ - { - "src": { - "name": "sub1", - "type": "subnet" - }, - "dst": { - "name": "policydb-endpoint-gateway", - "type": "vpe" - } - } - ] -} 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..2e4c7efb --- /dev/null +++ b/test/expected/optimize_sg_protocols_to_all_csv/sg_expected.csv @@ -0,0 +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/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,, +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 new file mode 100644 index 00000000..52e2f303 --- /dev/null +++ b/test/expected/optimize_sg_protocols_to_all_md/sg_expected.md @@ -0,0 +1,10 @@ + | 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 | | | + | 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 new file mode 100644 index 00000000..10f44116 --- /dev/null +++ b/test/expected/optimize_sg_protocols_to_all_tf/sg_expected.tf @@ -0,0 +1,82 @@ +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 = 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" +} + + +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 +} +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 new file mode 100644 index 00000000..7319be9e --- /dev/null +++ b/test/expected/optimize_sg_redundant/sg_expected.tf @@ -0,0 +1,90 @@ +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 = 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" { + 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_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" { + 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/sg_expected.tf b/test/expected/optimize_sg_t/sg_expected.tf new file mode 100644 index 00000000..448d25d8 --- /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/29" + tcp { + 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" + tcp { + port_max = 20 + } +} + + +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..0f4d41e0 --- /dev/null +++ b/test/expected/optimize_sg_t_all/sg_expected.tf @@ -0,0 +1,73 @@ +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 = 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" { + 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/synth_test_list.go b/test/main_test_list.go similarity index 84% rename from test/synth_test_list.go rename to test/main_test_list.go index b3c40448..709e0ae6 100644 --- a/test/synth_test_list.go +++ b/test/main_test_list.go @@ -7,16 +7,18 @@ 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" ) const ( - 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" + 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" + optimizeSGProtocolsToAllConfig = "%s/optimize_sg_protocols_to_all/config_object.json" aclExternalsSpec = "%s/acl_externals/conn_spec.json" aclNifSpec = "%s/acl_nif/conn_spec.json" @@ -35,10 +37,11 @@ const ( sgTgMultipleSpec = "%s/sg_tg_multiple/conn_spec.json" tfOutputFmt = "tf" + vsi1 = "test-vpc1--vsi1" ) func allMainTests() []testCase { - return append(synthACLTestsList(), synthSGTestsList()...) + return slices.Concat(synthACLTestsList(), synthSGTestsList(), optimizeSGTestsLists()) } //nolint:funlen //all acl synthesis tests @@ -421,3 +424,66 @@ func synthSGTestsList() []testCase { }, } } + +// 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{ + { + 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", + }, + }, + { + 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", + }, + }, + { + 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", + }, + }, + { + 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", + }, + }, + { + 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 c20ff849..4d96e1bf 100644 --- a/test/tests_defs.go +++ b/test/tests_defs.go @@ -15,16 +15,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 ( @@ -36,6 +37,7 @@ const ( defaultDirectoryPermission = 0o755 synthesis string = "synth" + optimize string = "optimize" acl string = "acl" sg string = "sg" ) @@ -73,6 +75,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 }