diff --git a/cmd/upgrade/accountroles/cmd.go b/cmd/upgrade/accountroles/cmd.go index 8093075e5e..c4acbcddfc 100644 --- a/cmd/upgrade/accountroles/cmd.go +++ b/cmd/upgrade/accountroles/cmd.go @@ -218,7 +218,7 @@ func run(cmd *cobra.Command, argv []string) error { reporter.Infof("Run the following commands to upgrade the account role policies:\n") } commands := buildCommands(prefix, creator.AccountID, isUpgradeNeedForAccountRolePolicies, - isUpgradeNeedForOperatorRolePolicies) + isUpgradeNeedForOperatorRolePolicies, awsClient) fmt.Println(commands) if args.isInvokedFromClusterUpgrade { reporter.Infof("Run the following command to continue scheduling cluster upgrade"+ @@ -236,8 +236,8 @@ func run(cmd *cobra.Command, argv []string) error { func upgradeAccountRolePolicies(reporter *rprtr.Object, awsClient aws.Client, prefix string, accountID string) error { for file, role := range aws.AccountRoles { - name := aws.GetRoleName(prefix, role.Name) - if !confirm.Prompt(true, "Upgrade the '%s' role policy to version %s?", name, + roleName := aws.GetRoleName(prefix, role.Name) + if !confirm.Prompt(true, "Upgrade the '%s' role policy to version %s?", roleName, aws.DefaultPolicyVersion) { if args.isInvokedFromClusterUpgrade { return reporter.Errorf("Account roles need to be upgraded to proceed" + @@ -247,7 +247,7 @@ func upgradeAccountRolePolicies(reporter *rprtr.Object, awsClient aws.Client, pr } filename := fmt.Sprintf("sts_%s_permission_policy.json", file) path := fmt.Sprintf("templates/policies/%s", filename) - policyARN := aws.GetPolicyARN(accountID, fmt.Sprintf("%s-Policy", name)) + policyARN := aws.GetPolicyARN(accountID, fmt.Sprintf("%s-Policy", roleName)) policy, err := aws.ReadPolicyDocument(path) if err != nil { @@ -262,8 +262,18 @@ func upgradeAccountRolePolicies(reporter *rprtr.Object, awsClient aws.Client, pr if err != nil { return err } + + err = awsClient.AttachRolePolicy(roleName, policyARN) + if err != nil { + return err + } + //Delete if present else continue + err = awsClient.DeleteInlineRolePolicies(roleName) + if err != nil { + reporter.Debugf("Error deleting inline role policy %s : %s", policyARN, err) + } reporter.Infof("Upgraded policy with ARN '%s' to version '%s'", policyARN, aws.DefaultPolicyVersion) - err = awsClient.UpdateTag(name) + err = awsClient.UpdateTag(roleName) if err != nil { return err } @@ -304,7 +314,7 @@ func upgradeOperatorRolePolicies(reporter *rprtr.Object, awsClient aws.Client, a } func buildCommands(prefix string, accountID string, isUpgradeNeedForAccountRolePolicies bool, - isUpgradeNeedForOperatorRolePolicies bool) string { + isUpgradeNeedForOperatorRolePolicies bool, awsClient aws.Client) string { commands := []string{} if isUpgradeNeedForAccountRolePolicies { for file, role := range aws.AccountRoles { @@ -314,15 +324,6 @@ func buildCommands(prefix string, accountID string, isUpgradeNeedForAccountRoleP "Key=%s,Value=%s", tags.OpenShiftVersion, aws.DefaultPolicyVersion, ) - createPolicyVersion := fmt.Sprintf("aws iam create-policy-version \\\n"+ - "\t--policy-arn %s \\\n"+ - "\t--policy-document file://sts_%s_permission_policy.json \\\n"+ - "\t--set-as-default", - policyARN, file) - tagPolicies := fmt.Sprintf("aws iam tag-policy \\\n"+ - "\t--tags %s \\\n"+ - "\t--policy-arn %s", - policyTags, policyARN) iamRoleTags := fmt.Sprintf( "Key=%s,Value=%s", tags.OpenShiftVersion, aws.DefaultPolicyVersion) @@ -330,7 +331,46 @@ func buildCommands(prefix string, accountID string, isUpgradeNeedForAccountRoleP "\t--tags %s \\\n"+ "\t--role-name %s", iamRoleTags, name) - commands = append(commands, createPolicyVersion, tagPolicies, tagRole) + //check if the policy exists if not output create and attach + _, err := awsClient.IsPolicyExists(policyARN) + if err != nil { + policyName := fmt.Sprintf("%s-Policy", name) + iamTags := fmt.Sprintf( + "Key=%s,Value=%s Key=%s,Value=%s Key=%s,Value=%s", + tags.OpenShiftVersion, aws.DefaultPolicyVersion, + tags.RolePrefix, prefix, + tags.RoleType, file, + ) + createPolicy := fmt.Sprintf("aws iam create-policy \\\n"+ + "\t--policy-name %s \\\n"+ + "\t--policy-document file://sts_%s_permission_policy.json"+ + "\t--tags %s", + policyName, file, iamTags) + attachRolePolicy := fmt.Sprintf("aws iam attach-role-policy \\\n"+ + "\t--role-name %s \\\n"+ + "\t--policy-arn %s", + name, aws.GetPolicyARN(accountID, policyName)) + + _, _ = awsClient.IsRolePolicyExists(name, policyName) + if err != nil { + commands = append(commands, createPolicy, attachRolePolicy, tagRole) + } else { + deletePolicy := fmt.Sprintf("\taws iam delete-role-policy --role-name %s --policy-name %s", + name, policyName) + commands = append(commands, createPolicy, attachRolePolicy, tagRole, deletePolicy) + } + } else { + createPolicyVersion := fmt.Sprintf("aws iam create-policy-version \\\n"+ + "\t--policy-arn %s \\\n"+ + "\t--policy-document file://sts_%s_permission_policy.json \\\n"+ + "\t--set-as-default", + policyARN, file) + tagPolicies := fmt.Sprintf("aws iam tag-policy \\\n"+ + "\t--tags %s \\\n"+ + "\t--policy-arn %s", + policyTags, policyARN) + commands = append(commands, createPolicyVersion, tagPolicies, tagRole) + } } } if isUpgradeNeedForOperatorRolePolicies { diff --git a/pkg/aws/client.go b/pkg/aws/client.go index a879b717eb..eff47cc1de 100644 --- a/pkg/aws/client.go +++ b/pkg/aws/client.go @@ -130,7 +130,9 @@ type Client interface { IsPolicyCompatible(policyArn string, version string) (bool, error) GetAccountRoleVersion(roleName string) (string, error) IsPolicyExists(policyARN string) (*iam.GetPolicyOutput, error) + IsRolePolicyExists(roleName string, policyName string) (*iam.GetRolePolicyOutput, error) IsAdminRole(roleName string) (bool, error) + DeleteInlineRolePolicies(roleName string) error IsUserRole(roleName *string) (bool, error) } diff --git a/pkg/aws/policies.go b/pkg/aws/policies.go index f5269c76f5..bfde6a0cab 100644 --- a/pkg/aws/policies.go +++ b/pkg/aws/policies.go @@ -433,6 +433,14 @@ func (c *awsClient) IsPolicyExists(policyArn string) (*iam.GetPolicyOutput, erro return output, err } +func (c *awsClient) IsRolePolicyExists(roleName string, policyName string) (*iam.GetRolePolicyOutput, error) { + output, err := c.iamClient.GetRolePolicy(&iam.GetRolePolicyInput{ + PolicyName: aws.String(policyName), + RoleName: aws.String(roleName), + }) + return output, err +} + func (c *awsClient) createPolicy(policyArn string, document string, tagList map[string]string) (string, error) { parsedArn, err := arn.Parse(policyArn) if err != nil { @@ -986,15 +994,15 @@ func (c *awsClient) detachAttachedRolePolicies(role *string) error { return nil } -func (c *awsClient) deleteInlineRolePolicies(role *string) error { - listRolePolicyOutput, err := c.iamClient.ListRolePolicies(&iam.ListRolePoliciesInput{RoleName: role}) +func (c *awsClient) DeleteInlineRolePolicies(role string) error { + listRolePolicyOutput, err := c.iamClient.ListRolePolicies(&iam.ListRolePoliciesInput{RoleName: aws.String(role)}) if err != nil { return err } for _, policyName := range listRolePolicyOutput.PolicyNames { _, err = c.iamClient.DeleteRolePolicy(&iam.DeleteRolePolicyInput{ PolicyName: policyName, - RoleName: role, + RoleName: aws.String(role), }) if err != nil { if aerr, ok := err.(awserr.Error); ok { @@ -1015,7 +1023,7 @@ func (c *awsClient) deleteAccountRolePolicies(role *string) error { if err != nil { return err } - err = c.deleteInlineRolePolicies(role) + err = c.DeleteInlineRolePolicies(aws.StringValue(role)) if err != nil { return err } @@ -1037,6 +1045,7 @@ func (c *awsClient) GetAttachedPolicy(role *string) ([]PolicyDetail, error) { return policies, err } } + for _, policy := range attachedPoliciesOutput.AttachedPolicies { policyDetail := PolicyDetail{ PolicyName: aws.StringValue(policy.PolicyName), @@ -1481,10 +1490,12 @@ func (c *awsClient) validateRoleUpgradeVersionCompatibility(roleName string, if err != nil { return false, err } + isAttachedPolicyExists := false for _, attachedPolicy := range attachedPolicies { - if attachedPolicy.PolicyArn == "" { + if attachedPolicy.PolicType == Inline { continue } + isAttachedPolicyExists = true isCompatible, err := c.isRolePoliciesCompatibleForUpgrade(attachedPolicy.PolicyArn, version) if err != nil { return false, errors.Errorf("Failed to validate role polices : %v", err) @@ -1493,6 +1504,9 @@ func (c *awsClient) validateRoleUpgradeVersionCompatibility(roleName string, return false, nil } } + if !isAttachedPolicyExists { + return false, nil + } return true, nil }