Skip to content

Commit

Permalink
update attached role policies
Browse files Browse the repository at this point in the history
  • Loading branch information
kkb0318 committed Jul 5, 2024
1 parent fff9016 commit 33ba984
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 32 deletions.
72 changes: 48 additions & 24 deletions internal/aws/aws_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ func (r *RoleManager) PolicyArn(policy string) *string {
}

// ExtractNewPolicies returns the names of the policies that are in the current settings (r.Policies) but are not yet attached to the role.

func (r *RoleManager) ExtractNewPolicies(l *iam.ListAttachedRolePoliciesOutput) []string {
result := []string{}
if l == nil {
return r.Policies // return all policies
}
for _, p := range r.Policies {
if slices.ContainsFunc(l.AttachedPolicies, func(a types.AttachedPolicy) bool {
return *r.PolicyArn(p) != *a.PolicyArn
Expand All @@ -56,6 +58,9 @@ func (r *RoleManager) ExtractNewPolicies(l *iam.ListAttachedRolePoliciesOutput)
// ExtractStalePolicies returns the ARNs of the policies that are attached to the role but are not in the current settings (r.Policies).
func (r *RoleManager) ExtractStalePolicies(l *iam.ListAttachedRolePoliciesOutput) []string {
result := []string{}
if l == nil {
return result
}
for _, ap := range l.AttachedPolicies {
if slices.ContainsFunc(r.Policies, func(p string) bool {
return *r.PolicyArn(p) != *ap.PolicyArn
Expand All @@ -69,17 +74,11 @@ func (r *RoleManager) ExtractStalePolicies(l *iam.ListAttachedRolePoliciesOutput
// DeleteIRSARole detaches specified policies from the IAM role and deletes the IAM role
func (a *AwsIamClient) DeleteIRSARole(ctx context.Context, r RoleManager) error {
for _, policy := range r.Policies {
detachRolePolicyInput := &iam.DetachRolePolicyInput{
RoleName: aws.String(r.RoleName),
PolicyArn: r.PolicyArn(policy),
}
_, err := a.Client.DetachRolePolicy(ctx, detachRolePolicyInput)
// Ignore error if the policy is already detached or the role does not exist
if errorHandler(err, []string{"NoSuchEntity"}) != nil {
err := a.DetachRolePolicy(ctx, aws.String(r.RoleName), r.PolicyArn(policy))
if err != nil {
return err
}
log.Printf("Policy %s detached from role %s successfully", policy, r.RoleName)

}
input := &iam.DeleteRoleInput{RoleName: aws.String(r.RoleName)}
_, err := a.Client.DeleteRole(ctx, input)
Expand All @@ -91,8 +90,32 @@ func (a *AwsIamClient) DeleteIRSARole(ctx context.Context, r RoleManager) error
return nil
}

// CreateIRSARole creates an IAM role with the specified trust policy and attaches specified policies to it
func (a *AwsIamClient) CreateIRSARole(ctx context.Context, issuerMeta issuer.OIDCIssuerMeta, r RoleManager) error {
// DetachRolePolicy detaches specified policies from the IAM role
func (a *AwsIamClient) DetachRolePolicy(ctx context.Context, roleName, policyArn *string) error {
detachRolePolicyInput := &iam.DetachRolePolicyInput{
RoleName: roleName,
PolicyArn: policyArn,
}
_, err := a.Client.DetachRolePolicy(ctx, detachRolePolicyInput)
// Ignore error if the policy is already detached or the role does not exist
if errorHandler(err, []string{"NoSuchEntity"}) != nil {
return err
}
return nil
}

// AttachRolePolicy attaches specidied policy
func (a *AwsIamClient) AttachRolePolicy(ctx context.Context, roleName, policyArn *string) error {
attachRolePolicyInput := &iam.AttachRolePolicyInput{
RoleName: roleName,
PolicyArn: policyArn,
}
_, err := a.Client.AttachRolePolicy(ctx, attachRolePolicyInput)
return err
}

// UpdateIRSARole creates an IAM role with the specified trust policy and attaches specified policies to it
func (a *AwsIamClient) UpdateIRSARole(ctx context.Context, issuerMeta issuer.OIDCIssuerMeta, r RoleManager) error {
providerArn := fmt.Sprintf("arn:aws:iam::%s:oidc-provider/%s", r.AccountId, issuerMeta.IssuerHostPath())
statement := make([]map[string]interface{}, len(r.ServiceAccount.Namespaces))
for i, ns := range r.ServiceAccount.Namespaces {
Expand Down Expand Up @@ -137,26 +160,27 @@ func (a *AwsIamClient) CreateIRSARole(ctx context.Context, issuerMeta issuer.OID
if err != nil {
return fmt.Errorf("failed to update assume role policy for role %s: %w", r.RoleName, err)
}
log.Printf("Assume role policy for %s updated successfully", r.RoleName)
// TODO:
// listPoliciesOutput, err := a.Client.ListAttachedRolePolicies(ctx, &iam.ListAttachedRolePoliciesInput{RoleName: aws.String(r.RoleName)})
// if err != nil {
// return fmt.Errorf("failed to list attached role policies with %s: %w", r.RoleName, err)
// }

for _, policy := range r.Policies {
attachRolePolicyInput := &iam.AttachRolePolicyInput{
RoleName: aws.String(r.RoleName),
PolicyArn: r.PolicyArn(policy),
}
listPoliciesOutput, err := a.Client.ListAttachedRolePolicies(ctx, &iam.ListAttachedRolePoliciesInput{RoleName: aws.String(r.RoleName)})
if err != nil {
return fmt.Errorf("failed to list attached role policies with %s: %w", r.RoleName, err)
}

_, err = a.Client.AttachRolePolicy(ctx, attachRolePolicyInput)
for _, policy := range r.ExtractNewPolicies(listPoliciesOutput) {
err := a.AttachRolePolicy(ctx, aws.String(r.RoleName), r.PolicyArn(policy))
if err != nil {
return err
}
log.Printf("Policy %s attached to role %s successfully", policy, r.RoleName)

}
for _, policy := range r.ExtractStalePolicies(listPoliciesOutput) {
err := a.DetachRolePolicy(ctx, aws.String(r.RoleName), r.PolicyArn(policy))
if err != nil {
return err
}
log.Printf("Policy %s attached to role %s successfully", policy, r.RoleName)
}
log.Printf("Assume role policy for %s updated successfully", r.RoleName)
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion internal/controller/irsa_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func (r *IRSAReconciler) reconcile(ctx context.Context, obj *irsav1alpha1.IRSA,
Policies: obj.Spec.IamPolicies,
AccountId: accountId,
}
err = r.AwsClient.IamClient().CreateIRSARole(
err = r.AwsClient.IamClient().UpdateIRSARole(
ctx,
issuerMeta,
roleManager,
Expand Down
19 changes: 12 additions & 7 deletions internal/controller/irsasetup_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,14 @@ func (m *mockAwsClient) StsClient() *awsclient.AwsStsClient {

type (
mockAwsIamAPI struct {
createOidcErr error
deleteOidcErr error
createRoleErr error
deleteRoleErr error
updateAssumeRolePolicyError error
attachRolePolicyError error
detachRolePolicyError error
createOidcErr error
deleteOidcErr error
createRoleErr error
deleteRoleErr error
updateAssumeRolePolicyError error
listAttachedRolePoliciesError error
attachRolePolicyError error
detachRolePolicyError error
}
mockAwsS3API struct {
createBucketErr bool
Expand All @@ -374,6 +375,10 @@ func (m *mockAwsIamAPI) CreateRole(ctx context.Context, params *iam.CreateRoleIn
return nil, m.createRoleErr
}

func (m *mockAwsIamAPI) ListAttachedRolePolicies(ctx context.Context, params *iam.ListAttachedRolePoliciesInput, optFns ...func(*iam.Options)) (*iam.ListAttachedRolePoliciesOutput, error) {
return nil, m.listAttachedRolePoliciesError
}

func (m *mockAwsIamAPI) UpdateAssumeRolePolicy(ctx context.Context, params *iam.UpdateAssumeRolePolicyInput, optFns ...func(*iam.Options)) (*iam.UpdateAssumeRolePolicyOutput, error) {
return nil, m.updateAssumeRolePolicyError
}
Expand Down

0 comments on commit 33ba984

Please sign in to comment.