func (rd *IAMRoleDeleter) DeleteResources(cfg *DeleteConfig) error {
	if len(rd.ResourceNames) == 0 {
		return nil
	}
	rls, rerr := rd.RequestIAMRoles()
	if rerr != nil && !cfg.IgnoreErrors {
		return rerr
	}
	fmtStr := "Deleted IAM Role"
	var (
		params *iam.DeleteRoleInput
		rpd    *IAMRolePolicyDeleter
	)
	for _, rl := range rls {
		nameStr := aws.StringValue(rl.RoleName)
		rpd = &IAMRolePolicyDeleter{RoleName: arn.ResourceName(nameStr)}
		policyNames, rerr := rpd.RequestIAMRolePoliciesFromRoles()
		if rerr != nil && !cfg.IgnoreErrors {
			continue
		}
		rpd.PolicyNames = policyNames
		if err := rpd.DeleteResources(cfg); err != nil {
			continue
		}
		if cfg.DryRun {
			fmt.Println(drStr, fmtStr, nameStr)
			continue
		}
		params = &iam.DeleteRoleInput{
			RoleName: rl.RoleName,
		}
		ctx := aws.BackgroundContext()
		_, err := rd.GetClient().DeleteRoleWithContext(ctx, params)
		if err != nil {
			cfg.logRequestError(arn.IAMRoleRType, nameStr, err)
			if cfg.IgnoreErrors {
				continue
			}
			return err
		}
		cfg.logRequestSuccess(arn.IAMRoleRType, nameStr)
		fmt.Println(fmtStr, nameStr)
	}
	return nil
}
DeleteResources deletes IAM roles from AWS
package deleter
import (
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/aws/aws-sdk-go/service/iam/iamiface"
	"github.com/coreos/grafiti/arn"
	"github.com/sirupsen/logrus"
)
type IAMInstanceProfileDeleter struct {
	Client        iamiface.IAMAPI
	ResourceType  arn.ResourceType
	ResourceNames arn.ResourceNames
}
func (rd *IAMInstanceProfileDeleter) String() string {
	return fmt.Sprintf(`{"Type": "%s", "Names": %v}`, rd.ResourceType, rd.ResourceNames)
}
func (rd *IAMInstanceProfileDeleter) GetClient() iamiface.IAMAPI {
	if rd.Client == nil {
		rd.Client = iam.New(setUpAWSSession())
	}
	return rd.Client
}
func (rd *IAMInstanceProfileDeleter) AddResourceNames(ns ...arn.ResourceName) {
	rd.ResourceNames = append(rd.ResourceNames, ns...)
}
func (rd *IAMInstanceProfileDeleter) DeleteResources(cfg *DeleteConfig) error {
	if len(rd.ResourceNames) == 0 {
		return nil
	}
	iprs, err := rd.RequestIAMInstanceProfiles()
	if err != nil && !cfg.IgnoreErrors {
		return err
	}
	if err := rd.deleteIAMRolesFromInstanceProfiles(cfg, iprs); err != nil {
		return err
	}
	fmtStr := "Deleted IAM InstanceProfile"
	var params *iam.DeleteInstanceProfileInput
	for _, ipr := range iprs {
		nameStr := aws.StringValue(ipr.InstanceProfileName)
		if cfg.DryRun {
			fmt.Println(drStr, fmtStr, nameStr)
			continue
		}
		params = &iam.DeleteInstanceProfileInput{
			InstanceProfileName: ipr.InstanceProfileName,
		}
		ctx := aws.BackgroundContext()
		_, err := rd.GetClient().DeleteInstanceProfileWithContext(ctx, params)
		if err != nil {
			cfg.logRequestError(arn.IAMInstanceProfileRType, nameStr, err)
			if cfg.IgnoreErrors {
				continue
			}
			return err
		}
		cfg.logRequestSuccess(arn.IAMInstanceProfileRType, nameStr)
		fmt.Println(fmtStr, nameStr)
	}
	return nil
}
func (rd *IAMInstanceProfileDeleter) deleteIAMRolesFromInstanceProfiles(cfg *DeleteConfig, iprs []*iam.InstanceProfile) error {
	if len(iprs) == 0 {
		return nil
	}
	var params *iam.RemoveRoleFromInstanceProfileInput
	for _, ipr := range iprs {
		iprNameStr := aws.StringValue(ipr.InstanceProfileName)
		for _, rl := range ipr.Roles {
			roleNameStr := aws.StringValue(rl.RoleName)
			if cfg.DryRun {
				fmt.Printf("%s Removed Role %s from IAM InstanceProfile %s\n", drStr, roleNameStr, iprNameStr)
				continue
			}
			params = &iam.RemoveRoleFromInstanceProfileInput{
				InstanceProfileName: ipr.InstanceProfileName,
				RoleName:            rl.RoleName,
			}
			ctx := aws.BackgroundContext()
			_, err := rd.GetClient().RemoveRoleFromInstanceProfileWithContext(ctx, params)
			if err != nil {
				cfg.logRequestError(arn.IAMRoleRType, roleNameStr, err, logrus.Fields{
					"parent_resource_type": arn.IAMInstanceProfileRType,
					"parent_resource_name": iprNameStr,
				})
				if cfg.IgnoreErrors {
					continue
				}
				return err
			}
			cfg.logRequestSuccess(arn.IAMRoleRType, roleNameStr, logrus.Fields{
				"parent_resource_type": arn.IAMInstanceProfileRType,
				"parent_resource_name": iprNameStr,
			})
			fmt.Printf("Removed Role %s from IAM InstanceProfile %s\n", iprNameStr, roleNameStr)
		}
	}
	return nil
}
func (rd *IAMInstanceProfileDeleter) RequestIAMInstanceProfiles() ([]*iam.InstanceProfile, error) {
	if len(rd.ResourceNames) == 0 {
		return nil, nil
	}
	want, iprs := createResourceNameMapFromResourceNames(rd.ResourceNames), make([]*iam.InstanceProfile, 0)
	params := &iam.ListInstanceProfilesInput{
		MaxItems: aws.Int64(100),
	}
	for {
		ctx := aws.BackgroundContext()
		resp, err := rd.GetClient().ListInstanceProfilesWithContext(ctx, params)
		if err != nil {
			fmt.Printf("{\"error\": \"%s\"}\n", err)
			return iprs, err
		}
		for _, rp := range resp.InstanceProfiles {
			if _, ok := want[arn.ToResourceName(rp.InstanceProfileName)]; ok {
				iprs = append(iprs, rp)
			}
		}
		if !aws.BoolValue(resp.IsTruncated) {
			break
		}
		params.Marker = resp.Marker
	}
	return iprs, nil
}
func createResourceNameMapFromResourceNames(names arn.ResourceNames) map[arn.ResourceName]struct{} {
	want := map[arn.ResourceName]struct{}{}
	for _, n := range names {
		if _, ok := want[n]; !ok {
			want[n] = struct{}{}
		}
	}
	return want
}
type IAMRoleDeleter struct {
	Client        iamiface.IAMAPI
	ResourceType  arn.ResourceType
	ResourceNames arn.ResourceNames
}
func (rd *IAMRoleDeleter) String() string {
	return fmt.Sprintf(`{"Type": "%s", "Names": %v}`, rd.ResourceType, rd.ResourceNames)
}
func (rd *IAMRoleDeleter) GetClient() iamiface.IAMAPI {
	if rd.Client == nil {
		rd.Client = iam.New(setUpAWSSession())
	}
	return rd.Client
}
func (rd *IAMRoleDeleter) AddResourceNames(ns ...arn.ResourceName) {
	rd.ResourceNames = append(rd.ResourceNames, ns...)
}