Skip to content

Commit

Permalink
Merge pull request #61 from davidleerh/OCM-9166
Browse files Browse the repository at this point in the history
OCM-9166 | fix: create common validator to check duplicated IAM role arns for ROSA STS cluster
  • Loading branch information
davidleerh authored Jun 27, 2024
2 parents 12656d8 + b4973ea commit 35b747c
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 0 deletions.
25 changes: 25 additions & 0 deletions pkg/aws/validations/iam_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@ package validations

import (
"fmt"
"maps"

"github.com/aws/aws-sdk-go-v2/aws"

iamtypes "github.com/aws/aws-sdk-go-v2/service/iam/types"
semver "github.com/hashicorp/go-version"
. "github.com/openshift-online/ocm-common/pkg/aws/consts"
. "github.com/openshift-online/ocm-common/pkg/rosa/accountroles"
. "github.com/openshift-online/ocm-common/pkg/rosa/operatorroles"
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
)

const (
duplicateIamRoleArnErrorMsg = "ROSA IAM roles must have unique ARNs " +
"and should not be shared with other IAM roles within the same cluster. " +
"Duplicated role arn: %s"
)

func GetRoleName(prefix string, role string) string {
Expand Down Expand Up @@ -62,3 +73,17 @@ func IamResourceHasTag(iamTags []iamtypes.Tag, tagKey string, tagValue string) b

return false
}

func IamRoleArnsValidator(cluster *cmv1.Cluster) error {
validatingMap := map[string]struct{}{}
clusterIamRoles := GetAccountRolesArnsMap(cluster)
maps.Copy(clusterIamRoles, GetOperatorRolesArnsMap(cluster))

for _, arn := range clusterIamRoles {
if _, exist := validatingMap[arn]; exist {
return fmt.Errorf(duplicateIamRoleArnErrorMsg, arn)
}
validatingMap[arn] = struct{}{}
}
return nil
}
47 changes: 47 additions & 0 deletions pkg/aws/validations/iam_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package validations

import (
"fmt"

"github.com/aws/aws-sdk-go-v2/aws"
iamtypes "github.com/aws/aws-sdk-go-v2/service/iam/types"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
)

var _ = Describe("AWS iamtypes Functions", func() {
Expand Down Expand Up @@ -141,4 +143,49 @@ var _ = Describe("AWS iamtypes Functions", func() {
Expect(result).To(BeFalse())
})
})

var _ = Describe("IamRoleArnsValidator", func() {
It("should return error if duplicate arns exist", func() {
fakeCluster, err := cmv1.NewCluster().
AWS(
cmv1.NewAWS().
STS(
cmv1.NewSTS().
RoleARN("installer").
SupportRoleARN("support").
InstanceIAMRoles(
cmv1.NewInstanceIAMRoles().
MasterRoleARN("installer").
WorkerRoleARN("worker"),
),
),
).Build()
Expect(err).ToNot(HaveOccurred())
err = IamRoleArnsValidator(fakeCluster)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(Equal(
fmt.Sprintf(duplicateIamRoleArnErrorMsg, "installer"),
))
})

It("should return nil no duplicate arns are detected", func() {
fakeCluster, err := cmv1.NewCluster().
AWS(
cmv1.NewAWS().
STS(
cmv1.NewSTS().
RoleARN("installer").
SupportRoleARN("support").
InstanceIAMRoles(
cmv1.NewInstanceIAMRoles().
MasterRoleARN("controlplane").
WorkerRoleARN("worker"),
),
),
).Build()
Expect(err).ToNot(HaveOccurred())
err = IamRoleArnsValidator(fakeCluster)
Expect(err).ToNot(HaveOccurred())
})
})
})
13 changes: 13 additions & 0 deletions pkg/rosa/operatorroles/operatorroles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package operatorroles

import (
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
)

func GetOperatorRolesArnsMap(cluster *cmv1.Cluster) map[string]string {
operatorRolesMap := map[string]string{}
for _, role := range cluster.AWS().STS().OperatorIAMRoles() {
operatorRolesMap[role.Name()] = role.RoleARN()
}
return operatorRolesMap
}
13 changes: 13 additions & 0 deletions pkg/rosa/operatorroles/operatorroles_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package operatorroles_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestOperatorroles(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Operatorroles Suite")
}
34 changes: 34 additions & 0 deletions pkg/rosa/operatorroles/operatorroles_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package operatorroles_test

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/openshift-online/ocm-common/pkg/rosa/operatorroles"
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
)

var _ = Describe("Operator Role functions", func() {
var _ = Describe("Validates GetOperatorRolesArnsMap function", func() {
It("Checks the operator roles are retrieved from a cluster", func() {
fakeCluster, err := cmv1.NewCluster().
AWS(
cmv1.NewAWS().
STS(
cmv1.NewSTS().
OperatorIAMRoles(
cmv1.NewOperatorIAMRole().Name("operator-role-1").RoleARN("arn-1"),
cmv1.NewOperatorIAMRole().Name("operator-role-2").RoleARN("arn-2"),
cmv1.NewOperatorIAMRole().Name("operator-role-3").RoleARN("arn-3"),
),
),
).Build()
Expect(err).ToNot(HaveOccurred())
operatorRolesMap := GetOperatorRolesArnsMap(fakeCluster)
Expect(len(operatorRolesMap)).To(Equal(3))
for name, arn := range operatorRolesMap {
Expect(name).ToNot(Equal(""))
Expect(arn).ToNot(Equal(""))
}
})
})
})

0 comments on commit 35b747c

Please sign in to comment.