Skip to content

Commit

Permalink
OCM-7729 | fix: check policy attached in detach manual mode
Browse files Browse the repository at this point in the history
Signed-off-by: marcolan018 <llan@redhat.com>
  • Loading branch information
marcolan018 committed May 1, 2024
1 parent cd2d1ab commit e4b2263
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 22 deletions.
15 changes: 12 additions & 3 deletions cmd/detach/policy/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,18 @@ func DetachPolicyRunner(userOptions *RosaDetachPolicyOptions) rosa.CommandRunner
return err
}
case interactive.ModeManual:
r.Reporter.Infof("Run the following command to detach the policy:")
fmt.Print(policySvc.ManualDetachArbitraryPolicy(options.roleName, policyArns,
r.Creator.AccountID, orgID))
output, warn, err := policySvc.ManualDetachArbitraryPolicy(options.roleName, policyArns,
r.Creator.AccountID, orgID)
if err != nil {
return err
}
if len(warn) > 0 {
fmt.Print(warn)
}
if len(output) > 0 {
r.Reporter.Infof("Run the following command to detach the policy:")
fmt.Print(output)
}
default:
return fmt.Errorf("Invalid mode. Allowed values are %s", interactive.Modes)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/aws/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ type Client interface {
ListOCMRoles() ([]Role, error)
ListAccountRoles(version string) ([]Role, error)
ListOperatorRoles(version string, clusterID string) (map[string][]OperatorRoleDetail, error)
ListAttachedRolePolicies(roleName string) ([]string, error)
ListOidcProviders(targetClusterId string, config *cmv1.OidcConfig) ([]OidcProviderOutput, error)
GetRoleByARN(roleARN string) (iamtypes.Role, error)
GetRoleByName(roleName string) (iamtypes.Role, error)
Expand Down
15 changes: 15 additions & 0 deletions pkg/aws/mock_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions pkg/aws/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -1927,6 +1927,20 @@ func (c *awsClient) ValidateHCPAccountRolesManagedPolicies(prefix string,
return nil
}

func (c *awsClient) ListAttachedRolePolicies(roleName string) ([]string, error) {
policies := []string{}
listPolicies, err := c.iamClient.ListAttachedRolePolicies(context.Background(), &iam.ListAttachedRolePoliciesInput{
RoleName: aws.String(roleName),
})
if err != nil {
return policies, err
}
for _, policy := range listPolicies.AttachedPolicies {
policies = append(policies, *policy.PolicyArn)
}
return policies, nil
}

func (c *awsClient) validateManagedPolicy(policies map[string]*cmv1.AWSSTSPolicy, policyKey string,
roleName string) error {
managedPolicyARN, err := GetManagedPolicyARN(policies, policyKey)
Expand Down
36 changes: 23 additions & 13 deletions pkg/policy/policy_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type PolicyService interface {
ManualAttachArbitraryPolicy(roleName string, policyArns []string, accountID, orgID string) string
ValidateDetachOptions(roleName string, policyArns []string) error
AutoDetachArbitraryPolicy(roleName string, policyArns []string, accountID, orgID string) (string, error)
ManualDetachArbitraryPolicy(roleName string, policyArns []string, accountID, orgID string) string
ManualDetachArbitraryPolicy(roleName string, policyArns []string, accountID, orgID string) (string, string, error)
}

type policyService struct {
Expand Down Expand Up @@ -92,7 +92,7 @@ func (p *policyService) AutoAttachArbitraryPolicy(roleName string, policyArns []
ocm.PolicyArn: policyArn,
})
}
return output, nil
return output[:len(output)-1], nil
}

func (p *policyService) ManualAttachArbitraryPolicy(roleName string, policyArns []string,
Expand Down Expand Up @@ -134,23 +134,33 @@ func (p *policyService) AutoDetachArbitraryPolicy(roleName string, policyArns []
})
}
}
return output, nil
return output[:len(output)-1], nil
}

func (p *policyService) ManualDetachArbitraryPolicy(roleName string, policyArns []string,
accountID, orgID string) string {
accountID, orgID string) (string, string, error) {
cmd := ""
warn := ""
policies, err := p.AWSClient.ListAttachedRolePolicies(roleName)
if err != nil {
return cmd, warn, err
}
for _, policyArn := range policyArns {
cmd = cmd + fmt.Sprintf("aws iam detach-role-policy --role-name %s --policy-arn %s\n",
roleName, policyArn)
p.OCMClient.LogEvent("ROSADetachPolicyManual", map[string]string{
ocm.Account: accountID,
ocm.Organization: orgID,
ocm.RoleName: roleName,
ocm.PolicyArn: policyArn,
})
if slices.Contains(policies, policyArn) {
cmd = cmd + fmt.Sprintf("aws iam detach-role-policy --role-name %s --policy-arn %s\n",
roleName, policyArn)
p.OCMClient.LogEvent("ROSADetachPolicyManual", map[string]string{
ocm.Account: accountID,
ocm.Organization: orgID,
ocm.RoleName: roleName,
ocm.PolicyArn: policyArn,
})
} else {
warn = warn + fmt.Sprintf("The policy '%s' is currently not attached to role '%s'\n",
policyArn, roleName)
}
}
return cmd
return cmd, warn, nil
}

func validatePolicyQuota(c aws.Client, roleName string, policyArns []string) error {
Expand Down
16 changes: 10 additions & 6 deletions pkg/policy/policy_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ var _ = Describe("Policy Service", func() {
"sample-account-id", "sample-org-id")
Expect(err).ShouldNot(HaveOccurred())
Expect(output).To(Equal(fmt.Sprintf("Attached policy '%s' to role '%s'\n"+
"Attached policy '%s' to role '%s'\n",
"Attached policy '%s' to role '%s'",
policyArn1, roleName, policyArn2, roleName)))
})
It("Test ManualAttachArbitraryPolicy", func() {
Expand All @@ -147,16 +147,20 @@ var _ = Describe("Policy Service", func() {
"sample-account-id", "sample-org-id")
Expect(err).ShouldNot(HaveOccurred())
Expect(output).To(Equal(fmt.Sprintf("Detached policy '%s' from role '%s'\n"+
"The policy '%s' is currently not attached to role '%s'\n",
"The policy '%s' is currently not attached to role '%s'",
policyArn1, roleName, policyArn2, roleName)))
})
It("Test ManualDetachArbitraryPolicy", func() {
output := policySvc.ManualDetachArbitraryPolicy(roleName, policyArns,
awsClient.EXPECT().ListAttachedRolePolicies(roleName).Return([]string{policyArn1}, nil)
output, warn, err := policySvc.ManualDetachArbitraryPolicy(roleName, policyArns,
"sample-account-id", "sample-org-id")
Expect(err).ShouldNot(HaveOccurred())
Expect(warn).To(Equal(fmt.Sprintf(
"The policy '%s' is currently not attached to role '%s'\n",
policyArn2, roleName)))
Expect(output).To(Equal(fmt.Sprintf(
"aws iam detach-role-policy --role-name %s --policy-arn %s\n"+
"aws iam detach-role-policy --role-name %s --policy-arn %s\n",
roleName, policyArn1, roleName, policyArn2)))
"aws iam detach-role-policy --role-name %s --policy-arn %s\n",
roleName, policyArn1)))
})
})
})

0 comments on commit e4b2263

Please sign in to comment.