diff --git a/cloudmock/aws/mockiam/iaminstanceprofile.go b/cloudmock/aws/mockiam/iaminstanceprofile.go index 5c12dde79c..92fca04ccb 100644 --- a/cloudmock/aws/mockiam/iaminstanceprofile.go +++ b/cloudmock/aws/mockiam/iaminstanceprofile.go @@ -18,6 +18,7 @@ package mockiam import ( "fmt" + "strings" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -31,7 +32,7 @@ func (m *MockIAM) GetInstanceProfile(request *iam.GetInstanceProfileInput) (*iam defer m.mutex.Unlock() ip := m.InstanceProfiles[aws.StringValue(request.InstanceProfileName)] - if ip == nil { + if ip == nil || strings.Contains(aws.StringValue(ip.InstanceProfileName), "__no_entity__") { return nil, awserr.New(iam.ErrCodeNoSuchEntityException, "No such entity", nil) } response := &iam.GetInstanceProfileOutput{ diff --git a/pkg/resources/aws/aws.go b/pkg/resources/aws/aws.go index d29514e610..1a69bd2456 100644 --- a/pkg/resources/aws/aws.go +++ b/pkg/resources/aws/aws.go @@ -2007,10 +2007,10 @@ func ListIAMRoles(cloud fi.Cloud, clusterName string) ([]*resources.Resource, er if awserror.StatusCode() == 403 { klog.Warningf("failed to determine ownership of %q: %v", *r.RoleName, awserror) - return true + continue } else if awsup.AWSErrorCode(err) == iam.ErrCodeNoSuchEntityException { klog.Warningf("could not find instance profile %q. Resource may already have been deleted: %v", name, awserror) - return true + continue } } else { getRoleErr = fmt.Errorf("calling IAM GetRole on %s: %w", name, err) @@ -2096,6 +2096,7 @@ func ListIAMInstanceProfiles(cloud fi.Cloud, clusterName string) ([]*resources.R if awserror, ok := err.(awserr.Error); ok { if awserror.Code() == iam.ErrCodeNoSuchEntityException { klog.Warningf("could not find instance profile %q. Resource may already have been deleted: %v", *p.InstanceProfileName, awserror) + continue } } getProfileErr = fmt.Errorf("calling IAM GetInstanceProfile on %s: %w", name, err) diff --git a/pkg/resources/aws/aws_test.go b/pkg/resources/aws/aws_test.go index 1711c04ce6..799db31652 100644 --- a/pkg/resources/aws/aws_test.go +++ b/pkg/resources/aws/aws_test.go @@ -94,6 +94,80 @@ func TestAddUntaggedRouteTables(t *testing.T) { } } +func TestListIAMInstanceProfiles(t *testing.T) { + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") + // resources := make(map[string]*Resource) + clusterName := "me.example.com" + ownershipTagKey := "kubernetes.io/cluster/" + clusterName + + c := &mockiam.MockIAM{ + InstanceProfiles: make(map[string]*iam.InstanceProfile), + } + cloud.MockIAM = c + + tags := []*iam.Tag{ + { + Key: &ownershipTagKey, + Value: fi.String("owned"), + }, + } + + { + name := "prefixed." + clusterName + + c.InstanceProfiles[name] = &iam.InstanceProfile{ + InstanceProfileName: &name, + Tags: tags, + } + } + { + + name := clusterName + ".not-prefixed" + + c.InstanceProfiles[name] = &iam.InstanceProfile{ + InstanceProfileName: &name, + Tags: tags, + } + } + { + name := "prefixed2." + clusterName + owner := "kubernetes.io/cluster/foo." + clusterName + c.InstanceProfiles[name] = &iam.InstanceProfile{ + InstanceProfileName: &name, + Tags: []*iam.Tag{ + { + Key: &owner, + Value: fi.String("owned"), + }, + }, + } + } + + { + name := "prefixed3." + clusterName + c.InstanceProfiles[name] = &iam.InstanceProfile{ + InstanceProfileName: &name, + } + } + + // This is a special entity that will appear in list, but not in get + { + name := "__no_entity__." + clusterName + c.InstanceProfiles[name] = &iam.InstanceProfile{ + InstanceProfileName: &name, + } + } + + resourceTrackers, err := ListIAMInstanceProfiles(cloud, clusterName) + if err != nil { + t.Fatalf("error listing IAM roles: %v", err) + } + + if len(resourceTrackers) != 2 { + t.Errorf("Unexpected number of resources to delete. Expected 2, got %d", len(resourceTrackers)) + } +} + func TestListIAMRoles(t *testing.T) { cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") // resources := make(map[string]*Resource)