Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCM-9166 | fix: create common validator to check duplicated IAM role arns for ROSA STS cluster #61

Merged
merged 1 commit into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"

davidleerh marked this conversation as resolved.
Show resolved Hide resolved
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(""))
}
})
})
})
Loading