diff --git a/cmd/analyzer/main_test.go b/cmd/analyzer/main_test.go index 64436e6ff..4cbb96d40 100644 --- a/cmd/analyzer/main_test.go +++ b/cmd/analyzer/main_test.go @@ -231,7 +231,7 @@ func TestMainWithExpectedOut(t *testing.T) { // comparison should be insensitive to line comparators; cleaning strings from line comparators func cleanStr(str string) string { - return strings.ReplaceAll(strings.ReplaceAll(str, "/n", ""), "\r", "") + return strings.ReplaceAll(str, "\r", "") } func removeGeneratedFiles() { diff --git a/cmd/analyzer/subcmds/explain.go b/cmd/analyzer/subcmds/explain.go index 0a2b57a56..ff0747556 100644 --- a/cmd/analyzer/subcmds/explain.go +++ b/cmd/analyzer/subcmds/explain.go @@ -11,7 +11,6 @@ import ( "github.com/spf13/cobra" - "github.com/np-guard/models/pkg/connection" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" @@ -64,7 +63,7 @@ func NewExplainCommand(args *inArgs) *cobra.Command { } func portInRange(port int64) bool { - if port > connection.MaxPort || port < connection.MinPort { + if port > netp.MaxPort || port < netp.MinPort { return false } @@ -112,7 +111,7 @@ func validateExplainFlags(cmd *cobra.Command, args *inArgs) error { if !portInRange(args.eSrcMinPort) || !portInRange(args.eSrcMaxPort) || !portInRange(args.eDstMinPort) || !portInRange(args.eDstMaxPort) { return fmt.Errorf("port number must be in between %d, %d, inclusive", - connection.MinPort, connection.MaxPort) + netp.MinPort, netp.MaxPort) } return nil diff --git a/go.mod b/go.mod index 4079ff2ca..49ff41c9e 100644 --- a/go.mod +++ b/go.mod @@ -4,32 +4,32 @@ go 1.23.1 require ( github.com/IBM/networking-go-sdk v0.49.0 - github.com/IBM/vpc-go-sdk v0.58.0 + github.com/IBM/vpc-go-sdk v0.60.0 github.com/aws/aws-sdk-go-v2/service/ec2 v1.163.0 - github.com/np-guard/cloud-resource-collector v0.15.0 - github.com/np-guard/models v0.4.0 + github.com/np-guard/cloud-resource-collector v0.16.0 + github.com/np-guard/models v0.5.2 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 ) require ( github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240510130133-9f76aa34af27 // indirect - github.com/IBM/go-sdk-core/v5 v5.17.4 // indirect - github.com/IBM/platform-services-go-sdk v0.65.0 // indirect + github.com/IBM/go-sdk-core/v5 v5.17.5 // indirect + github.com/IBM/platform-services-go-sdk v0.69.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go-v2 v1.30.3 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.27 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.27 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect - github.com/aws/smithy-go v1.20.3 // indirect + github.com/aws/aws-sdk-go-v2 v1.32.0 // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.41 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.39 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.15 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.0 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.32.0 // indirect + github.com/aws/smithy-go v1.22.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/gabriel-vasile/mimetype v1.4.4 // indirect diff --git a/go.sum b/go.sum index 7e4a24ace..0daf04ef9 100644 --- a/go.sum +++ b/go.sum @@ -2,46 +2,46 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240510130133-9f76aa34af27 h1:WJ7RTGvACcoV5wgwfQ/BEiYn45V7ewzqtaNOuNapqec= github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240510130133-9f76aa34af27/go.mod h1:xUQL9SGAjoZFd4GNjrjjtEpjpkgU7RFXRyHesbKTjiY= github.com/IBM/go-sdk-core/v5 v5.5.1/go.mod h1:Sn+z+qTDREQvCr+UFa22TqqfXNxx3o723y8GsfLV8e0= -github.com/IBM/go-sdk-core/v5 v5.17.4 h1:VGb9+mRrnS2HpHZFM5hy4J6ppIWnwNrw0G+tLSgcJLc= -github.com/IBM/go-sdk-core/v5 v5.17.4/go.mod h1:KsAAI7eStAWwQa4F96MLy+whYSh39JzNjklZRbN/8ns= +github.com/IBM/go-sdk-core/v5 v5.17.5 h1:AjGC7xNee5tgDIjndekBDW5AbypdERHSgib3EZ1KNsA= +github.com/IBM/go-sdk-core/v5 v5.17.5/go.mod h1:KsAAI7eStAWwQa4F96MLy+whYSh39JzNjklZRbN/8ns= github.com/IBM/networking-go-sdk v0.49.0 h1:lPS34u3C0JVrbxH+Ulua76Nwl6Frv8BEfq6LRkyvOv0= github.com/IBM/networking-go-sdk v0.49.0/go.mod h1:G9CKbmPE8gSLjN+ABh4hIZ1bMx076enl5Eekvj6zQnA= -github.com/IBM/platform-services-go-sdk v0.65.0 h1:SAk/Rsn2BLRmeU3z6YJm54TK23/9QJaOPjrjYNGBiPU= -github.com/IBM/platform-services-go-sdk v0.65.0/go.mod h1:6rYd3stLSnotYmZlxclw45EJPaQuLmh5f7c+Mg7rOg4= -github.com/IBM/vpc-go-sdk v0.58.0 h1:Slk1jkcV7tPnf0iECQV2Oja7W8Bom0z7k9M4fMBY4bI= -github.com/IBM/vpc-go-sdk v0.58.0/go.mod h1:swmxiYLT+OfBsBYqJWGeRd6NPmBk4u/het2PZdtzIaw= +github.com/IBM/platform-services-go-sdk v0.69.1 h1:Wb8BYVpsPIppWbOQCgF7ytm+BbSOXdWWCf9zcZ6xGA4= +github.com/IBM/platform-services-go-sdk v0.69.1/go.mod h1:ZP3zUDxR1qRdUqzFdnJOlQN0QpVYol2eOUCv4uk03Jc= +github.com/IBM/vpc-go-sdk v0.60.0 h1:4MD9dTmg+alJivsAEPmKE4qx59nv0Gsweju/XF+Z2jo= +github.com/IBM/vpc-go-sdk v0.60.0/go.mod h1:swmxiYLT+OfBsBYqJWGeRd6NPmBk4u/het2PZdtzIaw= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= -github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= -github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= -github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= -github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI= -github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= +github.com/aws/aws-sdk-go-v2 v1.32.0 h1:GuHp7GvMN74PXD5C97KT5D87UhIy4bQPkflQKbfkndg= +github.com/aws/aws-sdk-go-v2 v1.32.0/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= +github.com/aws/aws-sdk-go-v2/config v1.27.41 h1:esG3WpmEuNJ6F4kVFLumN8nCfA5VBav1KKb3JPx83O4= +github.com/aws/aws-sdk-go-v2/config v1.27.41/go.mod h1:haUg09ebP+ClvPjU3EB/xe0HF9PguO19PD2fdjM2X14= +github.com/aws/aws-sdk-go-v2/credentials v1.17.39 h1:tmVexAhoGqJxNE2oc4/SJqL+Jz1x1iCPt5ts9XcqZCU= +github.com/aws/aws-sdk-go-v2/credentials v1.17.39/go.mod h1:zgOdbDI9epE608PdboJ87CYvPIejAgFevazeJW6iauQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.15 h1:kGjlNc2IXXcxPDcfMyCshNCjVgxUhC/vTJv7NvC9wKk= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.15/go.mod h1:rk/HmqPo+dX0Uv0Q1+4w3QKFdICEGSsTYz1hRWvH8UI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19 h1:Q/k5wCeJkSWs+62kDfOillkNIJ5NqmE3iOfm48g/W8c= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19/go.mod h1:Wns1C66VvtA2Bv/cUBuKZKQKdjo7EVMhp90aAa+8oTI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19 h1:AYLE0lUfKvN6icFTR/p+NmD1amYKTbqHQ1Nm+jwE6BM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19/go.mod h1:1giLakj64GjuH1NBzF/DXqly5DWHtMTaOzRZ53nFX0I= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= github.com/aws/aws-sdk-go-v2/service/ec2 v1.163.0 h1:gwthjSMr5tW2fYBJNt3LQGgtkREvv5IcuaWRjeo1fh0= github.com/aws/aws-sdk-go-v2/service/ec2 v1.163.0/go.mod h1:eu3DWRK5GBq4hjCr7nAbnQiHSan5RJ6ue3qQVp5PJs0= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ= -github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= -github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0 h1:AdbiDUgQZmM28rDIZbiSwFxz8+3B94aOXxzs6oH+EA0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0/go.mod h1:uV476Bd80tiDTX4X2redMtagQUg65aU/gzPojSJ4kSI= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.0 h1:71FvP6XFj53NK+YiAEGVzeiccLVeFnHOCvMig0zOHsE= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.0/go.mod h1:UVJqtKXSd9YppRKgdBIkyv7qgbSGv5DchM3yX0BN2mU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.0 h1:Uco4o19bi3AmBapImNzuMk+rfzlui52BDyVK1UfJeRA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.0/go.mod h1:+HLFhCpnG08hBee8bUdfd1mBK+rFKPt4O5igR9lXDfk= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.0 h1:GiQUjZM2KUZX68o/LpZ1xqxYMuvoxpRrOwYARYog3vc= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.0/go.mod h1:dKnu7M4MAS2SDlng1ytxd03H+y0LoUfEQ5E2VaaSw/4= +github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= +github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -165,10 +165,10 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/np-guard/cloud-resource-collector v0.15.0 h1:jkmxql6D1uBr/qmSOsBzUgeDxlUXSCe7dBKfqfK+QZ4= -github.com/np-guard/cloud-resource-collector v0.15.0/go.mod h1:klCHnNnuuVcCtGQHA7R1a8fqnvfMCk/5Jdld6V7sN2A= -github.com/np-guard/models v0.4.0 h1:lU9XymcjwOJ5RQdVpziurqBmcLtlKVIQxVUwm+qMczk= -github.com/np-guard/models v0.4.0/go.mod h1:mqE2Irf8r+7HWh8fII0fWbWyQRMHGEo2SgSLN/6VKs8= +github.com/np-guard/cloud-resource-collector v0.16.0 h1:KxFLcH19ZIvfGU63jJuMNN5sxW1uSdOrhCDwKHOyy0M= +github.com/np-guard/cloud-resource-collector v0.16.0/go.mod h1:93qwf/IT1L2Bv+6C6kund2GmKrSupTPujT0Nh6qB+mg= +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/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/awsvpc/nacl_analysis.go b/pkg/awsvpc/nacl_analysis.go index 5d4a920b4..700acf4e8 100644 --- a/pkg/awsvpc/nacl_analysis.go +++ b/pkg/awsvpc/nacl_analysis.go @@ -12,8 +12,8 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ec2/types" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" ) @@ -21,7 +21,7 @@ import ( // AWSNACLAnalyzer implements commonvpc.SpecificNACLAnalyzer type AWSNACLAnalyzer struct { naclResource *types.NetworkAcl - referencedIPblocks []*ipblock.IPBlock + referencedIPblocks []*netset.IPBlock // all over the analyzer code, we assume that the acl rules are ordered by their priority. // however, in aws, the priority is being config by the rule number, and the order has no meaning. // so prioritiesEntries are the entries as in naclResource.Entries, sorted by the rule number: @@ -43,18 +43,18 @@ func (na *AWSNACLAnalyzer) Name() *string { return getResourceName(na.naclResource.Tags, na.naclResource.NetworkAclId) } -func (na *AWSNACLAnalyzer) ReferencedIPblocks() []*ipblock.IPBlock { +func (na *AWSNACLAnalyzer) ReferencedIPblocks() []*netset.IPBlock { return na.referencedIPblocks } // SetReferencedIPblocks updates referenced ip blocks -func (na *AWSNACLAnalyzer) SetReferencedIPblocks(referencedIPblocks []*ipblock.IPBlock) { +func (na *AWSNACLAnalyzer) SetReferencedIPblocks(referencedIPblocks []*netset.IPBlock) { na.referencedIPblocks = referencedIPblocks } // GetNACLRule gets index of the rule and returns the rule results line and obj func (na *AWSNACLAnalyzer) GetNACLRule(index int) (ruleStr string, ruleRes *commonvpc.NACLRule, isIngress bool, err error) { - var conns *connection.Set + var conns *netset.TransportSet var connStr string ruleObj := na.prioritiesEntries[index] protocol := convertProtocol(*ruleObj.Protocol) @@ -62,13 +62,13 @@ func (na *AWSNACLAnalyzer) GetNACLRule(index int) (ruleStr string, ruleRes *comm portsStr := "" switch protocol { case allProtocols: - conns = connection.All() + conns = netset.AllTransports() case protocolTCP, protocolUDP: minPort := int64(*ruleObj.PortRange.From) maxPort := int64(*ruleObj.PortRange.To) conns = commonvpc.GetTCPUDPConns(protocol, - connection.MinPort, - connection.MaxPort, + netp.MinPort, + netp.MaxPort, minPort, maxPort, ) @@ -86,19 +86,19 @@ func (na *AWSNACLAnalyzer) GetNACLRule(index int) (ruleStr string, ruleRes *comm if ruleObj.IcmpTypeCode.Code != nil && *ruleObj.IcmpTypeCode.Code != -1 { portsStr += fmt.Sprintf(", code: %d", *ruleObj.IcmpTypeCode.Code) } - conns = connection.ICMPConnection(icmpTypeMin, icmpTypeMax, icmpCodeMin, icmpCodeMax) + conns = netset.NewICMPTransport(icmpTypeMin, icmpTypeMax, icmpCodeMin, icmpCodeMax) default: err = fmt.Errorf("GetNACLRule unsupported protocol type: %s ", *ruleObj.Protocol) return "", nil, false, err } connStr = "protocol: " + protocol + portsStr action := string(ruleObj.RuleAction) - ip, err := ipblock.FromCidr(*ruleObj.CidrBlock) + ip, err := netset.IPBlockFromCidr(*ruleObj.CidrBlock) if err != nil { return "", nil, false, err } isIngress = !*ruleObj.Egress - src, dst := ipblock.GetCidrAll(), ip + src, dst := netset.GetCidrAll(), ip direction := commonvpc.Outbound if isIngress { src, dst = dst, src diff --git a/pkg/awsvpc/parser.go b/pkg/awsvpc/parser.go index 4d24d6761..c71881439 100644 --- a/pkg/awsvpc/parser.go +++ b/pkg/awsvpc/parser.go @@ -18,7 +18,7 @@ import ( "github.com/np-guard/cloud-resource-collector/pkg/aws" "github.com/np-guard/cloud-resource-collector/pkg/common" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/logging" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" @@ -125,7 +125,7 @@ func (rc *AWSresourcesContainer) VPCConfigsFromResources(resourceGroup string, v return nil, err } - var vpcInternalAddressRange map[string]*ipblock.IPBlock // map from vpc name to its internal address range + var vpcInternalAddressRange map[string]*netset.IPBlock // map from vpc name to its internal address range subnetIDToNetIntf := map[string][]*commonvpc.NetworkInterface{} netIntfToSGs := map[string][]types.GroupIdentifier{} @@ -248,8 +248,8 @@ func (rc *AWSresourcesContainer) getSubnetsConfig( res *vpcmodel.MultipleVPCConfigs, subnetNameToNetIntf map[string][]*commonvpc.NetworkInterface, skipByVPC map[string]bool, -) (vpcInternalAddressRange map[string]*ipblock.IPBlock, err error) { - vpcInternalAddressRange = map[string]*ipblock.IPBlock{} +) (vpcInternalAddressRange map[string]*netset.IPBlock, err error) { + vpcInternalAddressRange = map[string]*netset.IPBlock{} for vpcUID := range res.Configs() { vpcInternalAddressRange[vpcUID] = nil } diff --git a/pkg/awsvpc/sg_analysis.go b/pkg/awsvpc/sg_analysis.go index ed65d7367..db6a1cdf1 100644 --- a/pkg/awsvpc/sg_analysis.go +++ b/pkg/awsvpc/sg_analysis.go @@ -11,8 +11,9 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ec2/types" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-analyzer/pkg/common" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" ) @@ -26,7 +27,7 @@ const ( // AWSSGAnalyzer implements commonvpc.SpecificSGAnalyzer type AWSSGAnalyzer struct { sgResource *types.SecurityGroup - referencedIPblocks []*ipblock.IPBlock + referencedIPblocks []*netset.IPBlock sgMap map[string]*commonvpc.SecurityGroup } @@ -40,8 +41,8 @@ func (sga *AWSSGAnalyzer) Name() *string { } func (sga *AWSSGAnalyzer) getRemoteCidr(ipRanges []types.IpRange, userIDGroupPairs []types.UserIdGroupPair) ( - remote *ipblock.IPBlock, err error) { - remote = ipblock.New() + remote *netset.IPBlock, err error) { + remote = netset.NewIPBlock() for i := range ipRanges { target, _, err := commonvpc.GetIPBlockResult(ipRanges[i].CidrIp, nil, nil, sga.sgMap) if err != nil { @@ -75,7 +76,7 @@ func (sga *AWSSGAnalyzer) getProtocolAllRule(ruleObj *types.IpPermission, direct } ruleRes.Remote = commonvpc.NewRuleTarget(remote, "") ruleStr = getRuleStr(direction, connStr, ruleRes.Remote.Cidr.String()) - ruleRes.Connections = connection.All() + ruleRes.Connections = netset.AllTransports() return ruleStr, ruleRes, nil } @@ -92,8 +93,8 @@ func (sga *AWSSGAnalyzer) getProtocolTCPUDPRule(ruleObj *types.IpPermission, dir ruleRes = &commonvpc.SGRule{ // TODO: src ports can be considered here? Connections: commonvpc.GetTCPUDPConns(protocol, - connection.MinPort, - connection.MaxPort, + netp.MinPort, + netp.MaxPort, minPort, maxPort, ), @@ -118,12 +119,12 @@ func handleIcmpTypeCode(icmpType, icmpCode *int32) (newIcmpTypeMin, newIcmpTypeM newIcmpCodeMax = int64(*icmpCode) if newIcmpCodeMin == -1 { - newIcmpCodeMin = connection.MinICMPCode - newIcmpCodeMax = connection.MaxICMPCode + newIcmpCodeMin = int64(netp.MinICMPCode) + newIcmpCodeMax = int64(netp.MaxICMPCode) } if newIcmpTypeMin == -1 { - newIcmpTypeMin = connection.MinICMPType - newIcmpTypeMax = connection.MaxICMPType + newIcmpTypeMin = int64(netp.MinICMPType) + newIcmpTypeMax = int64(netp.MaxICMPType) } return @@ -138,8 +139,8 @@ func (sga *AWSSGAnalyzer) getProtocolICMPRule(ruleObj *types.IpPermission, direc if err != nil { return "", nil, err } - conns := connection.ICMPConnection(icmpTypeMin, icmpTypeMax, icmpCodeMin, icmpCodeMax) - connStr := fmt.Sprintf("protocol: %s, icmpType: %s", *ruleObj.IpProtocol, conns) + conns := netset.NewICMPTransport(icmpTypeMin, icmpTypeMax, icmpCodeMin, icmpCodeMax) + connStr := fmt.Sprintf("protocol: %s, icmpType: %s", *ruleObj.IpProtocol, common.LongString(conns)) remote, err := sga.getRemoteCidr(ruleObj.IpRanges, ruleObj.UserIdGroupPairs) if err != nil { return "", nil, err @@ -200,7 +201,7 @@ func (sga *AWSSGAnalyzer) GetSGRule(index int) ( if err != nil { return "", nil, false, err } - ruleRes.Local = ipblock.GetCidrAll() + ruleRes.Local = netset.GetCidrAll() ruleRes.Index = index tableName := "Inbound" if !isIngress { @@ -220,7 +221,7 @@ func (sga *AWSSGAnalyzer) SetSGmap(sgMap map[string]*commonvpc.SecurityGroup) { } // ReferencedIPblocks returns referencedIPblocks filed -func (sga *AWSSGAnalyzer) ReferencedIPblocks() []*ipblock.IPBlock { +func (sga *AWSSGAnalyzer) ReferencedIPblocks() []*netset.IPBlock { return sga.referencedIPblocks } diff --git a/pkg/awsvpc/sg_analysis_test.go b/pkg/awsvpc/sg_analysis_test.go index 4e03f7fe4..ce6d92574 100644 --- a/pkg/awsvpc/sg_analysis_test.go +++ b/pkg/awsvpc/sg_analysis_test.go @@ -14,9 +14,8 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ec2/types" "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -148,18 +147,18 @@ type sgTest struct { expectedConnectivityMap commonvpc.ConnectivityResultMap } -func fromIPRangeStrWithoutValidation(ipRange string) *ipblock.IPBlock { - ip, _ := ipblock.FromIPRangeStr(ipRange) +func fromIPRangeStrWithoutValidation(ipRange string) *netset.IPBlock { + ip, _ := netset.IPBlockFromIPRangeStr(ipRange) return ip } -func fromIPAddressStrWithoutValidation(ipAddress string) *ipblock.IPBlock { - ip, _ := ipblock.FromIPAddress(ipAddress) +func fromIPAddressStrWithoutValidation(ipAddress string) *netset.IPBlock { + ip, _ := netset.IPBlockFromIPAddress(ipAddress) return ip } -func newIPBlockFromCIDROrAddressWithoutValidation(cidr string) *ipblock.IPBlock { - res, _ := ipblock.FromCidrOrAddress(cidr) +func newIPBlockFromCIDROrAddressWithoutValidation(cidr string) *netset.IPBlock { + res, _ := netset.IPBlockFromCidrOrAddress(cidr) return res } @@ -169,40 +168,40 @@ var sgTests = []sgTest{ rules: []*commonvpc.SGRule{ { Remote: commonvpc.NewRuleTarget(newIPBlockFromCIDROrAddressWithoutValidation("10.250.10.1"), "ola"), - Connections: connection.TCPorUDPConnection(netp.ProtocolString("UDP"), 5, 87, 10, 3245), + Connections: netset.NewTCPorUDPTransport(netp.ProtocolString("UDP"), 5, 87, 10, 3245), Index: 1, - Local: ipblock.GetCidrAll(), + Local: netset.GetCidrAll(), }, { Remote: commonvpc.NewRuleTarget(newIPBlockFromCIDROrAddressWithoutValidation("10.250.10.0/30"), "ola"), - Connections: connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000), + Connections: netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000), Index: 2, - Local: ipblock.GetCidrAll(), + Local: netset.GetCidrAll(), }, }, isIngress: false, - expectedConnectivityMap: map[*ipblock.IPBlock]*commonvpc.ConnectivityResult{ - ipblock.GetCidrAll(): { + expectedConnectivityMap: map[*netset.IPBlock]*commonvpc.ConnectivityResult{ + netset.GetCidrAll(): { IsIngress: false, - AllowedConns: map[*ipblock.IPBlock]*connection.Set{ - fromIPAddressStrWithoutValidation("10.250.10.0"): connection.TCPorUDPConnection( + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPAddressStrWithoutValidation("10.250.10.0"): netset.NewTCPorUDPTransport( netp.ProtocolString("TCP"), 1, 100, 5, 1000), - fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): connection.TCPorUDPConnection( + fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): netset.NewTCPorUDPTransport( netp.ProtocolString("TCP"), 1, 100, 5, 1000), - fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): connection.None(), - fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): connection.None(), - fromIPAddressStrWithoutValidation("10.250.10.1"): connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000). - Union(connection.TCPorUDPConnection(netp.ProtocolString("UDP"), 5, 87, 10, 3245)), + fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): netset.NoTransports(), + fromIPAddressStrWithoutValidation("10.250.10.1"): netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000). + Union(netset.NewTCPorUDPTransport(netp.ProtocolString("UDP"), 5, 87, 10, 3245)), }, - AllowRules: map[*ipblock.IPBlock][]int{ + AllowRules: map[*netset.IPBlock][]int{ fromIPAddressStrWithoutValidation("10.250.10.0"): {2}, fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): {2}, fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): {}, fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): {}, fromIPAddressStrWithoutValidation("10.250.10.1"): {1, 2}, }, - DeniedConns: map[*ipblock.IPBlock]*connection.Set{}, - DenyRules: map[*ipblock.IPBlock][]int{}, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{}, + DenyRules: map[*netset.IPBlock][]int{}, }, }, }, @@ -211,46 +210,46 @@ var sgTests = []sgTest{ rules: []*commonvpc.SGRule{ { Remote: commonvpc.NewRuleTarget(newIPBlockFromCIDROrAddressWithoutValidation("10.250.10.1"), "ola"), - Connections: connection.TCPorUDPConnection(netp.ProtocolString("UDP"), 5, 87, 10, 3245), + Connections: netset.NewTCPorUDPTransport(netp.ProtocolString("UDP"), 5, 87, 10, 3245), Index: 1, - Local: ipblock.GetCidrAll(), + Local: netset.GetCidrAll(), }, { Remote: commonvpc.NewRuleTarget(newIPBlockFromCIDROrAddressWithoutValidation("10.250.10.0/30"), "ola"), - Connections: connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 244, 7576), + Connections: netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 244, 7576), Index: 2, - Local: ipblock.GetCidrAll(), + Local: netset.GetCidrAll(), }, { Remote: commonvpc.NewRuleTarget(newIPBlockFromCIDROrAddressWithoutValidation("10.250.10.0"), "ola"), - Connections: connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 23, 244, 7576), + Connections: netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 23, 244, 7576), Index: 3, - Local: ipblock.GetCidrAll(), + Local: netset.GetCidrAll(), }, }, isIngress: true, - expectedConnectivityMap: map[*ipblock.IPBlock]*commonvpc.ConnectivityResult{ - ipblock.GetCidrAll(): { + expectedConnectivityMap: map[*netset.IPBlock]*commonvpc.ConnectivityResult{ + netset.GetCidrAll(): { IsIngress: false, - AllowedConns: map[*ipblock.IPBlock]*connection.Set{ - fromIPAddressStrWithoutValidation("10.250.10.0"): connection.TCPorUDPConnection( + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPAddressStrWithoutValidation("10.250.10.0"): netset.NewTCPorUDPTransport( netp.ProtocolString("TCP"), 1, 100, 244, 7576), - fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): connection.TCPorUDPConnection( + fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): netset.NewTCPorUDPTransport( netp.ProtocolString("TCP"), 1, 100, 244, 7576), - fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): connection.None(), - fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): connection.None(), - fromIPAddressStrWithoutValidation("10.250.10.1"): connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 244, 7576). - Union(connection.TCPorUDPConnection(netp.ProtocolString("UDP"), 5, 87, 10, 3245)), + fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): netset.NoTransports(), + fromIPAddressStrWithoutValidation("10.250.10.1"): netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 244, 7576). + Union(netset.NewTCPorUDPTransport(netp.ProtocolString("UDP"), 5, 87, 10, 3245)), }, - AllowRules: map[*ipblock.IPBlock][]int{ + AllowRules: map[*netset.IPBlock][]int{ fromIPAddressStrWithoutValidation("10.250.10.0"): {2, 3}, fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): {2}, fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): {}, fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): {}, fromIPAddressStrWithoutValidation("10.250.10.1"): {1, 2}, }, - DeniedConns: map[*ipblock.IPBlock]*connection.Set{}, - DenyRules: map[*ipblock.IPBlock][]int{}, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{}, + DenyRules: map[*netset.IPBlock][]int{}, }, }, }, diff --git a/pkg/awsvpc/vpc.go b/pkg/awsvpc/vpc.go index e30c5e9a1..8bb8e305e 100644 --- a/pkg/awsvpc/vpc.go +++ b/pkg/awsvpc/vpc.go @@ -9,7 +9,7 @@ package awsvpc import ( "errors" - "github.com/np-guard/models/pkg/connection" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -47,30 +47,30 @@ func (igw *InternetGateway) ExternalIP() string { return "" } -func (igw *InternetGateway) AllowedConnectivity(src, dst vpcmodel.VPCResourceIntf) (*connection.Set, error) { +func (igw *InternetGateway) AllowedConnectivity(src, dst vpcmodel.VPCResourceIntf) (*netset.TransportSet, error) { if areNodes, srcNode, dstNode := isNodesPair(src, dst); areNodes { if vpcmodel.HasNode(igw.Sources(), srcNode) && dstNode.IsExternal() { - return connection.All(), nil + return netset.AllTransports(), nil } if vpcmodel.HasNode(igw.Sources(), dstNode) && srcNode.IsExternal() { - return connection.All(), nil + return netset.AllTransports(), nil } - return connection.None(), nil + return netset.NoTransports(), nil } if src.Kind() == commonvpc.ResourceTypeSubnet { srcSubnet := src.(*commonvpc.Subnet) if dstNode, ok := dst.(vpcmodel.Node); ok { if dstNode.IsExternal() && hasSubnet(igw.srcSubnets, srcSubnet) { - return connection.All(), nil + return netset.AllTransports(), nil } } dstSubnet := src.(*commonvpc.Subnet) if srcNode, ok := dst.(vpcmodel.Node); ok { if srcNode.IsExternal() && hasSubnet(igw.srcSubnets, dstSubnet) { - return connection.All(), nil + return netset.AllTransports(), nil } } - return connection.None(), nil + return netset.NoTransports(), nil } return nil, errors.New("unexpected src/dst input types") } diff --git a/pkg/common/strings.go b/pkg/common/strings.go new file mode 100644 index 000000000..797e46fc5 --- /dev/null +++ b/pkg/common/strings.go @@ -0,0 +1,171 @@ +/* +Copyright 2023- IBM Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package common + +import ( + "fmt" + "sort" + "strings" + + "github.com/np-guard/models/pkg/ds" + + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" +) + +const ( + AllConnections = "All Connections" + NoConnections = "No Connections" +) +const ( + spaceString = " " + protocolString = "protocol: " + semicolonString = "; " +) + +func tcpudpProtocolString(p *netset.ProtocolSet, shortVersion bool) string { + var str string + switch { + case p.Size() == 2: + str = string(netp.ProtocolStringTCP + "," + netp.ProtocolStringUDP) + case p.Contains(netset.TCPCode): + str = string(netp.ProtocolStringTCP) + case p.Contains(netset.UDPCode): + str = string(netp.ProtocolStringUDP) + default: + return "" + } + if shortVersion { + return str + } + return protocolString + str +} + +func getTCPUDPCubeStr(cube ds.Triple[*netset.ProtocolSet, *netset.PortSet, *netset.PortSet], shortVersion bool) string { + var ports []string + if !cube.S2.Equal(netset.AllPorts()) { + ports = append(ports, "src-ports: "+cube.S2.String()) + } + if !cube.S3.Equal(netset.AllPorts()) { + ports = append(ports, "dst-ports: "+cube.S3.String()) + } + res := tcpudpProtocolString(cube.S1, shortVersion) + if len(ports) > 0 { + res += spaceString + } + return res + strings.Join(ports, spaceString) +} + +func getICMPCubeStr(cube ds.Pair[*netset.TypeSet, *netset.CodeSet]) string { + if cube.Left.Equal(netset.AllICMPTypes()) && cube.Right.Equal(netset.AllICMPCodes()) { + return "" + } + if cube.Right.Equal(netset.AllICMPCodes()) { + if cube.Left.IsSingleNumber() { + return fmt.Sprintf("icmp-type: %s", cube.Left.String()) + } + return fmt.Sprintf("icmp-type: %s icmp-code: 0", cube.Left.String()) + } + return fmt.Sprintf("icmp-type: %s icmp-code: %s", cube.Left.String(), cube.Right.String()) +} + +// tCPUDPString returns a string representation of a TransportSet object +// partial cubes only +func tCPUDPString(c *netset.TCPUDPSet, shortVersion bool) string { + if netset.AllTCPTransport().TCPUDPSet().IsSubset(c) { + c = c.Subtract(netset.AllTCPTransport().TCPUDPSet()) + } + if netset.AllUDPTransport().TCPUDPSet().IsSubset(c) { + c = c.Subtract(netset.AllUDPTransport().TCPUDPSet()) + } + if c.IsEmpty() { + return "" + } + cubes := c.Partitions() + var resStrings = make([]string, len(cubes)) + for i, cube := range cubes { + resStrings[i] = getTCPUDPCubeStr(cube, shortVersion) + } + sort.Strings(resStrings) + return strings.Join(resStrings, semicolonString) +} + +// iCMPString returns a string representation of an ICMPSet object +// partial cubes only +func iCMPString(c *netset.ICMPSet, shortVersion bool) string { + if netset.AllICMPTransport().ICMPSet().IsSubset(c) { + c = c.Subtract(netset.AllICMPTransport().ICMPSet()) + } + if c.IsEmpty() { + return "" + } + cubes := c.Partitions() + var resStrings = make([]string, len(cubes)) + for i, cube := range cubes { + resStrings[i] = getICMPCubeStr(cube) + } + sort.Strings(resStrings) + str := "ICMP" + if !shortVersion { + str = protocolString + str + } + last := strings.Join(resStrings, semicolonString) + if last != "" { + str += spaceString + last + } + return str +} + +func completeProtocols(c *netset.TransportSet, shortVersion bool) string { + completeProtocols := []string{} + if netset.AllICMPSet().IsSubset(c.ICMPSet()) { + completeProtocols = append(completeProtocols, string(netp.ProtocolStringICMP)) + } + if netset.AllTCPTransport().IsSubset(c) { + completeProtocols = append(completeProtocols, string(netp.ProtocolStringTCP)) + } + if netset.AllUDPTransport().IsSubset(c) { + completeProtocols = append(completeProtocols, string(netp.ProtocolStringUDP)) + } + + res := strings.Join(completeProtocols, ",") + if !shortVersion && res != "" { + res = protocolString + res + } + + return res +} + +func appendIfNotEmpty(res []string, s string) []string { + if s != "" { + res = append(res, s) + } + return res +} + +func Stringify(c *netset.TransportSet, shortVersion bool) string { + if c.IsEmpty() { + return NoConnections + } else if c.IsAll() { + return AllConnections + } + + resStrs := []string{} + resStrs = appendIfNotEmpty(resStrs, completeProtocols(c, shortVersion)) + resStrs = appendIfNotEmpty(resStrs, iCMPString(c.ICMPSet(), shortVersion)) // partial cubes only + resStrs = appendIfNotEmpty(resStrs, tCPUDPString(c.TCPUDPSet(), shortVersion)) // partial cubes only + + return strings.Join(resStrs, semicolonString) +} + +func ShortString(connections *netset.TransportSet) string { + return Stringify(connections, true) +} + +func LongString(connections *netset.TransportSet) string { + return Stringify(connections, false) +} diff --git a/pkg/commonvpc/connectivity_result.go b/pkg/commonvpc/connectivity_result.go index a0d483812..7d42a45b6 100644 --- a/pkg/commonvpc/connectivity_result.go +++ b/pkg/commonvpc/connectivity_result.go @@ -12,25 +12,25 @@ import ( "sort" "strings" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-analyzer/pkg/common" ) // ConnectivityResultMap is a map from IPBlock to ConnectivityResult, used to map disjointLocals IPBlocks to ConnectivityResult -type ConnectivityResultMap map[*ipblock.IPBlock]*ConnectivityResult +type ConnectivityResultMap map[*netset.IPBlock]*ConnectivityResult // ConnectivityResult is built on disjoint ip-blocks for targets of all relevant sg/nacl results // ConnectivityResult is per VSI network interface: contains allowed connectivity (with connection attributes) per target type ConnectivityResult struct { IsIngress bool - AllowedConns map[*ipblock.IPBlock]*connection.Set // allowed target and its allowed connections - AllowRules map[*ipblock.IPBlock][]int // indexes of (positive) allowRules contributing to this connectivity + AllowedConns map[*netset.IPBlock]*netset.TransportSet // allowed target and its allowed connections + AllowRules map[*netset.IPBlock][]int // indexes of (positive) allowRules contributing to this connectivity // the following are relevant only to filters with deny rules - nacl - DeniedConns map[*ipblock.IPBlock]*connection.Set // denied target and its allowed connections, by deny rules. - DenyRules map[*ipblock.IPBlock][]int // indexes of deny rules relevant to this connectivity + DeniedConns map[*netset.IPBlock]*netset.TransportSet // denied target and its allowed connections, by deny rules. + DenyRules map[*netset.IPBlock][]int // indexes of deny rules relevant to this connectivity } -func storeAndSortKeys[T any](m map[*ipblock.IPBlock]T) []string { +func storeAndSortKeys[T any](m map[*netset.IPBlock]T) []string { keys := make([]string, len(m)) i := 0 for ipBlock := range m { @@ -41,7 +41,7 @@ func storeAndSortKeys[T any](m map[*ipblock.IPBlock]T) []string { return keys } -func equalKeys[T any](first, second map[*ipblock.IPBlock]T) bool { +func equalKeys[T any](first, second map[*netset.IPBlock]T) bool { if len(first) != len(second) { return false } @@ -51,7 +51,7 @@ func equalKeys[T any](first, second map[*ipblock.IPBlock]T) bool { return reflect.DeepEqual(keys1, keys2) } -func equalConns(conns1, conns2 map[*ipblock.IPBlock]*connection.Set) bool { +func equalConns(conns1, conns2 map[*netset.IPBlock]*netset.TransportSet) bool { if !equalKeys(conns1, conns2) { return false } @@ -68,7 +68,7 @@ func equalConns(conns1, conns2 map[*ipblock.IPBlock]*connection.Set) bool { return true } -func equalRules(rules1, rules2 map[*ipblock.IPBlock][]int) bool { +func equalRules(rules1, rules2 map[*netset.IPBlock][]int) bool { if !equalKeys(rules1, rules2) { return false } @@ -117,7 +117,7 @@ func (cr ConnectivityResultMap) Equal(other ConnectivityResultMap) bool { func (cr *ConnectivityResult) String() string { res := []string{} for t, conn := range cr.AllowedConns { - res = append(res, fmt.Sprintf("remote: %s, conn: %s", t.ToIPRanges(), conn.String())) + res = append(res, fmt.Sprintf("remote: %s, conn: %s", t.ToIPRanges(), common.LongString(conn))) } sort.Strings(res) return strings.Join(res, "\n") diff --git a/pkg/commonvpc/nacl_analysis.go b/pkg/commonvpc/nacl_analysis.go index ef27438a7..1e1774043 100644 --- a/pkg/commonvpc/nacl_analysis.go +++ b/pkg/commonvpc/nacl_analysis.go @@ -12,9 +12,9 @@ import ( "sort" "strings" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-analyzer/pkg/common" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -35,11 +35,11 @@ type NACLAnalyzer struct { // interface to be implemented by aws and ibm nacl analyzer type SpecificNACLAnalyzer interface { GetNACLRules() (ingressRules, egressRules []*NACLRule, err error) - ReferencedIPblocks() []*ipblock.IPBlock + ReferencedIPblocks() []*netset.IPBlock GetNumberOfRules() int GetNACLRule(index int) (ruleStr string, ruleRes *NACLRule, isIngress bool, err error) Name() *string - SetReferencedIPblocks(referencedIPblocks []*ipblock.IPBlock) + SetReferencedIPblocks(referencedIPblocks []*netset.IPBlock) } type AnalysisResultPerSubnet struct { @@ -65,9 +65,9 @@ func NewNACLAnalyzer(analyzer SpecificNACLAnalyzer) (res *NACLAnalyzer, err erro // NACLRule represents an nacl rule, used in ibm and aws type NACLRule struct { - Src *ipblock.IPBlock - Dst *ipblock.IPBlock - Connections *connection.Set + Src *netset.IPBlock + Dst *netset.IPBlock + Connections *netset.TransportSet Action string Index int // index of original rule in it's NetworkACL // add ingress/egress ? @@ -75,7 +75,7 @@ type NACLRule struct { func (rule *NACLRule) dumpRule() string { return fmt.Sprintf("index: %d, src: %s, dst: %s, conn: %s, action: %s", - rule.Index, rule.Src.ToIPRanges(), rule.Dst.ToIPRanges(), rule.Connections.String(), rule.Action) + rule.Index, rule.Src.ToIPRanges(), rule.Dst.ToIPRanges(), common.LongString(rule.Connections), rule.Action) } var _ = (*NACLAnalyzer).dumpNACLrules // avoiding "unused" warning @@ -98,27 +98,27 @@ func (na *NACLAnalyzer) dumpNACLrules() string { // given ingress/egress rules from NACL , specific src, subnet cidr and disjoint peers of dest ip-blocks -- // get the allowed connections, the relevant allow rules and relevant deny rules -func GetAllowedXgressConnections(rules []*NACLRule, src, subnetCidr *ipblock.IPBlock, - disjointPeers []*ipblock.IPBlock, isIngress bool, -) (allowedXgress, deniedXgress map[string]*connection.Set, allowRules, denyRules map[string][]int) { - allowedXgress = map[string]*connection.Set{} - deniedXgress = map[string]*connection.Set{} +func GetAllowedXgressConnections(rules []*NACLRule, src, subnetCidr *netset.IPBlock, + disjointPeers []*netset.IPBlock, isIngress bool, +) (allowedXgress, deniedXgress map[string]*netset.TransportSet, allowRules, denyRules map[string][]int) { + allowedXgress = map[string]*netset.TransportSet{} + deniedXgress = map[string]*netset.TransportSet{} allowRules = map[string][]int{} denyRules = map[string][]int{} for _, cidr := range disjointPeers { - if cidr.ContainedIn(subnetCidr) { - allowedXgress[cidr.ToIPRanges()] = connection.None() - deniedXgress[cidr.ToIPRanges()] = connection.None() + if cidr.IsSubset(subnetCidr) { + allowedXgress[cidr.ToIPRanges()] = netset.NoTransports() + deniedXgress[cidr.ToIPRanges()] = netset.NoTransports() allowRules[cidr.ToIPRanges()] = []int{} denyRules[cidr.ToIPRanges()] = []int{} } } - if src.ContainedIn(subnetCidr) { + if src.IsSubset(subnetCidr) { // no need to check nacl rules for connections within the subnet for _, cidr := range disjointPeers { - if cidr.ContainedIn(subnetCidr) { - allowedXgress[cidr.ToIPRanges()] = connection.All() + if cidr.IsSubset(subnetCidr) { + allowedXgress[cidr.ToIPRanges()] = netset.AllTransports() } } return allowedXgress, deniedXgress, allowRules, denyRules @@ -126,14 +126,14 @@ func GetAllowedXgressConnections(rules []*NACLRule, src, subnetCidr *ipblock.IPB for _, rule := range rules { s, d := rule.getSrcDst(isIngress) - if !src.ContainedIn(s) { + if !src.IsSubset(s) { continue } destCidr := d.Intersect(subnetCidr) // split destCidr to disjoint ip-blocks - destCidrList := []*ipblock.IPBlock{} + destCidrList := []*netset.IPBlock{} for _, cidr := range disjointPeers { - if cidr.ContainedIn(destCidr) { + if cidr.IsSubset(destCidr) { destCidrList = append(destCidrList, cidr) } } @@ -162,7 +162,7 @@ func GetAllowedXgressConnections(rules []*NACLRule, src, subnetCidr *ipblock.IPB return allowedXgress, deniedXgress, allowRules, denyRules } -func (rule *NACLRule) getSrcDst(isIngress bool) (src, dst *ipblock.IPBlock) { +func (rule *NACLRule) getSrcDst(isIngress bool) (src, dst *netset.IPBlock) { if isIngress { return rule.Src, rule.Dst } @@ -170,13 +170,13 @@ func (rule *NACLRule) getSrcDst(isIngress bool) (src, dst *ipblock.IPBlock) { } func getDisjointPeersForIngressOrEgressAnalysis( - rules []*NACLRule, subnet *ipblock.IPBlock, isIngress bool) ( + rules []*NACLRule, subnet *netset.IPBlock, isIngress bool) ( disjointSrcPeers, - disjointDstPeers []*ipblock.IPBlock) { - var srcPeers, dstPeers []*ipblock.IPBlock - srcPeers = make([]*ipblock.IPBlock, 1+len(rules)) - dstPeers = make([]*ipblock.IPBlock, 1+len(rules)) - cidrAll := ipblock.GetCidrAll() + disjointDstPeers []*netset.IPBlock) { + var srcPeers, dstPeers []*netset.IPBlock + srcPeers = make([]*netset.IPBlock, 1+len(rules)) + dstPeers = make([]*netset.IPBlock, 1+len(rules)) + cidrAll := netset.GetCidrAll() if isIngress { srcPeers[0] = cidrAll dstPeers[0] = subnet @@ -189,28 +189,28 @@ func getDisjointPeersForIngressOrEgressAnalysis( dstPeers[i+1] = rule.Dst } if isIngress { - disjointSrcPeers = ipblock.DisjointIPBlocks(srcPeers, []*ipblock.IPBlock{ipblock.GetCidrAll()}) - disjointDstPeers = ipblock.DisjointIPBlocks(dstPeers, []*ipblock.IPBlock{subnet}) + disjointSrcPeers = netset.DisjointIPBlocks(srcPeers, []*netset.IPBlock{netset.GetCidrAll()}) + disjointDstPeers = netset.DisjointIPBlocks(dstPeers, []*netset.IPBlock{subnet}) } else { - disjointSrcPeers = ipblock.DisjointIPBlocks(srcPeers, []*ipblock.IPBlock{subnet}) - disjointDstPeers = ipblock.DisjointIPBlocks(dstPeers, []*ipblock.IPBlock{ipblock.GetCidrAll()}) + disjointSrcPeers = netset.DisjointIPBlocks(srcPeers, []*netset.IPBlock{subnet}) + disjointDstPeers = netset.DisjointIPBlocks(dstPeers, []*netset.IPBlock{netset.GetCidrAll()}) } return } -func getDisjointPeersForIngressAnalysis(rules []*NACLRule, subnet *ipblock.IPBlock) (srcPeers, dstPeers []*ipblock.IPBlock) { +func getDisjointPeersForIngressAnalysis(rules []*NACLRule, subnet *netset.IPBlock) (srcPeers, dstPeers []*netset.IPBlock) { return getDisjointPeersForIngressOrEgressAnalysis(rules, subnet, true) } -func getDisjointPeersForEgressAnalysis(rules []*NACLRule, subnet *ipblock.IPBlock) (srcPeers, dstPeers []*ipblock.IPBlock) { +func getDisjointPeersForEgressAnalysis(rules []*NACLRule, subnet *netset.IPBlock) (srcPeers, dstPeers []*netset.IPBlock) { return getDisjointPeersForIngressOrEgressAnalysis(rules, subnet, false) } // AnalyzeNACLRulesPerDisjointTargets get connectivity result for each disjoint target in the subnet func AnalyzeNACLRulesPerDisjointTargets( - rules []*NACLRule, subnet *ipblock.IPBlock, isIngress bool) map[string]*ConnectivityResult { + rules []*NACLRule, subnet *netset.IPBlock, isIngress bool) map[string]*ConnectivityResult { res := map[string]*ConnectivityResult{} - var disjointSrcPeers, disjointDstPeers []*ipblock.IPBlock + var disjointSrcPeers, disjointDstPeers []*netset.IPBlock if isIngress { disjointSrcPeers, disjointDstPeers = getDisjointPeersForIngressAnalysis(rules, subnet) } else { @@ -225,10 +225,10 @@ func AnalyzeNACLRulesPerDisjointTargets( return res } -func updateAllowDeny(allow, isIngress bool, xgressConn map[string]*connection.Set, rules map[string][]int, - srcIngDstEgr *ipblock.IPBlock, res map[string]*ConnectivityResult) { +func updateAllowDeny(allow, isIngress bool, xgressConn map[string]*netset.TransportSet, rules map[string][]int, + srcIngDstEgr *netset.IPBlock, res map[string]*ConnectivityResult) { for dstIngSrcEg, conn := range xgressConn { - if dstIngSrcEgIPBlock, err := ipblock.FromIPRangeStr(dstIngSrcEg); err == nil { + if dstIngSrcEgIPBlock, err := netset.IPBlockFromIPRangeStr(dstIngSrcEg); err == nil { dstIngSrcEgIPRange := dstIngSrcEgIPBlock.ToIPRanges() initConnectivityResult(res, dstIngSrcEgIPRange, isIngress) if allow { @@ -247,8 +247,8 @@ func updateAllowDeny(allow, isIngress bool, xgressConn map[string]*connection.Se func initConnectivityResult(connectivityMap map[string]*ConnectivityResult, indxToinit string, isIngress bool) { if _, ok := connectivityMap[indxToinit]; !ok { connectivityMap[indxToinit] = &ConnectivityResult{IsIngress: isIngress, - AllowedConns: map[*ipblock.IPBlock]*connection.Set{}, AllowRules: map[*ipblock.IPBlock][]int{}, - DeniedConns: map[*ipblock.IPBlock]*connection.Set{}, DenyRules: map[*ipblock.IPBlock][]int{}} + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{}, AllowRules: map[*netset.IPBlock][]int{}, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{}, DenyRules: map[*netset.IPBlock][]int{}} } } @@ -257,13 +257,13 @@ func getConnStr(src, dst, conn string) string { } // AnalyzeNACLRules todo: this is used only in testing. Did not expand for deny. -func (na *NACLAnalyzer) AnalyzeNACLRules(rules []*NACLRule, subnet *ipblock.IPBlock, - isIngress bool, subnetDisjointTarget *ipblock.IPBlock, +func (na *NACLAnalyzer) AnalyzeNACLRules(rules []*NACLRule, subnet *netset.IPBlock, + isIngress bool, subnetDisjointTarget *netset.IPBlock, ) (string, *ConnectivityResult) { res := []string{} connResult := &ConnectivityResult{IsIngress: isIngress} - connResult.AllowedConns = map[*ipblock.IPBlock]*connection.Set{} - connResult.DeniedConns = map[*ipblock.IPBlock]*connection.Set{} + connResult.AllowedConns = map[*netset.IPBlock]*netset.TransportSet{} + connResult.DeniedConns = map[*netset.IPBlock]*netset.TransportSet{} if subnetDisjointTarget == nil { connResult = nil } @@ -273,9 +273,9 @@ func (na *NACLAnalyzer) AnalyzeNACLRules(rules []*NACLRule, subnet *ipblock.IPBl for _, src := range disjointSrcPeers { allowedIngressConns, _, allowRules, _ := GetAllowedXgressConnections(rules, src, subnet, disjointDstPeers, true) for dst, conn := range allowedIngressConns { - res = append(res, getConnStr(src.ToIPRanges(), dst, conn.String())) - dstIP, err := ipblock.FromIPRangeStr(dst) - if err == nil && subnetDisjointTarget != nil && subnetDisjointTarget.ContainedIn(dstIP) { + res = append(res, getConnStr(src.ToIPRanges(), dst, common.LongString(conn))) + dstIP, err := netset.IPBlockFromIPRangeStr(dst) + if err == nil && subnetDisjointTarget != nil && subnetDisjointTarget.IsSubset(dstIP) { connResult.AllowedConns[src] = conn // the indexing of allowedIngressConns and allowRules are identical connResult.AllowRules[src] = allowRules[dst] @@ -289,9 +289,9 @@ func (na *NACLAnalyzer) AnalyzeNACLRules(rules []*NACLRule, subnet *ipblock.IPBl for _, dst := range disjointDstPeers { allowedEgressConns, _, allowRules, _ := GetAllowedXgressConnections(rules, dst, subnet, disjointSrcPeers, false) for src, conn := range allowedEgressConns { - res = append(res, getConnStr(src, dst.ToIPRanges(), conn.String())) - srcIP, err := ipblock.FromIPRangeStr(src) - if err == nil && subnetDisjointTarget != nil && subnetDisjointTarget.ContainedIn(srcIP) { + res = append(res, getConnStr(src, dst.ToIPRanges(), common.LongString(conn))) + srcIP, err := netset.IPBlockFromIPRangeStr(src) + if err == nil && subnetDisjointTarget != nil && subnetDisjointTarget.IsSubset(srcIP) { connResult.AllowedConns[dst] = conn // the indexing of allowedEgressConns and allowRules are identical connResult.AllowRules[dst] = allowRules[src] @@ -303,7 +303,7 @@ func (na *NACLAnalyzer) AnalyzeNACLRules(rules []*NACLRule, subnet *ipblock.IPBl // TODO: return a map from each possible subnetDisjointTarget to its ConnectivityResult, instead of a specific ConnectivityResult // get allowed and denied connections (ingress and egress) for a certain subnet to which this nacl is applied -func (na *NACLAnalyzer) AnalyzeNACL(subnet *ipblock.IPBlock) ( +func (na *NACLAnalyzer) AnalyzeNACL(subnet *netset.IPBlock) ( ingressResConnectivity, egressResConnectivity map[string]*ConnectivityResult) { ingressResConnectivity = AnalyzeNACLRulesPerDisjointTargets(na.IngressRules, subnet, true) egressResConnectivity = AnalyzeNACLRulesPerDisjointTargets(na.EgressRules, subnet, false) @@ -388,7 +388,7 @@ const notFoundMsg = "isIngress: %t , target %s, subnetCidr: %s, inSubentCidr %s, // AllowedConnectivity returns set of allowed connections given src/dst and direction // if the input subnet was not yet analyzed, it first adds its analysis to saved results func (na *NACLAnalyzer) AllowedConnectivity(subnet *Subnet, nodeInSubnet, targetNode vpcmodel.Node, isIngress bool) ( - *connection.Set, error) { + *netset.TransportSet, error) { // add analysis of the given subnet // analyzes per subnet disjoint cidrs (it is not necessarily entire subnet cidr) targetIPblock := targetNode.IPBlock() @@ -396,13 +396,13 @@ func (na *NACLAnalyzer) AllowedConnectivity(subnet *Subnet, nodeInSubnet, target analyzedConns := na.initConnectivityRelatedCompute(subnet, isIngress) for disjointSubnetCidr, analyzedConnsPerCidr := range analyzedConns { - disjointSubnetCidrIPblock, err := ipblock.FromIPRangeStr(disjointSubnetCidr) + disjointSubnetCidrIPblock, err := netset.IPBlockFromIPRangeStr(disjointSubnetCidr) if err != nil { return nil, err } - if inSubnetIPblock.ContainedIn(disjointSubnetCidrIPblock) { + if inSubnetIPblock.IsSubset(disjointSubnetCidrIPblock) { for resTarget, conn := range analyzedConnsPerCidr.AllowedConns { - if targetIPblock.ContainedIn(resTarget) { + if targetIPblock.IsSubset(resTarget) { return conn, nil } } @@ -417,7 +417,7 @@ func (na *NACLAnalyzer) AllowedConnectivity(subnet *Subnet, nodeInSubnet, target // if the input subnet was not yet analyzed, it first adds its analysis to saved results func (na *NACLAnalyzer) rulesFilterInConnectivity(subnet *Subnet, nodeInSubnet, targetNode vpcmodel.Node, - connQuery *connection.Set, + connQuery *netset.TransportSet, isIngress bool) ( allow, deny []int, err error) { // add analysis of the given subnet @@ -427,13 +427,13 @@ func (na *NACLAnalyzer) rulesFilterInConnectivity(subnet *Subnet, analyzedConns := na.initConnectivityRelatedCompute(subnet, isIngress) for disjointSubnetCidr, analyzedConnsPerCidr := range analyzedConns { - disjointSubnetCidrIPblock, err := ipblock.FromIPRangeStr(disjointSubnetCidr) + disjointSubnetCidrIPblock, err := netset.IPBlockFromIPRangeStr(disjointSubnetCidr) if err != nil { return nil, nil, err } - if inSubnetIPblock.ContainedIn(disjointSubnetCidrIPblock) { + if inSubnetIPblock.IsSubset(disjointSubnetCidrIPblock) { for resTarget, allowRules := range analyzedConnsPerCidr.AllowRules { - if !targetIPblock.ContainedIn(resTarget) { + if !targetIPblock.IsSubset(resTarget) { continue } // this is the relevant targetIPblock; takes denyRules as well @@ -459,9 +459,9 @@ func (na *NACLAnalyzer) rulesFilterInConnectivity(subnet *Subnet, // given a list of allow and deny rules and a connection, // return the allow and deny sublists of rules that contributes to the connection func (na *NACLAnalyzer) getRulesRelevantConn(rules []int, - connQuery *connection.Set) (allowRelevant, denyRelevant []int, err error) { + connQuery *netset.TransportSet) (allowRelevant, denyRelevant []int, err error) { allowRelevant, denyRelevant = []int{}, []int{} - curConn := connection.None() + curConn := netset.NoTransports() for _, rule := range append(na.IngressRules, na.EgressRules...) { if !slices.Contains(rules, rule.Index) || connQuery.Intersect(rule.Connections).IsEmpty() { continue @@ -472,7 +472,7 @@ func (na *NACLAnalyzer) getRulesRelevantConn(rules []int, } else if rule.Action == DENY { denyRelevant = append(denyRelevant, rule.Index) } - contains := connQuery.ContainedIn(curConn) + contains := connQuery.IsSubset(curConn) if contains { // if the required connQuery is contained in connections thus far, lower priority rules not relevant return allowRelevant, denyRelevant, nil @@ -486,7 +486,7 @@ func GetNACLRules(na SpecificNACLAnalyzer) (ingressRules, egressRules []*NACLRule, err error) { ingressRules = []*NACLRule{} egressRules = []*NACLRule{} - var referencedIPblocks []*ipblock.IPBlock + var referencedIPblocks []*netset.IPBlock for index := 0; index < na.GetNumberOfRules(); index++ { _, ruleObj, isIngress, err := na.GetNACLRule(index) if err != nil { diff --git a/pkg/commonvpc/parser.go b/pkg/commonvpc/parser.go index 8b37eb0e5..b39a678fa 100644 --- a/pkg/commonvpc/parser.go +++ b/pkg/commonvpc/parser.go @@ -10,7 +10,7 @@ import ( "fmt" "strings" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/logging" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -106,7 +106,7 @@ func NewVSI(name, uid, zone string, vpc vpcmodel.VPCResourceIntf, res *vpcmodel. // UpdateConfigWithSubnet creates new subnets from provided args and update it's vpc object and subnets list func UpdateConfigWithSubnet(name, uid, zone, cidr, vpcUID string, res *vpcmodel.MultipleVPCConfigs, - vpcInternalAddressRange map[string]*ipblock.IPBlock, + vpcInternalAddressRange map[string]*netset.IPBlock, subnetIDToNetIntf map[string][]*NetworkInterface) (*Subnet, error) { subnetNodes := []vpcmodel.Node{} vpc, err := GetVPCObjectByUID(res, vpcUID) @@ -166,7 +166,7 @@ func NewSGResource(name, uid, pairingID string, vpc vpcmodel.VPC, analyzer Speci } // UpdateVPCSAddressRanges assigns to each vpc object its internal address range, as inferred from its subnets -func UpdateVPCSAddressRanges(vpcInternalAddressRange map[string]*ipblock.IPBlock, +func UpdateVPCSAddressRanges(vpcInternalAddressRange map[string]*netset.IPBlock, vpcsMap *vpcmodel.MultipleVPCConfigs) error { for vpcUID, addressRange := range vpcInternalAddressRange { var vpc *VPC @@ -214,7 +214,7 @@ func NewVPC(name, uid, region string, zonesToAP map[string][]string, regionToStr } for zoneName, zoneCidrsList := range zonesToAP { vpcNodeSet.AddressPrefixesList = append(vpcNodeSet.AddressPrefixesList, zoneCidrsList...) - zoneIPBlock, err := ipblock.FromCidrList(zoneCidrsList) + zoneIPBlock, err := netset.IPBlockFromCidrList(zoneCidrsList) if err != nil { return nil, err } @@ -224,7 +224,7 @@ func NewVPC(name, uid, region string, zonesToAP map[string][]string, regionToStr IPblock: zoneIPBlock} } - vpcNodeSet.AddressPrefixesIPBlock, err = ipblock.FromCidrList(vpcNodeSet.AddressPrefixesList) + vpcNodeSet.AddressPrefixesIPBlock, err = netset.IPBlockFromCidrList(vpcNodeSet.AddressPrefixesList) if err != nil { return nil, err } @@ -280,7 +280,7 @@ func NewSubnet(name, uid, zone, cidr string, vpc vpcmodel.VPCResourceIntf) (*Sub Cidr: cidr, } - cidrIPBlock, err := ipblock.FromCidr(subnetNode.Cidr) + cidrIPBlock, err := netset.IPBlockFromCidr(subnetNode.Cidr) if err != nil { return nil, err } @@ -317,7 +317,7 @@ func PrintRule(ruleStr string, index int, err error) { } // filter VPCs with empty address ranges, then add for remaining VPCs the external nodes -func FilterVPCSAndAddExternalNodes(vpcInternalAddressRange map[string]*ipblock.IPBlock, res *vpcmodel.MultipleVPCConfigs) error { +func FilterVPCSAndAddExternalNodes(vpcInternalAddressRange map[string]*netset.IPBlock, res *vpcmodel.MultipleVPCConfigs) error { for vpcUID, vpcConfig := range res.Configs() { if vpcInternalAddressRange[vpcUID] == nil { logging.Warnf("Ignoring VPC %s, no subnets found for this VPC\n", vpcUID) @@ -332,7 +332,7 @@ func FilterVPCSAndAddExternalNodes(vpcInternalAddressRange map[string]*ipblock.I return nil } -func handlePublicInternetNodes(res *vpcmodel.VPCConfig, vpcInternalAddressRange *ipblock.IPBlock) error { +func handlePublicInternetNodes(res *vpcmodel.VPCConfig, vpcInternalAddressRange *netset.IPBlock) error { externalNodes, err := addExternalNodes(res, vpcInternalAddressRange) if err != nil { return err @@ -350,21 +350,21 @@ func handlePublicInternetNodes(res *vpcmodel.VPCConfig, vpcInternalAddressRange return nil } -func addExternalNodes(config *vpcmodel.VPCConfig, vpcInternalAddressRange *ipblock.IPBlock) ([]vpcmodel.Node, error) { - ipBlocks := []*ipblock.IPBlock{} +func addExternalNodes(config *vpcmodel.VPCConfig, vpcInternalAddressRange *netset.IPBlock) ([]vpcmodel.Node, error) { + ipBlocks := []*netset.IPBlock{} for _, f := range config.FilterResources { ipBlocks = append(ipBlocks, f.ReferencedIPblocks()...) } - externalRefIPBlocks := []*ipblock.IPBlock{} + externalRefIPBlocks := []*netset.IPBlock{} for _, ipBlock := range ipBlocks { - if ipBlock.ContainedIn(vpcInternalAddressRange) { + if ipBlock.IsSubset(vpcInternalAddressRange) { continue } externalRefIPBlocks = append(externalRefIPBlocks, ipBlock.Subtract(vpcInternalAddressRange)) } - disjointRefExternalIPBlocks := ipblock.DisjointIPBlocks(externalRefIPBlocks, []*ipblock.IPBlock{}) + disjointRefExternalIPBlocks := netset.DisjointIPBlocks(externalRefIPBlocks, []*netset.IPBlock{}) externalNodes, err := vpcmodel.GetExternalNetworkNodes(disjointRefExternalIPBlocks) if err != nil { diff --git a/pkg/commonvpc/sg_analysis.go b/pkg/commonvpc/sg_analysis.go index f2a9d7b11..d3c445287 100644 --- a/pkg/commonvpc/sg_analysis.go +++ b/pkg/commonvpc/sg_analysis.go @@ -11,9 +11,8 @@ import ( "slices" "strings" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/common" "github.com/np-guard/vpc-network-config-analyzer/pkg/logging" ) @@ -34,7 +33,7 @@ type SGAnalyzer struct { // interface to be implemented by aws and ibm sg analyzer type SpecificSGAnalyzer interface { GetSGRules() (ingressRules, egressRules []*SGRule, err error) - ReferencedIPblocks() []*ipblock.IPBlock + ReferencedIPblocks() []*netset.IPBlock SetSGmap(sgMap map[string]*SecurityGroup) GetNumberOfRules() int GetSGRule(index int) (ruleStr string, ruleRes *SGRule, isIngress bool, err error) @@ -56,54 +55,54 @@ func GetProperty(p *int64, defaultP int64) int64 { } // GetTCPUDPConns returns TCP or UDP connection -func GetTCPUDPConns(p string, srcPortMin, srcPortMax, dstPortMin, dstPortMax int64) *connection.Set { +func GetTCPUDPConns(p string, srcPortMin, srcPortMax, dstPortMin, dstPortMax int64) *netset.TransportSet { protocol := netp.ProtocolStringUDP if p == protocolTCP { protocol = netp.ProtocolStringTCP } - return connection.TCPorUDPConnection(protocol, srcPortMin, srcPortMax, dstPortMin, dstPortMax) + return netset.NewTCPorUDPTransport(protocol, srcPortMin, srcPortMax, dstPortMin, dstPortMax) } // GetICMPconn returns ICMP connection -func GetICMPconn(icmpType, icmpCode *int64) *connection.Set { - typeMin := GetProperty(icmpType, connection.MinICMPType) - typeMax := GetProperty(icmpType, connection.MaxICMPType) - codeMin := GetProperty(icmpCode, connection.MinICMPCode) - codeMax := GetProperty(icmpCode, connection.MaxICMPCode) - return connection.ICMPConnection(typeMin, typeMax, codeMin, codeMax) +func GetICMPconn(icmpType, icmpCode *int64) *netset.TransportSet { + typeMin := GetProperty(icmpType, int64(netp.MinICMPType)) + typeMax := GetProperty(icmpType, int64(netp.MaxICMPType)) + codeMin := GetProperty(icmpCode, int64(netp.MinICMPCode)) + codeMax := GetProperty(icmpCode, int64(netp.MaxICMPCode)) + return netset.NewICMPTransport(typeMin, typeMax, codeMin, codeMax) } // RuleTarget represents a securityGroup rule target, used in ibm and aws type RuleTarget struct { - Cidr *ipblock.IPBlock + Cidr *netset.IPBlock SgName string // target specified is SG } -func NewRuleTarget(cidr *ipblock.IPBlock, sgName string) *RuleTarget { +func NewRuleTarget(cidr *netset.IPBlock, sgName string) *RuleTarget { res := &RuleTarget{Cidr: cidr, SgName: sgName} return res } type SGRule struct { Remote *RuleTarget - Connections *connection.Set + Connections *netset.TransportSet Index int // index of original rule in *vpc1.SecurityGroup.Rules - Local *ipblock.IPBlock + Local *netset.IPBlock } // analyzeSGRules gets security group rules and returns it's connectivity results func analyzeSGRules(rules []*SGRule, isIngress bool) *ConnectivityResult { - remotes := []*ipblock.IPBlock{} + remotes := []*netset.IPBlock{} for i := range rules { if rules[i].Remote.Cidr != nil && !rules[i].Remote.Cidr.IsEmpty() { remotes = append(remotes, rules[i].Remote.Cidr) } } - disjointTargets := ipblock.DisjointIPBlocks(remotes, []*ipblock.IPBlock{ipblock.GetCidrAll()}) - res := &ConnectivityResult{IsIngress: isIngress, AllowedConns: map[*ipblock.IPBlock]*connection.Set{}, - AllowRules: map[*ipblock.IPBlock][]int{}} + disjointTargets := netset.DisjointIPBlocks(remotes, []*netset.IPBlock{netset.GetCidrAll()}) + res := &ConnectivityResult{IsIngress: isIngress, AllowedConns: map[*netset.IPBlock]*netset.TransportSet{}, + AllowRules: map[*netset.IPBlock][]int{}} for i := range disjointTargets { - res.AllowedConns[disjointTargets[i]] = connection.None() + res.AllowedConns[disjointTargets[i]] = netset.NoTransports() res.AllowRules[disjointTargets[i]] = []int{} } for i := range rules { @@ -111,7 +110,7 @@ func analyzeSGRules(rules []*SGRule, isIngress bool) *ConnectivityResult { remote := rule.Remote conn := rule.Connections for disjointTarget := range res.AllowedConns { - if disjointTarget.ContainedIn(remote.Cidr) { + if disjointTarget.IsSubset(remote.Cidr) { res.AllowedConns[disjointTarget] = res.AllowedConns[disjointTarget].Union(conn) res.AllowRules[disjointTarget] = append(res.AllowRules[disjointTarget], rule.Index) } @@ -124,13 +123,13 @@ func analyzeSGRules(rules []*SGRule, isIngress bool) *ConnectivityResult { // analyzeSGRules gets security group rules and returns a map from local ip block intervals to it's connectivity results func MapAndAnalyzeSGRules(rules []*SGRule, isIngress bool, currentSg *SecurityGroup) (connectivityMap ConnectivityResultMap) { connectivityMap = make(ConnectivityResultMap) - locals := []*ipblock.IPBlock{} + locals := []*netset.IPBlock{} for i := range rules { if rules[i].Local != nil { locals = append(locals, rules[i].Local) } } - disjointLocals := ipblock.DisjointIPBlocks(locals, []*ipblock.IPBlock{ipblock.GetCidrAll()}) + disjointLocals := netset.DisjointIPBlocks(locals, []*netset.IPBlock{netset.GetCidrAll()}) keysToConnectivityResult := map[common.SetAsKey]*ConnectivityResult{} unifiedMembersIPBlock := currentSg.unifiedMembersIPBlock() for i := range disjointLocals { @@ -140,7 +139,7 @@ func MapAndAnalyzeSGRules(rules []*SGRule, isIngress bool, currentSg *SecurityGr } relevantRules := []*SGRule{} for j := range rules { - if disjointLocals[i].ContainedIn(rules[j].Local) { + if disjointLocals[i].IsSubset(rules[j].Local) { relevantRules = append(relevantRules, rules[j]) } } @@ -186,25 +185,25 @@ func (sga *SGAnalyzer) areSGRulesDefault() bool { if len(egressRuleCidrs) != 1 { return false } - if egressRuleCidrs[0] == ipblock.CidrAll && egressRule.Connections.IsAll() { + if egressRuleCidrs[0] == netset.CidrAll && egressRule.Connections.IsAll() { return true } return false } -func (sga *SGAnalyzer) allowedConnectivity(target, local *ipblock.IPBlock, isIngress bool) *connection.Set { +func (sga *SGAnalyzer) allowedConnectivity(target, local *netset.IPBlock, isIngress bool) *netset.TransportSet { analyzedConnsMap := sga.ingressOrEgressConnectivity(isIngress) for definedLocal, analyzedConns := range analyzedConnsMap { - if local.ContainedIn(definedLocal) { + if local.IsSubset(definedLocal) { for definedTarget, conn := range analyzedConns.AllowedConns { - if target.ContainedIn(definedTarget) { + if target.IsSubset(definedTarget) { return conn } } } } - return connection.None() + return netset.NoTransports() } // rulesFilterInConnectivity list of SG rules contributing to the connectivity, if the required connection exists @@ -212,12 +211,13 @@ func (sga *SGAnalyzer) allowedConnectivity(target, local *ipblock.IPBlock, isIng // 2. If connection is part of the query: is the required connection contained in the existing connection? // if it does, then the contributing rules are detected: rules that intersect the required connection // otherwise, the answer to the query is "no" and nil is returned -func (sga *SGAnalyzer) rulesFilterInConnectivity(target, local *ipblock.IPBlock, connQuery *connection.Set, isIngress bool) ([]int, error) { +func (sga *SGAnalyzer) rulesFilterInConnectivity(target, local *netset.IPBlock, + connQuery *netset.TransportSet, isIngress bool) ([]int, error) { analyzedConnsMap := sga.ingressOrEgressConnectivity(isIngress) for definedLocal, analyzedConns := range analyzedConnsMap { - if local.ContainedIn(definedLocal) { + if local.IsSubset(definedLocal) { for definedTarget, rules := range analyzedConns.AllowRules { - if target.ContainedIn(definedTarget) { + if target.IsSubset(definedTarget) { if connQuery == nil { return rules, nil // connection not part of query - all rules are relevant } @@ -238,7 +238,7 @@ func (sga *SGAnalyzer) rulesFilterInConnectivity(target, local *ipblock.IPBlock, } // given a list of rules and a connection, return the sublist of rules that contributes to the connection -func (sga *SGAnalyzer) getRulesRelevantConn(rules []int, conn *connection.Set) ([]int, error) { +func (sga *SGAnalyzer) getRulesRelevantConn(rules []int, conn *netset.TransportSet) ([]int, error) { relevantRules := []int{} for _, rule := range append(sga.ingressRules, sga.egressRules...) { if slices.Contains(rules, rule.Index) && !conn.Intersect(rule.Connections).IsEmpty() { @@ -257,28 +257,28 @@ func (sga *SGAnalyzer) ingressOrEgressConnectivity(isIngress bool) ConnectivityR // GetIPBlockResult gets an cidr, address or name of the remote/local rule object, and returns it's IPBlock func GetIPBlockResult(cidr, address, name *string, - sgMap map[string]*SecurityGroup) (*ipblock.IPBlock, string, error) { - var ipBlock *ipblock.IPBlock + sgMap map[string]*SecurityGroup) (*netset.IPBlock, string, error) { + var ipBlock *netset.IPBlock var cidrRes string var err error switch { case cidr != nil: - ipBlock, err = ipblock.FromCidr(*cidr) + ipBlock, err = netset.IPBlockFromCidr(*cidr) if err != nil { return nil, "", err } cidrRes = ipBlock.ToCidrList()[0] case address != nil: - ipBlock, err = ipblock.FromIPAddress(*address) + ipBlock, err = netset.IPBlockFromIPAddress(*address) if err != nil { return nil, "", err } cidrRes = ipBlock.ToCidrList()[0] case name != nil: - ipBlock = ipblock.New() + ipBlock = netset.NewIPBlock() if sg, ok := sgMap[*name]; ok { for member := range sg.Members { - memberIPBlock, err := ipblock.FromIPAddress(member) + memberIPBlock, err := netset.IPBlockFromIPAddress(member) if err != nil { return nil, "", err } diff --git a/pkg/commonvpc/vpc.go b/pkg/commonvpc/vpc.go index ac99c542b..3c44a9b9e 100644 --- a/pkg/commonvpc/vpc.go +++ b/pkg/commonvpc/vpc.go @@ -12,8 +12,7 @@ import ( "sort" "strings" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -37,7 +36,7 @@ func (r *Region) SynthesisKind() spec.ResourceType { type Zone struct { Name string Cidrs []string - IPblock *ipblock.IPBlock + IPblock *netset.IPBlock Vpc *VPC // TODO: extend: zone can span over multiple VPCs } @@ -108,19 +107,19 @@ type VPC struct { Zones map[string]*Zone VPCregion *Region // internalAddressRange is the union of all the vpc's subnets' CIDRs - InternalAddressRange *ipblock.IPBlock + InternalAddressRange *netset.IPBlock SubnetsList []*Subnet - AddressPrefixesIPBlock *ipblock.IPBlock + AddressPrefixesIPBlock *netset.IPBlock AddressPrefixesList []string } -func (v *VPC) AddressPrefixes() *ipblock.IPBlock { +func (v *VPC) AddressPrefixes() *netset.IPBlock { return v.AddressPrefixesIPBlock } -func (v *VPC) GetZoneByIPBlock(ipb *ipblock.IPBlock) (string, error) { +func (v *VPC) GetZoneByIPBlock(ipb *netset.IPBlock) (string, error) { for _, z := range v.Zones { - if ipb.ContainedIn(z.IPblock) { + if ipb.IsSubset(z.IPblock) { return z.Name, nil } } @@ -138,7 +137,7 @@ func (v *VPC) Nodes() []vpcmodel.Node { return v.VPCnodes } -func (v *VPC) AddressRange() *ipblock.IPBlock { +func (v *VPC) AddressRange() *netset.IPBlock { return v.InternalAddressRange } @@ -165,9 +164,9 @@ const ( // Subnet implements vpcmodel.Subnet interface type Subnet struct { vpcmodel.VPCResource - VPCnodes []vpcmodel.Node `json:"-"` - Cidr string `json:"-"` - IPblock *ipblock.IPBlock `json:"-"` + VPCnodes []vpcmodel.Node `json:"-"` + Cidr string `json:"-"` + IPblock *netset.IPBlock `json:"-"` subnetExpose SubnetExpose } @@ -183,7 +182,7 @@ func (s *Subnet) Nodes() []vpcmodel.Node { return s.VPCnodes } -func (s *Subnet) AddressRange() *ipblock.IPBlock { +func (s *Subnet) AddressRange() *netset.IPBlock { return s.IPblock } func (s *Subnet) IsPrivate() bool { @@ -278,12 +277,12 @@ func (v *Vsi) Nodes() []vpcmodel.Node { return v.VPCnodes } -func (v *Vsi) AddressRange() *ipblock.IPBlock { +func (v *Vsi) AddressRange() *netset.IPBlock { return nodesAddressRange(v.VPCnodes) } -func nodesAddressRange(nodes []vpcmodel.Node) *ipblock.IPBlock { - var res *ipblock.IPBlock +func nodesAddressRange(nodes []vpcmodel.Node) *netset.IPBlock { + var res *netset.IPBlock for _, n := range nodes { if res == nil { res = n.IPBlock() @@ -335,8 +334,8 @@ func (nl *NaclLayer) GetConnectivityOutputPerEachElemSeparately() string { return strings.Join(res, "\n") } -func (nl *NaclLayer) AllowedConnectivity(src, dst vpcmodel.Node, isIngress bool) (*connection.Set, error) { - res := connection.None() +func (nl *NaclLayer) AllowedConnectivity(src, dst vpcmodel.Node, isIngress bool) (*netset.TransportSet, error) { + res := netset.NoTransports() for _, nacl := range nl.NaclList { naclConn, err := nacl.AllowedConnectivity(src, dst, isIngress) if err != nil { @@ -349,7 +348,7 @@ func (nl *NaclLayer) AllowedConnectivity(src, dst vpcmodel.Node, isIngress bool) // RulesInConnectivity list of NACL rules contributing to the connectivity func (nl *NaclLayer) RulesInConnectivity(src, dst vpcmodel.Node, - connQuery *connection.Set, isIngress bool) (allowRes []vpcmodel.RulesInTable, + connQuery *netset.TransportSet, isIngress bool) (allowRes []vpcmodel.RulesInTable, denyRes []vpcmodel.RulesInTable, err error) { for index, nacl := range nl.NaclList { tableRelevant, allowRules, denyRules, err1 := nacl.rulesFilterInConnectivity(src, dst, connQuery, isIngress) @@ -375,7 +374,7 @@ func (nl *NaclLayer) Name() string { } func appendToRulesInFilter(resRulesInFilter *[]vpcmodel.RulesInTable, rules *[]int, filterIndex int, - tableConn *connection.Set, tableEffect vpcmodel.TableEffect, isAllow bool) { + tableConn *netset.TransportSet, tableEffect vpcmodel.TableEffect, isAllow bool) { var rType vpcmodel.RulesType switch { case len(*rules) == 0: @@ -395,8 +394,8 @@ func appendToRulesInFilter(resRulesInFilter *[]vpcmodel.RulesInTable, rules *[]i *resRulesInFilter = append(*resRulesInFilter, rulesInNacl) } -func (nl *NaclLayer) ReferencedIPblocks() []*ipblock.IPBlock { - res := []*ipblock.IPBlock{} +func (nl *NaclLayer) ReferencedIPblocks() []*netset.IPBlock { + res := []*netset.IPBlock{} for _, n := range nl.NaclList { res = append(res, n.Analyzer.NaclAnalyzer.ReferencedIPblocks()...) } @@ -500,32 +499,32 @@ func (n *NACL) initConnectivityComputation(src, dst vpcmodel.Node, } // checking if targetNode is internal, to save a call to ContainedIn for external nodes if connectivityInput.targetNode.IsInternal() && - connectivityInput.targetNode.IPBlock().ContainedIn(connectivityInput.subnet.IPblock) { + connectivityInput.targetNode.IPBlock().IsSubset(connectivityInput.subnet.IPblock) { connectivityInput.targetWithinSubnet = true } return connectivityInput, nil } -func (n *NACL) AllowedConnectivity(src, dst vpcmodel.Node, isIngress bool) (*connection.Set, error) { +func (n *NACL) AllowedConnectivity(src, dst vpcmodel.Node, isIngress bool) (*netset.TransportSet, error) { connectivityInput, err := n.initConnectivityComputation(src, dst, isIngress) if err != nil { return nil, err } // check if the subnet of the given node is affected by this nacl if !connectivityInput.subnetAffectedByNACL { - return connection.None(), nil // not affected by current nacl + return netset.NoTransports(), nil // not affected by current nacl } // TODO: differentiate between "has no effect" vs "affects with allow-all / allow-none " if connectivityInput.targetWithinSubnet { - return connection.All(), nil // nacl has no control on traffic between two instances in its subnet + return netset.AllTransports(), nil // nacl has no control on traffic between two instances in its subnet } return n.Analyzer.AllowedConnectivity(connectivityInput.subnet, connectivityInput.nodeInSubnet, connectivityInput.targetNode, isIngress) } // TODO: rulesFilterInConnectivity has some duplicated code with AllowedConnectivity -func (n *NACL) rulesFilterInConnectivity(src, dst vpcmodel.Node, conn *connection.Set, +func (n *NACL) rulesFilterInConnectivity(src, dst vpcmodel.Node, conn *netset.TransportSet, isIngress bool) (tableRelevant bool, allow, deny []int, err error) { connectivityInput, err1 := n.initConnectivityComputation(src, dst, isIngress) if err1 != nil { @@ -565,8 +564,8 @@ func (sgl *SecurityGroupLayer) GetConnectivityOutputPerEachElemSeparately() stri // AllowedConnectivity // TODO: fix: is it possible that no sg applies to the input peer? if so, should not return "no conns" when none applies -func (sgl *SecurityGroupLayer) AllowedConnectivity(src, dst vpcmodel.Node, isIngress bool) (*connection.Set, error) { - res := connection.None() +func (sgl *SecurityGroupLayer) AllowedConnectivity(src, dst vpcmodel.Node, isIngress bool) (*netset.TransportSet, error) { + res := netset.NoTransports() for _, sg := range sgl.SgList { sgConn := sg.AllowedConnectivity(src, dst, isIngress) res = res.Union(sgConn) @@ -578,7 +577,7 @@ func (sgl *SecurityGroupLayer) AllowedConnectivity(src, dst vpcmodel.Node, isIng // or between src and dst of connection connQuery if connQuery specified // denyRules not relevant here - returns nil func (sgl *SecurityGroupLayer) RulesInConnectivity(src, dst vpcmodel.Node, - connQuery *connection.Set, isIngress bool) (allowRes []vpcmodel.RulesInTable, + connQuery *netset.TransportSet, isIngress bool) (allowRes []vpcmodel.RulesInTable, denyRes []vpcmodel.RulesInTable, err error) { for index, sg := range sgl.SgList { tableRelevant, sgRules, err1 := sg.rulesFilterInConnectivity(src, dst, connQuery, isIngress) @@ -605,8 +604,8 @@ func (sgl *SecurityGroupLayer) RulesInConnectivity(src, dst vpcmodel.Node, return allowRes, nil, nil } -func (sgl *SecurityGroupLayer) ReferencedIPblocks() []*ipblock.IPBlock { - res := []*ipblock.IPBlock{} +func (sgl *SecurityGroupLayer) ReferencedIPblocks() []*netset.IPBlock { + res := []*netset.IPBlock{} for _, sg := range sgl.SgList { res = append(res, sg.Analyzer.SgAnalyzer.ReferencedIPblocks()...) } @@ -640,7 +639,7 @@ func (sgl *SecurityGroupLayer) getIngressOrEgressRules(isIngress bool) ([]vpcmod sgName := *sg.Analyzer.SgAnalyzer.Name() for _, ruleOfSG := range sgRules { ruleDesc, _, _, _ := sg.Analyzer.SgAnalyzer.GetSGRule(ruleOfSG.Index) - var srcBlock, dstBlock *ipblock.IPBlock + var srcBlock, dstBlock *netset.IPBlock if isIngress { srcBlock, dstBlock = ruleOfSG.Remote.Cidr, ruleOfSG.Local } else { @@ -676,17 +675,17 @@ type SecurityGroup struct { Members map[string]vpcmodel.Node } -func (sg *SecurityGroup) AllowedConnectivity(src, dst vpcmodel.Node, isIngress bool) *connection.Set { +func (sg *SecurityGroup) AllowedConnectivity(src, dst vpcmodel.Node, isIngress bool) *netset.TransportSet { memberIPBlock, targetIPBlock, memberStrAddress := sg.getMemberTargetStrAddress(src, dst, isIngress) if _, ok := sg.Members[memberStrAddress]; !ok { - return connection.None() // connectivity not affected by this SG resource - input node is not its member + return netset.NoTransports() // connectivity not affected by this SG resource - input node is not its member } return sg.Analyzer.allowedConnectivity(targetIPBlock, memberIPBlock, isIngress) } // unifiedMembersIPBlock returns an *IPBlock object with union of all members IPBlock -func (sg *SecurityGroup) unifiedMembersIPBlock() (unifiedMembersIPBlock *ipblock.IPBlock) { - unifiedMembersIPBlock = ipblock.New() +func (sg *SecurityGroup) unifiedMembersIPBlock() (unifiedMembersIPBlock *netset.IPBlock) { + unifiedMembersIPBlock = netset.NewIPBlock() for _, memberNode := range sg.Members { unifiedMembersIPBlock = unifiedMembersIPBlock.Union(memberNode.IPBlock()) } @@ -695,7 +694,7 @@ func (sg *SecurityGroup) unifiedMembersIPBlock() (unifiedMembersIPBlock *ipblock } // rulesFilterInConnectivity list of SG rules contributing to the connectivity -func (sg *SecurityGroup) rulesFilterInConnectivity(src, dst vpcmodel.Node, conn *connection.Set, +func (sg *SecurityGroup) rulesFilterInConnectivity(src, dst vpcmodel.Node, conn *netset.TransportSet, isIngress bool) (tableRelevant bool, rules []int, err error) { memberIPBlock, targetIPBlock, memberStrAddress := sg.getMemberTargetStrAddress(src, dst, isIngress) if _, ok := sg.Members[memberStrAddress]; !ok { @@ -706,7 +705,7 @@ func (sg *SecurityGroup) rulesFilterInConnectivity(src, dst vpcmodel.Node, conn } func (sg *SecurityGroup) getMemberTargetStrAddress(src, dst vpcmodel.Node, - isIngress bool) (memberIPBlock, targetIPBlock *ipblock.IPBlock, memberStrAddress string) { + isIngress bool) (memberIPBlock, targetIPBlock *netset.IPBlock, memberStrAddress string) { var member, target vpcmodel.Node if isIngress { member, target = dst, src @@ -717,7 +716,7 @@ func (sg *SecurityGroup) getMemberTargetStrAddress(src, dst vpcmodel.Node, return member.IPBlock(), target.IPBlock(), member.CidrOrAddress() } -func getTableConnEffect(connQuery, conn *connection.Set) (*connection.Set, vpcmodel.TableEffect) { +func getTableConnEffect(connQuery, conn *netset.TransportSet) (*netset.TransportSet, vpcmodel.TableEffect) { switch { case connQuery == nil: // connection not part of query if !conn.IsEmpty() { @@ -726,8 +725,8 @@ func getTableConnEffect(connQuery, conn *connection.Set) (*connection.Set, vpcmo return conn, vpcmodel.Deny } case conn.Intersect(connQuery).IsEmpty(): - return connection.None(), vpcmodel.Deny - case connQuery.ContainedIn(conn): + return netset.NoTransports(), vpcmodel.Deny + case connQuery.IsSubset(conn): return connQuery, vpcmodel.Allow default: return conn.Intersect(connQuery), vpcmodel.PartlyAllow diff --git a/pkg/ibmvpc/connectivityAnalysis_test.go b/pkg/ibmvpc/connectivityAnalysis_test.go index 1f341b2e0..166c42fc9 100644 --- a/pkg/ibmvpc/connectivityAnalysis_test.go +++ b/pkg/ibmvpc/connectivityAnalysis_test.go @@ -12,8 +12,8 @@ import ( "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/connection" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" @@ -93,7 +93,7 @@ var nc3 = &naclConfig{ { Src: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), Dst: newIPBlockFromCIDROrAddressWithoutValidation("10.240.20.0/24"), - Connections: connection.All(), + Connections: netset.AllTransports(), Action: "allow", }, }, @@ -108,15 +108,15 @@ var nc4 = &naclConfig{ { Src: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), Dst: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), - Connections: connection.TCPorUDPConnection(netp.ProtocolStringTCP, netp.MinPort, netp.MaxPort, netp.MinPort, netp.MaxPort), + Connections: netset.NewTCPorUDPTransport(netp.ProtocolStringTCP, netp.MinPort, netp.MaxPort, netp.MinPort, netp.MaxPort), Action: "allow", }, }, subnets: []string{"10.240.20.0/24"}, } -func nc5Conn() *connection.Set { - return connection.TCPorUDPConnection(netp.ProtocolStringTCP, 10, 100, 443, 443) +func nc5Conn() *netset.TransportSet { + return netset.NewTCPorUDPTransport(netp.ProtocolStringTCP, 10, 100, 443, 443) } // nc5 - applied to subnet-1, limited egress (certain TCP ports allowed) @@ -134,8 +134,8 @@ var nc5 = &naclConfig{ subnets: []string{"10.240.10.0/24"}, } -func nc6Conn() *connection.Set { - return connection.TCPorUDPConnection(netp.ProtocolStringTCP, 443, 443, 10, 100) +func nc6Conn() *netset.TransportSet { + return netset.NewTCPorUDPTransport(netp.ProtocolStringTCP, 443, 443, 10, 100) } var nc6 = &naclConfig{ @@ -240,7 +240,7 @@ func getAllowAllRules() []*commonvpc.NACLRule { { Src: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), Dst: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), - Connections: connection.All(), + Connections: netset.AllTransports(), Action: "allow", }, } @@ -251,7 +251,7 @@ func getDenyAllRules() []*commonvpc.NACLRule { { Src: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), Dst: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), - Connections: connection.All(), + Connections: netset.AllTransports(), Action: "deny", }, } @@ -268,10 +268,8 @@ func getAllowICMPRules() []*commonvpc.NACLRule { } } -func icmpConn() *connection.Set { - return connection.ICMPConnection( - connection.MinICMPType, connection.MaxICMPType, - connection.MinICMPCode, connection.MaxICMPCode) +func icmpConn() *netset.TransportSet { + return netset.AllICMPTransport() } func addInterfaceNode(config *vpcmodel.VPCConfig, name, address, vsiName, subnetName string) { diff --git a/pkg/ibmvpc/egress_routing_test.go b/pkg/ibmvpc/egress_routing_test.go index e7ec372b3..822635081 100644 --- a/pkg/ibmvpc/egress_routing_test.go +++ b/pkg/ibmvpc/egress_routing_test.go @@ -31,7 +31,7 @@ func genConfig(vpc *commonvpc.VPC, subnets []*commonvpc.Subnet, res.NodeSets = append(res.NodeSets, subnet) // add references from subnet to nodes, and from node to subnet for _, node := range netInterfaces { - if node.IPBlockObj.ContainedIn(subnet.AddressRange()) { + if node.IPBlockObj.IsSubset(subnet.AddressRange()) { subnet.VPCnodes = append(subnet.VPCnodes, node) node.SubnetResource = subnet // currently skipping nodes without subnets diff --git a/pkg/ibmvpc/examples/out/analysis_out/multi_regions_all_vpcs_.txt b/pkg/ibmvpc/examples/out/analysis_out/multi_regions_all_vpcs_.txt index 34701798b..b521af8a0 100644 --- a/pkg/ibmvpc/examples/out/analysis_out/multi_regions_all_vpcs_.txt +++ b/pkg/ibmvpc/examples/out/analysis_out/multi_regions_all_vpcs_.txt @@ -12,7 +12,7 @@ Endpoint connectivity for VPC ete-backup-and-storage Endpoint connectivity for VPC ete-storage-project Public Internet 1.0.0.0-9.255.255.255,11.0.0.0-100.63.255.255,100.128.0.0-126.255.255.255,128.0.0.0-129.33.255.255,129.35.0.0-129.41.45.255,129.41.48.0/21,129.41.60.0-129.41.85.255,129.41.88.0-161.25.255.255,161.27.0.0-161.202.246.191,161.202.246.224-166.7.255.255,166.12.0.0-169.253.255.255,169.255.0.0-172.15.255.255,172.32.0.0-191.255.255.255,192.0.1.0/24,192.0.3.0-192.88.98.255,192.88.100.0-192.167.255.255,192.169.0.0-195.110.39.255,195.110.42.0-198.17.255.255,198.20.0.0-198.51.99.255,198.51.101.0-203.0.112.255,203.0.114.0-223.255.255.255 => ete-basic-01[10.248.64.4] : protocol: ICMP icmp-type: 8 Public Internet 129.34.0.0/16,161.202.246.192/27,195.110.40.0/23 => ete-basic-01[10.248.64.4] : protocol: ICMP icmp-type: 8; protocol: TCP dst-ports: 22 -Public Internet 129.41.46.0/23,129.41.56.0/22,129.41.86.0/23 => ete-basic-01[10.248.64.4] : protocol: ICMP icmp-type: 8; protocol: TCP +Public Internet 129.41.46.0/23,129.41.56.0/22,129.41.86.0/23 => ete-basic-01[10.248.64.4] : protocol: TCP; protocol: ICMP icmp-type: 8 Public Internet 161.26.0.0/16,166.8.0.0/14 => ete-basic-01[10.248.64.4] : All Connections ete-basic-01[10.248.64.4] => Public Internet (all ranges) : All Connections ete-basic-01[10.248.64.4] => xc-login-01[10.248.64.9] : All Connections diff --git a/pkg/ibmvpc/examples/out/analysis_out/tgw_basic_example_multiple_regions_all_vpcs_.txt b/pkg/ibmvpc/examples/out/analysis_out/tgw_basic_example_multiple_regions_all_vpcs_.txt index 4a04f7029..56d292f2e 100644 --- a/pkg/ibmvpc/examples/out/analysis_out/tgw_basic_example_multiple_regions_all_vpcs_.txt +++ b/pkg/ibmvpc/examples/out/analysis_out/tgw_basic_example_multiple_regions_all_vpcs_.txt @@ -18,7 +18,7 @@ Endpoint connectivity for VPC ete-backup-and-storage Endpoint connectivity for VPC ete-storage-project Public Internet 1.0.0.0-9.255.255.255,11.0.0.0-100.63.255.255,100.128.0.0-126.255.255.255,128.0.0.0-129.33.255.255,129.35.0.0-129.41.45.255,129.41.48.0/21,129.41.60.0-129.41.85.255,129.41.88.0-161.25.255.255,161.27.0.0-161.202.246.191,161.202.246.224-166.7.255.255,166.12.0.0-169.253.255.255,169.255.0.0-172.15.255.255,172.32.0.0-191.255.255.255,192.0.1.0/24,192.0.3.0-192.88.98.255,192.88.100.0-192.167.255.255,192.169.0.0-195.110.39.255,195.110.42.0-198.17.255.255,198.20.0.0-198.51.99.255,198.51.101.0-203.0.112.255,203.0.114.0-223.255.255.255 => ete-basic-01[10.248.64.4] : protocol: ICMP icmp-type: 8 Public Internet 129.34.0.0/16,161.202.246.192/27,195.110.40.0/23 => ete-basic-01[10.248.64.4] : protocol: ICMP icmp-type: 8; protocol: TCP dst-ports: 22 -Public Internet 129.41.46.0/23,129.41.56.0/22,129.41.86.0/23 => ete-basic-01[10.248.64.4] : protocol: ICMP icmp-type: 8; protocol: TCP +Public Internet 129.41.46.0/23,129.41.56.0/22,129.41.86.0/23 => ete-basic-01[10.248.64.4] : protocol: TCP; protocol: ICMP icmp-type: 8 Public Internet 161.26.0.0/16,166.8.0.0/14 => ete-basic-01[10.248.64.4] : All Connections ete-basic-01[10.248.64.4] => Public Internet (all ranges) : All Connections ete-basic-01[10.248.64.4] => xc-login-01[10.248.64.9] : All Connections diff --git a/pkg/ibmvpc/explainability_test.go b/pkg/ibmvpc/explainability_test.go index 1a7666584..f08c02832 100644 --- a/pkg/ibmvpc/explainability_test.go +++ b/pkg/ibmvpc/explainability_test.go @@ -13,7 +13,6 @@ import ( "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/connection" "github.com/np-guard/models/pkg/netp" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc/testfunc" @@ -160,10 +159,10 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "vsi1-ky", EDst: "161.26.0.0/16", EProtocol: netp.ProtocolStringUDP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, - EDstMinPort: connection.MinPort, - EDstMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, + EDstMinPort: netp.MinPort, + EDstMaxPort: netp.MaxPort, DetailExplain: true, }, // the required connection is contained in the existing one per connection @@ -235,8 +234,8 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "147.235.219.206/32", EDst: "vsi2-ky", EProtocol: netp.ProtocolStringTCP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, EDstMinPort: 10, EDstMaxPort: 30, DetailExplain: true, @@ -260,10 +259,10 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "vsi3a-ky", EDst: "vsi1-ky", EProtocol: netp.ProtocolStringUDP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, - EDstMinPort: connection.MinPort, - EDstMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, + EDstMinPort: netp.MinPort, + EDstMaxPort: netp.MaxPort, DetailExplain: true, }, // only a subset of the rules are relevant, port wise and protocol wise @@ -275,8 +274,8 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "vsi3a-ky", EDst: "vsi1-ky", EProtocol: netp.ProtocolStringTCP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, EDstMinPort: 50, EDstMaxPort: 54, DetailExplain: true, @@ -290,8 +289,8 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "vsi3a-ky", EDst: "vsi1-ky", EProtocol: netp.ProtocolStringTCP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, EDstMinPort: 120, EDstMaxPort: 230, DetailExplain: true, @@ -387,10 +386,10 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "vsi1-ky", EDst: "161.26.0.0/16", EProtocol: netp.ProtocolStringUDP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, - EDstMinPort: connection.MinPort, - EDstMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, + EDstMinPort: netp.MinPort, + EDstMaxPort: netp.MaxPort, DetailExplain: true, }, { @@ -401,10 +400,10 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "vsi1-ky", EDst: "161.26.0.0/16", EProtocol: netp.ProtocolStringTCP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, - EDstMinPort: connection.MinPort, - EDstMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, + EDstMinPort: netp.MinPort, + EDstMaxPort: netp.MaxPort, DetailExplain: true, }, // src: one of these network interfaces, dst: internal address of 4 network interfaces @@ -447,10 +446,10 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "vsi1-ky", EDst: "161.26.0.0/16", EProtocol: netp.ProtocolStringTCP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, - EDstMinPort: connection.MinPort, - EDstMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, + EDstMinPort: netp.MinPort, + EDstMaxPort: netp.MaxPort, DetailExplain: true, }, // without the "all" rule since udp rule has higher priority @@ -462,10 +461,10 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "10.240.10.4/32", EDst: "161.26.0.0/16", EProtocol: netp.ProtocolStringUDP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, - EDstMinPort: connection.MinPort, - EDstMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, + EDstMinPort: netp.MinPort, + EDstMaxPort: netp.MaxPort, DetailExplain: true, }, { @@ -476,10 +475,10 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "vsi1-ky", EDst: "vsi2-ky", EProtocol: netp.ProtocolStringICMP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, - EDstMinPort: connection.MinPort, - EDstMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, + EDstMinPort: netp.MinPort, + EDstMaxPort: netp.MaxPort, DetailExplain: true, }, // allow connection subset of the queried one @@ -491,10 +490,10 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "vsi1-ky", EDst: "161.26.0.0/16", EProtocol: netp.ProtocolStringUDP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, - EDstMinPort: connection.MinPort, - EDstMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, + EDstMinPort: netp.MinPort, + EDstMaxPort: netp.MaxPort, DetailExplain: true, }, // two SGs attached to one VSI @@ -721,10 +720,10 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "192.168.40.5", EDst: "192.168.0.4", EProtocol: netp.ProtocolStringTCP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, - EDstMinPort: connection.MinPort, - EDstMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, + EDstMinPort: netp.MinPort, + EDstMaxPort: netp.MaxPort, DetailExplain: true, }, // iks-node no connection (specific protocol) @@ -736,10 +735,10 @@ var explainTests = []*testfunc.VpcExplainTest{ ESrc: "192.168.40.5", EDst: "192.168.0.4", EProtocol: netp.ProtocolStringICMP, - ESrcMinPort: connection.MinPort, - ESrcMaxPort: connection.MaxPort, - EDstMinPort: connection.MinPort, - EDstMaxPort: connection.MaxPort, + ESrcMinPort: netp.MinPort, + ESrcMaxPort: netp.MaxPort, + EDstMinPort: netp.MinPort, + EDstMaxPort: netp.MaxPort, DetailExplain: true, }, // load_balancer to iks-node, which is a pool member, should be allowed diff --git a/pkg/ibmvpc/implicit_routing.go b/pkg/ibmvpc/implicit_routing.go index 34ab3a360..12d2139dc 100644 --- a/pkg/ibmvpc/implicit_routing.go +++ b/pkg/ibmvpc/implicit_routing.go @@ -9,7 +9,7 @@ package ibmvpc import ( "fmt" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/logging" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" @@ -62,7 +62,7 @@ type systemRTConfig struct { pgwList []*PublicGateway } -func (rt *systemImplicitRT) destAsPath(dest *ipblock.IPBlock) vpcmodel.Path { +func (rt *systemImplicitRT) destAsPath(dest *netset.IPBlock) vpcmodel.Path { internalNodes := rt.vpcConfig.GetNodesWithinInternalAddress(dest) if len(internalNodes) != 1 { // TODO: add error handling here? @@ -86,9 +86,9 @@ func systemRTConfigFromVPCConfig(vpcConfig *vpcmodel.VPCConfig) *systemRTConfig return res } -func isDestPublicInternet(dest *ipblock.IPBlock) bool { +func isDestPublicInternet(dest *netset.IPBlock) bool { _, publicRange, _ := vpcmodel.GetPublicInternetIPblocksList() - return dest.ContainedIn(publicRange) + return dest.IsSubset(publicRange) } func fipHasSource(src vpcmodel.Node, fip *FloatingIP) bool { @@ -101,13 +101,13 @@ func fipHasSource(src vpcmodel.Node, fip *FloatingIP) bool { } func pgwHasSource(src vpcmodel.Node, pgw *PublicGateway) bool { - cidrs, _ := ipblock.FromCidrList(pgw.subnetCidr) - return src.IPBlock().ContainedIn(cidrs) + cidrs, _ := netset.IPBlockFromCidrList(pgw.subnetCidr) + return src.IPBlock().IsSubset(cidrs) // another option: compare by nodes within pgw.src (currently breaks test) } // getIngressPath returns a path to dest -func (rt *systemImplicitRT) getIngressPath(dest *ipblock.IPBlock) (vpcmodel.Path, error) { +func (rt *systemImplicitRT) getIngressPath(dest *netset.IPBlock) (vpcmodel.Path, error) { // traffic from some source is by default simply routed to dest node path := rt.destAsPath(dest) if len(path) == 0 { @@ -119,10 +119,10 @@ func (rt *systemImplicitRT) getIngressPath(dest *ipblock.IPBlock) (vpcmodel.Path // getEgressPath returns a path from src to dst if such exists, or nil otherwise // TODO: src should be InternalNodeIntf, but it does not implement VPCResourceIntf -func (rt *systemImplicitRT) getEgressPath(src vpcmodel.Node, dest *ipblock.IPBlock) vpcmodel.Path { +func (rt *systemImplicitRT) getEgressPath(src vpcmodel.Node, dest *netset.IPBlock) vpcmodel.Path { // TODO: split dest by disjoint ip-blocks of the vpc-config (the known destinations ip-blocks) - if dest.ContainedIn(rt.vpc.AddressPrefixes()) { + if dest.IsSubset(rt.vpc.AddressPrefixes()) { // direct connection return vpcmodel.ConcatPaths(vpcmodel.PathFromResource(src), rt.destAsPath(dest)) } @@ -162,7 +162,7 @@ func (rt *systemImplicitRT) getEgressPath(src vpcmodel.Node, dest *ipblock.IPBlo // (the dest VPC could publish its AddressPrefix, but may not have the required dest subnet ) for _, prefix := range availablePrefixes { logging.Debugf("check available prefix: %s", prefix.ToCidrListString()) - if dest.ContainedIn(prefix) { + if dest.IsSubset(prefix) { // path through tgw // TODO: should be concatenated to path from tgw to dest by ingress routing table in the second vpc return vpcmodel.ConcatPaths(vpcmodel.PathFromResource(src), vpcmodel.PathFromTGWResource(tgw, vpcUID)) diff --git a/pkg/ibmvpc/implicit_routing_test.go b/pkg/ibmvpc/implicit_routing_test.go index ce4acba9d..3ff7e741a 100644 --- a/pkg/ibmvpc/implicit_routing_test.go +++ b/pkg/ibmvpc/implicit_routing_test.go @@ -11,14 +11,14 @@ import ( "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) type testImplicitRT struct { name string - dest *ipblock.IPBlock + dest *netset.IPBlock expectedPath vpcmodel.Path } diff --git a/pkg/ibmvpc/ingress_routing_test.go b/pkg/ibmvpc/ingress_routing_test.go index ab635ea8e..bf1b1af5e 100644 --- a/pkg/ibmvpc/ingress_routing_test.go +++ b/pkg/ibmvpc/ingress_routing_test.go @@ -16,7 +16,7 @@ import ( "github.com/np-guard/cloud-resource-collector/pkg/common" "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -67,8 +67,8 @@ func addTGWConfig(tgwObj *TransitGateway, configs *vpcmodel.MultipleVPCConfigs) //nolint:unparam // currently `nextHop` always receives `"10.1.15.197", due to current test func pathFromNextHopValues(nextHop, origDest string) vpcmodel.Path { - n, _ := ipblock.FromCidrOrAddress(nextHop) - o, _ := ipblock.FromCidrOrAddress(origDest) + n, _ := netset.IPBlockFromCidrOrAddress(nextHop) + o, _ := netset.IPBlockFromCidrOrAddress(origDest) return []*vpcmodel.Endpoint{{NextHop: &vpcmodel.NextHopEntry{NextHop: n, OrigDest: o}}} } @@ -463,7 +463,7 @@ var config4Tests = []*testGlobalAnalyzer{ func (tga *testGlobalAnalyzer) run(t *testing.T, globalAnalyzer *GlobalRTAnalyzer, configs *vpcmodel.MultipleVPCConfigs) { srcNode, _ := configs.GetInternalNodeFromAddress(tga.src) - dstIPBlock, _ := ipblock.FromIPAddress(tga.dst) + dstIPBlock, _ := netset.IPBlockFromIPAddress(tga.dst) path, err := globalAnalyzer.GetRoutingPath(srcNode, dstIPBlock) fmt.Printf("path: %s\n", path.String()) require.Nil(t, err) diff --git a/pkg/ibmvpc/naclAnalysis_test.go b/pkg/ibmvpc/naclAnalysis_test.go index f934ebfb4..880ce159d 100644 --- a/pkg/ibmvpc/naclAnalysis_test.go +++ b/pkg/ibmvpc/naclAnalysis_test.go @@ -13,8 +13,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc/testfunc" ) @@ -51,13 +50,13 @@ func TestGetAllowedXgressConnections(t *testing.T) { { Src: newIPBlockFromCIDROrAddressWithoutValidation("1.2.3.4/32"), Dst: newIPBlockFromCIDROrAddressWithoutValidation("10.0.0.1/32"), - Connections: connection.All(), + Connections: netset.AllTransports(), Action: "deny", }, { Src: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), Dst: newIPBlockFromCIDROrAddressWithoutValidation("0.0.0.0/0"), - Connections: connection.All(), + Connections: netset.AllTransports(), Action: "allow", }, } @@ -118,14 +117,14 @@ func TestGetAllowedXgressConnections(t *testing.T) { naclRules []*commonvpc.NACLRule src []string dst []string - expectedConns []*connection.Set + expectedConns []*netset.TransportSet }{ { testName: "a", naclRules: rulesTest1, src: []string{"1.1.1.1/32", "1.2.3.4/32", "1.2.3.4/32"}, dst: []string{"10.0.0.0/24", "10.0.0.1/32", "10.0.0.0/32"}, - expectedConns: []*connection.Set{connection.All(), connection.None(), connection.All()}, + expectedConns: []*netset.TransportSet{netset.AllTransports(), netset.NoTransports(), netset.AllTransports()}, }, } @@ -135,7 +134,7 @@ func TestGetAllowedXgressConnections(t *testing.T) { for i := range tt.src { src := newIPBlockFromCIDROrAddressWithoutValidation(tt.src[i]) dst := newIPBlockFromCIDROrAddressWithoutValidation(tt.dst[i]) - disjointPeers := []*ipblock.IPBlock{dst} + disjointPeers := []*netset.IPBlock{dst} expectedConn := tt.expectedConns[i] res, _, _, _ := commonvpc.GetAllowedXgressConnections(tt.naclRules, src, dst, disjointPeers, true) dstStr := dst.ToIPRanges() @@ -147,7 +146,7 @@ func TestGetAllowedXgressConnections(t *testing.T) { //nolint:all /*src := common.FromCidr("1.1.1.1/32") dst := common.FromCidr("10.0.0.0/24") - disjointPeers := []*ipblock.IPBlock{dst} + disjointPeers := []*netset.IPBlock{dst} res := commonvpc.GetAllowedXgressConnections(rulesTest1, src, dst, disjointPeers, true) for d, c := range res { fmt.Printf("%s => %s : %s\n", src.ToIPAdress(), d, c.String()) diff --git a/pkg/ibmvpc/nacl_analysis.go b/pkg/ibmvpc/nacl_analysis.go index 72a854600..ddd25ff0f 100644 --- a/pkg/ibmvpc/nacl_analysis.go +++ b/pkg/ibmvpc/nacl_analysis.go @@ -11,8 +11,8 @@ import ( vpc1 "github.com/IBM/vpc-go-sdk/vpcv1" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" ) @@ -20,7 +20,7 @@ import ( // IBMNACLAnalyzer implements commonvpc.SpecificNACLAnalyzer type IBMNACLAnalyzer struct { naclResource *vpc1.NetworkACL - referencedIPblocks []*ipblock.IPBlock + referencedIPblocks []*netset.IPBlock } func NewIBMNACLAnalyzer(nacl *vpc1.NetworkACL) *IBMNACLAnalyzer { @@ -40,18 +40,18 @@ func (na *IBMNACLAnalyzer) Name() *string { return na.naclResource.Name } -func (na *IBMNACLAnalyzer) ReferencedIPblocks() []*ipblock.IPBlock { +func (na *IBMNACLAnalyzer) ReferencedIPblocks() []*netset.IPBlock { return na.referencedIPblocks } // SetReferencedIPblocks updates referenced ip blocks -func (na *IBMNACLAnalyzer) SetReferencedIPblocks(referencedIPblocks []*ipblock.IPBlock) { +func (na *IBMNACLAnalyzer) SetReferencedIPblocks(referencedIPblocks []*netset.IPBlock) { na.referencedIPblocks = referencedIPblocks } // GetNACLRule gets index of the rule and returns the rule results line and obj func (na *IBMNACLAnalyzer) GetNACLRule(index int) (ruleStr string, ruleRes *commonvpc.NACLRule, isIngress bool, err error) { - var conns *connection.Set + var conns *netset.TransportSet var direction, src, dst, action string var name, connStr string rule := na.naclResource.Rules[index] @@ -59,7 +59,7 @@ func (na *IBMNACLAnalyzer) GetNACLRule(index int) (ruleStr string, ruleRes *comm switch ruleObj := rule.(type) { case *vpc1.NetworkACLRuleItemNetworkACLRuleProtocolAll: name = *ruleObj.Name - conns = connection.All() + conns = netset.AllTransports() protocol = *ruleObj.Protocol direction = *ruleObj.Direction src = *ruleObj.Source @@ -68,10 +68,10 @@ func (na *IBMNACLAnalyzer) GetNACLRule(index int) (ruleStr string, ruleRes *comm case *vpc1.NetworkACLRuleItemNetworkACLRuleProtocolTcpudp: name = *ruleObj.Name conns = commonvpc.GetTCPUDPConns(*ruleObj.Protocol, - commonvpc.GetProperty(ruleObj.SourcePortMin, connection.MinPort), - commonvpc.GetProperty(ruleObj.SourcePortMax, connection.MaxPort), - commonvpc.GetProperty(ruleObj.DestinationPortMin, connection.MinPort), - commonvpc.GetProperty(ruleObj.DestinationPortMax, connection.MaxPort), + commonvpc.GetProperty(ruleObj.SourcePortMin, netp.MinPort), + commonvpc.GetProperty(ruleObj.SourcePortMax, netp.MaxPort), + commonvpc.GetProperty(ruleObj.DestinationPortMin, netp.MinPort), + commonvpc.GetProperty(ruleObj.DestinationPortMax, netp.MaxPort), ) srcPorts := getPortsStr(*ruleObj.SourcePortMin, *ruleObj.SourcePortMax) dstPorts := getPortsStr(*ruleObj.DestinationPortMin, *ruleObj.DestinationPortMax) @@ -101,7 +101,7 @@ func (na *IBMNACLAnalyzer) GetNACLRule(index int) (ruleStr string, ruleRes *comm } connStr = "protocol: " + protocol + portsStr - srcIP, dstIP, err := ipblock.PairCIDRsToIPBlocks(src, dst) + srcIP, dstIP, err := netset.PairCIDRsToIPBlocks(src, dst) if err != nil { return "", nil, false, err } diff --git a/pkg/ibmvpc/parser.go b/pkg/ibmvpc/parser.go index 7d79f08a1..efc3c60b3 100644 --- a/pkg/ibmvpc/parser.go +++ b/pkg/ibmvpc/parser.go @@ -18,7 +18,7 @@ import ( "github.com/np-guard/cloud-resource-collector/pkg/common" "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/logging" @@ -142,7 +142,7 @@ func (rc *IBMresourcesContainer) VPCConfigsFromResources(resourceGroup string, v return nil, err } - var vpcInternalAddressRange map[string]*ipblock.IPBlock // map from vpc name to its internal address range + var vpcInternalAddressRange map[string]*netset.IPBlock // map from vpc name to its internal address range subnetIDToNetIntf := map[string][]*commonvpc.NetworkInterface{} err = rc.getInstancesConfig(subnetIDToNetIntf, res, filteredOut, shouldSkipVpcIds) @@ -442,8 +442,8 @@ func (rc *IBMresourcesContainer) getSubnetsConfig( pgwToSubnet map[string][]*commonvpc.Subnet, subnetIDToNetIntf map[string][]*commonvpc.NetworkInterface, skipByVPC map[string]bool, -) (vpcInternalAddressRange map[string]*ipblock.IPBlock, err error) { - vpcInternalAddressRange = map[string]*ipblock.IPBlock{} +) (vpcInternalAddressRange map[string]*netset.IPBlock, err error) { + vpcInternalAddressRange = map[string]*netset.IPBlock{} for vpcUID := range res.Configs() { vpcInternalAddressRange[vpcUID] = nil } @@ -799,8 +799,8 @@ func newTGW(name, uid, region string, regionToStructMap map[string]*commonvpc.Re Region: region, }, vpcs: []*commonvpc.VPC{}, - availableRoutes: map[string][]*ipblock.IPBlock{}, - vpcsAPToPrefixRules: map[string]map[*ipblock.IPBlock]vpcmodel.RulesInTable{}, + availableRoutes: map[string][]*netset.IPBlock{}, + vpcsAPToPrefixRules: map[string]map[*netset.IPBlock]vpcmodel.RulesInTable{}, region: commonvpc.GetRegionByName(region, regionToStructMap), tgwConnList: tgwConnList, } @@ -824,7 +824,7 @@ func (tgw *TransitGateway) addVPC(vpc *commonvpc.VPC, tgwConn *datamodel.Transit // explainability related struct initialization for ipB, rulesInTable := range vpcAPToPrefixRules { if _, ok := tgw.vpcsAPToPrefixRules[vpcUID]; !ok { - tgw.vpcsAPToPrefixRules[vpcUID] = map[*ipblock.IPBlock]vpcmodel.RulesInTable{} + tgw.vpcsAPToPrefixRules[vpcUID] = map[*netset.IPBlock]vpcmodel.RulesInTable{} } tgw.vpcsAPToPrefixRules[vpcUID][ipB] = rulesInTable } @@ -911,12 +911,12 @@ func (rc *IBMresourcesContainer) getTgwObjects( // validateVPCsAddressPrefixesForTGW checks that all VPCs address prefixes (connected by TGW) are disjoint, // returns error if address prefixes are missing or overlapping func validateVPCsAddressPrefixesForTGW(vpcsList []*commonvpc.VPC) (err error) { - ipBlocksForAP := make([]*ipblock.IPBlock, len(vpcsList)) + ipBlocksForAP := make([]*netset.IPBlock, len(vpcsList)) for i, vpc := range vpcsList { if len(vpc.AddressPrefixesList) == 0 { return fmt.Errorf("TGW analysis requires all VPCs have configured address prefixes, but this is missing for vpc %s", vpc.NameAndUID()) } - ipBlocksForAP[i], err = ipblock.FromCidrList(vpc.AddressPrefixesList) + ipBlocksForAP[i], err = netset.IPBlockFromCidrList(vpc.AddressPrefixesList) if err != nil { return err } @@ -969,7 +969,7 @@ func (tgw *TransitGateway) newConfigFromTGW(configs *vpcmodel.MultipleVPCConfigs IsMultipleVPCsConfig: true, } - var vpcsAddressRanges *ipblock.IPBlock // collect all internal address ranges of involved VPCs + var vpcsAddressRanges *netset.IPBlock // collect all internal address ranges of involved VPCs nacls := &commonvpc.NaclLayer{VPCResource: vpcmodel.VPCResource{ResourceType: vpcmodel.NaclLayer}} sgs := &commonvpc.SecurityGroupLayer{VPCResource: vpcmodel.VPCResource{ResourceType: vpcmodel.SecurityGroupLayer}} for _, vpc := range tgw.vpcs { // iterate the involved VPCs -- all of them are connected (all to all) @@ -1045,9 +1045,9 @@ func (tgw *TransitGateway) newConfigFromTGW(configs *vpcmodel.MultipleVPCConfigs return newConfig, nil } -func getSubnetByIPAddress(addressIPblock *ipblock.IPBlock, c *vpcmodel.VPCConfig) (subnet *commonvpc.Subnet, err error) { +func getSubnetByIPAddress(addressIPblock *netset.IPBlock, c *vpcmodel.VPCConfig) (subnet *commonvpc.Subnet, err error) { for _, s := range c.Subnets { - if addressIPblock.ContainedIn(s.AddressRange()) { + if addressIPblock.IsSubset(s.AddressRange()) { return s.(*commonvpc.Subnet), nil } } @@ -1364,10 +1364,10 @@ func getLoadBalancerIPs(vpcConfig *vpcmodel.VPCConfig, vpc *commonvpc.VPC, subnetsBlocks subnetsIPBlocks) ([]vpcmodel.Node, error) { // first we collect the subnets that has private IPs: - subnetsPIPsAddresses := map[vpcmodel.Subnet]*ipblock.IPBlock{} // map from the subnet to the address block - subnetsPIPsIndexes := map[vpcmodel.Subnet]int{} // map from a subnet to the pip index + subnetsPIPsAddresses := map[vpcmodel.Subnet]*netset.IPBlock{} // map from the subnet to the address block + subnetsPIPsIndexes := map[vpcmodel.Subnet]int{} // map from a subnet to the pip index for pipIndex, pIP := range loadBalancerObj.PrivateIps { - address, err := ipblock.FromIPAddress(*pIP.Address) + address, err := netset.IPBlockFromIPAddress(*pIP.Address) if err != nil { return nil, err } @@ -1398,7 +1398,7 @@ func getLoadBalancerIPs(vpcConfig *vpcmodel.VPCConfig, // first get name, id, address, publicAddress: var name, id, address, publicAddress string blockHasPrivateIP := subnetsPIPsAddresses[subnet] != nil && - subnetsPIPsAddresses[subnet].ContainedIn(subnetBlock) + subnetsPIPsAddresses[subnet].IsSubset(subnetBlock) switch { case blockHasPrivateIP: // subnet block has a private IP, we take it from the config @@ -1450,7 +1450,7 @@ func getLoadBalancerIPs(vpcConfig *vpcmodel.VPCConfig, // also update vpcConfig & subnet with the result func createPrivateIP(name, id, address, publicAddress string, vpc vpcmodel.VPCResourceIntf, loadBalancer *LoadBalancer, vpcConfig *vpcmodel.VPCConfig, - original bool, block *ipblock.IPBlock, subnet *commonvpc.Subnet) (*PrivateIP, error) { + original bool, block *netset.IPBlock, subnet *commonvpc.Subnet) (*PrivateIP, error) { privateIP := &PrivateIP{ VPCResource: vpcmodel.VPCResource{ ResourceName: name, diff --git a/pkg/ibmvpc/parser_test.go b/pkg/ibmvpc/parser_test.go index 27c4a92e5..5f6a5948b 100644 --- a/pkg/ibmvpc/parser_test.go +++ b/pkg/ibmvpc/parser_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/require" "github.com/np-guard/cloud-resource-collector/pkg/common" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc/testfunc" @@ -66,7 +66,7 @@ func TestRegionMethodTGW(t *testing.T) { Region: "us-east", }, vpcs: nil, - availableRoutes: map[string][]*ipblock.IPBlock{}, + availableRoutes: map[string][]*netset.IPBlock{}, region: commonvpc.GetRegionByName("us-east", regionToStructMap), } region := tgw.Region() diff --git a/pkg/ibmvpc/routing_tables_analysis.go b/pkg/ibmvpc/routing_tables_analysis.go index 3ac825654..f4b7febc2 100644 --- a/pkg/ibmvpc/routing_tables_analysis.go +++ b/pkg/ibmvpc/routing_tables_analysis.go @@ -11,7 +11,7 @@ import ( "slices" "strings" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/drawio" "github.com/np-guard/vpc-network-config-analyzer/pkg/logging" @@ -46,7 +46,7 @@ func (ga *GlobalRTAnalyzer) getRTAnalyzerPerVPC(vpcUID string) (*RTAnalyzer, err return rtAnalyzer, nil } -func (ga *GlobalRTAnalyzer) GetRoutingPath(src vpcmodel.InternalNodeIntf, dest *ipblock.IPBlock) (vpcmodel.Path, error) { +func (ga *GlobalRTAnalyzer) GetRoutingPath(src vpcmodel.InternalNodeIntf, dest *netset.IPBlock) (vpcmodel.Path, error) { vpcUID := src.Subnet().VPC().UID() rtAnalyzer, err := ga.getRTAnalyzerPerVPC(vpcUID) if err != nil { @@ -81,7 +81,7 @@ func (ga *GlobalRTAnalyzer) GetRoutingPath(src vpcmodel.InternalNodeIntf, dest * return res, err } -func getZoneByIPBlock(ipb *ipblock.IPBlock, allConfigs *vpcmodel.MultipleVPCConfigs) (string, error) { +func getZoneByIPBlock(ipb *netset.IPBlock, allConfigs *vpcmodel.MultipleVPCConfigs) (string, error) { for _, config := range allConfigs.Configs() { if zone, err := config.VPC.(*commonvpc.VPC).GetZoneByIPBlock(ipb); err == nil { return zone, nil @@ -135,7 +135,7 @@ func newRTAnalyzer(vpcConfig *vpcmodel.VPCConfig) *RTAnalyzer { return res } -func (rt *RTAnalyzer) getEgressPathFromAddressSrc(src, dest *ipblock.IPBlock) (vpcmodel.Path, error) { +func (rt *RTAnalyzer) getEgressPathFromAddressSrc(src, dest *netset.IPBlock) (vpcmodel.Path, error) { for _, node := range rt.vpcConfig.Nodes { if node.IsInternal() && node.IPBlock().Equal(src) { return rt.getEgressPath(node.(vpcmodel.InternalNodeIntf), dest) @@ -144,7 +144,7 @@ func (rt *RTAnalyzer) getEgressPathFromAddressSrc(src, dest *ipblock.IPBlock) (v return nil, fmt.Errorf("could not find internal node with address %s", src.ToIPAddressString()) } -func (rt *RTAnalyzer) getEgressPath(src vpcmodel.InternalNodeIntf, dest *ipblock.IPBlock) (vpcmodel.Path, error) { +func (rt *RTAnalyzer) getEgressPath(src vpcmodel.InternalNodeIntf, dest *netset.IPBlock) (vpcmodel.Path, error) { subnet := src.Subnet() srcRT, ok := rt.subnetUIDToRT[subnet.UID()] if !ok { @@ -155,7 +155,7 @@ func (rt *RTAnalyzer) getEgressPath(src vpcmodel.InternalNodeIntf, dest *ipblock return srcRT.getEgressPath(src.(vpcmodel.Node), dest, subnet.ZoneName()) } -func (rt *RTAnalyzer) getIngressPath(sourceType ingressRTSource, dest *ipblock.IPBlock, destZone, srcZone string) (vpcmodel.Path, error) { +func (rt *RTAnalyzer) getIngressPath(sourceType ingressRTSource, dest *netset.IPBlock, destZone, srcZone string) (vpcmodel.Path, error) { for _, ingressRt := range rt.ingressRT { if ingressRt.source == sourceType { return ingressRt.getIngressPath(dest, destZone, srcZone) @@ -282,8 +282,8 @@ type route struct { // (same as each vpc connected to a tgw advertises its APs to the tgw ) advertise bool - destIPBlock *ipblock.IPBlock - nextHopIPBlock *ipblock.IPBlock + destIPBlock *netset.IPBlock + nextHopIPBlock *netset.IPBlock destPrefixLen int64 } @@ -298,7 +298,7 @@ func newRoute(name, dest, nextHop, zone string, action routingAction, prio int, zone: zone, } - res.destIPBlock, err = ipblock.FromCidr(dest) + res.destIPBlock, err = netset.IPBlockFromCidr(dest) if err != nil { return nil, err } @@ -307,7 +307,7 @@ func newRoute(name, dest, nextHop, zone string, action routingAction, prio int, return nil, err } if action == deliver { // next hop relevant only for 'deliver' action - res.nextHopIPBlock, err = ipblock.FromCidrOrAddress(nextHop) + res.nextHopIPBlock, err = netset.IPBlockFromCidrOrAddress(nextHop) if err != nil { return nil, err } @@ -335,11 +335,11 @@ func (r *route) string() string { type routingResult struct { // nextHops is a map from disjoint ip-blocks, after considering route preferences and actions - nextHops map[*ipblock.IPBlock]*ipblock.IPBlock // delivered ip-blocks + nextHops map[*netset.IPBlock]*netset.IPBlock // delivered ip-blocks - droppedDestinations *ipblock.IPBlock // union of all ip-ranges for dropped destinations + droppedDestinations *netset.IPBlock // union of all ip-ranges for dropped destinations - delegatedDestinations *ipblock.IPBlock // union of all ip-ranges for delegated destinations + delegatedDestinations *netset.IPBlock // union of all ip-ranges for delegated destinations } // routingTable implements VPCResourceIntf (TODO: should implement RoutingResource interface or another separate interface?) @@ -389,10 +389,10 @@ func newRoutingTable(routes []*route, implicitRT *systemImplicitRT, vpcResource return res, nil } -func (rt *routingResult) computeRoutingForDisjointDest(routesList []*route, disjointDest *ipblock.IPBlock) error { +func (rt *routingResult) computeRoutingForDisjointDest(routesList []*route, disjointDest *netset.IPBlock) error { // find the relevant rule from the sorted list of rules for _, routeRule := range routesList { - if disjointDest.ContainedIn(routeRule.destIPBlock) { + if disjointDest.IsSubset(routeRule.destIPBlock) { logging.Debugf("%s contained in %s\n", disjointDest.ToIPRanges(), routeRule.destination) switch routeRule.action { case deliver: @@ -418,9 +418,9 @@ func (rt *routingResult) computeRoutingForDisjointDest(routesList []*route, disj // TODO: handle ECMP routing func computeDisjointRouting(routesList []*route) (*routingResult, error) { res := &routingResult{ - nextHops: map[*ipblock.IPBlock]*ipblock.IPBlock{}, - droppedDestinations: ipblock.New(), - delegatedDestinations: ipblock.New(), + nextHops: map[*netset.IPBlock]*netset.IPBlock{}, + droppedDestinations: netset.NewIPBlock(), + delegatedDestinations: netset.NewIPBlock(), } // sort routes list by prefix length, then by priority @@ -434,11 +434,11 @@ func computeDisjointRouting(routesList []*route) (*routingResult, error) { return 1 }) - destIPBlocks := []*ipblock.IPBlock{} + destIPBlocks := []*netset.IPBlock{} for _, route := range routesList { destIPBlocks = append(destIPBlocks, route.destIPBlock) } - disjointDestinations := ipblock.DisjointIPBlocks(destIPBlocks, destIPBlocks) + disjointDestinations := netset.DisjointIPBlocks(destIPBlocks, destIPBlocks) for _, disjointDest := range disjointDestinations { logging.Debugf("disjoint dest: %s\n", disjointDest.ToIPRanges()) if err := res.computeRoutingForDisjointDest(routesList, disjointDest); err != nil { @@ -450,7 +450,7 @@ func computeDisjointRouting(routesList []*route) (*routingResult, error) { // semantics of `zone` field in route: If subnets are attached to the route's routing table, egress traffic from those // subnets in this zone will be subject to this route -func (rt *routingTable) getEgressPath(src vpcmodel.Node, dest *ipblock.IPBlock, zone string) (vpcmodel.Path, error) { +func (rt *routingTable) getEgressPath(src vpcmodel.Node, dest *netset.IPBlock, zone string) (vpcmodel.Path, error) { path, shouldDelegate, _ := rt.getPath(dest, zone) if shouldDelegate { return rt.implicitRT.getEgressPath(src, dest), nil @@ -458,7 +458,7 @@ func (rt *routingTable) getEgressPath(src vpcmodel.Node, dest *ipblock.IPBlock, return path.PrependResource(src), nil } -func (rt *routingTable) evaluatedPath(dest *ipblock.IPBlock, path vpcmodel.Path, shouldDelegate bool) (vpcmodel.Path, error) { +func (rt *routingTable) evaluatedPath(dest *netset.IPBlock, path vpcmodel.Path, shouldDelegate bool) (vpcmodel.Path, error) { if shouldDelegate { return rt.implicitRT.getIngressPath(dest) } @@ -466,7 +466,7 @@ func (rt *routingTable) evaluatedPath(dest *ipblock.IPBlock, path vpcmodel.Path, } // traffic from those ingress sources arriving in this zone will be subject to this route. -func (rt *routingTable) getIngressPath(dest *ipblock.IPBlock, destZone, srcZone string) (vpcmodel.Path, error) { +func (rt *routingTable) getIngressPath(dest *netset.IPBlock, destZone, srcZone string) (vpcmodel.Path, error) { // TODO: validate the logic of this function (first consider dest zone, then src zone) // if the dest zone is not empty - consider only dest zone routes if destZone != "" { @@ -502,7 +502,7 @@ func (rt *routingTable) getIngressPath(dest *ipblock.IPBlock, destZone, srcZone return rt.implicitRT.getIngressPath(dest) } -func (rt *routingTable) getPath(dest *ipblock.IPBlock, zone string) (path vpcmodel.Path, shouldDelegate, matchedInTable bool) { +func (rt *routingTable) getPath(dest *netset.IPBlock, zone string) (path vpcmodel.Path, shouldDelegate, matchedInTable bool) { if _, ok := rt.routingResultMap[zone]; !ok { return nil, true, false } @@ -512,16 +512,16 @@ func (rt *routingTable) getPath(dest *ipblock.IPBlock, zone string) (path vpcmod logging.Debugf("%s", z) } for tableDest, nextHop := range rt.routingResultMap[zone].nextHops { - if dest.ContainedIn(tableDest) { + if dest.IsSubset(tableDest) { return vpcmodel.Path([]*vpcmodel.Endpoint{ {NextHop: &vpcmodel.NextHopEntry{NextHop: nextHop, OrigDest: dest}}}), false, true } } - if dest.ContainedIn(rt.routingResultMap[zone].delegatedDestinations) { + if dest.IsSubset(rt.routingResultMap[zone].delegatedDestinations) { // explicit delegate return nil, true, true } - if dest.ContainedIn(rt.routingResultMap[zone].droppedDestinations) { + if dest.IsSubset(rt.routingResultMap[zone].droppedDestinations) { // explicit drop return nil, false, true // no path } @@ -656,10 +656,10 @@ func (irt *ingressRoutingTable) advertiseRoutes(vpcConfig *vpcmodel.VPCConfig) { } } -func updateTGWWithAdvertisedRoute(tgw *TransitGateway, vpc *commonvpc.VPC, cidr *ipblock.IPBlock) { +func updateTGWWithAdvertisedRoute(tgw *TransitGateway, vpc *commonvpc.VPC, cidr *netset.IPBlock) { _, ok := tgw.availableRoutes[vpc.UID()] if !ok { - tgw.availableRoutes[vpc.UID()] = []*ipblock.IPBlock{} + tgw.availableRoutes[vpc.UID()] = []*netset.IPBlock{} } tgw.availableRoutes[vpc.UID()] = append(tgw.availableRoutes[vpc.UID()], cidr) } diff --git a/pkg/ibmvpc/sg_analysis.go b/pkg/ibmvpc/sg_analysis.go index 1a220021f..d7d175b8a 100644 --- a/pkg/ibmvpc/sg_analysis.go +++ b/pkg/ibmvpc/sg_analysis.go @@ -11,8 +11,9 @@ import ( vpc1 "github.com/IBM/vpc-go-sdk/vpcv1" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-analyzer/pkg/common" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" ) @@ -20,7 +21,7 @@ import ( type IBMSGAnalyzer struct { SgResource *vpc1.SecurityGroup sgMap map[string]*commonvpc.SecurityGroup - referencedIPblocks []*ipblock.IPBlock + referencedIPblocks []*netset.IPBlock } func NewIBMSGAnalyzer(sg *vpc1.SecurityGroup) *IBMSGAnalyzer { @@ -43,7 +44,7 @@ func (sga *IBMSGAnalyzer) Name() *string { } // getRemoteCidr gets remote rule object interface and returns it's IPBlock -func (sga *IBMSGAnalyzer) getRemoteCidr(remote vpc1.SecurityGroupRuleRemoteIntf) (target *ipblock.IPBlock, +func (sga *IBMSGAnalyzer) getRemoteCidr(remote vpc1.SecurityGroupRuleRemoteIntf) (target *netset.IPBlock, cidrRes string, remoteSGName string, err error) { // TODO: on actual run from SG example, the type of remoteObj is SecurityGroupRuleRemote and not SecurityGroupRuleRemoteCIDR, // even if cidr is defined @@ -70,13 +71,13 @@ func (sga *IBMSGAnalyzer) getRemoteCidr(remote vpc1.SecurityGroupRuleRemoteIntf) return target, cidrRes, remoteSGName, nil } -func getDefaultLocal() (ipb *ipblock.IPBlock, cidr string) { - return ipblock.GetCidrAll(), ipblock.CidrAll +func getDefaultLocal() (ipb *netset.IPBlock, cidr string) { + return netset.GetCidrAll(), netset.CidrAll } // getRemoteCidr gets local rule object interface and returns it's IPBlock -func (sga *IBMSGAnalyzer) getLocalCidr(local vpc1.SecurityGroupRuleLocalIntf) (*ipblock.IPBlock, string, error) { - var localIP *ipblock.IPBlock +func (sga *IBMSGAnalyzer) getLocalCidr(local vpc1.SecurityGroupRuleLocalIntf) (*netset.IPBlock, string, error) { + var localIP *netset.IPBlock var cidrRes string var err error if localObj, ok := local.(*vpc1.SecurityGroupRuleLocal); ok { @@ -104,7 +105,7 @@ func (sga *IBMSGAnalyzer) getProtocolAllRule(ruleObj *vpc1.SecurityGroupRuleSecu isIngress = isIngressRule(ruleObj.Direction) protocol := *ruleObj.Protocol remoteCidr, localCidr, remoteSGName := "", "", "" - var remote, local *ipblock.IPBlock + var remote, local *netset.IPBlock remote, remoteCidr, remoteSGName, err = sga.getRemoteCidr(ruleObj.Remote) if err != nil { return "", nil, false, err @@ -117,7 +118,7 @@ func (sga *IBMSGAnalyzer) getProtocolAllRule(ruleObj *vpc1.SecurityGroupRuleSecu ruleStr = getRuleStr(direction, *ruleObj.ID, connStr, remoteCidr, remoteSGName, localCidr) ruleRes.Remote = commonvpc.NewRuleTarget(remote, remoteSGName) ruleRes.Local = local - ruleRes.Connections = connection.All() + ruleRes.Connections = netset.AllTransports() return ruleStr, ruleRes, isIngress, nil } @@ -133,16 +134,16 @@ func (sga *IBMSGAnalyzer) getProtocolTCPUDPRule(ruleObj *vpc1.SecurityGroupRuleS if err != nil { return "", nil, false, err } - dstPortMin := commonvpc.GetProperty(ruleObj.PortMin, connection.MinPort) - dstPortMax := commonvpc.GetProperty(ruleObj.PortMax, connection.MaxPort) + dstPortMin := commonvpc.GetProperty(ruleObj.PortMin, netp.MinPort) + dstPortMax := commonvpc.GetProperty(ruleObj.PortMax, netp.MaxPort) dstPorts := fmt.Sprintf("%d-%d", dstPortMin, dstPortMax) connStr := fmt.Sprintf("protocol: %s, dstPorts: %s", *ruleObj.Protocol, dstPorts) ruleStr = getRuleStr(direction, *ruleObj.ID, connStr, remoteCidr, remoteSGName, localCidr) ruleRes = &commonvpc.SGRule{ // TODO: src ports can be considered here? Connections: commonvpc.GetTCPUDPConns(*ruleObj.Protocol, - connection.MinPort, - connection.MaxPort, + netp.MinPort, + netp.MaxPort, dstPortMin, dstPortMax, ), @@ -172,7 +173,7 @@ func (sga *IBMSGAnalyzer) getProtocolICMPRule(ruleObj *vpc1.SecurityGroupRuleSec return } conns := commonvpc.GetICMPconn(ruleObj.Type, ruleObj.Code) - ruleStr = getRuleStr(*ruleObj.Direction, *ruleObj.ID, conns.String(), remoteCidr, remoteSGName, localCidr) + ruleStr = getRuleStr(*ruleObj.Direction, *ruleObj.ID, common.LongString(conns), remoteCidr, remoteSGName, localCidr) ruleRes = &commonvpc.SGRule{ Connections: conns, Remote: commonvpc.NewRuleTarget(remote, remoteSGName), @@ -209,7 +210,7 @@ func (sga *IBMSGAnalyzer) GetSGRules() (ingressRules, egressRules []*commonvpc.S } // ReferencedIPblocks returns referencedIPblocks filed -func (sga *IBMSGAnalyzer) ReferencedIPblocks() []*ipblock.IPBlock { +func (sga *IBMSGAnalyzer) ReferencedIPblocks() []*netset.IPBlock { return sga.referencedIPblocks } diff --git a/pkg/ibmvpc/sg_analysis_test.go b/pkg/ibmvpc/sg_analysis_test.go index f2a818dca..7a692dc49 100644 --- a/pkg/ibmvpc/sg_analysis_test.go +++ b/pkg/ibmvpc/sg_analysis_test.go @@ -14,9 +14,8 @@ import ( "github.com/stretchr/testify/require" "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" @@ -120,13 +119,13 @@ type sgTest struct { expectedConnectivityMap commonvpc.ConnectivityResultMap } -func fromIPRangeStrWithoutValidation(ipRange string) *ipblock.IPBlock { - ip, _ := ipblock.FromIPRangeStr(ipRange) +func fromIPRangeStrWithoutValidation(ipRange string) *netset.IPBlock { + ip, _ := netset.IPBlockFromIPRangeStr(ipRange) return ip } -func fromIPAddressStrWithoutValidation(ipAddress string) *ipblock.IPBlock { - ip, _ := ipblock.FromIPAddress(ipAddress) +func fromIPAddressStrWithoutValidation(ipAddress string) *netset.IPBlock { + ip, _ := netset.IPBlockFromIPAddress(ipAddress) return ip } @@ -136,37 +135,37 @@ var sgTests = []sgTest{ rules: []*commonvpc.SGRule{ { Remote: commonvpc.NewRuleTarget(newIPBlockFromCIDROrAddressWithoutValidation("10.250.10.1"), "ola"), - Connections: connection.TCPorUDPConnection(netp.ProtocolString("UDP"), 5, 87, 10, 3245), + Connections: netset.NewTCPorUDPTransport(netp.ProtocolString("UDP"), 5, 87, 10, 3245), Index: 1, - Local: ipblock.GetCidrAll(), + Local: netset.GetCidrAll(), }, { Remote: commonvpc.NewRuleTarget(newIPBlockFromCIDROrAddressWithoutValidation("10.250.10.0/30"), "ola"), - Connections: connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000), + Connections: netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000), Index: 2, - Local: ipblock.GetCidrAll(), + Local: netset.GetCidrAll(), }, }, isIngress: false, - expectedConnectivityMap: map[*ipblock.IPBlock]*commonvpc.ConnectivityResult{ - ipblock.GetCidrAll(): { + expectedConnectivityMap: map[*netset.IPBlock]*commonvpc.ConnectivityResult{ + netset.GetCidrAll(): { IsIngress: false, - AllowedConns: map[*ipblock.IPBlock]*connection.Set{ - fromIPAddressStrWithoutValidation("10.250.10.0"): connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000), - fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000), - fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): connection.None(), - fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): connection.None(), - fromIPAddressStrWithoutValidation("10.250.10.1"): connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000).Union(connection.TCPorUDPConnection(netp.ProtocolString("UDP"), 5, 87, 10, 3245)), + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPAddressStrWithoutValidation("10.250.10.0"): netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000), + fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000), + fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): netset.NoTransports(), + fromIPAddressStrWithoutValidation("10.250.10.1"): netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000).Union(netset.NewTCPorUDPTransport(netp.ProtocolString("UDP"), 5, 87, 10, 3245)), }, - AllowRules: map[*ipblock.IPBlock][]int{ + AllowRules: map[*netset.IPBlock][]int{ fromIPAddressStrWithoutValidation("10.250.10.0"): {2}, fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): {2}, fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): {}, fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): {}, fromIPAddressStrWithoutValidation("10.250.10.1"): {1, 2}, }, - DeniedConns: map[*ipblock.IPBlock]*connection.Set{}, - DenyRules: map[*ipblock.IPBlock][]int{}, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{}, + DenyRules: map[*netset.IPBlock][]int{}, }, }, }, @@ -175,68 +174,68 @@ var sgTests = []sgTest{ rules: []*commonvpc.SGRule{ { Remote: commonvpc.NewRuleTarget(newIPBlockFromCIDROrAddressWithoutValidation("10.250.10.1"), "ola"), - Connections: connection.TCPorUDPConnection(netp.ProtocolString("UDP"), 5, 87, 10, 3245), + Connections: netset.NewTCPorUDPTransport(netp.ProtocolString("UDP"), 5, 87, 10, 3245), Index: 1, Local: newIPBlockFromCIDROrAddressWithoutValidation("10.240.10.1"), }, { Remote: commonvpc.NewRuleTarget(newIPBlockFromCIDROrAddressWithoutValidation("10.250.10.0/30"), "ola"), - Connections: connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000), + Connections: netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000), Index: 2, Local: newIPBlockFromCIDROrAddressWithoutValidation("10.240.10.0/30"), }, }, isIngress: false, - expectedConnectivityMap: map[*ipblock.IPBlock]*commonvpc.ConnectivityResult{ + expectedConnectivityMap: map[*netset.IPBlock]*commonvpc.ConnectivityResult{ fromIPAddressStrWithoutValidation("10.240.10.1"): { IsIngress: false, - AllowedConns: map[*ipblock.IPBlock]*connection.Set{ - fromIPAddressStrWithoutValidation("10.250.10.0"): connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000), - fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000), - fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): connection.None(), - fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): connection.None(), - fromIPAddressStrWithoutValidation("10.250.10.1"): connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000).Union( - connection.TCPorUDPConnection(netp.ProtocolString("UDP"), 5, 87, 10, 3245)), + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPAddressStrWithoutValidation("10.250.10.0"): netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000), + fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000), + fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): netset.NoTransports(), + fromIPAddressStrWithoutValidation("10.250.10.1"): netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000).Union( + netset.NewTCPorUDPTransport(netp.ProtocolString("UDP"), 5, 87, 10, 3245)), }, - AllowRules: map[*ipblock.IPBlock][]int{ + AllowRules: map[*netset.IPBlock][]int{ fromIPAddressStrWithoutValidation("10.250.10.0"): {2}, fromIPRangeStrWithoutValidation("10.250.10.2-10.250.10.3"): {2}, fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): {}, fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): {}, fromIPAddressStrWithoutValidation("10.250.10.1"): {1, 2}, }, - DeniedConns: map[*ipblock.IPBlock]*connection.Set{}, - DenyRules: map[*ipblock.IPBlock][]int{}, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{}, + DenyRules: map[*netset.IPBlock][]int{}, }, fromIPAddressStrWithoutValidation("10.240.10.0"): { IsIngress: false, - AllowedConns: map[*ipblock.IPBlock]*connection.Set{ - fromIPRangeStrWithoutValidation("10.250.10.0-10.250.10.3"): connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000), - fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): connection.None(), - fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): connection.None(), + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("10.250.10.0-10.250.10.3"): netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000), + fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): netset.NoTransports(), }, - AllowRules: map[*ipblock.IPBlock][]int{ + AllowRules: map[*netset.IPBlock][]int{ fromIPRangeStrWithoutValidation("10.250.10.0-10.250.10.3"): {2}, fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): {}, fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): {}, }, - DeniedConns: map[*ipblock.IPBlock]*connection.Set{}, - DenyRules: map[*ipblock.IPBlock][]int{}, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{}, + DenyRules: map[*netset.IPBlock][]int{}, }, fromIPRangeStrWithoutValidation("10.240.10.2-10.240.10.3"): { IsIngress: false, - AllowedConns: map[*ipblock.IPBlock]*connection.Set{ - fromIPRangeStrWithoutValidation("10.250.10.0-10.250.10.3"): connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000), - fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): connection.None(), - fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): connection.None(), + AllowedConns: map[*netset.IPBlock]*netset.TransportSet{ + fromIPRangeStrWithoutValidation("10.250.10.0-10.250.10.3"): netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000), + fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): netset.NoTransports(), + fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): netset.NoTransports(), }, - AllowRules: map[*ipblock.IPBlock][]int{ + AllowRules: map[*netset.IPBlock][]int{ fromIPRangeStrWithoutValidation("10.250.10.0-10.250.10.3"): {2}, fromIPRangeStrWithoutValidation("0.0.0.0-10.250.9.255"): {}, fromIPRangeStrWithoutValidation("10.250.10.4-255.255.255.255"): {}, }, - DeniedConns: map[*ipblock.IPBlock]*connection.Set{}, - DenyRules: map[*ipblock.IPBlock][]int{}, + DeniedConns: map[*netset.IPBlock]*netset.TransportSet{}, + DenyRules: map[*netset.IPBlock][]int{}, }, }, }, @@ -274,8 +273,8 @@ func TestMapAndAnalyzeSGRules(t *testing.T) { func TestCaching(t *testing.T) { // test to check caching in mapAndAnalyzeSGRules - c1 := connection.TCPorUDPConnection(netp.ProtocolString("UDP"), 5, 87, 10, 3245) - c2 := connection.TCPorUDPConnection(netp.ProtocolString("TCP"), 1, 100, 5, 1000) + c1 := netset.NewTCPorUDPTransport(netp.ProtocolString("UDP"), 5, 87, 10, 3245) + c2 := netset.NewTCPorUDPTransport(netp.ProtocolString("TCP"), 1, 100, 5, 1000) var endpoint1 = &commonvpc.NetworkInterface{InternalNode: vpcmodel.InternalNode{ AddressStr: "10.240.10.1", IPBlockObj: fromIPAddressStrWithoutValidation("10.240.10.1"), @@ -313,7 +312,7 @@ func TestCaching(t *testing.T) { require.True(t, connectivityResult1 == connectivityResult2) // compare pointers-- to make sure that caching worked } -func newIPBlockFromCIDROrAddressWithoutValidation(cidr string) *ipblock.IPBlock { - res, _ := ipblock.FromCidrOrAddress(cidr) +func newIPBlockFromCIDROrAddressWithoutValidation(cidr string) *netset.IPBlock { + res, _ := netset.IPBlockFromCidrOrAddress(cidr) return res } diff --git a/pkg/ibmvpc/subnetsIPBlocks.go b/pkg/ibmvpc/subnetsIPBlocks.go index 3f30590a9..2023f8a59 100644 --- a/pkg/ibmvpc/subnetsIPBlocks.go +++ b/pkg/ibmvpc/subnetsIPBlocks.go @@ -12,7 +12,7 @@ import ( vpc1 "github.com/IBM/vpc-go-sdk/vpcv1" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" ) // /////////////////////////////////////////////////////////////////////// @@ -46,12 +46,12 @@ import ( // ///////////////////////////////////////////////////////////////////////////////////////// // oneSubnetBlocks hold the blocks of one subnet type oneSubnetBlocks struct { - subnetOriginalBlock *ipblock.IPBlock // the block of the cidr of the subnet + subnetOriginalBlock *netset.IPBlock // the block of the cidr of the subnet // splitByFiltersBlocks are the atomic blocks induced by the filters, the union of this slice is the subnetOriginalBlock - splitByFiltersBlocks []*ipblock.IPBlock + splitByFiltersBlocks []*netset.IPBlock // freeAddressesBlocks are the splitByFiltersBlocks minus the reserved IPs // each block in splitByFiltersBlocks has a corresponding block at freeAddressesBlocks - freeAddressesBlocks []*ipblock.IPBlock + freeAddressesBlocks []*netset.IPBlock // fullyReservedBlocks is a bool per block. // its true if all the addresses in the original block are reserved IP // for these blocks there is no need to create private IPs @@ -94,7 +94,7 @@ func (subnetsBlocks subnetsIPBlocks) getSubnetsOriginalBlocks(rc *IBMresourcesCo continue } subnetsBlocks[*subnetObj.CRN] = &oneSubnetBlocks{} - subnetsBlocks[*subnetObj.CRN].subnetOriginalBlock, err = ipblock.FromCidr(*subnetObj.Ipv4CIDRBlock) + subnetsBlocks[*subnetObj.CRN].subnetOriginalBlock, err = netset.IPBlockFromCidr(*subnetObj.Ipv4CIDRBlock) if err != nil { return err } @@ -117,8 +117,8 @@ func (subnetsBlocks subnetsIPBlocks) splitSubnetsOriginalBlocks(rc *IBMresources // splitSubnetsOriginalBlocks() splits one subnet's cidr(s) to (maximal) disjoint blocks - // such that each block is atomic w.r.t. the filters rules -func splitSubnetOriginalBlock(subnetOriginalBlock *ipblock.IPBlock, filtersBlocks []*ipblock.IPBlock) []*ipblock.IPBlock { - filtersBlocksOnSubnet := []*ipblock.IPBlock{} +func splitSubnetOriginalBlock(subnetOriginalBlock *netset.IPBlock, filtersBlocks []*netset.IPBlock) []*netset.IPBlock { + filtersBlocksOnSubnet := []*netset.IPBlock{} for _, filterBlock := range filtersBlocks { filterBlocksOnSubnet := subnetOriginalBlock.Intersect(filterBlock) if !filterBlocksOnSubnet.IsEmpty() { @@ -138,7 +138,7 @@ func (subnetsBlocks subnetsIPBlocks) getSubnetsFreeBlocks(rc *IBMresourcesContai if skipByVPC[*subnetObj.VPC.ID] { continue } - subnetsBlocks[*subnetObj.CRN].freeAddressesBlocks = make([]*ipblock.IPBlock, len(subnetsBlocks[*subnetObj.CRN].splitByFiltersBlocks)) + subnetsBlocks[*subnetObj.CRN].freeAddressesBlocks = make([]*netset.IPBlock, len(subnetsBlocks[*subnetObj.CRN].splitByFiltersBlocks)) subnetsBlocks[*subnetObj.CRN].fullyReservedBlocks = make([]bool, len(subnetsBlocks[*subnetObj.CRN].splitByFiltersBlocks)) for blockIndex, block := range subnetsBlocks[*subnetObj.CRN].splitByFiltersBlocks { subnetsBlocks[*subnetObj.CRN].freeAddressesBlocks[blockIndex] = block.Copy() @@ -168,7 +168,7 @@ func (subnetsBlocks subnetsIPBlocks) allocSubnetFreeAddress(subnetCRN string, bl address := subnetsBlocks[subnetCRN].freeAddressesBlocks[blockIndex].FirstIPAddress() return address, subnetsBlocks.removeAddressFromFree(address, subnetCRN, blockIndex) } -func (subnetsBlocks subnetsIPBlocks) subnetBlocks(subnetCRN string) []*ipblock.IPBlock { +func (subnetsBlocks subnetsIPBlocks) subnetBlocks(subnetCRN string) []*netset.IPBlock { return subnetsBlocks[subnetCRN].splitByFiltersBlocks } func (subnetsBlocks subnetsIPBlocks) isFullyReservedBlock(subnetCRN string, blockIndex int) bool { @@ -176,7 +176,7 @@ func (subnetsBlocks subnetsIPBlocks) isFullyReservedBlock(subnetCRN string, bloc } func (subnetsBlocks subnetsIPBlocks) removeAddressFromFree(address, subnetCRN string, blockIndex int) error { - addressBlock, err := ipblock.FromIPAddress(address) + addressBlock, err := netset.IPBlockFromIPAddress(address) if err != nil { return err } @@ -187,7 +187,7 @@ func (subnetsBlocks subnetsIPBlocks) removeAddressFromFree(address, subnetCRN st // filtersBlocks is a map from VPC UID to a list of IPBlocks, // which holds the list of disjoint IPBlocks computed from all referenced CIDRs in that VPC's filters rules -type filtersBlocks map[string][]*ipblock.IPBlock +type filtersBlocks map[string][]*netset.IPBlock // /////////////////////////////////////////// // getFiltersBlocks() create a slice of disjoint blocks for each vpc, split according to the rules blocks, and their sum is allCidr: @@ -198,13 +198,13 @@ func getFiltersBlocks(filtersCidrs []map[string][]*string) (blocks filtersBlocks return disjointVpcCidrs(vpcCidrs) } -// getVpcsCidrs() sort the cidr of all filters for each vpc separately, adding ipblock.CidrAll for every vpc +// getVpcsCidrs() sort the cidr of all filters for each vpc separately, adding netset.CidrAll for every vpc func getVpcsCidrs(filtersCidrs []map[string][]*string) map[string][]string { vpcCidrs := map[string][]string{} for _, filterCidrsOrAddresses := range filtersCidrs { for vpc, vpcCidrsOrAddresses := range filterCidrsOrAddresses { if _, ok := vpcCidrs[vpc]; !ok { - vpcCidrs[vpc] = []string{ipblock.CidrAll} + vpcCidrs[vpc] = []string{netset.CidrAll} } for _, cidrOrAddress := range vpcCidrsOrAddresses { if cidrOrAddress != nil { @@ -237,11 +237,11 @@ func disjointVpcCidrs(cidr map[string][]string) (blocks filtersBlocks, err error // // please notice - there is a method models.DisjointIPBlocks(), this method is not suitable for this case: // at the output of models.DisjointIPBlocks(), each ipblock must be a range of IPs -func disjointCidrs(cidrs []string) ([]*ipblock.IPBlock, error) { +func disjointCidrs(cidrs []string) ([]*netset.IPBlock, error) { compactCidrs := slices.Compact(cidrs) - cidrBlocks := make([]*ipblock.IPBlock, len(compactCidrs)) + cidrBlocks := make([]*netset.IPBlock, len(compactCidrs)) for i, cidr := range compactCidrs { - block, err := ipblock.FromCidrOrAddress(cidr) + block, err := netset.IPBlockFromCidrOrAddress(cidr) if err != nil { return nil, err } @@ -254,8 +254,8 @@ func disjointCidrs(cidrs []string) ([]*ipblock.IPBlock, error) { PrefixLengthJ, _ := cidrBlocks[j].PrefixLength() return PrefixLengthI > PrefixLengthJ }) - unionOfPreviousBlocks := ipblock.New() - disjointBlocks := []*ipblock.IPBlock{} + unionOfPreviousBlocks := netset.NewIPBlock() + disjointBlocks := []*netset.IPBlock{} for _, b := range cidrBlocks { newBlock := b.Subtract(unionOfPreviousBlocks) if !newBlock.IsEmpty() { diff --git a/pkg/ibmvpc/subnetsIPBlocks_test.go b/pkg/ibmvpc/subnetsIPBlocks_test.go index 2ba2374c3..e34dd2c83 100644 --- a/pkg/ibmvpc/subnetsIPBlocks_test.go +++ b/pkg/ibmvpc/subnetsIPBlocks_test.go @@ -12,13 +12,13 @@ import ( "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" ) func TestSubnetsBlocks(t *testing.T) { subnetsBlocks := subnetsIPBlocks{} subnetID, vpcID := "subId1", "vpcId" - subnetOrigBlock, _ := ipblock.FromCidr("10.240.0.0/23") + subnetOrigBlock, _ := netset.IPBlockFromCidr("10.240.0.0/23") subnetsBlocks[subnetID] = &oneSubnetBlocks{subnetOriginalBlock: subnetOrigBlock} filtersCidrs := map[string][]string{} diff --git a/pkg/ibmvpc/tgw_analysis.go b/pkg/ibmvpc/tgw_analysis.go index a06a97050..24bf8ea5a 100644 --- a/pkg/ibmvpc/tgw_analysis.go +++ b/pkg/ibmvpc/tgw_analysis.go @@ -10,7 +10,7 @@ import ( "errors" "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -38,7 +38,7 @@ func isSubnetTGWDestination(tg *TransitGateway, subnet *commonvpc.Subnet) bool { // overlapping address prefixes the TGW may choose available route from a different VPC routesListPerVPC := tg.availableRoutes[subnet.VPCRef.UID()] for _, routeCIDR := range routesListPerVPC { - if dstIPB.ContainedIn(routeCIDR) { + if dstIPB.IsSubset(routeCIDR) { return true } } @@ -52,15 +52,15 @@ func isSubnetTGWDestination(tg *TransitGateway, subnet *commonvpc.Subnet) bool { // Note that there is always a single prefix filter that determines the route (allow/deny) for each address prefix // (could be the default); this is since each atomic src/dst is an endpoint and since // prefix filter rules do not include protocol or ports (unlike nacls and sgs) -func getVPCAdvertisedRoutes(tc *datamodel.TransitConnection, tcIndex int, vpc *commonvpc.VPC) (advertisedRoutesRes []*ipblock.IPBlock, - vpcAPToPrefixRules map[*ipblock.IPBlock]vpcmodel.RulesInTable, err error) { - vpcAPToPrefixRules = map[*ipblock.IPBlock]vpcmodel.RulesInTable{} +func getVPCAdvertisedRoutes(tc *datamodel.TransitConnection, tcIndex int, vpc *commonvpc.VPC) (advertisedRoutesRes []*netset.IPBlock, + vpcAPToPrefixRules map[*netset.IPBlock]vpcmodel.RulesInTable, err error) { + vpcAPToPrefixRules = map[*netset.IPBlock]vpcmodel.RulesInTable{} for _, ap := range vpc.AddressPrefixesList { filterIndex, isPermitAction, err := getMatchedFilterIndexAndAction(ap, tc) if err != nil { return nil, nil, err } - apIPBlock, err := ipblock.FromCidr(ap) + apIPBlock, err := netset.IPBlockFromCidr(ap) if err != nil { return nil, nil, err } @@ -125,7 +125,7 @@ func parseActionString(action *string) (bool, error) { // prefixLeGeMatch checks if a vpc's address-prefix cidr is matched by a given rule's prefix with le/ge attributes func prefixLeGeMatch(prefix *string, le, ge *int64, cidr string) (bool, error) { - prefixIPBlock, cidrBlock, err := ipblock.PairCIDRsToIPBlocks(*prefix, cidr) + prefixIPBlock, cidrBlock, err := netset.PairCIDRsToIPBlocks(*prefix, cidr) if err != nil { return false, err } @@ -137,10 +137,10 @@ func prefixLeGeMatch(prefix *string, le, ge *int64, cidr string) (bool, error) { case ge == nil && le == nil: return cidrBlock.Equal(prefixIPBlock), nil case ge == nil: - return cidrBlock.ContainedIn(prefixIPBlock) && subnetCIDRLen <= *le, nil + return cidrBlock.IsSubset(prefixIPBlock) && subnetCIDRLen <= *le, nil case le == nil: - return cidrBlock.ContainedIn(prefixIPBlock) && subnetCIDRLen >= *ge, nil + return cidrBlock.IsSubset(prefixIPBlock) && subnetCIDRLen >= *ge, nil default: - return cidrBlock.ContainedIn(prefixIPBlock) && subnetCIDRLen >= *ge && subnetCIDRLen <= *le, nil + return cidrBlock.IsSubset(prefixIPBlock) && subnetCIDRLen >= *ge && subnetCIDRLen <= *le, nil } } diff --git a/pkg/ibmvpc/tgw_analysis_test.go b/pkg/ibmvpc/tgw_analysis_test.go index 6a8768825..4e2de1e7e 100644 --- a/pkg/ibmvpc/tgw_analysis_test.go +++ b/pkg/ibmvpc/tgw_analysis_test.go @@ -15,7 +15,7 @@ import ( "github.com/stretchr/testify/require" "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" @@ -220,7 +220,7 @@ func (tt *tgwTest) runTest(t *testing.T) { for _, r := range availableRoutes { fmt.Printf("%s\n", r.ToCidrList()) } - availableRoutesMap := map[string][]*ipblock.IPBlock{tt.vpc.UID(): availableRoutes} + availableRoutesMap := map[string][]*netset.IPBlock{tt.vpc.UID(): availableRoutes} permittedSubnets := getVPCdestSubnetsByAdvertisedRoutes(&TransitGateway{availableRoutes: availableRoutesMap}, tt.vpc) require.Nil(t, err) for _, subnet := range tt.vpc.SubnetsList { diff --git a/pkg/ibmvpc/vpc.go b/pkg/ibmvpc/vpc.go index af8bc3028..fc69ddee4 100644 --- a/pkg/ibmvpc/vpc.go +++ b/pkg/ibmvpc/vpc.go @@ -14,8 +14,7 @@ import ( "strings" "github.com/np-guard/cloud-resource-collector/pkg/ibm/datamodel" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" "github.com/np-guard/vpc-network-config-analyzer/pkg/commonvpc" "github.com/np-guard/vpc-network-config-analyzer/pkg/logging" @@ -59,7 +58,7 @@ type PrivateIP struct { // original - does the private IP was originally at the config file, or is it a potential one original bool // the potential block which the pip was created for: - block *ipblock.IPBlock + block *netset.IPBlock } func (pip *PrivateIP) NameForAnalyzerOut(c *vpcmodel.VPCConfig) string { @@ -109,7 +108,7 @@ func (v *Vpe) Nodes() []vpcmodel.Node { return v.nodes } -func (v *Vpe) AddressRange() *ipblock.IPBlock { +func (v *Vpe) AddressRange() *netset.IPBlock { return nodesAddressRange(v.nodes) } @@ -118,8 +117,8 @@ func (v *Vpe) Zone() (*commonvpc.Zone, error) { return nil, nil } -func nodesAddressRange(nodes []vpcmodel.Node) *ipblock.IPBlock { - var res *ipblock.IPBlock +func nodesAddressRange(nodes []vpcmodel.Node) *netset.IPBlock { + var res *netset.IPBlock for _, n := range nodes { if res == nil { res = n.IPBlock() @@ -156,7 +155,7 @@ func (lb *LoadBalancer) NameForAnalyzerOut(c *vpcmodel.VPCConfig) string { func (lb *LoadBalancer) Nodes() []vpcmodel.Node { return lb.nodes } -func (lb *LoadBalancer) AddressRange() *ipblock.IPBlock { +func (lb *LoadBalancer) AddressRange() *netset.IPBlock { return nodesAddressRange(lb.nodes) } @@ -249,15 +248,15 @@ func (fip *FloatingIP) SetExternalDestinations(destinations []vpcmodel.Node) { fip.destinations = destinations } -func (fip *FloatingIP) AllowedConnectivity(src, dst vpcmodel.VPCResourceIntf) (*connection.Set, error) { +func (fip *FloatingIP) AllowedConnectivity(src, dst vpcmodel.VPCResourceIntf) (*netset.TransportSet, error) { if areNodes, src1, dst1 := isNodesPair(src, dst); areNodes { if vpcmodel.HasNode(fip.Sources(), src1) && dst1.IsExternal() { - return connection.All(), nil + return netset.AllTransports(), nil } if vpcmodel.HasNode(fip.Sources(), dst1) && src1.IsExternal() { - return connection.All(), nil + return netset.AllTransports(), nil } - return connection.None(), nil + return netset.NoTransports(), nil } return nil, errors.New("FloatingIP.AllowedConnectivity unexpected src/dst types") } @@ -323,20 +322,20 @@ func (pgw *PublicGateway) ExternalIP() string { return "" } -func (pgw *PublicGateway) AllowedConnectivity(src, dst vpcmodel.VPCResourceIntf) (*connection.Set, error) { +func (pgw *PublicGateway) AllowedConnectivity(src, dst vpcmodel.VPCResourceIntf) (*netset.TransportSet, error) { if areNodes, src1, dst1 := isNodesPair(src, dst); areNodes { if vpcmodel.HasNode(pgw.Sources(), src1) && dst1.IsExternal() { - return connection.All(), nil + return netset.AllTransports(), nil } - return connection.None(), nil + return netset.NoTransports(), nil } if src.Kind() == commonvpc.ResourceTypeSubnet { srcSubnet := src.(*commonvpc.Subnet) if dstNode, ok := dst.(vpcmodel.Node); ok { if dstNode.IsExternal() && hasSubnet(pgw.srcSubnets, srcSubnet) { - return connection.All(), nil + return netset.AllTransports(), nil } - return connection.None(), nil + return netset.NoTransports(), nil } } return nil, errors.New("unexpected src/dst input types") @@ -370,7 +369,7 @@ type TransitGateway struct { // availableRoutes are the published address prefixes from all connected vpcs that arrive at the TGW's table of available routes, // as considered from prefix filters: map from vpc UID to its available routes in the routes table - availableRoutes map[string][]*ipblock.IPBlock + availableRoutes map[string][]*netset.IPBlock // sourceSubnets are the subnets from the connected vpcs that can have connection to destination // subnet from another vpc @@ -389,7 +388,7 @@ type TransitGateway struct { // these details includes map of each relevant IPBlock to the transit connection (its index in the tgwConnList) // and the index of the matching filter in the transit connection if exists (index "-1" is for default ) // this struct can be though of as the "explain" parallel of availableRoutes; note that unlike availableRoutes it also lists deny prefixes - vpcsAPToPrefixRules map[string]map[*ipblock.IPBlock]vpcmodel.RulesInTable + vpcsAPToPrefixRules map[string]map[*netset.IPBlock]vpcmodel.RulesInTable } func (tgw *TransitGateway) addSourceAndDestNodes() { @@ -431,24 +430,24 @@ func isPairRelevantToTGW(src, dst vpcmodel.VPCResourceIntf) bool { return !(src.IsExternal() || dst.IsExternal()) && src.VPC().UID() != dst.VPC().UID() } -func (tgw *TransitGateway) AllowedConnectivity(src, dst vpcmodel.VPCResourceIntf) (*connection.Set, error) { +func (tgw *TransitGateway) AllowedConnectivity(src, dst vpcmodel.VPCResourceIntf) (*netset.TransportSet, error) { if !isPairRelevantToTGW(src, dst) { logging.Debugf("pair not relevant to TGW") - return connection.None(), nil + return netset.NoTransports(), nil } if areNodes, src1, dst1 := isNodesPair(src, dst); areNodes { if vpcmodel.HasNode(tgw.sourceNodes, src1) && vpcmodel.HasNode(tgw.destNodes, dst1) { logging.Debugf("tgw enables this connectivity") - return connection.All(), nil + return netset.AllTransports(), nil } logging.Debugf("tgw disables this connectivity") - return connection.None(), nil + return netset.NoTransports(), nil } if areSubnets, src1, dst1 := isSubnetsPair(src, dst); areSubnets { if hasSubnet(tgw.sourceSubnets, src1) && hasSubnet(tgw.destSubnets, dst1) { - return connection.All(), nil + return netset.AllTransports(), nil } - return connection.None(), nil + return netset.NoTransports(), nil } logging.Debugf("err") diff --git a/pkg/linter/lintRuleCIDROutOfRange.go b/pkg/linter/lintRuleCIDROutOfRange.go index 40d5650cb..92262d912 100644 --- a/pkg/linter/lintRuleCIDROutOfRange.go +++ b/pkg/linter/lintRuleCIDROutOfRange.go @@ -9,7 +9,7 @@ package linter import ( "fmt" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -70,8 +70,8 @@ func findRuleNonRelevantCIDR(configs map[string]*vpcmodel.VPCConfig, filterLayer if rules[i].IsIngress { relevantBlock = rules[i].DstCidr } - if !relevantBlock.Equal(ipblock.GetCidrAll()) { // 0.0.0.0/0 common practice in rules - if !relevantBlock.ContainedIn(vpcAddressRange) { + if !relevantBlock.Equal(netset.GetCidrAll()) { // 0.0.0.0/0 common practice in rules + if !relevantBlock.IsSubset(vpcAddressRange) { res = append(res, &ruleNonRelevantCIDR{rule: rules[i], vpcResource: config.VPC, disjoint: !relevantBlock.Overlap(vpcAddressRange)}) } diff --git a/pkg/linter/lintRuleShadowedOrImplied.go b/pkg/linter/lintRuleShadowedOrImplied.go index 4896ea7db..b017bab8e 100644 --- a/pkg/linter/lintRuleShadowedOrImplied.go +++ b/pkg/linter/lintRuleShadowedOrImplied.go @@ -12,8 +12,7 @@ import ( "sort" "strings" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -112,14 +111,14 @@ func findRuleSyntacticRedundant(configs map[string]*vpcmodel.VPCConfig, containRules := map[int]*vpcmodel.RuleOfFilter{} for _, srcAtomicBlock := range srcBlocks { for _, dstAtomicBlock := range dstBlocks { - connOfOthers := connection.None() + connOfOthers := netset.NoTransports() // computes the connection of other/higher priority rules in this atomic point in the 3-dimension space for _, otherRule := range rulesToIterate { // otherRule contributes to the shadowing/implication? // namely, it contains src, dst and has a relevant connection? if redundantRule.IsIngress == otherRule.IsIngress && - srcAtomicBlock.ContainedIn(otherRule.SrcCidr) && - dstAtomicBlock.ContainedIn(otherRule.DstCidr) && + srcAtomicBlock.IsSubset(otherRule.SrcCidr) && + dstAtomicBlock.IsSubset(otherRule.DstCidr) && !redundantRule.Conn.Intersect(otherRule.Conn).IsEmpty() { connOfOthers = connOfOthers.Union(otherRule.Conn) if _, ok := containRules[otherRule.RuleIndex]; !ok { @@ -128,7 +127,7 @@ func findRuleSyntacticRedundant(configs map[string]*vpcmodel.VPCConfig, } } // is shadowed/implied by other rules? - if !redundantRule.Conn.ContainedIn(connOfOthers) { + if !redundantRule.Conn.IsSubset(connOfOthers) { ruleIsRedundant = false break } @@ -143,10 +142,10 @@ func findRuleSyntacticRedundant(configs map[string]*vpcmodel.VPCConfig, return res, nil } -func getAtomicBlocks(atomicBlocks []*ipblock.IPBlock, srcOrdst *ipblock.IPBlock) []*ipblock.IPBlock { - res := []*ipblock.IPBlock{} +func getAtomicBlocks(atomicBlocks []*netset.IPBlock, srcOrdst *netset.IPBlock) []*netset.IPBlock { + res := []*netset.IPBlock{} for _, block := range atomicBlocks { - if block.ContainedIn(srcOrdst) { + if block.IsSubset(srcOrdst) { res = append(res, block) } } @@ -157,14 +156,14 @@ func getAtomicBlocks(atomicBlocks []*ipblock.IPBlock, srcOrdst *ipblock.IPBlock) // 1. To a slice of its rules, where the location in the slice is the index of the rule // 2. To slice of the atomic blocks of the table func getTablesRulesAndAtomicBlocks(config *vpcmodel.VPCConfig, filterLayerName string) (tableToRules map[int][]*vpcmodel.RuleOfFilter, - tableToAtomicBlocks map[int][]*ipblock.IPBlock, err error) { + tableToAtomicBlocks map[int][]*netset.IPBlock, err error) { filterLayer := config.GetFilterTrafficResourceOfKind(filterLayerName) rules, err := filterLayer.GetRules() if err != nil { return nil, nil, err } tableToRules = map[int][]*vpcmodel.RuleOfFilter{} - tableToAtomicBlocks = map[int][]*ipblock.IPBlock{} + tableToAtomicBlocks = map[int][]*netset.IPBlock{} for i := range rules { filterIndex := rules[i].Filter.FilterIndex tableToRules[filterIndex] = append(tableToRules[filterIndex], &rules[i]) @@ -175,7 +174,7 @@ func getTablesRulesAndAtomicBlocks(config *vpcmodel.VPCConfig, filterLayerName s slices.SortFunc(tableToRules[tableIndex], func(r1, r2 *vpcmodel.RuleOfFilter) int { return r1.RuleIndex - r2.RuleIndex }) - tableToAtomicBlocks[tableIndex] = ipblock.DisjointIPBlocks(tableToAtomicBlocks[tableIndex], nil) + tableToAtomicBlocks[tableIndex] = netset.DisjointIPBlocks(tableToAtomicBlocks[tableIndex], nil) } return tableToRules, tableToAtomicBlocks, err } diff --git a/pkg/linter/lintRuleSplitSubnet.go b/pkg/linter/lintRuleSplitSubnet.go index 6b3535e59..3778dfbcd 100644 --- a/pkg/linter/lintRuleSplitSubnet.go +++ b/pkg/linter/lintRuleSplitSubnet.go @@ -10,7 +10,7 @@ import ( "fmt" "strings" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -65,7 +65,7 @@ func findSplitRulesSubnet(configs map[string]*vpcmodel.VPCConfig, filterLayerNam for i := range rules { subnetsSplitByRule := []vpcmodel.Subnet{} for _, subnet := range config.Subnets { - splitSubnet := ruleSplitSubnet(subnet, [2]*ipblock.IPBlock{rules[i].SrcCidr, rules[i].DstCidr}) + splitSubnet := ruleSplitSubnet(subnet, [2]*netset.IPBlock{rules[i].SrcCidr, rules[i].DstCidr}) if splitSubnet { subnetsSplitByRule = append(subnetsSplitByRule, subnet) } @@ -79,10 +79,10 @@ func findSplitRulesSubnet(configs map[string]*vpcmodel.VPCConfig, filterLayerNam } // given a subnet and IPBlocks mentioned in a rule, returns true if the rules split any of the blocks -func ruleSplitSubnet(subnet vpcmodel.Subnet, ruleIPBlocks [2]*ipblock.IPBlock) bool { +func ruleSplitSubnet(subnet vpcmodel.Subnet, ruleIPBlocks [2]*netset.IPBlock) bool { subnetCidrIPBlock := subnet.AddressRange() for _, ruleIPBlock := range ruleIPBlocks { - if ruleIPBlock.Overlap(subnetCidrIPBlock) && !subnetCidrIPBlock.ContainedIn(ruleIPBlock) { + if ruleIPBlock.Overlap(subnetCidrIPBlock) && !subnetCidrIPBlock.IsSubset(ruleIPBlock) { return true } } diff --git a/pkg/linter/lintSubnetCIDROverlap.go b/pkg/linter/lintSubnetCIDROverlap.go index 39acb10e8..2346797c3 100644 --- a/pkg/linter/lintSubnetCIDROverlap.go +++ b/pkg/linter/lintSubnetCIDROverlap.go @@ -9,7 +9,7 @@ package linter import ( "fmt" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -32,7 +32,7 @@ func newSubnetCIDROverlap(name string, configs map[string]*vpcmodel.VPCConfig, // a couple of overlapping subnets type overlapSubnets struct { overlapSubnets [2]vpcmodel.Subnet - overlapIPBlocks *ipblock.IPBlock + overlapIPBlocks *netset.IPBlock } // ///////////////////////////////////////////////////////// diff --git a/pkg/linter/lintTCPReposnseBlocked.go b/pkg/linter/lintTCPReposnseBlocked.go index 43b5ee58a..24ff5cd25 100644 --- a/pkg/linter/lintTCPReposnseBlocked.go +++ b/pkg/linter/lintTCPReposnseBlocked.go @@ -8,9 +8,9 @@ package linter import ( "fmt" - "strings" - "github.com/np-guard/models/pkg/connection" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-analyzer/pkg/common" "github.com/np-guard/vpc-network-config-analyzer/pkg/vpcmodel" ) @@ -38,7 +38,7 @@ func newTCPResponseBlocked(name string, configs map[string]*vpcmodel.VPCConfig, type blockedTCPResponseConn struct { src vpcmodel.EndpointElem dst vpcmodel.EndpointElem - tcpRspDisable *connection.Set + tcpRspDisable *netset.TransportSet } // ///////////////////////////////////////////////////////// @@ -79,7 +79,7 @@ func (finding *blockedTCPResponseConn) string() string { vpcSrcName, finding.src.NameForAnalyzerOut(nil), vpcDstName, finding.dst.NameForAnalyzerOut(nil)) return fmt.Sprintf("In the connection %s %s response is blocked", srcToDstStr, - strings.ReplaceAll(finding.tcpRspDisable.String(), "protocol: ", "")) + common.ShortString(finding.tcpRspDisable)) } func (finding *blockedTCPResponseConn) getVpcName(i int) string { @@ -91,15 +91,15 @@ func (finding *blockedTCPResponseConn) getVpcName(i int) string { // TCP connection with no response type blockedTCPResponseConnJSON struct { - Src string `json:"source"` - Dst string `json:"destination"` - TCPRspDisable connection.Details `json:"tcp_non_responsive"` + Src string `json:"source"` + Dst string `json:"destination"` + TCPRspDisable netset.Details `json:"tcp_non_responsive"` } func (finding *blockedTCPResponseConn) toJSON() any { vpcSrcName := finding.vpc()[0].Name() vpcDstName := finding.vpc()[1].Name() res := blockedTCPResponseConnJSON{Src: vpcSrcName + deliminator + finding.src.NameForAnalyzerOut(nil), - Dst: vpcDstName + deliminator + finding.dst.NameForAnalyzerOut(nil), TCPRspDisable: connection.ToJSON(finding.tcpRspDisable)} + Dst: vpcDstName + deliminator + finding.dst.NameForAnalyzerOut(nil), TCPRspDisable: netset.ToJSON(finding.tcpRspDisable)} return res } diff --git a/pkg/vpcmodel/abstractVPC.go b/pkg/vpcmodel/abstractVPC.go index 483414cd1..1d7a816da 100644 --- a/pkg/vpcmodel/abstractVPC.go +++ b/pkg/vpcmodel/abstractVPC.go @@ -7,8 +7,7 @@ SPDX-License-Identifier: Apache-2.0 package vpcmodel import ( - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" ) @@ -109,7 +108,7 @@ type Node interface { // CidrOrAddress returns the string of the Node's IP-address (for internal node) or CIDR (for external node) CidrOrAddress() string // IPBlock returns the IPBlock object of the IP addresses associated with this node - IPBlock() *ipblock.IPBlock + IPBlock() *netset.IPBlock // IsInternal returns true if the node is internal, within a VPC IsInternal() bool // IsPublicInternet returns true if the node is external, @@ -129,7 +128,7 @@ type InternalNodeIntf interface { // an InternalNodeIntf has an exact one IP Address Address() string // IPBlock returns the IPBlock object representing the node's IP Address - IPBlock() *ipblock.IPBlock + IPBlock() *netset.IPBlock // Subnet returns the subnet of the internal node Subnet() Subnet // AppliedFiltersKinds returns relevant filters for connectivity between internal nodes @@ -145,7 +144,7 @@ type InternalNode struct { // This field is skipped in the JSON output (nodes connectivity output in JSON format), // since it is sufficient to have the AddressStr, and no need to represent IPBlockObj as another // attribute in the JSON output. - IPBlockObj *ipblock.IPBlock `json:"-"` + IPBlockObj *netset.IPBlock `json:"-"` // SubnetResource is the subnet on which this node resides in SubnetResource Subnet `json:"-"` } @@ -154,7 +153,7 @@ func (n *InternalNode) Address() string { return n.AddressStr } -func (n *InternalNode) IPBlock() *ipblock.IPBlock { +func (n *InternalNode) IPBlock() *netset.IPBlock { return n.IPBlockObj } @@ -174,7 +173,7 @@ func (n *InternalNode) AppliedFiltersKinds(otherNode InternalNodeIntf) map[strin // SetIPBlockFromAddress sets the node's IPBlockObj field from its AddressStr field. // Assumes its AddressStr field is assigned with valid IPv4 string value. func (n *InternalNode) SetIPBlockFromAddress() (err error) { - n.IPBlockObj, err = ipblock.FromIPAddress(n.AddressStr) + n.IPBlockObj, err = netset.IPBlockFromIPAddress(n.AddressStr) return err } @@ -203,12 +202,12 @@ func (n *InternalNode) RepresentedByAddress() bool { type NodeSet interface { VPCResourceIntf Nodes() []Node - AddressRange() *ipblock.IPBlock + AddressRange() *netset.IPBlock } type VPC interface { NodeSet - AddressPrefixes() *ipblock.IPBlock + AddressPrefixes() *netset.IPBlock } type Subnet interface { @@ -273,19 +272,19 @@ type RulesInTable struct { TableIndex int // sg/nacl/transit connection index in sgList/naclList/tgwConnList Rules []int // list of indexes of rules in the sg/nacl/transit connection RulesOfType RulesType - TableConn *connection.Set // connection of the table w.r.t. queried src, dst and query - TableHasEffect TableEffect // effect of the table w.r.t. queried src, dst and query + TableConn *netset.TransportSet // connection of the table w.r.t. queried src, dst and query + TableHasEffect TableEffect // effect of the table w.r.t. queried src, dst and query } // RuleOfFilter a single rule in filter given the layer (SGLayer/NACLLayer) type RuleOfFilter struct { Filter Filter - RuleIndex int `json:"rule_index"` - IsIngress bool `json:"inbound_rule"` - SrcCidr *ipblock.IPBlock `json:"src_cidr"` - DstCidr *ipblock.IPBlock `json:"dst_cidr"` - Conn *connection.Set `json:"rule_connection"` - RuleDesc string `json:"rule_description"` + RuleIndex int `json:"rule_index"` + IsIngress bool `json:"inbound_rule"` + SrcCidr *netset.IPBlock `json:"src_cidr"` + DstCidr *netset.IPBlock `json:"dst_cidr"` + Conn *netset.TransportSet `json:"rule_connection"` + RuleDesc string `json:"rule_description"` } type Filter struct { @@ -295,7 +294,7 @@ type Filter struct { } func NewRuleOfFilter(layerName, filterName, desc string, filterIndex, ruleIndex int, - isIngress bool, srcBlock, dstBlock *ipblock.IPBlock, conn *connection.Set) *RuleOfFilter { + isIngress bool, srcBlock, dstBlock *netset.IPBlock, conn *netset.TransportSet) *RuleOfFilter { table := Filter{LayerName: layerName, FilterIndex: filterIndex, FilterName: filterName} srcBlock = getCidrAllIfNil(srcBlock) dstBlock = getCidrAllIfNil(dstBlock) @@ -303,9 +302,9 @@ func NewRuleOfFilter(layerName, filterName, desc string, filterIndex, ruleIndex SrcCidr: srcBlock, DstCidr: dstBlock, Conn: conn} } -func getCidrAllIfNil(block *ipblock.IPBlock) *ipblock.IPBlock { +func getCidrAllIfNil(block *netset.IPBlock) *netset.IPBlock { if block == nil { - return ipblock.GetCidrAll() + return netset.GetCidrAll() } return block } @@ -317,15 +316,15 @@ type FiltersAttachedResources map[Filter][]VPCResourceIntf type FilterTrafficResource interface { VPCResourceIntf // AllowedConnectivity computes the connectivity from src Node to dst Node considering this filterTraffic resource - AllowedConnectivity(src, dst Node, isIngress bool) (*connection.Set, error) + AllowedConnectivity(src, dst Node, isIngress bool) (*netset.TransportSet, error) // RulesInConnectivity computes the list of rules of a given filter that contributes to the connection between src and dst // if conn is also given the above is per connection - RulesInConnectivity(src, dst Node, conn *connection.Set, isIngress bool) ([]RulesInTable, []RulesInTable, error) + RulesInConnectivity(src, dst Node, conn *netset.TransportSet, isIngress bool) ([]RulesInTable, []RulesInTable, error) // GetRules gets a list of all rules with description GetRules() ([]RuleOfFilter, error) // GetFiltersAttachedResources gets a map from each filter to the resources attached to it; e.g. from NACL to subnets GetFiltersAttachedResources() FiltersAttachedResources - ReferencedIPblocks() []*ipblock.IPBlock + ReferencedIPblocks() []*netset.IPBlock ConnectivityMap() (map[string]*IPbasedConnectivityResult, error) GetConnectivityOutputPerEachElemSeparately() string } @@ -338,7 +337,7 @@ type RoutingResource interface { SourcesSubnets() []Subnet Destinations() []Node SetExternalDestinations([]Node) - AllowedConnectivity(src, dst VPCResourceIntf) (*connection.Set, error) + AllowedConnectivity(src, dst VPCResourceIntf) (*netset.TransportSet, error) RulesInConnectivity(src, dst Node) []RulesInTable ExternalIP() string // ExternalIP of fip, empty string for other resources // RouterDefined is this router defined for src and dst? while fip, pgw are defined for src, dst iff they enable traffic diff --git a/pkg/vpcmodel/commonConnectivity.go b/pkg/vpcmodel/commonConnectivity.go index 795f24570..48f7e3567 100644 --- a/pkg/vpcmodel/commonConnectivity.go +++ b/pkg/vpcmodel/commonConnectivity.go @@ -7,37 +7,35 @@ SPDX-License-Identifier: Apache-2.0 package vpcmodel import ( - "github.com/np-guard/models/pkg/connection" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" ) -func newTCPConn(srcMinP, srcMaxP, dstMinP, dstMaxP int64) *connection.Set { - return connection.TCPorUDPConnection(netp.ProtocolStringTCP, srcMinP, srcMaxP, dstMinP, dstMaxP) +func newTCPConn(srcMinP, srcMaxP, dstMinP, dstMaxP int64) *netset.TransportSet { + return netset.NewTCPorUDPTransport(netp.ProtocolStringTCP, srcMinP, srcMaxP, dstMinP, dstMaxP) } -func newUDPConn(srcMinP, srcMaxP, dstMinP, dstMaxP int64) *connection.Set { - return connection.TCPorUDPConnection(netp.ProtocolStringUDP, srcMinP, srcMaxP, dstMinP, dstMaxP) +func newUDPConn(srcMinP, srcMaxP, dstMinP, dstMaxP int64) *netset.TransportSet { + return netset.NewTCPorUDPTransport(netp.ProtocolStringUDP, srcMinP, srcMaxP, dstMinP, dstMaxP) } -func newICMPconn() *connection.Set { - return connection.ICMPConnection( - connection.MinICMPType, connection.MaxICMPType, - connection.MinICMPCode, connection.MaxICMPCode) +func newICMPconn() *netset.TransportSet { + return netset.AllICMPTransport() } -func newTCPUDPSet(p netp.ProtocolString) *connection.Set { - return connection.TCPorUDPConnection(p, - connection.MinPort, connection.MaxPort, - connection.MinPort, connection.MaxPort) +func newTCPUDPSet(p netp.ProtocolString) *netset.TransportSet { + return netset.NewTCPorUDPTransport(p, + netp.MinPort, netp.MaxPort, + netp.MinPort, netp.MaxPort) } -func allTCPconn() *connection.Set { - return newTCPConn(connection.MinPort, connection.MaxPort, - connection.MinPort, connection.MaxPort) +func allTCPconn() *netset.TransportSet { + return newTCPConn(netp.MinPort, netp.MaxPort, + netp.MinPort, netp.MaxPort) } // PartitionTCPNonTCP given a connection returns its TCP and non-TCP sub-connections -func partitionTCPNonTCP(conn *connection.Set) (tcp, nonTCP *connection.Set) { +func partitionTCPNonTCP(conn *netset.TransportSet) (tcp, nonTCP *netset.TransportSet) { tcpFractionOfConn := allTCPconn().Intersect(conn) nonTCPFractionOfConn := conn.Subtract(tcpFractionOfConn) return tcpFractionOfConn, nonTCPFractionOfConn @@ -46,15 +44,15 @@ func partitionTCPNonTCP(conn *connection.Set) (tcp, nonTCP *connection.Set) { // GeneralConnectivityMap describes basic connectivity of the given network; // for each ordered couple of VPCResourceIntf that have connection between src to dst // it lists the protocols and ports for which the connection is enabled -type GeneralConnectivityMap map[VPCResourceIntf]map[VPCResourceIntf]*connection.Set +type GeneralConnectivityMap map[VPCResourceIntf]map[VPCResourceIntf]*netset.TransportSet // GeneralResponsiveConnectivityMap describes connectivity similarly to GeneralConnectivityMap; // only here the describes connection includes respond details, namely in what cases a TCP respond is enabled type GeneralResponsiveConnectivityMap map[VPCResourceIntf]map[VPCResourceIntf]*detailedConn -func (allowConnCombined GeneralConnectivityMap) updateAllowedConnsMap(src, dst VPCResourceIntf, conn *connection.Set) { +func (allowConnCombined GeneralConnectivityMap) updateAllowedConnsMap(src, dst VPCResourceIntf, conn *netset.TransportSet) { if _, ok := allowConnCombined[src]; !ok { - allowConnCombined[src] = map[VPCResourceIntf]*connection.Set{} + allowConnCombined[src] = map[VPCResourceIntf]*netset.TransportSet{} } allowConnCombined[src][dst] = conn } @@ -72,7 +70,7 @@ func (responsiveConnMap GeneralResponsiveConnectivityMap) copy() GeneralResponsi return newConnectivityMap } -// it is assumed that the components of detailedConn are legal connection.Set, namely not nil +// it is assumed that the components of detailedConn are legal netset.TransportSet, namely not nil func (responsiveConnMap GeneralResponsiveConnectivityMap) updateAllowedResponsiveConnsMap(src, dst VPCResourceIntf, conn *detailedConn) { if _, ok := responsiveConnMap[src]; !ok { diff --git a/pkg/vpcmodel/connectivityAbstration_test.go b/pkg/vpcmodel/connectivityAbstration_test.go index aa422a6aa..f10a3bbd6 100644 --- a/pkg/vpcmodel/connectivityAbstration_test.go +++ b/pkg/vpcmodel/connectivityAbstration_test.go @@ -10,12 +10,12 @@ import ( "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/connection" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" ) var allConn *detailedConn = detailedConnForAllRsp() -var halfConn *detailedConn = detailedConnForResponsive(connection.TCPorUDPConnection(netp.ProtocolStringTCP, 10, 100, 443, 443)) +var halfConn *detailedConn = detailedConnForResponsive(netset.NewTCPorUDPTransport(netp.ProtocolStringTCP, 10, 100, 443, 443)) var emptyConn *detailedConn = emptyDetailedConn() type abstractionTest struct { diff --git a/pkg/vpcmodel/detailedConn.go b/pkg/vpcmodel/detailedConn.go index 3556901aa..c1cb097c9 100644 --- a/pkg/vpcmodel/detailedConn.go +++ b/pkg/vpcmodel/detailedConn.go @@ -9,7 +9,8 @@ package vpcmodel import ( "strings" - "github.com/np-guard/models/pkg/connection" + "github.com/np-guard/models/pkg/netset" + common "github.com/np-guard/vpc-network-config-analyzer/pkg/common" ) const asterisk = " * " @@ -25,10 +26,10 @@ const asterisk = " * " // note: TCPRspDisable is not independent and is calculated based on the other properties; // it is kept since it is widely used - to determine if the connection is responsive type detailedConn struct { - tcpRspEnable *connection.Set // responsive TCP connection between - nonTCP *connection.Set // non TCP connection (for which responsiveness is non-relevant) - allConn *connection.Set // entire connection - TCPRspDisable *connection.Set // non-responsive TCP connection between ; complementary of tcpRspEnable + tcpRspEnable *netset.TransportSet // responsive TCP connection between + nonTCP *netset.TransportSet // non TCP connection (for which responsiveness is non-relevant) + allConn *netset.TransportSet // entire connection + TCPRspDisable *netset.TransportSet // non-responsive TCP connection between ; complementary of tcpRspEnable // connection is defined to be responsive if nonTCP is empty } @@ -37,7 +38,7 @@ type detailedConn struct { // TCPRspDisable - the tcp complementary of tcpRspEnable w.r.t. allConn - // is computed as allConn minus (tcpRspEnable union nonTCP) -func newDetailedConn(tspRspConn, otherConn, allConn *connection.Set) *detailedConn { +func newDetailedConn(tspRspConn, otherConn, allConn *netset.TransportSet) *detailedConn { return &detailedConn{ tcpRspEnable: tspRspConn, TCPRspDisable: (allConn.Subtract(otherConn)).Subtract(tspRspConn), @@ -51,14 +52,14 @@ func emptyDetailedConn() *detailedConn { } // detailedConnForTCPRsp returns a new detailedConn from input TCP responsive connection and the entire connection objects -func detailedConnForTCPRsp(tcpResponsive, allConn *connection.Set) *detailedConn { +func detailedConnForTCPRsp(tcpResponsive, allConn *netset.TransportSet) *detailedConn { _, nonTCPFraction := partitionTCPNonTCP(allConn) return newDetailedConn(tcpResponsive, nonTCPFraction, allConn) } // detailedConnForResponsive: is given the tcp responsive conn, assuming there is only // a tcp responsive component in the connection -func detailedConnForResponsive(tcpResponsive *connection.Set) *detailedConn { +func detailedConnForResponsive(tcpResponsive *netset.TransportSet) *detailedConn { return newDetailedConn(tcpResponsive, NoConns(), tcpResponsive) } @@ -70,7 +71,7 @@ func detailedConnForAllRsp() *detailedConn { // isAllObliviousRsp: returns true iff detailedConn contains all the connection domain // (regardless of what part is responsive and what part isn't) func (d *detailedConn) isAllObliviousRsp() bool { - return d.allConn.Equal(connection.All()) + return d.allConn.Equal(netset.AllTransports()) } // isEmpty: return true iff the detailedConn is empty @@ -107,7 +108,7 @@ func (d *detailedConn) hasTCPComponent() bool { } // returns the tcp responsive and non-tcp component -func (d *detailedConn) nonTCPAndResponsiveTCPComponent() *connection.Set { +func (d *detailedConn) nonTCPAndResponsiveTCPComponent() *netset.TransportSet { return d.tcpRspEnable.Union(d.nonTCP) } @@ -115,16 +116,16 @@ func (d *detailedConn) nonTCPAndResponsiveTCPComponent() *connection.Set { // for cosmetic reasons remove the protocol word from cubes prints func (d *detailedConn) string() string { if d.allConn.IsEmpty() { - return d.allConn.String() + return common.LongString(d.allConn) } resStrSlice := []string{} if !d.TCPRspDisable.IsEmpty() { - tcpNonResponsive := d.TCPRspDisable.String() + tcpNonResponsive := common.LongString(d.TCPRspDisable) tcpNonResponsive = strings.ReplaceAll(tcpNonResponsive, ";", asterisk+";") resStrSlice = append(resStrSlice, tcpNonResponsive+asterisk) } if !d.nonTCPAndResponsiveTCPComponent().IsEmpty() { - resStrSlice = append(resStrSlice, d.nonTCPAndResponsiveTCPComponent().String()) + resStrSlice = append(resStrSlice, common.LongString(d.nonTCPAndResponsiveTCPComponent())) } // todo: remove "protocol" from the original cube printing funcs return strings.ReplaceAll(strings.Join(resStrSlice, "; "), "protocol: ", "") @@ -136,21 +137,21 @@ func (d *detailedConn) string() string { // this separation is done here: the former is returned for bidirectional and the latter for false func (d *detailedConn) connStrPerConnectionType(nonTCPAndResponsiveTCP bool) string { if nonTCPAndResponsiveTCP { - return d.nonTCPAndResponsiveTCPComponent().String() + return common.LongString(d.nonTCPAndResponsiveTCPComponent()) } - return d.TCPRspDisable.String() + asterisk + return common.LongString(d.TCPRspDisable) + asterisk } // computeDetailedConn computes the detailedConn object, given input `srcToDst` // that represents a src-to-dst connection, and `dstToSrc` that represents dst-to-src connection. -func computeDetailedConn(srcToDst, dstToSrc *connection.Set) *detailedConn { +func computeDetailedConn(srcToDst, dstToSrc *netset.TransportSet) *detailedConn { connTCP := srcToDst.Intersect(allTCPconn()) if connTCP.IsEmpty() { return detailedConnForTCPRsp(NoConns(), srcToDst) } tcpSecondDirection := dstToSrc.Intersect(allTCPconn()) // flip src/dst ports before intersection - tcpSecondDirectionFlipped := tcpSecondDirection.SwitchSrcDstPorts() + tcpSecondDirectionFlipped := tcpSecondDirection.SwapPorts() // tcp connection responsive subset return detailedConnForTCPRsp(connTCP.Intersect(tcpSecondDirectionFlipped), srcToDst) } diff --git a/pkg/vpcmodel/explainabilityConnectivity.go b/pkg/vpcmodel/explainabilityConnectivity.go index 6ed5e6d9d..7457ba86b 100644 --- a/pkg/vpcmodel/explainabilityConnectivity.go +++ b/pkg/vpcmodel/explainabilityConnectivity.go @@ -10,7 +10,7 @@ import ( "fmt" "slices" - "github.com/np-guard/models/pkg/connection" + "github.com/np-guard/models/pkg/netset" ) var FilterLayers = [2]string{SecurityGroupLayer, NaclLayer} @@ -37,8 +37,8 @@ type srcDstDetails struct { // the part of the connection relevant to the query otherwise. // used to detect ingress and egress block and to // detect cases in which there is no connection due to empty intersection between ingress and egress - ingressConn *connection.Set - egressConn *connection.Set + ingressConn *netset.TransportSet + egressConn *netset.TransportSet conn *detailedConn externalRouter RoutingResource // the router (fip or pgw) to external network; nil if none or not relevant crossVpcRouter RoutingResource // the (currently only tgw) router between src and dst from different VPCs; nil if none or not relevant @@ -74,7 +74,7 @@ func NewExplanationArgs(src, dst, protocol string, srcMinPort, srcMaxPort, dstMi type Explanation struct { c *VPCConfig - connQuery *connection.Set + connQuery *netset.TransportSet rulesAndDetails *rulesAndConnDetails // rules and more details for a single src->dst src string dst string @@ -91,7 +91,7 @@ type Explanation struct { } // ExplainConnectivity returns Explanation object, that explains connectivity of a single couple given by the user -func (c *MultipleVPCConfigs) ExplainConnectivity(src, dst string, connQuery *connection.Set) (res *Explanation, err error) { +func (c *MultipleVPCConfigs) ExplainConnectivity(src, dst string, connQuery *netset.TransportSet) (res *Explanation, err error) { vpcConfig, srcNodes, dstNodes, err := c.getVPCConfigAndSrcDstNodes(src, dst) if err != nil { return nil, err @@ -111,7 +111,7 @@ func (c *MultipleVPCConfigs) ExplainConnectivity(src, dst string, connQuery *con // explainConnectivityForVPC for a vpcConfig, given src, dst and connQuery returns a struct with all explanation details // nil connQuery means connection is not part of the query func (c *VPCConfig) explainConnectivityForVPC(src, dst string, srcNodes, dstNodes []Node, - connQuery *connection.Set, connectivity *VPCConnectivity) (res *Explanation, err error) { + connQuery *netset.TransportSet, connectivity *VPCConnectivity) (res *Explanation, err error) { // we do not support multiple configs, yet rulesAndDetails, err1 := c.computeExplainRules(srcNodes, dstNodes, connQuery) if err1 != nil { @@ -151,7 +151,7 @@ func (c *VPCConfig) explainConnectivityForVPC(src, dst string, srcNodes, dstNode // computeExplainRules computes the egress and ingress rules contributing to the (existing or missing) connection func (c *VPCConfig) computeExplainRules(srcNodes, dstNodes []Node, - conn *connection.Set) (rulesAndConn rulesAndConnDetails, err error) { + conn *netset.TransportSet) (rulesAndConn rulesAndConnDetails, err error) { // the size is not known in this stage due to the corner case in which we have the same node both in srcNodes and dstNodes rulesAndConn = rulesAndConnDetails{} for _, src := range srcNodes { @@ -225,12 +225,12 @@ func (details *rulesAndConnDetails) computeActualRules() { // ingress disabled due to private subnet? privateSubnetRule := singleSrcDstDetails.privateSubnetRule if privateSubnetRule != nil && privateSubnetRule.Deny(true) { - ingressConn = connection.None() + ingressConn = netset.NoTransports() } actualAllowEgress, egressConn := computeActualRulesGivenRulesFilter(singleSrcDstDetails.potentialAllowRules.egressRules, filterRelevant) if privateSubnetRule != nil && privateSubnetRule.Deny(false) { - egressConn = connection.None() + egressConn = netset.NoTransports() } actualDenyIngress, _ := computeActualRulesGivenRulesFilter(singleSrcDstDetails.potentialDenyRules.ingressRules, filterRelevant) actualDenyEgress, _ := computeActualRulesGivenRulesFilter(singleSrcDstDetails.potentialDenyRules.egressRules, filterRelevant) @@ -247,9 +247,9 @@ func (details *rulesAndConnDetails) computeActualRules() { // could be different than the connection implied by the rules, in case there are both deny and allow rules). // this is called separately for each direction (ingress/egress) and allow/deny (for nacl, sg has only allow) func computeActualRulesGivenRulesFilter(rulesLayers rulesInLayers, filters map[string]bool) (*rulesInLayers, - *connection.Set) { + *netset.TransportSet) { actualRules := rulesInLayers{} - conn := connection.All() + conn := netset.AllTransports() // connection of direction: intersection between connections of layers; for _, layer := range FilterLayers { filterIsRelevant := filters[layer] @@ -263,8 +263,8 @@ func computeActualRulesGivenRulesFilter(rulesLayers rulesInLayers, filters map[s } // connection of each layer is the union of the connection's of tables in the layer; (nacl single table; relevant for sg) -func connOfLayer(layerTables []RulesInTable) *connection.Set { - conn := connection.None() +func connOfLayer(layerTables []RulesInTable) *netset.TransportSet { + conn := netset.NoTransports() for _, table := range layerTables { conn = conn.Union(table.TableConn) } @@ -330,7 +330,7 @@ func mergeAllowDeny(allow, deny rulesInLayers) rulesInLayers { } func (c *VPCConfig) getFiltersRulesBetweenNodesPerDirectionAndLayer( - src, dst Node, conn *connection.Set, isIngress bool, layer string) (allowRules *[]RulesInTable, + src, dst Node, conn *netset.TransportSet, isIngress bool, layer string) (allowRules *[]RulesInTable, denyRules *[]RulesInTable, err error) { filter := c.GetFilterTrafficResourceOfKind(layer) if filter == nil { @@ -344,7 +344,7 @@ func (c *VPCConfig) getFiltersRulesBetweenNodesPerDirectionAndLayer( } func (c *VPCConfig) getRulesOfConnection(src, dst Node, - conn *connection.Set) (allowRulesOfConnection, denyRulesOfConnection *rulesConnection, err error) { + conn *netset.TransportSet) (allowRulesOfConnection, denyRulesOfConnection *rulesConnection, err error) { ingressAllowPerLayer, egressAllowPerLayer := rulesInLayers{}, rulesInLayers{} ingressDenyPerLayer, egressDenyPerLayer := rulesInLayers{}, rulesInLayers{} for _, layer := range FilterLayers { @@ -401,7 +401,7 @@ func (c *VPCConfig) getContainingConfigNode(node Node) (Node, error) { continue } configNodeIPBlock := configNode.IPBlock() - if nodeIPBlock.ContainedIn(configNodeIPBlock) { + if nodeIPBlock.IsSubset(configNodeIPBlock) { return configNode, nil } } @@ -414,7 +414,7 @@ func (c *VPCConfig) getContainingConfigNode(node Node) (Node, error) { // todo: connectivity is computed for the entire network, even though we need only for specific src, dst pairs // this is seems the time spent here should be neglectable, not worth the effort of adding dedicated code func (details *rulesAndConnDetails) computeConnections(c *VPCConfig, - connQuery *connection.Set, connectivity *VPCConnectivity) (err error) { + connQuery *netset.TransportSet, connectivity *VPCConnectivity) (err error) { for _, srcDstDetails := range *details { conn, err := connectivity.getConnection(c, srcDstDetails.src, srcDstDetails.dst) if err != nil { @@ -465,7 +465,7 @@ func (v *VPCConnectivity) getConnection(c *VPCConfig, src, dst Node) (conn *deta // updates respondRules of each line in rulesAndConnDetails // respondRules are the rules enabling/disabling the response when relevant: // respond is relevant for TCP, and respond rules are relevant when non-stateful filters are relevant (NACL) -func (details *rulesAndConnDetails) updateRespondRules(c *VPCConfig, connQuery *connection.Set) error { +func (details *rulesAndConnDetails) updateRespondRules(c *VPCConfig, connQuery *netset.TransportSet) error { responseConn := allTCPconn() if connQuery != nil { responseConn = responseConn.Intersect(connQuery) @@ -499,7 +499,7 @@ func respondRulesRelevant(conn *detailedConn, filtersRelevant map[string]bool, c // gets the NACL rules that enables/disables respond for connection conn, assuming nacl is applied func (c *VPCConfig) getRespondRules(src, dst Node, - conn *connection.Set) (respondRules *rulesConnection, err error) { + conn *netset.TransportSet) (respondRules *rulesConnection, err error) { mergedIngressRules, mergedEgressRules := rulesInLayers{}, rulesInLayers{} // respond: from dst to src; thus, ingress rules: relevant only if *src* is internal, egress is *dst* is internal if src.IsInternal() { @@ -519,12 +519,12 @@ func (c *VPCConfig) getRespondRules(src, dst Node, return &rulesConnection{mergedIngressRules, mergedEgressRules}, nil } -func (c *VPCConfig) computeAndUpdateDirectionRespondRules(src, dst Node, conn *connection.Set, +func (c *VPCConfig) computeAndUpdateDirectionRespondRules(src, dst Node, conn *netset.TransportSet, isIngress bool) (rulesInLayers, error) { // respond: dst and src switched, src and dst ports also switched // computes allowRulesPerLayer/denyRulePerLayer: ingress/egress rules enabling/disabling respond // note that there could be both allow and deny in case part of the connection is enabled and part blocked - connSwitch := conn.SwitchSrcDstPorts() + connSwitch := conn.SwapPorts() allowRules, denyRules, err1 := c.getFiltersRulesBetweenNodesPerDirectionAndLayer(dst, src, connSwitch, isIngress, statelessLayerName) if err1 != nil { diff --git a/pkg/vpcmodel/explainabilityInput.go b/pkg/vpcmodel/explainabilityInput.go index 966182b49..b8e24360a 100644 --- a/pkg/vpcmodel/explainabilityInput.go +++ b/pkg/vpcmodel/explainabilityInput.go @@ -12,9 +12,8 @@ import ( "sort" "strings" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" ) type ExplanationArgs struct { @@ -237,17 +236,15 @@ func (c *MultipleVPCConfigs) listNamesCrossVpcRouters( // GetConnectionSet TODO: handle also input ICMP properties (type, code) as input args // translates explanation args to a connection set -func (e *ExplanationArgs) GetConnectionSet() *connection.Set { +func (e *ExplanationArgs) GetConnectionSet() *netset.TransportSet { if e.protocol == "" { return nil } switch p := netp.ProtocolString(e.protocol); p { case netp.ProtocolStringICMP: - return connection.ICMPConnection( - connection.MinICMPType, connection.MaxICMPType, - connection.MinICMPCode, connection.MaxICMPCode) + return netset.AllICMPTransport() default: - return connection.TCPorUDPConnection(p, + return netset.NewTCPorUDPTransport(p, e.srcMinPort, e.srcMaxPort, e.dstMinPort, e.dstMaxPort) } } @@ -319,7 +316,7 @@ func (c *VPCConfig) getNodesFromInputString(cidrOrName string) (nodes []Node, // cidrOrName, if legal, references an address. // 3. cidrOrName references an ip address - ipBlock, err3 := ipblock.FromCidrOrAddress(cidrOrName) + ipBlock, err3 := netset.IPBlockFromCidrOrAddress(cidrOrName) if err3 != nil { // the input is not a legal cidr or IP address, which in this stage means it is not a // valid presentation for src/dst. Lint demands that an error is returned here @@ -402,7 +399,7 @@ func getResourceAndVpcNames(name string) (resource, vpc string) { // 4. else: it presents an internal address, return connected network interfaces and true, // // todo: 4 - replace subnet's address range in vpc's address prefix -func (c *VPCConfig) getNodesFromAddress(ipOrCidr string, inputIPBlock *ipblock.IPBlock) (nodes []Node, +func (c *VPCConfig) getNodesFromAddress(ipOrCidr string, inputIPBlock *netset.IPBlock) (nodes []Node, errType int, err error) { // 1. _, publicInternet, err1 := GetPublicInternetIPblocksList() @@ -410,7 +407,7 @@ func (c *VPCConfig) getNodesFromAddress(ipOrCidr string, inputIPBlock *ipblock.I return nil, fatalErr, err1 } isExternal := inputIPBlock.Overlap(publicInternet) - isInternal := !inputIPBlock.ContainedIn(publicInternet) + isInternal := !inputIPBlock.IsSubset(publicInternet) if isInternal && isExternal { return nil, fatalErr, fmt.Errorf("%s contains both external and internal IP addresses, which is not supported. "+ @@ -432,7 +429,7 @@ func (c *VPCConfig) getNodesFromAddress(ipOrCidr string, inputIPBlock *ipblock.I return networkInterfaces, noErr, nil // 4. } -func (c *VPCConfig) getNodesWithinInternalAddressFilterNonRelevant(inputIPBlock *ipblock.IPBlock) []Node { +func (c *VPCConfig) getNodesWithinInternalAddressFilterNonRelevant(inputIPBlock *netset.IPBlock) []Node { networkInterfaces := c.GetNodesWithinInternalAddress(inputIPBlock) // filtering out the nodes which are not represented by their address (currently only LB private IPs): networkInterfaces = slices.DeleteFunc(networkInterfaces, func(n Node) bool { return !n.RepresentedByAddress() }) @@ -449,9 +446,9 @@ func (c *VPCConfig) getNodesWithinInternalAddressFilterNonRelevant(inputIPBlock // 1. Calculate the IP blocks of the nodes N // 2. Calculate from N and the cidr block, disjoint IP blocks // 3. Return the nodes created from each block from 2 contained in the input cidr -func (c *VPCConfig) getCidrExternalNodes(inputIPBlock *ipblock.IPBlock) (cidrNodes []Node, errType int, err error) { +func (c *VPCConfig) getCidrExternalNodes(inputIPBlock *netset.IPBlock) (cidrNodes []Node, errType int, err error) { // 1. - vpcConfigNodesExternalBlock := []*ipblock.IPBlock{} + vpcConfigNodesExternalBlock := []*netset.IPBlock{} for _, node := range c.Nodes { if node.IsInternal() { continue @@ -459,11 +456,11 @@ func (c *VPCConfig) getCidrExternalNodes(inputIPBlock *ipblock.IPBlock) (cidrNod vpcConfigNodesExternalBlock = append(vpcConfigNodesExternalBlock, node.IPBlock()) } // 2. - disjointBlocks := ipblock.DisjointIPBlocks([]*ipblock.IPBlock{inputIPBlock}, vpcConfigNodesExternalBlock) + disjointBlocks := netset.DisjointIPBlocks([]*netset.IPBlock{inputIPBlock}, vpcConfigNodesExternalBlock) // 3. cidrNodes = []Node{} for _, block := range disjointBlocks { - if block.ContainedIn(inputIPBlock) { + if block.IsSubset(inputIPBlock) { node, err1 := newExternalNode(true, block) if err1 != nil { return nil, fatalErr, err1 // Should never get here. If still does - severe bug, exit with err diff --git a/pkg/vpcmodel/explainabilityPrint.go b/pkg/vpcmodel/explainabilityPrint.go index d0b054167..34a4d973c 100644 --- a/pkg/vpcmodel/explainabilityPrint.go +++ b/pkg/vpcmodel/explainabilityPrint.go @@ -12,7 +12,8 @@ import ( "sort" "strings" - "github.com/np-guard/models/pkg/connection" + "github.com/np-guard/models/pkg/netset" + common "github.com/np-guard/vpc-network-config-analyzer/pkg/common" ) const arrow = " -> " @@ -50,9 +51,9 @@ func explainHeader(explanation *Explanation) string { // connHeader is used to print 1) the query in the first header // 2) the actual allowed connection from the queried one in the 2nd header -func connHeader(connQuery *connection.Set) string { +func connHeader(connQuery *netset.TransportSet) string { if connQuery != nil { - return " using \"" + connQuery.String() + "\"" + return " using \"" + common.LongString(connQuery) + "\"" } return "" } @@ -91,7 +92,7 @@ func (explanation *Explanation) String(verbose bool) string { // missing cross vpc router // in this case there is no *VPCConfig we can work with, so this case is treated separately -func explainMissingCrossVpcRouter(src, dst string, connQuery *connection.Set) string { +func explainMissingCrossVpcRouter(src, dst string, connQuery *netset.TransportSet) string { return fmt.Sprintf("%vAll connections will be blocked since source and destination are in different VPCs with no transit gateway to "+ "connect them", noConnectionHeader(src, dst, connQuery)+newLine) } @@ -120,7 +121,7 @@ func explainMissingCrossVpcRouter(src, dst string, connQuery *connection.Set) st // the connection is blocked and only part of the path is printed then 2 is printed so that the relevant information // is provided regardless of where the is blocking // 4 is printed only in detailed mode -func (g *groupedConnLine) explainabilityLineStr(c *VPCConfig, connQuery *connection.Set, allRulesDetails *rulesDetails, +func (g *groupedConnLine) explainabilityLineStr(c *VPCConfig, connQuery *netset.TransportSet, allRulesDetails *rulesDetails, verbose bool) string { expDetails := g.CommonProperties.expDetails filtersRelevant := g.CommonProperties.expDetails.filtersRelevant @@ -145,7 +146,7 @@ func (g *groupedConnLine) explainabilityLineStr(c *VPCConfig, connQuery *connect loadBalancerHeader = "Load Balancer: " + loadBalancerRule.String(true) loadBalancerDetails = "\tLoad Balancer:\n" + doubleTab + loadBalancerRule.String(false) + newLine } - var crossVpcConnection *connection.Set + var crossVpcConnection *netset.TransportSet crossVpcConnection, crossRouterFilterHeader, crossRouterFilterDetails = crossRouterDetails(c, crossVpcRouter, crossVpcRules, src, dst) // noConnection is the 1 above when no connectivity @@ -208,11 +209,11 @@ func (g *groupedConnLine) explainabilityLineDetailStr(verbose bool, loadBalancer return details } -func egressIngressIntersectBlockStr(ingressEnable, egressEnable bool, ingressConn, egressConn *connection.Set) string { +func egressIngressIntersectBlockStr(ingressEnable, egressEnable bool, ingressConn, egressConn *netset.TransportSet) string { if ingressEnable && egressEnable && ingressConn.Intersect(egressConn).IsEmpty() { return fmt.Sprintf("\tconnectivity is blocked since traffic patterns allowed at ingress are disjoint "+ "from the traffic patterns allowed at egress.\n\t"+ - "allowed egress traffic: %v, allowed ingress traffic: %v", egressConn, ingressConn) + "allowed egress traffic: %v, allowed ingress traffic: %v", common.LongString(egressConn), common.LongString(ingressConn)) } return "" } @@ -231,7 +232,7 @@ func respondDetailsHeader(d *detailedConn) string { // after all data is gathered, generates the actual string to be printed func (g *groupedConnLine) explainPerCaseStr(c *VPCConfig, src, dst EndpointElem, - connQuery, crossVpcConnection *connection.Set, ingressBlocking, egressBlocking, loadBalancerBlocking, + connQuery, crossVpcConnection *netset.TransportSet, ingressBlocking, egressBlocking, loadBalancerBlocking, missingExternalRouter bool, egressIngressIntersectBlock, noConnection, resourceEffectHeader, path, details string) string { conn := g.CommonProperties.Conn crossVpcRouter := g.CommonProperties.expDetails.crossVpcRouter @@ -277,7 +278,7 @@ func blockSummary(ingressBlocking, egressBlocking, loadBalancerBlocking, missing } func crossRouterDetails(c *VPCConfig, crossVpcRouter RoutingResource, crossVpcRules []RulesInTable, - src, dst EndpointElem) (crossVpcConnection *connection.Set, + src, dst EndpointElem) (crossVpcConnection *netset.TransportSet, crossVpcRouterFilterHeader, crossVpcFilterDetails string) { if crossVpcRouter != nil { // an error here will pop up earlier, when computing connections @@ -300,13 +301,13 @@ func crossVpcRouterRequired(src, dst EndpointElem) bool { } // returns string of header in case a connection fails to exist -func noConnectionHeader(src, dst string, connQuery *connection.Set) string { +func noConnectionHeader(src, dst string, connQuery *netset.TransportSet) string { return fmt.Sprintf("No connectivity from %s to %s%s;", src, dst, connHeader(connQuery)) } // printing when connection exists. // computing "1" when there is a connection and adding to it already computed "2" and "3" as described in explainabilityLineStr -func existingConnectionStr(c *VPCConfig, connQuery *connection.Set, src, dst EndpointElem, +func existingConnectionStr(c *VPCConfig, connQuery *netset.TransportSet, src, dst EndpointElem, conn *detailedConn, path, details string) string { resComponents := []string{} // Computing the header, "1" described in explainabilityLineStr @@ -314,7 +315,7 @@ func existingConnectionStr(c *VPCConfig, connQuery *connection.Set, src, dst End if connQuery == nil { resComponents = append(resComponents, fmt.Sprintf("Connections from %v to %v: %v%v\n", src.NameForAnalyzerOut(c), dst.NameForAnalyzerOut(c), - conn.allConn.String(), respondConnStr)) + common.LongString(conn.allConn), respondConnStr)) } else { properSubsetConn := "" if !conn.allConn.Equal(connQuery) { @@ -421,7 +422,7 @@ func stringFilterEffect(allRulesDetails *rulesDetails, filterLayerName string, t // e.g.: "vsi1-ky[10.240.10.4] -> security group sg1-ky -> subnet1-ky -> | network ACL acl1-ky |" func pathStr(allRulesDetails *rulesDetails, filtersRelevant map[string]bool, src, dst EndpointElem, ingressBlocking, egressBlocking, loadBalancerBlocking, missingExternalRouter bool, - externalRouter, crossVpcRouter RoutingResource, crossVpcConnection *connection.Set, + externalRouter, crossVpcRouter RoutingResource, crossVpcConnection *netset.TransportSet, rules *rulesConnection, privateSubnetRule PrivateSubnetRule) string { var pathSlice []string pathSlice = append(pathSlice, "\t"+src.NameForAnalyzerOut(nil)) @@ -633,8 +634,7 @@ func respondString(d *detailedConn) string { // no tcp responsive component return "\n\tTCP response is blocked" default: - disabledToPrint := strings.ReplaceAll(d.TCPRspDisable.String(), - "protocol: ", "") + disabledToPrint := common.ShortString(d.TCPRspDisable) disabledToPrint = strings.ReplaceAll(disabledToPrint, "TCP ", "") return "\n\tHowever, TCP response is blocked for: " + disabledToPrint } diff --git a/pkg/vpcmodel/externalNetwork.go b/pkg/vpcmodel/externalNetwork.go index ec06fa861..1ae1560a1 100644 --- a/pkg/vpcmodel/externalNetwork.go +++ b/pkg/vpcmodel/externalNetwork.go @@ -9,7 +9,7 @@ package vpcmodel import ( "errors" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" ) @@ -48,7 +48,7 @@ type ExternalNetwork struct { ResourceType string CidrStr string isPublicInternet bool - ipblock *ipblock.IPBlock + ipblock *netset.IPBlock } func (exn *ExternalNetwork) UID() string { return exn.Name() } @@ -60,7 +60,7 @@ func (exn *ExternalNetwork) CidrOrAddress() string { return exn.CidrStr } -func (exn *ExternalNetwork) IPBlock() *ipblock.IPBlock { +func (exn *ExternalNetwork) IPBlock() *netset.IPBlock { return exn.ipblock } @@ -105,13 +105,13 @@ func (exn *ExternalNetwork) VPC() VPCResourceIntf { } // input ipList is a list of cidrs / ip-ranges (see getPublicInternetAddressList() as example) -func ipStringsToIPblocks(ipList []string) (ipbList []*ipblock.IPBlock, unionIPblock *ipblock.IPBlock, err error) { - ipbList = []*ipblock.IPBlock{} - unionIPblock = ipblock.New() +func ipStringsToIPblocks(ipList []string) (ipbList []*netset.IPBlock, unionIPblock *netset.IPBlock, err error) { + ipbList = []*netset.IPBlock{} + unionIPblock = netset.NewIPBlock() for _, ipAddressRange := range ipList { - var ipb *ipblock.IPBlock - if ipb, err = ipblock.FromIPRangeStr(ipAddressRange); err != nil { - ipb, err = ipblock.FromCidr(ipAddressRange) + var ipb *netset.IPBlock + if ipb, err = netset.IPBlockFromIPRangeStr(ipAddressRange); err != nil { + ipb, err = netset.IPBlockFromCidr(ipAddressRange) } if err != nil { return nil, nil, err @@ -122,12 +122,12 @@ func ipStringsToIPblocks(ipList []string) (ipbList []*ipblock.IPBlock, unionIPbl return ipbList, unionIPblock, nil } -func GetPublicInternetIPblocksList() (internetIPblocksList []*ipblock.IPBlock, allInternetRagnes *ipblock.IPBlock, err error) { +func GetPublicInternetIPblocksList() (internetIPblocksList []*netset.IPBlock, allInternetRagnes *netset.IPBlock, err error) { publicInternetAddressList := getPublicInternetAddressList() return ipStringsToIPblocks(publicInternetAddressList) } -func newExternalNode(isPublicInternet bool, ipb *ipblock.IPBlock) (Node, error) { +func newExternalNode(isPublicInternet bool, ipb *netset.IPBlock) (Node, error) { cidrsList := ipb.ToCidrList() if len(cidrsList) > 1 { return nil, errors.New("newExternalNode: input ip-block should be of a single CIDR") @@ -141,7 +141,7 @@ func newExternalNode(isPublicInternet bool, ipb *ipblock.IPBlock) (Node, error) } func newExternalNodeForCidr(cidr string) (Node, error) { - cidrIPBlodk, err := ipblock.FromCidr(cidr) + cidrIPBlodk, err := netset.IPBlockFromCidr(cidr) if err != nil { return nil, err } @@ -153,17 +153,17 @@ func newExternalNodeForCidr(cidr string) (Node, error) { }, nil } -func GetExternalNetworkNodes(disjointRefExternalIPBlocks []*ipblock.IPBlock) ([]Node, error) { +func GetExternalNetworkNodes(disjointRefExternalIPBlocks []*netset.IPBlock) ([]Node, error) { res := []Node{} internetIPblocks, allInternetRagnes, err := GetPublicInternetIPblocksList() if err != nil { return nil, err } - disjointRefExternalIPBlocksAll := ipblock.DisjointIPBlocks(internetIPblocks, disjointRefExternalIPBlocks) + disjointRefExternalIPBlocksAll := netset.DisjointIPBlocks(internetIPblocks, disjointRefExternalIPBlocks) for _, ipb := range disjointRefExternalIPBlocksAll { var isPublicInternet bool - if ipb.ContainedIn(allInternetRagnes) { + if ipb.IsSubset(allInternetRagnes) { isPublicInternet = true } else { // currently skip external nodes which are not in public internet ranges @@ -171,7 +171,7 @@ func GetExternalNetworkNodes(disjointRefExternalIPBlocks []*ipblock.IPBlock) ([] } cidrs := ipb.ToCidrList() for _, cidr := range cidrs { - nodeIPBlock, err := ipblock.FromCidr(cidr) + nodeIPBlock, err := netset.IPBlockFromCidr(cidr) if err != nil { return nil, err } diff --git a/pkg/vpcmodel/grouping.go b/pkg/vpcmodel/grouping.go index 413291152..8e5dbde57 100644 --- a/pkg/vpcmodel/grouping.go +++ b/pkg/vpcmodel/grouping.go @@ -12,8 +12,7 @@ import ( "sort" "strings" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" ) @@ -46,8 +45,8 @@ type explainDetails struct { privateSubnetRule PrivateSubnetRule filtersRelevant map[string]bool connEnabled bool - ingressConn *connection.Set - egressConn *connection.Set + ingressConn *netset.TransportSet + egressConn *netset.TransportSet } type groupedCommonProperties struct { @@ -301,7 +300,7 @@ func (g *groupedExternalNodes) SynthesisKind() spec.ResourceType { func (g *groupedExternalNodes) CidrOrAddress() string { isAllInternetRange, err := isEntirePublicInternetRange(*g) if err == nil && isAllInternetRange { - return ipblock.CidrAll + return netset.CidrAll } return g.String() } @@ -662,7 +661,7 @@ func (g *groupedExternalNodes) String() string { return strings.Join(unionBlock.ListToPrint(), commaSeparator) } -func (g *groupedExternalNodes) toIPBlock() *ipblock.IPBlock { +func (g *groupedExternalNodes) toIPBlock() *netset.IPBlock { // 1. Created a list of IPBlocks cidrList := make([]string, len(*g)) for i, n := range *g { @@ -670,10 +669,10 @@ func (g *groupedExternalNodes) toIPBlock() *ipblock.IPBlock { } ipbList, _, err := ipStringsToIPblocks(cidrList) if err != nil { - return ipblock.New() + return netset.NewIPBlock() } // 2. union all IPBlocks in a single one; its intervals will be the cidr blocks or ranges that should be printed, after all possible merges - unionBlock := ipblock.New() + unionBlock := netset.NewIPBlock() for _, ipBlock := range ipbList { unionBlock = unionBlock.Union(ipBlock) } diff --git a/pkg/vpcmodel/groupingGraphical.go b/pkg/vpcmodel/groupingGraphical.go index 16094b502..4f378f67d 100644 --- a/pkg/vpcmodel/groupingGraphical.go +++ b/pkg/vpcmodel/groupingGraphical.go @@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0 package vpcmodel import ( - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" ) // for the graphical (html, drawio, svg) representation. In the graph presentation, each node must have all relevant edges. @@ -30,8 +30,8 @@ func (g *GroupConnLines) consistencyEdgesExternal() { } // gets []*groupedConnLine and returns a map from the string presentation of each endpoint to its ipBlock -func getMapToIps(grouped []*groupedConnLine) map[string]*ipblock.IPBlock { - eeToIPBlock := map[string]*ipblock.IPBlock{} +func getMapToIps(grouped []*groupedConnLine) map[string]*netset.IPBlock { + eeToIPBlock := map[string]*netset.IPBlock{} for _, line := range grouped { addExternalEndpointToMap(line.Src, eeToIPBlock) addExternalEndpointToMap(line.Dst, eeToIPBlock) @@ -52,7 +52,7 @@ func getMapToEPEs(grouped []*groupedConnLine) map[string]EndpointElem { return eeNameToEE } -func addExternalEndpointToMap(ee EndpointElem, endpointsIPBlocks map[string]*ipblock.IPBlock) { +func addExternalEndpointToMap(ee EndpointElem, endpointsIPBlocks map[string]*netset.IPBlock) { if !ee.IsExternal() { return } @@ -63,8 +63,8 @@ func addExternalEndpointToMap(ee EndpointElem, endpointsIPBlocks map[string]*ipb endpointsIPBlocks[ee.Name()] = groupedExternalToIPBlock(ee.(*groupedExternalNodes)) } -func groupedExternalToIPBlock(ee *groupedExternalNodes) *ipblock.IPBlock { - var res = ipblock.New() +func groupedExternalToIPBlock(ee *groupedExternalNodes) *netset.IPBlock { + var res = netset.NewIPBlock() for _, e := range *ee { res = res.Union(e.ipblock) } @@ -73,7 +73,7 @@ func groupedExternalToIPBlock(ee *groupedExternalNodes) *ipblock.IPBlock { // given a map from external endpoints to their IPs returns a map from each endpoint to the endpoints that // it contained (if any) -func getContainedEndpointMap(endpointsIPBlocks map[string]*ipblock.IPBlock, +func getContainedEndpointMap(endpointsIPBlocks map[string]*netset.IPBlock, eeNameToEE map[string]EndpointElem) map[string][]EndpointElem { containedMap := map[string][]EndpointElem{} for containingEP, containingIP := range endpointsIPBlocks { @@ -82,7 +82,7 @@ func getContainedEndpointMap(endpointsIPBlocks map[string]*ipblock.IPBlock, if containedEP == containingEP { continue } - if containedIP.ContainedIn(containingIP) { + if containedIP.IsSubset(containingIP) { containedEPs = append(containedEPs, eeNameToEE[containedEP]) } } diff --git a/pkg/vpcmodel/grouping_test.go b/pkg/vpcmodel/grouping_test.go index 615892cba..cd4b6ebff 100644 --- a/pkg/vpcmodel/grouping_test.go +++ b/pkg/vpcmodel/grouping_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" "github.com/np-guard/vpc-network-config-analyzer/pkg/drawio" @@ -38,8 +38,8 @@ type mockNetIntf struct { func (m *mockNetIntf) CidrOrAddress() string { return m.cidr } -func (m *mockNetIntf) IPBlock() *ipblock.IPBlock { - res, _ := ipblock.FromCidrOrAddress(m.cidr) +func (m *mockNetIntf) IPBlock() *netset.IPBlock { + res, _ := netset.IPBlockFromCidrOrAddress(m.cidr) return res } func (m *mockNetIntf) Address() string { @@ -124,7 +124,7 @@ func (m *mockSubnet) NameForAnalyzerOut(c *VPCConfig) string { func (m *mockSubnet) Nodes() []Node { return m.nodes } -func (m *mockSubnet) AddressRange() *ipblock.IPBlock { +func (m *mockSubnet) AddressRange() *netset.IPBlock { return nil } func (m *mockSubnet) CIDR() string { diff --git a/pkg/vpcmodel/jsonOutput.go b/pkg/vpcmodel/jsonOutput.go index dd0cdc5fd..3726abb85 100644 --- a/pkg/vpcmodel/jsonOutput.go +++ b/pkg/vpcmodel/jsonOutput.go @@ -11,7 +11,7 @@ import ( "errors" "sort" - "github.com/np-guard/models/pkg/connection" + "github.com/np-guard/models/pkg/netset" ) type JSONoutputFormatter struct { @@ -45,21 +45,21 @@ func (j *JSONoutputFormatter) WriteOutput(c1, c2 *VPCConfig, } type connLine struct { - Src EndpointElem `json:"src"` - Dst EndpointElem `json:"dst"` - Conn connection.Details `json:"conn"` - UnidirectionalConn connection.Details `json:"unidirectional_conn,omitempty"` + Src EndpointElem `json:"src"` + Dst EndpointElem `json:"dst"` + Conn netset.Details `json:"conn"` + UnidirectionalConn netset.Details `json:"unidirectional_conn,omitempty"` } type diffLine struct { - SrcChange string `json:"src_change"` - DstChange string `json:"dst_change"` - Src EndpointElem `json:"src"` - Dst EndpointElem `json:"dst"` - Conn1 connection.Details `json:"conn1"` - UnidirectionalConn1 connection.Details `json:"unidirectional_conn1"` - Conn2 connection.Details `json:"conn2"` - UnidirectionalConn2 connection.Details `json:"unidirectional_conn2"` + SrcChange string `json:"src_change"` + DstChange string `json:"dst_change"` + Src EndpointElem `json:"src"` + Dst EndpointElem `json:"dst"` + Conn1 netset.Details `json:"conn1"` + UnidirectionalConn1 netset.Details `json:"unidirectional_conn1"` + Conn2 netset.Details `json:"conn2"` + UnidirectionalConn2 netset.Details `json:"unidirectional_conn2"` } func sortConnLines(connLines []connLine) { @@ -85,10 +85,10 @@ func getConnLines(conn *VPCConnectivity) []connLine { } responsiveAndOther := extConn.tcpRspEnable.Union(extConn.nonTCP) if !extConn.TCPRspDisable.IsEmpty() { - connLines = append(connLines, connLine{Src: src, Dst: dst, Conn: connection.ToJSON(responsiveAndOther), - UnidirectionalConn: connection.ToJSON(extConn.TCPRspDisable)}) + connLines = append(connLines, connLine{Src: src, Dst: dst, Conn: netset.ToJSON(responsiveAndOther), + UnidirectionalConn: netset.ToJSON(extConn.TCPRspDisable)}) } else { - connLines = append(connLines, connLine{Src: src, Dst: dst, Conn: connection.ToJSON(extConn.allConn)}) + connLines = append(connLines, connLine{Src: src, Dst: dst, Conn: netset.ToJSON(extConn.allConn)}) } } } @@ -122,8 +122,8 @@ func getConnLinesForSubnetsConnectivity(conn *VPCsubnetConnectivity) []connLine connLines = append(connLines, connLine{ Src: src, Dst: dst, - Conn: connection.ToJSON(extConns.tcpRspEnable.Union(extConns.nonTCP)), - UnidirectionalConn: connection.ToJSON(extConns.TCPRspDisable), + Conn: netset.ToJSON(extConns.tcpRspEnable.Union(extConns.nonTCP)), + UnidirectionalConn: netset.ToJSON(extConns.TCPRspDisable), }) } } @@ -170,10 +170,10 @@ func getDirectionalDiffLines(connectDiff connectivityDiff) []diffLine { diffDstStr = getDiffDstOther(connDiff.diff) } diffLines = append(diffLines, diffLine{diffSrcStr, diffDstStr, - src, dst, connection.ToJSON(connDiff.conn1.nonTCPAndResponsiveTCPComponent()), - connection.ToJSON(connDiff.conn1.TCPRspDisable), - connection.ToJSON(connDiff.conn2.nonTCPAndResponsiveTCPComponent()), - connection.ToJSON(connDiff.conn2.TCPRspDisable)}) + src, dst, netset.ToJSON(connDiff.conn1.nonTCPAndResponsiveTCPComponent()), + netset.ToJSON(connDiff.conn1.TCPRspDisable), + netset.ToJSON(connDiff.conn2.nonTCPAndResponsiveTCPComponent()), + netset.ToJSON(connDiff.conn2.TCPRspDisable)}) } } diff --git a/pkg/vpcmodel/multiExplainability.go b/pkg/vpcmodel/multiExplainability.go index 27aa17f1f..1f6e8198b 100644 --- a/pkg/vpcmodel/multiExplainability.go +++ b/pkg/vpcmodel/multiExplainability.go @@ -9,7 +9,7 @@ package vpcmodel import ( "fmt" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" ) type explainInputEntry struct { @@ -94,7 +94,7 @@ func (c *VPCConfig) getNodesFromEndpoint(endpoint EndpointElem) ([]Node, error) case LoadBalancer: return n.Nodes(), nil case *groupedExternalNodes: - var externalIP = ipblock.New() + var externalIP = netset.NewIPBlock() for _, e := range *n { externalIP = externalIP.Union(e.ipblock) } diff --git a/pkg/vpcmodel/nodesConnectivity.go b/pkg/vpcmodel/nodesConnectivity.go index a75cb4373..98783cf21 100644 --- a/pkg/vpcmodel/nodesConnectivity.go +++ b/pkg/vpcmodel/nodesConnectivity.go @@ -11,14 +11,15 @@ import ( "sort" "strings" - "github.com/np-guard/models/pkg/connection" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-analyzer/pkg/common" ) // Functions for the computation of VPC connectivity between nodes elements // GetVPCNetworkConnectivity computes VPCConnectivity in few steps // (1) compute AllowedConns (map[Node]*ConnectivityResult) : ingress or egress allowed conns separately -// (2) compute AllowedConnsCombined (map[Node]map[Node]*connection.Set) : allowed conns considering both ingress and egress directions +// (2) compute AllowedConnsCombined (map[Node]map[Node]*netset.TransportSet) : allowed conns considering both ingress and egress directions // (3) compute AllowedConnsCombinedResponsive extension of AllowedConnsCombined to contain accurate responsive info // (4) if lbAbstraction required - abstract each lb separately // (5) if grouping required - compute grouping of connectivity results @@ -89,7 +90,7 @@ func (c *VPCConfig) getPrivateSubnetRule(src, dst Node) PrivateSubnetRule { } // getNonFilterNonRouterRulesConn() return the connectivity of all rules that are not part of the filters and routers. -func (c *VPCConfig) getNonFilterNonRouterRulesConn(src, dst Node, isIngress bool) *connection.Set { +func (c *VPCConfig) getNonFilterNonRouterRulesConn(src, dst Node, isIngress bool) *netset.TransportSet { loadBalancerRule := c.getLoadBalancerRule(src, dst) if loadBalancerRule != nil && loadBalancerRule.Deny(isIngress) { return NoConns() @@ -104,7 +105,7 @@ func (c *VPCConfig) getNonFilterNonRouterRulesConn(src, dst Node, isIngress bool func (c *VPCConfig) getFiltersAllowedConnsBetweenNodesPerDirectionAndLayer( src, dst Node, isIngress bool, - layer string) (*connection.Set, error) { + layer string) (*netset.TransportSet, error) { filter := c.GetFilterTrafficResourceOfKind(layer) if filter == nil { return AllConns(), nil @@ -112,9 +113,9 @@ func (c *VPCConfig) getFiltersAllowedConnsBetweenNodesPerDirectionAndLayer( return filter.AllowedConnectivity(src, dst, isIngress) } -func updatePerLayerRes(res map[string]map[Node]*connection.Set, layer string, node Node, conn *connection.Set) { +func updatePerLayerRes(res map[string]map[Node]*netset.TransportSet, layer string, node Node, conn *netset.TransportSet) { if _, ok := res[layer]; !ok { - res[layer] = map[Node]*connection.Set{} + res[layer] = map[Node]*netset.TransportSet{} } res[layer][node] = conn } @@ -122,12 +123,12 @@ func updatePerLayerRes(res map[string]map[Node]*connection.Set, layer string, no // getAllowedConnsPerDirection returns: (1) map of allowed (ingress or egress) connectivity for capturedNode, considering // all relevant resources (nacl/sg/fip/pgw) , and (2) similar map per separated layers only (nacl/sg) func (c *VPCConfig) getAllowedConnsPerDirection(isIngress bool, capturedNode Node) ( - allLayersRes map[Node]*connection.Set, // result considering all layers - perLayerRes map[string]map[Node]*connection.Set, // result separated per layer + allLayersRes map[Node]*netset.TransportSet, // result considering all layers + perLayerRes map[string]map[Node]*netset.TransportSet, // result separated per layer err error, ) { - perLayerRes = map[string]map[Node]*connection.Set{} - allLayersRes = map[Node]*connection.Set{} + perLayerRes = map[string]map[Node]*netset.TransportSet{} + allLayersRes = map[Node]*netset.TransportSet{} // iterate pairs (capturedNode, peerNode) to analyze their allowed ingress/egress conns for _, peerNode := range c.Nodes { @@ -152,7 +153,7 @@ func (c *VPCConfig) getAllowedConnsPerDirection(isIngress bool, capturedNode Nod } if peerNode.IsInternal() { - var allowedConnsBetweenCapturedAndPeerNode *connection.Set + var allowedConnsBetweenCapturedAndPeerNode *netset.TransportSet if c.IsMultipleVPCsConfig { // in case of cross-vpc connectivity, do need a router (tgw) enabling this connection _, allowedConnsBetweenCapturedAndPeerNode, err = c.getRoutingResource(src, dst) @@ -259,7 +260,7 @@ func (v *VPCConnectivity) computeAllowedResponsiveConnections(c *VPCConfig, dstNode := dst.(Node) // get the allowed *responsive* conn result // check allowed conns per NACL-layer from dst to src (dst->src) (since SG is stateful) - var DstAllowedEgressToSrc, SrcAllowedIngressFromDst *connection.Set + var DstAllowedEgressToSrc, SrcAllowedIngressFromDst *netset.TransportSet // can dst egress to src? DstAllowedEgressToSrc = v.getPerLayerConnectivity(statelessLayerName, dstNode, srcNode, false) // can src ingress from dst? @@ -281,12 +282,12 @@ func (v *VPCConnectivity) computeAllowedResponsiveConnections(c *VPCConfig, } // getPerLayerConnectivity currently used for "NaclLayer" - to compute stateful allowed conns -func (v *VPCConnectivity) getPerLayerConnectivity(layer string, src, dst Node, isIngress bool) *connection.Set { +func (v *VPCConnectivity) getPerLayerConnectivity(layer string, src, dst Node, isIngress bool) *netset.TransportSet { // if the analyzed input node is not internal- assume all conns allowed if (isIngress && !dst.IsInternal()) || (!isIngress && !src.IsInternal()) { - return connection.All() + return netset.AllTransports() } - var result *connection.Set + var result *netset.TransportSet var connMap map[string]*ConnectivityResult if isIngress { connMap = v.AllowedConnsPerLayer[dst] @@ -349,7 +350,7 @@ func (responsiveConnMap GeneralResponsiveConnectivityMap) getCombinedConnsStr(on var connsStr string if onlyBidirectional { bidirectional := extConns.tcpRspEnable.Union(extConns.nonTCP) - connsStr = bidirectional.String() + connsStr = common.LongString(bidirectional) } else { connsStr = extConns.string() } diff --git a/pkg/vpcmodel/responsive_test.go b/pkg/vpcmodel/responsive_test.go index 0f44c0df8..88c4bf9ec 100644 --- a/pkg/vpcmodel/responsive_test.go +++ b/pkg/vpcmodel/responsive_test.go @@ -10,19 +10,19 @@ import ( "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/connection" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" ) type responsiveTest struct { name string - srcToDst *connection.Set - dstToSrc *connection.Set + srcToDst *netset.TransportSet + dstToSrc *netset.TransportSet // expectedTCPResponsiveConn represents the subset from srcToDst which is not related to the // "non-responsive" mark (*) on the srcToDst connection, - expectedTCPResponsiveConn *connection.Set - expectedTCPNonResponsiveConn *connection.Set - expectedAllConn *connection.Set + expectedTCPResponsiveConn *netset.TransportSet + expectedTCPNonResponsiveConn *netset.TransportSet + expectedAllConn *netset.TransportSet } func (tt responsiveTest) runTest(t *testing.T) { @@ -40,34 +40,34 @@ func TestAll(t *testing.T) { srcToDst: newTCPUDPSet(netp.ProtocolStringTCP), // TCP all ports dstToSrc: newTCPUDPSet(netp.ProtocolStringTCP), // TCP all ports expectedTCPResponsiveConn: newTCPUDPSet(netp.ProtocolStringTCP), // TCP all ports - expectedTCPNonResponsiveConn: connection.None(), + expectedTCPNonResponsiveConn: netset.NoTransports(), expectedAllConn: newTCPUDPSet(netp.ProtocolStringTCP), }, { name: "first_all_cons_second_tcp_with_ports", - srcToDst: connection.All(), // all connections - dstToSrc: newTCPConn(80, 80, connection.MinPort, connection.MaxPort), // TCP , src-ports: 80, dst-ports: all + srcToDst: netset.AllTransports(), // all connections + dstToSrc: newTCPConn(80, 80, netp.MinPort, netp.MaxPort), // TCP , src-ports: 80, dst-ports: all // TCP src-ports: all, dst-port: 80 - expectedTCPResponsiveConn: newTCPConn(connection.MinPort, connection.MaxPort, 80, 80), - expectedTCPNonResponsiveConn: allTCPconn().Subtract(newTCPConn(connection.MinPort, - connection.MaxPort, 80, 80)), - expectedAllConn: connection.All(), + expectedTCPResponsiveConn: newTCPConn(netp.MinPort, netp.MaxPort, 80, 80), + expectedTCPNonResponsiveConn: allTCPconn().Subtract(newTCPConn(netp.MinPort, + netp.MaxPort, 80, 80)), + expectedAllConn: netset.AllTransports(), }, { name: "first_all_conns_second_no_tcp", - srcToDst: connection.All(), // all connections - dstToSrc: newICMPconn(), // ICMP - expectedTCPResponsiveConn: connection.None(), + srcToDst: netset.AllTransports(), // all connections + dstToSrc: newICMPconn(), // ICMP + expectedTCPResponsiveConn: netset.NoTransports(), expectedTCPNonResponsiveConn: allTCPconn(), - expectedAllConn: connection.All(), + expectedAllConn: netset.AllTransports(), }, { name: "tcp_with_ports_both_directions_exact_match", srcToDst: newTCPConn(80, 80, 443, 443), dstToSrc: newTCPConn(443, 443, 80, 80), expectedTCPResponsiveConn: newTCPConn(80, 80, 443, 443), - expectedTCPNonResponsiveConn: connection.None(), + expectedTCPNonResponsiveConn: netset.NoTransports(), expectedAllConn: newTCPConn(80, 80, 443, 443), }, { @@ -82,7 +82,7 @@ func TestAll(t *testing.T) { name: "tcp_with_ports_both_directions_no_match", srcToDst: newTCPConn(80, 100, 443, 443), dstToSrc: newTCPConn(80, 80, 80, 80), - expectedTCPResponsiveConn: connection.None(), + expectedTCPResponsiveConn: netset.NoTransports(), expectedTCPNonResponsiveConn: newTCPConn(80, 100, 443, 443), expectedAllConn: newTCPConn(80, 100, 443, 443), }, @@ -90,7 +90,7 @@ func TestAll(t *testing.T) { name: "udp_and_tcp_with_ports_both_directions_no_match", srcToDst: newTCPConn(80, 100, 443, 443).Union(newUDPConn(80, 100, 443, 443)), dstToSrc: newTCPConn(80, 80, 80, 80).Union(newUDPConn(80, 80, 80, 80)), - expectedTCPResponsiveConn: connection.None(), + expectedTCPResponsiveConn: netset.NoTransports(), expectedTCPNonResponsiveConn: newTCPConn(80, 100, 443, 443), expectedAllConn: newTCPConn(80, 100, 443, 443).Union(newUDPConn(80, 100, 443, 443)), }, @@ -98,25 +98,25 @@ func TestAll(t *testing.T) { name: "no_tcp_in_first_direction", srcToDst: newUDPConn(70, 100, 443, 443), dstToSrc: newTCPConn(70, 80, 80, 80).Union(newUDPConn(70, 80, 80, 80)), - expectedTCPResponsiveConn: connection.None(), - expectedTCPNonResponsiveConn: connection.None(), + expectedTCPResponsiveConn: netset.NoTransports(), + expectedTCPNonResponsiveConn: netset.NoTransports(), expectedAllConn: newUDPConn(70, 100, 443, 443), }, { name: "empty_conn_in_first_direction", - srcToDst: connection.None(), + srcToDst: netset.NoTransports(), dstToSrc: newTCPConn(80, 80, 80, 80).Union(newTCPUDPSet(netp.ProtocolStringUDP)), - expectedTCPResponsiveConn: connection.None(), - expectedTCPNonResponsiveConn: connection.None(), - expectedAllConn: connection.None(), + expectedTCPResponsiveConn: netset.NoTransports(), + expectedTCPNonResponsiveConn: netset.NoTransports(), + expectedAllConn: netset.NoTransports(), }, { name: "only_udp_icmp_in_first_direction_and_empty_second_direction", srcToDst: newTCPUDPSet(netp.ProtocolStringUDP).Union(newICMPconn()), - dstToSrc: connection.None(), + dstToSrc: netset.NoTransports(), // responsive analysis does not apply to udp/icmp, thus TCP responsive component is empty - expectedTCPResponsiveConn: connection.None(), - expectedTCPNonResponsiveConn: connection.None(), + expectedTCPResponsiveConn: netset.NoTransports(), + expectedTCPNonResponsiveConn: netset.NoTransports(), expectedAllConn: newTCPUDPSet(netp.ProtocolStringUDP).Union(newICMPconn()), }, } diff --git a/pkg/vpcmodel/routing_paths.go b/pkg/vpcmodel/routing_paths.go index 9404c35b7..5dc9765e6 100644 --- a/pkg/vpcmodel/routing_paths.go +++ b/pkg/vpcmodel/routing_paths.go @@ -11,7 +11,7 @@ import ( "slices" "strings" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" ) // routing_paths: this file contains types for representing routing paths and their endpoints @@ -24,15 +24,15 @@ type Path []*Endpoint // Endpoint captures possible types for elements within routing paths: concrete vpc resource, IP Address, and nextHopEntry type Endpoint struct { VpcResource VPCResourceIntf - IPBlock *ipblock.IPBlock + IPBlock *netset.IPBlock NextHop *NextHopEntry TargetVPC string // if the VpcResource is tgw, the targetVPC is also assigned } // NextHopEntry captures an endpoint within a routing path, which redirects traffic to its nextHop instead of the original dest type NextHopEntry struct { - NextHop *ipblock.IPBlock // the next hop address - OrigDest *ipblock.IPBlock // the original destination + NextHop *netset.IPBlock // the next hop address + OrigDest *netset.IPBlock // the original destination // rt *routingTable // the routing table from which this next hop was determined } @@ -59,7 +59,7 @@ func PathFromResource(resource VPCResourceIntf) Path { return Path{{VpcResource: resource}} } -func PathFromIPBlock(ipb *ipblock.IPBlock) Path { +func PathFromIPBlock(ipb *netset.IPBlock) Path { return Path{{IPBlock: ipb}} } diff --git a/pkg/vpcmodel/routing_paths_test.go b/pkg/vpcmodel/routing_paths_test.go index d25da1092..378421156 100644 --- a/pkg/vpcmodel/routing_paths_test.go +++ b/pkg/vpcmodel/routing_paths_test.go @@ -11,15 +11,15 @@ import ( "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" ) func newNetIntForPathTest() *mockNetIntf { return &mockNetIntf{name: "vsi1[10.10.2.6]", cidr: "10.10.2.6"} } -func newIPBlock(inputCIDROrAddress string) *ipblock.IPBlock { - res, _ := ipblock.FromCidrOrAddress(inputCIDROrAddress) +func newIPBlock(inputCIDROrAddress string) *netset.IPBlock { + res, _ := netset.IPBlockFromCidrOrAddress(inputCIDROrAddress) return res } diff --git a/pkg/vpcmodel/semanticDiff.go b/pkg/vpcmodel/semanticDiff.go index fadf31db6..d1be682f3 100644 --- a/pkg/vpcmodel/semanticDiff.go +++ b/pkg/vpcmodel/semanticDiff.go @@ -11,8 +11,7 @@ import ( "sort" "strings" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" ) type DiffType = int @@ -305,7 +304,7 @@ func (diffCfgs *diffBetweenCfgs) hasStatelessConns() bool { // prints connection for the above string(..) where the connection could be empty func connStr(extConn *detailedConn) string { if extConn == nil { - return connection.NoConnections + return netset.NoConnections } return extConn.string() } @@ -353,7 +352,7 @@ func (confConnectivity *configConnectivity) getConnectivityWithSameIPBlocks(othe if err != nil { return nil, nil, err } - disjointIPblocks := ipblock.DisjointIPBlocks(connectivityIPBlist, otherIPBlist) + disjointIPblocks := netset.DisjointIPBlocks(connectivityIPBlist, otherIPBlist) // 2. copy configs and generates Nodes[] as per disjointIPblocks err = confConnectivity.config.refineConfigExternalNodes(disjointIPblocks) if err != nil { @@ -381,7 +380,7 @@ func (confConnectivity *configConnectivity) getConnectivityWithSameIPBlocks(othe } func (responsiveConnMap *GeneralResponsiveConnectivityMap) alignConnectionsGivenIPBlists(config *VPCConfig, - disjointIPblocks []*ipblock.IPBlock) ( + disjointIPblocks []*netset.IPBlock) ( alignedConnectivity GeneralResponsiveConnectivityMap, err error) { alignedConnectivitySrc, err := responsiveConnMap.actualAlignSrcOrDstGivenIPBlists(config, disjointIPblocks, true) if err != nil { @@ -393,7 +392,7 @@ func (responsiveConnMap *GeneralResponsiveConnectivityMap) alignConnectionsGiven // aligned config: copies from old config everything but external nodes, // external nodes are resized by disjointIPblocks -func (c *VPCConfig) refineConfigExternalNodes(disjointIPblocks []*ipblock.IPBlock) error { +func (c *VPCConfig) refineConfigExternalNodes(disjointIPblocks []*netset.IPBlock) error { // copy config var err error // nodes - external addresses - are resized @@ -401,7 +400,7 @@ func (c *VPCConfig) refineConfigExternalNodes(disjointIPblocks []*ipblock.IPBloc return err } -func resizeNodes(oldNodes []Node, disjointIPblocks []*ipblock.IPBlock) (newNodes []Node, err error) { +func resizeNodes(oldNodes []Node, disjointIPblocks []*netset.IPBlock) (newNodes []Node, err error) { newNodes = []Node{} // range over old nodes and inside range over disjoint blocks // if a disjoint block is contained in an old oldNode - create external oldNode and add it @@ -413,7 +412,7 @@ func resizeNodes(oldNodes []Node, disjointIPblocks []*ipblock.IPBlock) (newNodes } disjointContained := false for _, disjointIPBlock := range disjointIPblocks { - if disjointIPBlock.ContainedIn(oldNode.IPBlock()) { + if disjointIPBlock.IsSubset(oldNode.IPBlock()) { disjointContained = true for _, thisCidr := range disjointIPBlock.ToCidrList() { newNode, err := newExternalNodeForCidr(thisCidr) @@ -432,7 +431,7 @@ func resizeNodes(oldNodes []Node, disjointIPblocks []*ipblock.IPBlock) (newNodes } func (responsiveConnMap *GeneralResponsiveConnectivityMap) actualAlignSrcOrDstGivenIPBlists(config *VPCConfig, - disjointIPblocks []*ipblock.IPBlock, resizeSrc bool) ( + disjointIPblocks []*netset.IPBlock, resizeSrc bool) ( alignedConnectivity GeneralResponsiveConnectivityMap, err error) { // goes over all sources of connections in connectivity // if src is external then for each IPBlock in disjointIPblocks copies dsts and connection type @@ -454,7 +453,7 @@ func (responsiveConnMap *GeneralResponsiveConnectivityMap) actualAlignSrcOrDstGi } // the resizing element is external - go over all ipBlock and allocates the connection // if the ipBlock is contained in the original src/dst - var origIPBlock *ipblock.IPBlock + var origIPBlock *netset.IPBlock if resizeSrc { if node, ok := src.(Node); ok { origIPBlock = node.IPBlock() @@ -477,12 +476,12 @@ func (responsiveConnMap *GeneralResponsiveConnectivityMap) actualAlignSrcOrDstGi return alignedConnectivity, err } -func addIPBlockToConnectivityMap(c *VPCConfig, disjointIPblocks []*ipblock.IPBlock, - origIPBlock *ipblock.IPBlock, alignedConnectivity map[VPCResourceIntf]map[VPCResourceIntf]*detailedConn, +func addIPBlockToConnectivityMap(c *VPCConfig, disjointIPblocks []*netset.IPBlock, + origIPBlock *netset.IPBlock, alignedConnectivity map[VPCResourceIntf]map[VPCResourceIntf]*detailedConn, src, dst VPCResourceIntf, conns *detailedConn, resizeSrc bool) error { for _, ipBlock := range disjointIPblocks { // get ipBlock of resized index (src/dst) - if !ipBlock.ContainedIn(origIPBlock) { // ipBlock not relevant here + if !ipBlock.IsSubset(origIPBlock) { // ipBlock not relevant here continue } // origIPBlock has either several new disjointIPblocks contained in it or is contained in itself @@ -519,7 +518,7 @@ func findNodeWithCidr(configNodes []Node, cidr string) Node { } // get a list of IPBlocks of the src and dst of the connections -func (responsiveConnMap GeneralResponsiveConnectivityMap) getIPBlocksList() (ipbList []*ipblock.IPBlock, +func (responsiveConnMap GeneralResponsiveConnectivityMap) getIPBlocksList() (ipbList []*netset.IPBlock, myErr error) { for src, endpointConns := range responsiveConnMap { for dst, connsWithStateful := range endpointConns { @@ -647,7 +646,7 @@ func (responsiveConnMap GeneralResponsiveConnectivityMap) getIPBlocksList() (ipb //// todo: instead of adding functionality to grouping, I plan to have more generic connectivity items that will be grouped //// encode the cfgsDiff into this generic item as well as the other entities we are grouping //// and then decode in the printing -//// the idea is to use instead of *connection.Set in the grouped entity a string which will encode the connection +//// the idea is to use instead of *netset.TransportSet in the grouped entity a string which will encode the connection //// and also the diff where relevant //// this will requires some rewriting in the existing grouping functionality and the way it provides //// service to subnetsConnectivity and nodesConnectivity diff --git a/pkg/vpcmodel/semanticDiff_test.go b/pkg/vpcmodel/semanticDiff_test.go index 354bdda1c..07c43bc2c 100644 --- a/pkg/vpcmodel/semanticDiff_test.go +++ b/pkg/vpcmodel/semanticDiff_test.go @@ -14,8 +14,8 @@ import ( "github.com/stretchr/testify/require" - "github.com/np-guard/models/pkg/connection" "github.com/np-guard/models/pkg/netp" + "github.com/np-guard/models/pkg/netset" ) // simple diff: @@ -65,8 +65,8 @@ func configSimpleSubnetDiff() (subnetConfigConn1, subnetConfigConn2 *configConne &mockSubnet{nil, "10.4.20.0/22", "subnet4", []Node{cfg2.Nodes[2]}}, &mockSubnet{nil, "11.4.20.0/22", "subnet5", []Node{cfg2.Nodes[3]}}) - connResponsiveAll := detailedConnForResponsive(connection.All()) - connectionTCP := connection.TCPorUDPConnection(netp.ProtocolStringTCP, 10, 100, 443, 443) + connResponsiveAll := detailedConnForResponsive(netset.AllTransports()) + connectionTCP := netset.NewTCPorUDPTransport(netp.ProtocolStringTCP, 10, 100, 443, 443) connResponsiveTCP := detailedConnForResponsive(connectionTCP) subnetConnMap1 := &VPCsubnetConnectivity{AllowedConnsCombinedResponsive: GeneralResponsiveConnectivityMap{}} subnetConnMap1.AllowedConnsCombinedResponsive.updateAllowedResponsiveConnsMap(cfg1.Subnets[0], cfg1.Subnets[1], connResponsiveAll) @@ -175,7 +175,7 @@ func configSimpleIPAndSubnetDiff() (subnetConfigConn1, subnetConfigConn2 *config // and are comparable // and are comparable // and are comparable - connResponsive := detailedConnForResponsive(connection.All()) + connResponsive := detailedConnForResponsive(netset.AllTransports()) subnetConnMap1 := &VPCsubnetConnectivity{AllowedConnsCombinedResponsive: GeneralResponsiveConnectivityMap{}} subnetConnMap1.AllowedConnsCombinedResponsive.updateAllowedResponsiveConnsMap(cfg1.Nodes[0], cfg1.Subnets[0], connResponsive) subnetConnMap1.AllowedConnsCombinedResponsive.updateAllowedResponsiveConnsMap(cfg1.Nodes[0], cfg1.Subnets[1], connResponsive) @@ -188,7 +188,7 @@ func configSimpleIPAndSubnetDiff() (subnetConfigConn1, subnetConfigConn2 *config subnetConnMap2.AllowedConnsCombinedResponsive.updateAllowedResponsiveConnsMap(cfg2.Nodes[0], cfg2.Subnets[1], connResponsive) subnetConnMap2.AllowedConnsCombinedResponsive.updateAllowedResponsiveConnsMap(cfg2.Nodes[1], cfg2.Subnets[1], connResponsive) subnetConnMap2.AllowedConnsCombinedResponsive.updateAllowedResponsiveConnsMap(cfg2.Subnets[1], cfg2.Nodes[0], connResponsive) - connectionTCP := connection.TCPorUDPConnection(netp.ProtocolStringTCP, 0, 1000, 0, 443) + connectionTCP := netset.NewTCPorUDPTransport(netp.ProtocolStringTCP, 0, 1000, 0, 443) connTCP := detailedConnForResponsive(connectionTCP) subnetConnMap2.AllowedConnsCombinedResponsive.updateAllowedResponsiveConnsMap(cfg2.Subnets[1], cfg2.Nodes[2], connTCP) @@ -292,8 +292,8 @@ func configSimpleVsisDiff() (configConn1, configConn2 *configConnectivity) { cfg2.Subnets = append(cfg2.Subnets, &mockSubnet{nil, "10.0.20.0/22", "subnet0", []Node{cfg2.Nodes[0], cfg2.Nodes[1], cfg2.Nodes[2], cfg2.Nodes[3]}}) - connAll := detailedConnForResponsive(connection.All()) - connectionTCP := connection.TCPorUDPConnection(netp.ProtocolStringTCP, 10, 100, 443, 443) + connAll := detailedConnForResponsive(netset.AllTransports()) + connectionTCP := netset.NewTCPorUDPTransport(netp.ProtocolStringTCP, 10, 100, 443, 443) connTCP := detailedConnForResponsive(connectionTCP) cfg1Conn := &VPCConnectivity{AllowedConnsCombinedResponsive: GeneralResponsiveConnectivityMap{}} cfg1Conn.AllowedConnsCombinedResponsive.updateAllowedResponsiveConnsMap(cfg1.Nodes[0], cfg1.Nodes[1], connAll) diff --git a/pkg/vpcmodel/subnetsConnectivity.go b/pkg/vpcmodel/subnetsConnectivity.go index 0a420e9ad..777cc840b 100644 --- a/pkg/vpcmodel/subnetsConnectivity.go +++ b/pkg/vpcmodel/subnetsConnectivity.go @@ -10,8 +10,8 @@ import ( "errors" "fmt" - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" + "github.com/np-guard/vpc-network-config-analyzer/pkg/common" ) // VPCsubnetConnectivity captures allowed connectivity for subnets, considering nacl and pgw resources @@ -43,8 +43,8 @@ const ( errUnexpectedTypePeerNode = "unexpected type for peerNode in computeAllowedConnsCombined" ) -func subnetConnLine(subnet string, conn *connection.Set) string { - return fmt.Sprintf("%s : %s\n", subnet, conn.String()) +func subnetConnLine(subnet string, conn *netset.TransportSet) string { + return fmt.Sprintf("%s : %s\n", subnet, common.LongString(conn)) } func (c *ConfigBasedConnectivityResults) string(config *VPCConfig) string { @@ -71,16 +71,16 @@ func (v *VPCsubnetConnectivity) printAllowedConns(c *VPCConfig) { } } -func (c *VPCConfig) ipblockToNamedResourcesInConfig(ipb *ipblock.IPBlock, excludeExternalNodes bool) ([]VPCResourceIntf, error) { +func (c *VPCConfig) ipblockToNamedResourcesInConfig(ipb *netset.IPBlock, excludeExternalNodes bool) ([]VPCResourceIntf, error) { res := []VPCResourceIntf{} // consider subnets for _, subnet := range c.Subnets { - var subnetCidrIPB *ipblock.IPBlock + var subnetCidrIPB *netset.IPBlock if subnetCidrIPB = subnet.AddressRange(); subnetCidrIPB == nil { return nil, errors.New("missing AddressRange for subnet") } - if subnetCidrIPB.ContainedIn(ipb) { + if subnetCidrIPB.IsSubset(ipb) { res = append(res, subnet) } else if subnetCidrIPB.Overlap(ipb) { // the ACL splits connectivity to part of that subnet, @@ -100,7 +100,7 @@ func (c *VPCConfig) ipblockToNamedResourcesInConfig(ipb *ipblock.IPBlock, exclud continue } nodeCidrIPB := exn.IPBlock() - if nodeCidrIPB.ContainedIn(ipb) { + if nodeCidrIPB.IsSubset(ipb) { res = append(res, exn) } } @@ -237,9 +237,9 @@ func (c *VPCConfig) GetSubnetsConnectivity(includePGW bool, groupingType int) (* // updateSubnetsConnectivityByTransitGateway checks if subnets pair (src,dst) cross-vpc connection is enabled by tgw, // and if yes - returns the original computed combinedConns, else returns no-conns object func updateSubnetsConnectivityByTransitGateway(src, dst VPCResourceIntf, - combinedConns *connection.Set, + combinedConns *netset.TransportSet, c *VPCConfig) ( - *connection.Set, error) { + *netset.TransportSet, error) { // assuming a single router representing the tgw for a "MultipleVPCsConfig" if len(c.RoutingResources) != 1 { return nil, fmt.Errorf("unexpected number of RoutingResources for MultipleVPCsConfig, expecting only TGW") @@ -268,7 +268,7 @@ func (v *VPCsubnetConnectivity) computeAllowedConnsCombined() (GeneralConnectivi if !considerPair { continue } - var combinedConns *connection.Set + var combinedConns *netset.TransportSet // peerNode kind is expected to be Subnet or External peerNodeObj := v.VPCConfig.UIDToResource[peerNode.UID()] switch concPeerNode := peerNodeObj.(type) { @@ -329,7 +329,7 @@ func (v *VPCsubnetConnectivity) computeResponsiveConnections(allowedConnsCombine continue } dstObj := v.VPCConfig.UIDToResource[dst.UID()] - var otherDirectionConn *connection.Set + var otherDirectionConn *netset.TransportSet switch dstObj.(type) { case NodeSet: otherDirectionConn = allowedConnsCombined[dst][src] diff --git a/pkg/vpcmodel/synthesisOutput.go b/pkg/vpcmodel/synthesisOutput.go index 3144e0ab2..f12163883 100644 --- a/pkg/vpcmodel/synthesisOutput.go +++ b/pkg/vpcmodel/synthesisOutput.go @@ -12,8 +12,9 @@ import ( "fmt" "sort" - "github.com/np-guard/models/pkg/connection" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/models/pkg/spec" + common "github.com/np-guard/vpc-network-config-analyzer/pkg/common" ) type SynthesisOutputFormatter struct { @@ -95,7 +96,7 @@ func getSynthesisSpec(groupedLines []*groupedConnLine, grouping bool) *spec.Spec connLines = append(connLines, spec.SpecRequiredConnectionsElem{ Src: spec.Resource{Name: srcName, Type: srcType}, Dst: spec.Resource{Name: dstName, Type: dstType}, - AllowedProtocols: sortProtocolList(spec.ProtocolList(connection.ToJSON(groupedLine.CommonProperties.Conn.allConn))), + AllowedProtocols: sortProtocolList(spec.ProtocolList(netset.ToJSON(groupedLine.CommonProperties.Conn.allConn))), Bidirectional: bidirectional}) } s.Externals = externals @@ -112,11 +113,11 @@ func getBidirectionalMapKeyByConnLine(groupedLine *groupedConnLine, flip bool) s if flip { return getBidirectionalMapKeyByNames(groupedLine.Dst.SynthesisResourceName(), groupedLine.Src.SynthesisResourceName(), - groupedLine.CommonProperties.Conn.allConn.String()) + common.LongString(groupedLine.CommonProperties.Conn.allConn)) } return getBidirectionalMapKeyByNames(groupedLine.Src.SynthesisResourceName(), groupedLine.Dst.SynthesisResourceName(), - groupedLine.CommonProperties.Conn.allConn.String()) + common.LongString(groupedLine.CommonProperties.Conn.allConn)) } // Returns a map from string(src+dst+conn) to whether the connection is bidirectional. diff --git a/pkg/vpcmodel/unifyGrouping.go b/pkg/vpcmodel/unifyGrouping.go index 253c3dcb8..2b808b09d 100644 --- a/pkg/vpcmodel/unifyGrouping.go +++ b/pkg/vpcmodel/unifyGrouping.go @@ -9,7 +9,7 @@ package vpcmodel import ( "fmt" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" "github.com/np-guard/vpc-network-config-analyzer/pkg/common" ) @@ -50,7 +50,7 @@ func unifyMultiVPC(configs *MultipleVPCConfigs, nodesConn map[string]*VPCConnect configs.publicNetworkNode = cache.getAndSetGroupedExternalFromCache(getPublicNetworkNode()) } func getPublicNetworkNode() *groupedExternalNodes { - ns, _ := GetExternalNetworkNodes([]*ipblock.IPBlock{ipblock.GetCidrAll()}) + ns, _ := GetExternalNetworkNodes([]*netset.IPBlock{netset.GetCidrAll()}) group := groupedExternalNodes(make([]*ExternalNetwork, len(ns))) for i := range group { group[i] = ns[i].(*ExternalNetwork) diff --git a/pkg/vpcmodel/utils.go b/pkg/vpcmodel/utils.go index b6f708fd4..2dee82c69 100644 --- a/pkg/vpcmodel/utils.go +++ b/pkg/vpcmodel/utils.go @@ -7,15 +7,15 @@ SPDX-License-Identifier: Apache-2.0 package vpcmodel import ( - "github.com/np-guard/models/pkg/connection" + "github.com/np-guard/models/pkg/netset" ) -func AllConns() *connection.Set { - return connection.All() +func AllConns() *netset.TransportSet { + return netset.AllTransports() } -func NoConns() *connection.Set { - return connection.None() +func NoConns() *netset.TransportSet { + return netset.NoTransports() } func HasNode(listNodes []Node, node Node) bool { diff --git a/pkg/vpcmodel/vpcConfig.go b/pkg/vpcmodel/vpcConfig.go index 73221f87d..2e276b6f4 100644 --- a/pkg/vpcmodel/vpcConfig.go +++ b/pkg/vpcmodel/vpcConfig.go @@ -11,9 +11,7 @@ import ( "errors" - "github.com/np-guard/models/pkg/connection" - - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" ) // VPCConfig captures the configured resources for a VPC @@ -94,7 +92,7 @@ func (c *VPCConfig) shouldConsiderPairForConnectivity(r1, r2 VPCResourceIntf) (b // may refer to external routing or to routing between vpcs // node is associated with either a pgw or a fip for external router; // if the relevant network interface has both the parser will keep only the fip. -func (c *VPCConfig) getRoutingResource(src, dst Node) (RoutingResource, *connection.Set, error) { +func (c *VPCConfig) getRoutingResource(src, dst Node) (RoutingResource, *netset.TransportSet, error) { for _, router := range c.RoutingResources { routerConnRes, err := router.AllowedConnectivity(src, dst) if err != nil { @@ -115,9 +113,9 @@ func (c *VPCConfig) getRoutingResource(src, dst Node) (RoutingResource, *connect // GetNodesWithinInternalAddress gets input IPBlock // and returns the list of all internal nodes (should be VSI) within address -func (c *VPCConfig) GetNodesWithinInternalAddress(inputIPBlock *ipblock.IPBlock) (networkInterfaceNodes []Node) { +func (c *VPCConfig) GetNodesWithinInternalAddress(inputIPBlock *netset.IPBlock) (networkInterfaceNodes []Node) { for _, node := range c.Nodes { - if node.IsInternal() && node.IPBlock().ContainedIn(inputIPBlock) { + if node.IsInternal() && node.IPBlock().IsSubset(inputIPBlock) { networkInterfaceNodes = append(networkInterfaceNodes, node) } } diff --git a/pkg/vpcmodel/vpcConnectivity.go b/pkg/vpcmodel/vpcConnectivity.go index 368060df6..1bd7e6100 100644 --- a/pkg/vpcmodel/vpcConnectivity.go +++ b/pkg/vpcmodel/vpcConnectivity.go @@ -7,8 +7,7 @@ SPDX-License-Identifier: Apache-2.0 package vpcmodel import ( - "github.com/np-guard/models/pkg/connection" - "github.com/np-guard/models/pkg/ipblock" + "github.com/np-guard/models/pkg/netset" ) // VPCConnectivity holds detailed representation of allowed connectivity considering all resources in a vpc config1 instance @@ -34,11 +33,11 @@ type VPCConnectivity struct { // The ConnectivityResult holds the allowed ingress and egress connections (to/from the associated node) // with other Node objects and the connection attributes for each such node type ConnectivityResult struct { - IngressAllowedConns map[Node]*connection.Set - EgressAllowedConns map[Node]*connection.Set + IngressAllowedConns map[Node]*netset.TransportSet + EgressAllowedConns map[Node]*netset.TransportSet } -func (cr *ConnectivityResult) ingressOrEgressAllowedConns(isIngress bool) map[Node]*connection.Set { +func (cr *ConnectivityResult) ingressOrEgressAllowedConns(isIngress bool) map[Node]*netset.TransportSet { if isIngress { return cr.IngressAllowedConns } @@ -49,20 +48,20 @@ func (cr *ConnectivityResult) ingressOrEgressAllowedConns(isIngress bool) map[No // It is associated with a subnet when analyzing connectivity of subnets based on NACL resources // (see func (nl *NaclLayer) ConnectivityMap() ) type IPbasedConnectivityResult struct { - IngressAllowedConns map[*ipblock.IPBlock]*connection.Set - EgressAllowedConns map[*ipblock.IPBlock]*connection.Set + IngressAllowedConns map[*netset.IPBlock]*netset.TransportSet + EgressAllowedConns map[*netset.IPBlock]*netset.TransportSet } // ConfigBasedConnectivityResults is used to capture allowed connectivity to/from elements in the vpc config1 (subnets / external ip-blocks) // It is associated with a subnet when analyzing connectivity of subnets based on NACL resources type ConfigBasedConnectivityResults struct { - IngressAllowedConns map[VPCResourceIntf]*connection.Set - EgressAllowedConns map[VPCResourceIntf]*connection.Set + IngressAllowedConns map[VPCResourceIntf]*netset.TransportSet + EgressAllowedConns map[VPCResourceIntf]*netset.TransportSet } func NewConfigBasedConnectivityResults() *ConfigBasedConnectivityResults { return &ConfigBasedConnectivityResults{ - IngressAllowedConns: map[VPCResourceIntf]*connection.Set{}, - EgressAllowedConns: map[VPCResourceIntf]*connection.Set{}, + IngressAllowedConns: map[VPCResourceIntf]*netset.TransportSet{}, + EgressAllowedConns: map[VPCResourceIntf]*netset.TransportSet{}, } }