diff --git a/tests/e2e/test_rosacli_cluster_post.go b/tests/e2e/test_rosacli_cluster_post.go index be1ad200b8..6afc6044a2 100644 --- a/tests/e2e/test_rosacli_cluster_post.go +++ b/tests/e2e/test_rosacli_cluster_post.go @@ -7,6 +7,7 @@ import ( nets "net/http" "strings" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/iam" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -649,4 +650,42 @@ var _ = Describe("Post-Check testing for cluster creation", } }) + It("to verify cluster with the operator-roles attaching managed policy is created successfully - [id:57410]", + labels.High, labels.Runtime.Day1Post, + func() { + // Till now, only HCP clusters operator roles are attaching managed policies + By("Skip is the cluster is not HCP cluster") + profile := profilehandler.LoadProfileYamlFileByENV() + if !profile.ClusterConfig.HCP { + Skip("This case is only for STS cluster post check") + } + By("Check the attaching policies are managed") + clusterID = config.GetClusterID() + output, err := clusterService.DescribeCluster(clusterID) + Expect(err).To(BeNil()) + CD, err := clusterService.ReflectClusterDescription(output) + Expect(err).To(BeNil()) + operatorRolesArns := CD.OperatorIAMRoles + for _, policyArn := range operatorRolesArns { + By("Check role tag") + _, operatorRoleName, err := common.ParseRoleARN(policyArn) + Expect(err).To(BeNil()) + roleTags, err := awsClient.IamClient.ListRoleTags(context.TODO(), &iam.ListRoleTagsInput{ + RoleName: aws.String(operatorRoleName), + }) + Expect(err).To(BeNil()) + tagCheckPass := false + for _, tag := range roleTags.Tags { + if *tag.Key == "rosa_managed_policies" && *tag.Value == constants.TrueString { + tagCheckPass = true + break + } + } + Expect(tagCheckPass).To(BeTrue()) + By("Check policy is aws managed policy") + attachedPolicies, err := awsClient.ListAttachedRolePolicies(operatorRoleName) + Expect(err).To(BeNil()) + Expect(*attachedPolicies[0].PolicyArn).To(ContainSubstring("arn:aws:iam::aws")) + } + }) }) diff --git a/tests/e2e/test_rosacli_operator_roles.go b/tests/e2e/test_rosacli_operator_roles.go index 2b4d554126..4b54a587df 100644 --- a/tests/e2e/test_rosacli_operator_roles.go +++ b/tests/e2e/test_rosacli_operator_roles.go @@ -16,6 +16,7 @@ import ( "github.com/openshift/rosa/tests/ci/labels" "github.com/openshift/rosa/tests/utils/common" + "github.com/openshift/rosa/tests/utils/common/constants" "github.com/openshift/rosa/tests/utils/config" "github.com/openshift/rosa/tests/utils/exec/rosacli" "github.com/openshift/rosa/tests/utils/profilehandler" @@ -946,3 +947,136 @@ var _ = Describe("Detele operator roles with byo oidc", labels.Feature.OperatorR }) }) + +var _ = Describe("Create cluster with oprator roles which are attaching managed policies in manual mode", + labels.Feature.Cluster, func() { + defer GinkgoRecover() + var ( + rosaClient *rosacli.Client + clusterService rosacli.ClusterService + customProfile *profilehandler.Profile + ocmResourceService rosacli.OCMResourceService + AWSAccountID string + testingClusterName string + defaultDir string + dirForManual string + clusterID string + ) + + BeforeEach(func() { + // Init the client + By("Init client and service") + rosaClient = rosacli.NewClient() + ocmResourceService = rosaClient.OCMResource + clusterService = rosaClient.Cluster + + By("Get AWS account id") + rosaClient.Runner.JsonFormat() + whoamiOutput, err := ocmResourceService.Whoami() + Expect(err).To(BeNil()) + rosaClient.Runner.UnsetFormat() + whoamiData := ocmResourceService.ReflectAccountsInfo(whoamiOutput) + AWSAccountID = whoamiData.AWSAccountID + + By("Prepare custom profile") + customProfile = &profilehandler.Profile{ + ClusterConfig: &profilehandler.ClusterConfig{ + HCP: true, + MultiAZ: true, + STS: true, + OIDCConfig: "managed", + NetworkingSet: true, + BYOVPC: true, + Zones: "", + }, + AccountRoleConfig: &profilehandler.AccountRoleConfig{ + Path: "", + PermissionBoundary: "", + }, + Version: "latest", + ChannelGroup: "candidate", + Region: "us-west-2", + } + customProfile.NamePrefix = constants.DefaultNamePrefix + + By("Get the default dir") + defaultDir = rosaClient.Runner.GetDir() + }) + + AfterEach(func() { + + By("Go back original by setting runner dir") + rosaClient.Runner.SetDir(defaultDir) + + By("Delete cluster") + rosaClient.Runner.UnsetArgs() + _, err := clusterService.DeleteCluster(clusterID, "-y") + Expect(err).To(BeNil()) + + rosaClient.Runner.UnsetArgs() + err = clusterService.WaitClusterDeleted(clusterID, 3, 30) + Expect(err).To(BeNil()) + + By("Delete operator-roles") + _, err = ocmResourceService.DeleteOperatorRoles( + "-c", testingClusterName, + "--mode", "auto", + "-y", + ) + Expect(err).To(BeNil()) + + By("Clean resource") + errs := profilehandler.DestroyResourceByProfile(customProfile, rosaClient) + Expect(len(errs)).To(Equal(0)) + }) + + It("to create and delete operatorroles attaching managed policies in manual mode - [id:75504]", + labels.Critical, labels.Runtime.Day1Supplemental, func() { + By("Create hcp cluster in manual mode") + testingClusterName = "rosa75504" + testOperatorRolePrefix := "rosa75504opp" + flags, err := profilehandler.GenerateClusterCreateFlags(customProfile, rosaClient) + Expect(err).ToNot(HaveOccurred()) + + command := "rosa create cluster --cluster-name " + testingClusterName + " " + strings.Join(flags, " ") + rosalCommand := config.GenerateCommand(command) + rosalCommand.ReplaceFlagValue(map[string]string{ + "--operator-roles-prefix": testOperatorRolePrefix, + }) + + rosalCommand.AddFlags("--mode", "manual") + rosalCommand.AddFlags("--billing-account", AWSAccountID) + + By("Create a temp dir to execute the create commands") + dirForManual, err = os.MkdirTemp("", "*") + Expect(err).To(BeNil()) + + rosaClient.Runner.SetDir(dirForManual) + stdout, err := rosaClient.Runner.RunCMD(strings.Split(rosalCommand.GetFullCommand(), " ")) + Expect(err).To(BeNil()) + + commands := common.ExtractAWSCmdsForClusterCreation(stdout) + hasCreatePolicyFlag := false + for _, command := range commands { + if strings.Contains(command, "aws iam create-policy") { + hasCreatePolicyFlag = true + break + } + _, err := rosaClient.Runner.RunCMD(strings.Split(command, " ")) + Expect(err).To(BeNil()) + } + Expect(hasCreatePolicyFlag).To(BeFalse()) + + By("Check and wait cluster to installing status") + rosaClient.Runner.UnsetArgs() + clusterListout, err := clusterService.List() + Expect(err).To(BeNil()) + + clusterList, err := clusterService.ReflectClusterList(clusterListout) + Expect(err).To(BeNil()) + clusterID = clusterList.ClusterByName(testingClusterName).ID + rosaClient.Runner.UnsetArgs() + err = clusterService.WaitClusterStatus(clusterID, "installing", 3, 24) + Expect(err).To(BeNil(), "It met error or timeout when waiting cluster to installing status") + }) + }) diff --git a/tests/utils/common/constants/general.go b/tests/utils/common/constants/general.go index 12bf1e60ed..4d8d93d046 100644 --- a/tests/utils/common/constants/general.go +++ b/tests/utils/common/constants/general.go @@ -4,6 +4,7 @@ const ( Yes = "Yes" No = "No" YStreamPreviousVersion = "y-1" + TrueString = "true" ) // Ec2MetadataHttpTokens for hcp cluster diff --git a/tests/utils/common/role.go b/tests/utils/common/role.go index 30ce835b2c..53eb40c1d8 100644 --- a/tests/utils/common/role.go +++ b/tests/utils/common/role.go @@ -84,3 +84,40 @@ func ExtractCommandsToDeleteAccountRoles(bf bytes.Buffer) []string { } return newCommands } + +// Extract aws commands to create AWS resource promted by rosacli, this function supports to parse bellow commands +// `rosa create cluster --mode manual --sts /--hosted-cp` +func ExtractAWSCmdsForClusterCreation(bf bytes.Buffer) []string { + + var commands []string + //remove empty lines + lines := strings.Split(bf.String(), "\n") + var nonEmptyLines []string + for _, line := range lines { + if strings.TrimSpace(line) != "" { + nonEmptyLines = append(nonEmptyLines, line) + } + } + nonEmptyInput := strings.Join(nonEmptyLines, "\n") + //replace \ and \n and spaces with one space + re := regexp.MustCompile(`\\\s*\n\s*`) + processedInput := re.ReplaceAllString(nonEmptyInput, " ") + + output := strings.Split(processedInput, "\n") + for _, message := range output { + if strings.HasPrefix(message, "aws iam") { + commands = append(commands, message) + } + } + var newCommands []string + for _, command := range commands { + command = strings.ReplaceAll(command, "\\", "") + command = strings.ReplaceAll(command, "\n", " ") + spaceRegex := regexp.MustCompile(`\s+`) + command = spaceRegex.ReplaceAllString(command, " ") + command = strings.ReplaceAll(command, "'", "") + newCommands = append(newCommands, command) + + } + return newCommands +}