Skip to content

Commit

Permalink
Add IAM role cleaner. (#985)
Browse files Browse the repository at this point in the history
  • Loading branch information
jefchien authored Dec 7, 2023
1 parent 8d814c7 commit 1524426
Show file tree
Hide file tree
Showing 7 changed files with 372 additions and 37 deletions.
20 changes: 19 additions & 1 deletion .github/workflows/clean-aws-resources.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,22 @@ jobs:
aws-region: us-west-2

- name: Clean old asg
run: go run ./tool/clean/clean_auto_scaling_groups/clean_auto_scaling_groups.go --tags=clean
run: go run ./tool/clean/clean_auto_scaling_groups/clean_auto_scaling_groups.go --tags=clean

clean-iam-roles:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secrets.TERRAFORM_AWS_ASSUME_ROLE }}
aws-region: us-west-2

- name: Clean old IAM roles
run: go run ./tool/clean/clean_iam_roles/clean_iam_roles.go --tags=clean
19 changes: 5 additions & 14 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,10 @@ require (
github.com/Jeffail/gabs v1.4.0
github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware v0.0.0-20231023230448-f645697bf350
github.com/aws/aws-sdk-go v1.48.6
github.com/aws/aws-sdk-go-v2 v1.23.0
github.com/aws/aws-sdk-go-v2/config v1.25.1
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.4 // indirect
github.com/aws/aws-sdk-go-v2/service/autoscaling v1.35.0
github.com/aws/aws-sdk-go-v2 v1.23.5 // indirect
github.com/aws/aws-sdk-go-v2/config v1.25.1 // indirect
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.30.2
github.com/aws/aws-sdk-go-v2/service/ec2 v1.134.0
github.com/aws/aws-sdk-go-v2/service/ecs v1.33.1
github.com/aws/aws-sdk-go-v2/service/efs v1.23.2
github.com/aws/aws-sdk-go-v2/service/eks v1.33.1
github.com/aws/smithy-go v1.17.0
github.com/aws/smithy-go v1.18.1 // indirect
github.com/bigkevmcd/go-configparser v0.0.0-20200217161103-d137835d2579
github.com/deckarep/golang-set/v2 v2.3.1
github.com/go-kit/log v0.2.1
Expand Down Expand Up @@ -201,13 +195,10 @@ require (
github.com/apache/arrow/go/v12 v12.0.1 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.16.1 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.17.2 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.19.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.25.2 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
30 changes: 8 additions & 22 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ github.com/aws/aws-sdk-go v1.48.6 h1:hnL/TE3eRigirDLrdRE9AWE1ALZSVLAsC4wK8TGsMqk
github.com/aws/aws-sdk-go v1.48.6/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2 v1.23.0 h1:PiHAzmiQQr6JULBUdvR8fKlA+UPKLT/8KbiqpFBWiAo=
github.com/aws/aws-sdk-go-v2 v1.23.0/go.mod h1:i1XDttT4rnf6vxc9AuskLc6s7XBee8rlLilKlc03uAA=
github.com/aws/aws-sdk-go-v2 v1.23.5 h1:xK6C4udTyDMd82RFvNkDQxtAd00xlzFUtX4fF2nMZyg=
github.com/aws/aws-sdk-go-v2 v1.23.5/go.mod h1:t3szzKfP0NeRU27uBFczDivYJjsmSnqI8kIvKyWb9ds=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 h1:OPLEkmhXf6xFPiz0bLeDArZIDx1NNS4oJyG4nv3Gct0=
github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw=
github.com/aws/aws-sdk-go-v2/config v1.25.1 h1:YsjngBOl2mx4l3egkVWndr6/6TqtkdsWJFZIsQ924Ek=
Expand All @@ -222,32 +222,20 @@ github.com/aws/aws-sdk-go-v2/credentials v1.16.1 h1:WessyrdgyFN5TB+eLQdrFSlN/3oM
github.com/aws/aws-sdk-go-v2/credentials v1.16.1/go.mod h1:RQJyPxKcr+m4ArlIG1LUhMOrjposVfzbX6H8oR6oCgE=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.4 h1:9wKDWEjwSnXZre0/O3+ZwbBl1SmlgWYBbrTV10X/H1s=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.4/go.mod h1:t4i+yGHMCcUNIX1x7YVYa6bH/Do7civ5I6cG/6PMfyA=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.59 h1:E3Y+OfzOK1+rmRo/K2G0ml8Vs+Xqk0kOnf4nS0kUtBc=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.3 h1:DUwbD79T8gyQ23qVXFUthjzVMTviSHi3y4z58KvghhM=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.3/go.mod h1:7sGSz1JCKHWWBHq98m6sMtWQikmYPpxjqOydDemiVoM=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.3 h1:AplLJCtIaUZDCbr6+gLYdsYNxne4iuaboJhVt9d+WXI=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.3/go.mod h1:ify42Rb7nKeDDPkFjKn7q1bPscVPu/+gmHH8d2c+anU=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8 h1:8GVZIR0y6JRIUNSYI1xAMF4HDfV8H/bOsZ/8AD/uY5Q=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8/go.mod h1:rwBfu0SoUkBUZndVgPZKAD9Y2JigaZtRP68unRiYToQ=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8 h1:ZE2ds/qeBkhk3yqYvS3CDCFNvd9ir5hMjlVStLZWrvM=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8/go.mod h1:/lAPPymDYL023+TS6DJmjuL42nxix2AvEvfjqOBRODk=
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.0 h1:usgqiJtamuGIBj+OvYmMq89+Z1hIKkMJToz1WpoeNUY=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.0/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 h1:6lJvvkQ9HmbHZ4h/IEwclwv2mrTW8Uq1SOB/kXy0mfw=
github.com/aws/aws-sdk-go-v2/service/appconfig v1.4.2/go.mod h1:FZ3HkCe+b10uFZZkFdvf98LHW21k49W8o8J366lqVKY=
github.com/aws/aws-sdk-go-v2/service/autoscaling v1.35.0 h1:gximLUdElJagT16e3E6OzJK0RD/b4I5LaXSOzoMpDkc=
github.com/aws/aws-sdk-go-v2/service/autoscaling v1.35.0/go.mod h1:6NGYQhD5ky3wERvkhdhnFk7RKCg3nidKqE6DOEZgGgg=
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o=
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.30.2 h1:T2YjSwrDkLg2laNjhIunyTbjy9Qzd/oZ+yQjrAhdIEA=
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.30.2/go.mod h1:GuVYdn7tWjbyp/YtZSM6VczmceUUQW6v8Yq98wJ9dWY=
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.13.0 h1:NfqONXoDwWtBCnkPVz7GL/FKMo/s//TnHSwF+PjzG5c=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.14.0 h1:P+eF8PKkeaiTfN/VBe5GI3uNdhwCPVYCQxchRewJcWk=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.134.0 h1:ZozGfw2s79TxoqisrkALGCpXokhMkfZRQxPkd8+MK+Y=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.134.0/go.mod h1:xYJZQIo/YZxEbeBxUYRQJTCJ924EuKtDfrhVx76yzOE=
github.com/aws/aws-sdk-go-v2/service/ecs v1.33.1 h1:TozC9N4YIy3daojW5RoutyW0dIBCQvTtMXKDM7cSvW8=
github.com/aws/aws-sdk-go-v2/service/ecs v1.33.1/go.mod h1:twzaZjxQJVIuJBlk/PCQ/El6rwvxcCQ2uiO/5BguYHg=
github.com/aws/aws-sdk-go-v2/service/efs v1.23.2 h1:+Bal9jUaFSjYjiJkoE0eiqCvmknCboCvSCESznszsrQ=
github.com/aws/aws-sdk-go-v2/service/efs v1.23.2/go.mod h1:raG1iL/vkJ+4nVtmrc4PgmwH0JgZp5NBOcWFf9GBRJY=
github.com/aws/aws-sdk-go-v2/service/eks v1.33.1 h1:zRB7CTeejJmBpdpzrBkciNLMpg8T+06EvGA/H4Kkvcw=
github.com/aws/aws-sdk-go-v2/service/eks v1.33.1/go.mod h1:23btAyMrfTvG2zh/3+CZJ1c2eYWiVWP6tPRJwC67sk8=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 h1:rpkF4n0CyFcrJUG/rNNohoTmhtWlFTRI4BsZOh9PvLs=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1/go.mod h1:l9ymW25HOqymeU2m1gbUQ3rUIsTwKs8gYHXkqDQUhiI=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 h1:eev2yZX7esGRjqRbnVk1UxMLw4CyVZDpZXRCcy75oQk=
Expand All @@ -260,16 +248,14 @@ github.com/aws/aws-sdk-go-v2/service/kinesis v1.13.0 h1:wqLvwC4qdrrGikudu8Z9X2sb
github.com/aws/aws-sdk-go-v2/service/s3 v1.40.0 h1:wl5dxN1NONhTDQD9uaEvNsDRX29cBmGED/nl0jkWlt4=
github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk=
github.com/aws/aws-sdk-go-v2/service/sso v1.17.2 h1:V47N5eKgVZoRSvx2+RQ0EpAEit/pqOhqeSQFiS4OFEQ=
github.com/aws/aws-sdk-go-v2/service/sso v1.17.2/go.mod h1:/pE21vno3q1h4bbhUOEi+6Zu/aT26UK2WKkDXd+TssQ=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.19.2 h1:sMAcO7VHVw28HTAdZpTULDzFirHOsVm/x25CxhUH0jA=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.19.2/go.mod h1:dWqm5G767qwKPuayKfzm4rjzFmVjiBFbOJrpSPnAMDs=
github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g=
github.com/aws/aws-sdk-go-v2/service/sts v1.25.2 h1:vwyiRTnXLqsak/6WAQ+uTRhVqKI6vxUQ0HJXjKij0zM=
github.com/aws/aws-sdk-go-v2/service/sts v1.25.2/go.mod h1:4EqRHDCKP78hq3zOnmFXu5k0j4bXbRFfCh/zQ6KnEfQ=
github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.13.6 h1:HwNzaXr3lHe3YPEyyx7Fh41CZplz6G1YqB3OR0FJ2iw=
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/aws/smithy-go v1.17.0 h1:wWJD7LX6PBV6etBUwO0zElG0nWN9rUhp0WdYeHSHAaI=
github.com/aws/smithy-go v1.17.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
github.com/aws/smithy-go v1.18.1 h1:pOdBTUfXNazOlxLrgeYalVnuTpKreACHtc62xLwIB3c=
github.com/aws/smithy-go v1.18.1/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
github.com/aws/telegraf v0.10.2-0.20231103153700-d2a4b9e20b87 h1:/zmphBRn0vrwBzVOUmeXJQRuZxlvf1C0m+sHe81zwxg=
github.com/aws/telegraf v0.10.2-0.20231103153700-d2a4b9e20b87/go.mod h1:SMbtNz1+X7rQbr19B2Engg5+WWq+oI9rvRrEgy3qPho=
github.com/aws/telegraf/patches/gopsutil/v3 v3.0.0-20231109213610-a8c21c54a2be h1:sF6OUdk1hpuX7lf74vn+zBUFtQRe+hky0jmMYyFp5Kk=
Expand Down
130 changes: 130 additions & 0 deletions tool/clean/clean_iam_roles/clean_iam_roles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

package main

import (
"context"
"errors"
"fmt"
"log"
"strings"
"time"

"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/aws-sdk-go-v2/service/iam/types"

"github.com/aws/amazon-cloudwatch-agent/tool/clean"
)

const retentionPeriod = clean.KeepDurationOneWeek

var (
roleNamePrefixes = []string{
"cwa-integ-assume-role",
"cwagent-eks-Worker-Role",
"cwagent-integ-test-task-role",
"cwagent-operator-eks-Worker-Role",
"cwagent-operator-helm-integ-Worker-Role",
}
)

type iamClient interface {
ListRoles(ctx context.Context, input *iam.ListRolesInput, optFns ...func(*iam.Options)) (*iam.ListRolesOutput, error)
GetRole(ctx context.Context, input *iam.GetRoleInput, optFns ...func(*iam.Options)) (*iam.GetRoleOutput, error)
DeleteRole(ctx context.Context, input *iam.DeleteRoleInput, optFns ...func(*iam.Options)) (*iam.DeleteRoleOutput, error)
ListAttachedRolePolicies(ctx context.Context, input *iam.ListAttachedRolePoliciesInput, optFns ...func(*iam.Options)) (*iam.ListAttachedRolePoliciesOutput, error)
DetachRolePolicy(ctx context.Context, input *iam.DetachRolePolicyInput, optFns ...func(*iam.Options)) (*iam.DetachRolePolicyOutput, error)
}

func main() {
log.Print("Begin to clean IAM Roles")
ctx := context.Background()
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
log.Fatalf("unable to load AWS config: %v", err)
}
client := iam.NewFromConfig(cfg)
if err = deleteRoles(ctx, client, getExpirationDate()); err != nil {
log.Fatalf("errors cleaning: %v", err)
}
}

func getExpirationDate() time.Time {
return time.Now().UTC().Add(retentionPeriod)
}

func deleteRoles(ctx context.Context, client iamClient, expirationDate time.Time) error {
var errs error
var marker *string
for {
output, err := client.ListRoles(ctx, &iam.ListRolesInput{Marker: marker})
if err != nil {
return err
}
for _, role := range output.Roles {
if hasPrefix(*role.RoleName) && expirationDate.After(*role.CreateDate) {
var getRoleOutput *iam.GetRoleOutput
getRoleOutput, err = client.GetRole(ctx, &iam.GetRoleInput{RoleName: role.RoleName})
if err != nil {
return err
}
role = *getRoleOutput.Role
if role.RoleLastUsed == nil || role.RoleLastUsed.LastUsedDate == nil || expirationDate.After(*role.RoleLastUsed.LastUsedDate) {
errs = errors.Join(errs, deleteRole(ctx, client, role))
}
}
}
if output.Marker == nil {
break
}
marker = output.Marker
}
return errs
}

func deleteRole(ctx context.Context, client iamClient, role types.Role) error {
lastUsed := "never"
if role.RoleLastUsed != nil && role.RoleLastUsed.LastUsedDate != nil {
lastUsed = fmt.Sprintf("%d days ago", int(time.Since(*role.RoleLastUsed.LastUsedDate).Hours()/24))
}
log.Printf("Trying to delete role (%q) last used %s", *role.RoleName, lastUsed)
if err := detachPolicies(ctx, client, role); err != nil {
return err
}
if _, err := client.DeleteRole(ctx, &iam.DeleteRoleInput{RoleName: role.RoleName}); err != nil {
return err
}
log.Printf("Deleted role (%q) successfully", *role.RoleName)
return nil
}

func detachPolicies(ctx context.Context, client iamClient, role types.Role) error {
var marker *string
for {
output, err := client.ListAttachedRolePolicies(ctx, &iam.ListAttachedRolePoliciesInput{RoleName: role.RoleName, Marker: marker})
if err != nil {
return err
}
for _, policy := range output.AttachedPolicies {
if _, err = client.DetachRolePolicy(ctx, &iam.DetachRolePolicyInput{PolicyArn: policy.PolicyArn, RoleName: role.RoleName}); err != nil {
return fmt.Errorf("unable to detach policy (%q) from role (%q): %w", *policy.PolicyName, *role.RoleName, err)
}
}
if output.Marker == nil {
break
}
marker = output.Marker
}
return nil
}

func hasPrefix(roleName string) bool {
for _, prefix := range roleNamePrefixes {
if strings.HasPrefix(roleName, prefix) {
return true
}
}
return false
}
110 changes: 110 additions & 0 deletions tool/clean/clean_iam_roles/clean_iam_roles_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

package main

import (
"context"
"testing"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/aws-sdk-go-v2/service/iam/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

const (
expiredTestRoleName = "cwa-integ-assume-role-expired"
activeTestRoleName = "cwagent-integ-test-task-role-active"
)

type mockIamClient struct {
mock.Mock
}

var _ iamClient = (*mockIamClient)(nil)

func (m *mockIamClient) ListRoles(ctx context.Context, input *iam.ListRolesInput, optFns ...func(*iam.Options)) (*iam.ListRolesOutput, error) {
args := m.Called(ctx, input, optFns)
return args.Get(0).(*iam.ListRolesOutput), args.Error(1)
}

func (m *mockIamClient) GetRole(ctx context.Context, input *iam.GetRoleInput, optFns ...func(*iam.Options)) (*iam.GetRoleOutput, error) {
args := m.Called(ctx, input, optFns)
return args.Get(0).(*iam.GetRoleOutput), args.Error(1)
}

func (m *mockIamClient) DeleteRole(ctx context.Context, input *iam.DeleteRoleInput, optFns ...func(*iam.Options)) (*iam.DeleteRoleOutput, error) {
args := m.Called(ctx, input, optFns)
return args.Get(0).(*iam.DeleteRoleOutput), args.Error(1)
}

func (m *mockIamClient) ListAttachedRolePolicies(ctx context.Context, input *iam.ListAttachedRolePoliciesInput, optFns ...func(*iam.Options)) (*iam.ListAttachedRolePoliciesOutput, error) {
args := m.Called(ctx, input, optFns)
return args.Get(0).(*iam.ListAttachedRolePoliciesOutput), args.Error(1)
}

func (m *mockIamClient) DetachRolePolicy(ctx context.Context, input *iam.DetachRolePolicyInput, optFns ...func(*iam.Options)) (*iam.DetachRolePolicyOutput, error) {
args := m.Called(ctx, input, optFns)
return args.Get(0).(*iam.DetachRolePolicyOutput), args.Error(1)
}

func TestDeleteRoles(t *testing.T) {
expirationDate := getExpirationDate()

ctx := context.Background()
ignoredRole := types.Role{
CreateDate: aws.Time(expirationDate.Add(-2 * time.Hour)),
RoleName: aws.String("does-not-match-any-prefix"),
RoleLastUsed: &types.RoleLastUsed{
LastUsedDate: aws.Time(expirationDate.Add(-1 * time.Hour)),
},
}
expiredRole := types.Role{
CreateDate: aws.Time(expirationDate.Add(-2 * time.Hour)),
RoleName: aws.String(expiredTestRoleName),
RoleLastUsed: &types.RoleLastUsed{
LastUsedDate: aws.Time(expirationDate.Add(-1 * time.Hour)),
},
}
activeRole := types.Role{
CreateDate: aws.Time(expirationDate.Add(-2 * time.Hour)),
RoleName: aws.String(activeTestRoleName),
RoleLastUsed: &types.RoleLastUsed{
LastUsedDate: aws.Time(expirationDate.Add(time.Hour)),
},
}
testRoles := []types.Role{ignoredRole, expiredRole, activeRole}
testPolicies := []types.AttachedPolicy{
{
PolicyArn: aws.String("policy-arn"),
PolicyName: aws.String("policy-name"),
},
}

client := &mockIamClient{}
client.On("ListRoles", ctx, &iam.ListRolesInput{}, mock.Anything).Return(&iam.ListRolesOutput{Roles: testRoles}, nil)
client.On("GetRole", ctx, &iam.GetRoleInput{RoleName: aws.String(expiredTestRoleName)}, mock.Anything).Return(&iam.GetRoleOutput{Role: &expiredRole}, nil)
client.On("GetRole", ctx, &iam.GetRoleInput{RoleName: aws.String(activeTestRoleName)}, mock.Anything).Return(&iam.GetRoleOutput{Role: &activeRole}, nil)
client.On("DeleteRole", ctx, mock.Anything, mock.Anything).Return(&iam.DeleteRoleOutput{}, nil)
client.On("ListAttachedRolePolicies", ctx, mock.Anything, mock.Anything).Return(&iam.ListAttachedRolePoliciesOutput{AttachedPolicies: testPolicies}, nil)
client.On("DetachRolePolicy", ctx, mock.Anything, mock.Anything).Return(&iam.DetachRolePolicyOutput{}, nil)
assert.NoError(t, deleteRoles(ctx, client, expirationDate))
assert.Len(t, client.Calls, 6)
for _, call := range client.Calls {
switch call.Method {
case "DeleteRole":
input := call.Arguments.Get(1).(*iam.DeleteRoleInput)
assert.Equal(t, expiredTestRoleName, *input.RoleName)
case "ListAttachedRolePolicies":
input := call.Arguments.Get(1).(*iam.ListAttachedRolePoliciesInput)
assert.Equal(t, expiredTestRoleName, *input.RoleName)
case "DetachRolePolicy":
input := call.Arguments.Get(1).(*iam.DetachRolePolicyInput)
assert.Equal(t, expiredTestRoleName, *input.RoleName)
assert.Equal(t, "policy-arn", *input.PolicyArn)
}
}
}
Loading

0 comments on commit 1524426

Please sign in to comment.