diff --git a/go.mod b/go.mod index 368034a..bcdcdcc 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,10 @@ require ( github.com/onsi/gomega v1.27.8 ) +require github.com/jmespath/go-jmespath v0.4.0 // indirect + require ( + github.com/aws/aws-sdk-go v1.45.26 github.com/go-logr/logr v1.2.4 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/golang/glog v1.0.0 // indirect @@ -17,7 +20,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/openshift-online/ocm-sdk-go v0.1.362 // indirect + github.com/openshift-online/ocm-sdk-go v0.1.370 // indirect github.com/stretchr/testify v1.7.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/sys v0.9.0 // indirect diff --git a/go.sum b/go.sum index 2298d9f..c43f7a9 100644 --- a/go.sum +++ b/go.sum @@ -39,6 +39,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/aws/aws-sdk-go v1.45.26 h1:PJ2NJNY5N/yeobLYe1Y+xLdavBi67ZI8gvph6ftwVCg= +github.com/aws/aws-sdk-go v1.45.26/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -192,6 +194,9 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -251,6 +256,9 @@ github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= github.com/openshift-online/ocm-sdk-go v0.1.362 h1:MoaSMCSzcr8nSK9DBqKmZ9c5e4Cp8Q0KAWnB9F2TTJg= github.com/openshift-online/ocm-sdk-go v0.1.362/go.mod h1:KYOw8kAKAHyPrJcQoVR82CneQ4ofC02Na4cXXaTq4Nw= +github.com/openshift-online/ocm-sdk-go v0.1.370/go.mod h1:KYOw8kAKAHyPrJcQoVR82CneQ4ofC02Na4cXXaTq4Nw= +github.com/openshift/rosa v1.2.28 h1:ZSCPYkIXgvg6npvCZxqzjWqgx4F7NV08r6m30P8jnBc= +github.com/openshift/rosa v1.2.28/go.mod h1:Jwc02gMk9ILBvWXmNBsB+VzKR0kro4NdsTwTpuICBwM= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -300,6 +308,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -361,6 +370,7 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -402,6 +412,8 @@ golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -421,6 +433,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -474,11 +487,15 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -487,6 +504,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -539,6 +557,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -636,6 +655,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/aws/validations/iam_helpers.go b/pkg/aws/validations/iam_helpers.go new file mode 100644 index 0000000..c20c19d --- /dev/null +++ b/pkg/aws/validations/iam_helpers.go @@ -0,0 +1,69 @@ +package validations + +import ( + "fmt" + "github.com/aws/aws-sdk-go/service/iam" + "github.com/aws/aws-sdk-go/aws" + semver "github.com/hashicorp/go-version" + "github.com/openshift-online/ocm-common/pkg" +) + +func GetRoleName(prefix string, role string) string { + name := fmt.Sprintf("%s-%s-Role", prefix, role) + if len(name) > pkg.MaxByteSize { + name = name[0:pkg.MaxByteSize] + } + return name +} + +func IsManagedRole(roleTags []*iam.Tag) bool { + for _, tag := range roleTags { + if aws.StringValue(tag.Key) == ManagedPolicies && aws.StringValue(tag.Value) == "true" { + return true + } + } + + return false +} + +func HasCompatibleVersionTags(iamTags []*iam.Tag, version string) (bool, error) { + if len(iamTags) == 0 { + return false, nil + } + + for _, tag := range iamTags { + if aws.StringValue(tag.Key) == OpenShiftVersion { + if version == aws.StringValue(tag.Value) { + return true, nil + } + + return compareVersions(version, aws.StringValue(tag.Value)) + } + } + + return false, nil +} + +func compareVersions(wantedVersion, currentVersion string) (bool, error) { + wantedSemver, err := semver.NewVersion(wantedVersion) + if err != nil { + return false, err + } + + currentSemver, err := semver.NewVersion(currentVersion) + if err != nil { + return false, err + } + + return currentSemver.GreaterThanOrEqual(wantedSemver), nil +} + +func IamResourceHasTag(iamTags []*iam.Tag, tagKey string, tagValue string) bool { + for _, tag := range iamTags { + if aws.StringValue(tag.Key) == tagKey && aws.StringValue(tag.Value) == tagValue { + return true + } + } + + return false +} diff --git a/pkg/aws/validations/iam_helpers_test.go b/pkg/aws/validations/iam_helpers_test.go new file mode 100644 index 0000000..7001b12 --- /dev/null +++ b/pkg/aws/validations/iam_helpers_test.go @@ -0,0 +1,144 @@ +package validations + +import ( + "fmt" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iam" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("AWS IAM Functions", func() { + Describe("GetRoleName", func() { + It("should generate a role name with the given prefix and role name", func() { + prefix := "myPrefix" + roleName := "myRole" + expectedName := fmt.Sprintf("%s-%s-Role", prefix, roleName) + + name := GetRoleName(prefix, roleName) + + Expect(name).To(Equal(expectedName)) + }) + + It("should truncate the generated name if it exceeds 64 characters", func() { + prefix := "myPrefix" + roleName := "myVeryLongRoleNameThatExceedsSixtyFourCharacters123456" + expectedName := "myPrefix-myVeryLongRoleNameThatExceedsSixtyFourCharacters123456-" + + name := GetRoleName(prefix, roleName) + + Expect(name).To(Equal(expectedName)) + }) + }) + + Describe("isManagedRole", func() { + It("should return true if the 'ManagedPolicies' tag has the value 'true'", func() { + roleTags := []*iam.Tag{ + {Key: aws.String(ManagedPolicies), Value: aws.String("true")}, + } + + result := IsManagedRole(roleTags) + + Expect(result).To(BeTrue()) + }) + + It("should return false if the 'ManagedPolicies' tag does not have the value 'true'", func() { + roleTags := []*iam.Tag{ + {Key: aws.String(ManagedPolicies), Value: aws.String("false")}, + } + + result := IsManagedRole(roleTags) + + Expect(result).To(BeFalse()) + }) + + It("should return false if the 'ManagedPolicies' tag is not present", func() { + roleTags := []*iam.Tag{ + {Key: aws.String("SomeOtherTag"), Value: aws.String("true")}, + } + + result := IsManagedRole(roleTags) + + Expect(result).To(BeFalse()) + }) + }) + + var _ = Describe("HasCompatibleVersionTags", func() { + var iamTags []*iam.Tag + + BeforeEach(func() { + iamTags = []*iam.Tag{ + {Key: aws.String(OpenShiftVersion), Value: aws.String("1.2.3")}, + {Key: aws.String("SomeOtherTag"), Value: aws.String("value")}, + } + }) + + It("should return true if the version tag matches the provided version", func() { + version := "1.2.3" + + result, err := HasCompatibleVersionTags(iamTags, version) + + Expect(result).To(BeTrue()) + Expect(err).To(BeNil()) + }) + + It("should return false if the version tag does not match the provided version", func() { + version := "2.0.0" + + result, err := HasCompatibleVersionTags(iamTags, version) + + Expect(result).To(BeFalse()) + Expect(err).To(BeNil()) + }) + + It("should return false if the version tag is not present", func() { + version := "1.2.3" + iamTags = []*iam.Tag{ + {Key: aws.String("SomeOtherTag"), Value: aws.String("value")}, + } + + result, err := HasCompatibleVersionTags(iamTags, version) + + Expect(result).To(BeFalse()) + Expect(err).To(BeNil()) + }) + + It("should return an error if the provided version is not a valid semantic version", func() { + version := "invalid-version" + + result, err := HasCompatibleVersionTags(iamTags, version) + + Expect(result).To(BeFalse()) + Expect(err).ToNot(BeNil()) + }) + }) + + var _ = Describe("IamResourceHasTag", func() { + It("should return true if the tag with the specified key and value exists", func() { + iamTags := []*iam.Tag{ + {Key: aws.String("Tag1"), Value: aws.String("Value1")}, + {Key: aws.String("Tag2"), Value: aws.String("Value2")}, + } + tagKey := "Tag1" + tagValue := "Value1" + + result := IamResourceHasTag(iamTags, tagKey, tagValue) + + Expect(result).To(BeTrue()) + }) + + It("should return false if the tag with the specified key and value does not exist", func() { + iamTags := []*iam.Tag{ + {Key: aws.String("Tag1"), Value: aws.String("Value1")}, + {Key: aws.String("Tag2"), Value: aws.String("Value2")}, + } + tagKey := "Tag3" + tagValue := "Value3" + + result := IamResourceHasTag(iamTags, tagKey, tagValue) + + Expect(result).To(BeFalse()) + }) + }) +}) diff --git a/pkg/aws/validations/tags.go b/pkg/aws/validations/tags.go new file mode 100644 index 0000000..10b8a9e --- /dev/null +++ b/pkg/aws/validations/tags.go @@ -0,0 +1,9 @@ +package validations + +const prefix = "rosa_" + +const ManagedPolicies = prefix + "managed_policies" + +// OpenShiftVersion is the name of the tag that will contain +// the version of OpenShift that the resources are used for +const OpenShiftVersion = prefix + "openshift_version" \ No newline at end of file diff --git a/pkg/aws/validations/validation_suite_test.go b/pkg/aws/validations/validation_suite_test.go new file mode 100644 index 0000000..8ccf5dc --- /dev/null +++ b/pkg/aws/validations/validation_suite_test.go @@ -0,0 +1,13 @@ +package validations + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestValidations(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Validations Suite") +} diff --git a/pkg/consts.go b/pkg/consts.go new file mode 100644 index 0000000..d50c0d5 --- /dev/null +++ b/pkg/consts.go @@ -0,0 +1,3 @@ +package pkg + +const MaxByteSize = 64 \ No newline at end of file diff --git a/pkg/idp/validations/passwordValidator.go b/pkg/idp/validations/password_validator.go similarity index 100% rename from pkg/idp/validations/passwordValidator.go rename to pkg/idp/validations/password_validator.go diff --git a/pkg/idp/validations/passwordValidator_test.go b/pkg/idp/validations/password_validator_test.go similarity index 100% rename from pkg/idp/validations/passwordValidator_test.go rename to pkg/idp/validations/password_validator_test.go diff --git a/pkg/ocm/validations/helpers.go b/pkg/ocm/validations/helpers.go new file mode 100644 index 0000000..0f7b33c --- /dev/null +++ b/pkg/ocm/validations/helpers.go @@ -0,0 +1,24 @@ +package validations + +import ( + "fmt" + "net/url" + "strings" +) + +func ValidateIssuerUrlMatchesAssumePolicyDocument( + roleArn string, parsedUrl *url.URL, assumePolicyDocument string) error { + issuerUrl := parsedUrl.Host + if parsedUrl.Path != "" { + issuerUrl += parsedUrl.Path + } + decodedAssumePolicyDocument, err := url.QueryUnescape(assumePolicyDocument) + if err != nil { + return err + } + if !strings.Contains(decodedAssumePolicyDocument, issuerUrl) { + return fmt.Errorf("Operator role '%s' does not have trusted relationship to '%s' issuer URL", + roleArn, issuerUrl) + } + return nil +} diff --git a/pkg/ocm/validations/helpers_test.go b/pkg/ocm/validations/helpers_test.go new file mode 100644 index 0000000..1a3d9d1 --- /dev/null +++ b/pkg/ocm/validations/helpers_test.go @@ -0,0 +1,33 @@ +package validations + +import ( + "fmt" + "net/url" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("ValidateIssuerUrlMatchesAssumePolicyDocument", func() { + It("should return an error when the policy document does not have a trusted relationship to the issuer URL", func() { + roleArn := "your-role-arn" + parsedUrl, _ := url.Parse("http://your-issuer-url.com") + assumePolicyDocument := "your-assume-policy-document" + + err := ValidateIssuerUrlMatchesAssumePolicyDocument(roleArn, parsedUrl, assumePolicyDocument) + + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal(fmt.Sprintf("Operator role '%s' does not have trusted relationship to '%s' issuer URL", + roleArn, parsedUrl.Host+parsedUrl.Path))) + }) + + It("should not return an error when the policy document has a trusted relationship to the issuer URL", func() { + roleArn := "your-role-arn" + parsedUrl, _ := url.Parse("http://your-issuer-url.com") + assumePolicyDocument := "your-assume-policy-document with your-issuer-url.com" + + err := ValidateIssuerUrlMatchesAssumePolicyDocument(roleArn, parsedUrl, assumePolicyDocument) + + Expect(err).ToNot(HaveOccurred()) + }) +}) diff --git a/pkg/ocm/validations/validation_suite_test.go b/pkg/ocm/validations/validation_suite_test.go new file mode 100644 index 0000000..8ccf5dc --- /dev/null +++ b/pkg/ocm/validations/validation_suite_test.go @@ -0,0 +1,13 @@ +package validations + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestValidations(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Validations Suite") +} diff --git a/pkg/resource/validations/kmsArnRegexValidation.go b/pkg/resource/validations/kms_arn_regex_validation.go similarity index 100% rename from pkg/resource/validations/kmsArnRegexValidation.go rename to pkg/resource/validations/kms_arn_regex_validation.go diff --git a/pkg/resource/validations/kmsArnRegexValidation_test.go b/pkg/resource/validations/kms_arn_regex_validation_test.go similarity index 100% rename from pkg/resource/validations/kmsArnRegexValidation_test.go rename to pkg/resource/validations/kms_arn_regex_validation_test.go