Skip to content

Commit

Permalink
Merge branch 'main' into subnet-grouping2
Browse files Browse the repository at this point in the history
  • Loading branch information
haim-kermany committed Dec 27, 2023
2 parents 3db9e2b + e238dea commit bf29ee0
Show file tree
Hide file tree
Showing 114 changed files with 31,701 additions and 3,758 deletions.
29 changes: 21 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,32 @@ This repo contains packages and a CLI for analyzing the network connectivity of
$ ./bin/vpcanalyzer -h
Usage of vpc-network-config-analyzer:
-analysis-type string
supported analysis types: all_endpoints,all_subnets,single_subnet, diff_all_endpoints, diff_all_subnets (default "all_endpoints")
Supported analysis types:
* all_endpoints - supported with: txt, md, json, drawio, arch_drawio, debug
* all_subnets - supported with: txt, json
* single_subnet - supported with: txt
* diff_all_endpoints - supported with: txt, md
* diff_all_subnets - supported with: txt, md
(default "all_endpoints")
-debug
Run in debug mode
-format string
output format; must be one of txt,md,drawio,arch_drawio,json (default "txt")
Output format; must be one of:
txt, md, json, drawio, arch_drawio, debug (default "txt")
-grouping
whether to group together src/dst entries with identical connectivity
Whether to group together src/dst entries with identical connectivity
Does not support single_subnet, diff_all_endpoints and diff_all_subnets analysis-types and json output format
-output-file string
file path to store results
File path to store results
-version
Prints the release version number
-vpc string
CRN of the VPC to analyze
-vpc-config string
file path to input config
Required. File path to input config
-vpc-config-second string
file path to the 2nd input config; relevant only for analysis-type diff_all_endpoints and for diff_all_subnets
-version
prints the release version number
File path to the 2nd input config; relevant only for analysis-type diff_all_endpoints and for diff_all_subnets
```

### Input config files
Expand Down
2 changes: 1 addition & 1 deletion cmd/analyzer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func _main(cmdlineArgs []string) error {
}

var out string
out, err = vpcmodel.AggregateVPCsOutput(outputPerVPC, getOutputFormat(inArgs), outFile)
out, err = vpcmodel.AggregateVPCsOutput(outputPerVPC, getOutputFormat(inArgs), analysisTypeToUseCase(inArgs), outFile)
if err != nil {
return err
}
Expand Down
80 changes: 52 additions & 28 deletions cmd/analyzer/parse_args.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,35 +58,59 @@ const (
singleSubnet = "single_subnet" // single subnet connectivity analysis
allEndpointsDiff = "diff_all_endpoints" // semantic diff of allEndpoints analysis between two configurations
allSubnetsDiff = "diff_all_subnets" // semantic diff of allSubnets analysis between two configurations

// separator
separator = ", "
)

var supportedOutputFormats = map[string]bool{
var supportedOutputFormatsMap = map[string]bool{
JSONFormat: true,
TEXTFormat: true,
MDFormat: true,
DRAWIOFormat: true,
ARCHDRAWIOFormat: true,
DEBUGFormat: true,
}
var supportedAnalysisTypes = map[string]bool{
allEndpoints: true,
allSubnets: true,
singleSubnet: true,
allEndpointsDiff: true,
allSubnetsDiff: true,

// supportedAnalysisTypesMap is a map from analysis type to its list of supported output formats
var supportedAnalysisTypesMap = map[string][]string{
allEndpoints: {TEXTFormat, MDFormat, JSONFormat, DRAWIOFormat, ARCHDRAWIOFormat, DEBUGFormat},
allSubnets: {TEXTFormat, JSONFormat},
singleSubnet: {TEXTFormat},
allEndpointsDiff: {TEXTFormat, MDFormat},
allSubnetsDiff: {TEXTFormat, MDFormat},
}

// supportedOutputFormatsList is an ordered list of supported output formats (usage details presented in this order)
var supportedOutputFormatsList = []string{
TEXTFormat,
MDFormat,
JSONFormat,
DRAWIOFormat,
ARCHDRAWIOFormat,
DEBUGFormat,
}

func getSupportedValuesString(supportedValues map[string]bool) string {
valuesList := make([]string, len(supportedValues))
// supportedAnalysisTypesList is an ordered list of supported analysis types (usage details presented in this order)
var supportedAnalysisTypesList = []string{
allEndpoints,
allSubnets,
singleSubnet,
allEndpointsDiff,
allSubnetsDiff,
}

func getSupportedAnalysisTypesMapString() string {
valuesList := make([]string, len(supportedAnalysisTypesList)+1)
i := 0
for value := range supportedValues {
valuesList[i] = value
for _, key := range supportedAnalysisTypesList {
valuesList[i] = "* " + key + " - supported with: " + strings.Join(supportedAnalysisTypesMap[key], separator)
i += 1
}
return strings.Join(valuesList, ",")
return strings.Join(valuesList, "\n")
}

// parseCmdLine checks if unspported arguments were passed
// parseCmdLine checks if unsupported arguments were passed
func parseCmdLine(cmdlineArgs []string) error {
argIsFlag := true
for _, arg := range cmdlineArgs {
Expand Down Expand Up @@ -122,18 +146,19 @@ func parseCmdLine(cmdlineArgs []string) error {
func ParseInArgs(cmdlineArgs []string) (*InArgs, error) {
args := InArgs{}
flagset := flag.NewFlagSet("vpc-network-config-analyzer", flag.ContinueOnError)
args.InputConfigFile = flagset.String(InputConfigFile, "", "file path to input config")
args.InputSecondConfigFile = flagset.String(InputSecondConfigFile, "", "file path to the 2nd input config; "+
args.InputConfigFile = flagset.String(InputConfigFile, "", "Required. File path to input config")
args.InputSecondConfigFile = flagset.String(InputSecondConfigFile, "", "File path to the 2nd input config; "+
"relevant only for analysis-type diff_all_endpoints and for diff_all_subnets")
args.OutputFile = flagset.String(OutputFile, "", "file path to store results")
args.OutputFile = flagset.String(OutputFile, "", "File path to store results")
args.OutputFormat = flagset.String(OutputFormat, TEXTFormat,
"output format; must be one of "+getSupportedValuesString(supportedOutputFormats))
"Output format; must be one of:\n"+strings.Join(supportedOutputFormatsList, separator))
args.AnalysisType = flagset.String(AnalysisType, allEndpoints,
"supported analysis types: "+getSupportedValuesString(supportedAnalysisTypes))
args.Grouping = flagset.Bool(Grouping, false, "whether to group together src/dst entries with identical connectivity")
"Supported analysis types:\n"+getSupportedAnalysisTypesMapString())
args.Grouping = flagset.Bool(Grouping, false, "Whether to group together src/dst entries with identical connectivity\n"+
"Does not support single_subnet, diff_all_endpoints and diff_all_subnets analysis-types and json output format")
args.VPC = flagset.String(VPC, "", "CRN of the VPC to analyze")
args.Debug = flagset.Bool(Debug, false, "run in debug mode")
args.Version = flagset.Bool(Version, false, "prints the release version number")
args.Debug = flagset.Bool(Debug, false, "Run in debug mode")
args.Version = flagset.Bool(Version, false, "Prints the release version number")

// calling parseCmdLine prior to flagset.Parse to ensure that excessive and unsupported arguments are handled
// for example, flagset.Parse() ignores input args missing the `-`
Expand All @@ -157,19 +182,18 @@ func ParseInArgs(cmdlineArgs []string) (*InArgs, error) {

return &args, nil
}

func errorInErgs(args *InArgs, flagset *flag.FlagSet) error {
if !*args.Version && (args.InputConfigFile == nil || *args.InputConfigFile == "") {
flagset.PrintDefaults()
return fmt.Errorf("missing parameter: vpc-config")
}
if !supportedAnalysisTypes[*args.AnalysisType] {
if _, ok := supportedAnalysisTypesMap[*args.AnalysisType]; !ok {
flagset.PrintDefaults()
return fmt.Errorf("wrong analysis type %s; must be one of: %s", *args.AnalysisType, getSupportedValuesString(supportedAnalysisTypes))
return fmt.Errorf("wrong analysis type %s; must be one of: %s", *args.AnalysisType, strings.Join(supportedAnalysisTypesList, separator))
}
if !supportedOutputFormats[*args.OutputFormat] {
if !supportedOutputFormatsMap[*args.OutputFormat] {
flagset.PrintDefaults()
return fmt.Errorf("wrong output format %s; must be one of %s", *args.OutputFormat, getSupportedValuesString(supportedOutputFormats))
return fmt.Errorf("wrong output format %s; must be one of: %s", *args.OutputFormat, strings.Join(supportedOutputFormatsList, separator))
}
if *args.OutputFormat == DEBUGFormat && *args.AnalysisType != allEndpoints {
return fmt.Errorf("output format %s supported on for %s", DEBUGFormat, allEndpoints)
Expand All @@ -195,8 +219,8 @@ func notSupportedYetArgs(args *InArgs) error {
if diffAnalysis && *args.OutputFormat != TEXTFormat && *args.OutputFormat != MDFormat {
return fmt.Errorf("currently only txt/md output format supported with %s analysis type", *args.AnalysisType)
}
if *args.AnalysisType == singleSubnet && *args.Grouping {
return fmt.Errorf("currently singleSubnet analysis type does not support grouping")
if (*args.AnalysisType == singleSubnet || diffAnalysis) && *args.Grouping {
return fmt.Errorf("currently %s analysis type does not support grouping", *args.AnalysisType)
}
if *args.OutputFormat == JSONFormat && *args.Grouping {
return fmt.Errorf("json output format is not supported with grouping")
Expand Down
46 changes: 20 additions & 26 deletions pkg/ibmvpc/analysis_output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ func getTestFileName(testName string,
grouping bool,
format vpcmodel.OutFormat,
configName string,
numConfigs int,
allVPCs bool) (
expectedFileName,
actualFileName string,
Expand All @@ -76,12 +75,10 @@ func getTestFileName(testName string,

// if there are more than one vpc in the config, split to a file per one vpc analysis
baseName := testName
if numConfigs > 1 {
if allVPCs {
baseName += "_all_vpcs"
} else {
baseName += "_" + configName
}
if allVPCs {
baseName += "_all_vpcs_"
} else {
baseName += "_" + configName
}

switch uc {
Expand Down Expand Up @@ -531,11 +528,10 @@ func compareOrRegenerateOutputPerTest(t *testing.T,

func initTestFileNames(tt *vpcGeneralTest,
uc vpcmodel.OutputUseCase,
numConfigs int,
vpcName string,
allVPCs bool) error {
expectedFileName, actualFileName, err := getTestFileName(
tt.name, uc, tt.grouping, tt.format, vpcName, numConfigs, allVPCs)
tt.name, uc, tt.grouping, tt.format, vpcName, allVPCs)
if err != nil {
return err
}
Expand All @@ -559,7 +555,7 @@ func runTestPerUseCase(t *testing.T,
vpcConfig2nd = vpcConfig
}
for _, vpcConfig := range c1 {
if err := initTestFileNames(tt, uc, numConfigs, vpcConfig.VPC.Name(), false); err != nil {
if err := initTestFileNames(tt, uc, vpcConfig.VPC.Name(), false); err != nil {
return err
}

Expand All @@ -577,24 +573,22 @@ func runTestPerUseCase(t *testing.T,
return err
}
}
// if more then one vpc -- compare also the aggregated output
if numConfigs > 1 {
if err := initTestFileNames(tt, uc, numConfigs, "", true); err != nil {
return err
}
// compare also the aggregated output
if err := initTestFileNames(tt, uc, "", true); err != nil {
return err
}

// sort allVPCsOutput by vpc name
sort.Slice(allVPCsOutput, func(i, j int) bool {
return allVPCsOutput[i].VPC1Name < allVPCsOutput[j].VPC1Name
})
// sort allVPCsOutput by vpc name
sort.Slice(allVPCsOutput, func(i, j int) bool {
return allVPCsOutput[i].VPC1Name < allVPCsOutput[j].VPC1Name
})

actualOutput, err := vpcmodel.AggregateVPCsOutput(allVPCsOutput, tt.format, tt.actualOutput[uc])
if err != nil {
return err
}
if err := compareOrRegenerateOutputPerTest(t, mode, actualOutput, tt, uc); err != nil {
return err
}
actualOutput, err := vpcmodel.AggregateVPCsOutput(allVPCsOutput, tt.format, uc, tt.actualOutput[uc])
if err != nil {
return err
}
if err := compareOrRegenerateOutputPerTest(t, mode, actualOutput, tt, uc); err != nil {
return err
}

return nil
Expand Down
24 changes: 0 additions & 24 deletions pkg/ibmvpc/connectivityAnalysis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,9 @@ var expectedConnStrTest1 = `=================================== distributed inbo
=================================== combined connections - short version:
vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : All Connections
vsi-0-subnet-2[10.240.20.4] => vsi-0-subnet-1[10.240.10.4] : All Connections
connections are stateful unless marked with *
=================================== stateful combined connections - short version:
vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : All Connections
vsi-0-subnet-2[10.240.20.4] => vsi-0-subnet-1[10.240.10.4] : All Connections
connections are stateful unless marked with *
`

func TestAnalyzeConnectivity1(t *testing.T) {
Expand All @@ -173,13 +167,7 @@ var expectedConnStrTest2 = `=================================== distributed inbo
10.240.20.4 => 10.240.10.4 : No Connections
=================================== combined connections - short version:
vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : All Connections *
connections are stateful unless marked with *
=================================== stateful combined connections - short version:
connections are stateful unless marked with *
`

func TestAnalyzeConnectivity2(t *testing.T) {
Expand All @@ -197,15 +185,9 @@ var expectedConnStrTest3 = `=================================== distributed inbo
=================================== combined connections - short version:
vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : All Connections *
vsi-0-subnet-2[10.240.20.4] => vsi-0-subnet-1[10.240.10.4] : protocol: TCP
connections are stateful unless marked with *
=================================== stateful combined connections - short version:
vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : protocol: TCP
vsi-0-subnet-2[10.240.20.4] => vsi-0-subnet-1[10.240.10.4] : protocol: TCP
connections are stateful unless marked with *
`

func TestAnalyzeConnectivity3(t *testing.T) {
Expand All @@ -223,15 +205,9 @@ var expectedConnStrTest4 = `=================================== distributed inbo
=================================== combined connections - short version:
vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : protocol: TCP src-ports: 10-100 dst-ports: 443
vsi-0-subnet-2[10.240.20.4] => vsi-0-subnet-1[10.240.10.4] : protocol: TCP src-ports: 443 dst-ports: 10-100
connections are stateful unless marked with *
=================================== stateful combined connections - short version:
vsi-0-subnet-1[10.240.10.4] => vsi-0-subnet-2[10.240.20.4] : protocol: TCP src-ports: 10-100 dst-ports: 443
vsi-0-subnet-2[10.240.20.4] => vsi-0-subnet-1[10.240.10.4] : protocol: TCP src-ports: 443 dst-ports: 10-100
connections are stateful unless marked with *
`

func TestAnalyzeConnectivity4(t *testing.T) {
Expand Down
Loading

0 comments on commit bf29ee0

Please sign in to comment.