diff --git a/README.md b/README.md index e3f9053b..322d0a4d 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ Cloud-nuke suppports 🔎 inspecting and 🔥💀 deleting the following AWS res | Resource Family | Resource type | |-------------------------|----------------------------------------------------------| | App Runner | Service | +| Data Sync | Location | +| Data Sync | Task | | EC2 | Auto scaling groups | | EC2 | Elastic Load Balancers (v1 and v2) | | EC2 | EBS Volumes | @@ -28,17 +30,17 @@ Cloud-nuke suppports 🔎 inspecting and 🔥💀 deleting the following AWS res | EC2 | Elastic IPs | | EC2 | Launch Configurations | | EC2 | IPAM (Amazon VPC IP Address Manager) | -| EC2 | IPAM Pool | -| EC2 | IPAM Scope | -| EC2 | IPAM Custom Allocation | -| EC2 | IPAM BYOASN | -| EC2 | IPAM Resource Discovery | -| EC2 | Internet Gateway | -| EC2 | Network ACL | -| EC2 | Egress only internet gateway | -| EC2 | Endpoint | -| EC2 | Security Group | -| EC2 | Network Interface | +| EC2 | IPAM Pool | +| EC2 | IPAM Scope | +| EC2 | IPAM Custom Allocation | +| EC2 | IPAM BYOASN | +| EC2 | IPAM Resource Discovery | +| EC2 | Internet Gateway | +| EC2 | Network ACL | +| EC2 | Egress only internet gateway | +| EC2 | Endpoint | +| EC2 | Security Group | +| EC2 | Network Interface | | Certificate Manager | ACM Private CA | | Direct Connect | Transit Gateways | | Elasticache | Clusters | @@ -88,7 +90,7 @@ Cloud-nuke suppports 🔎 inspecting and 🔥💀 deleting the following AWS res | RDS | Neptune | | RDS | Document DB instances | | RDS | RDS parameter group | -| RDS | RDS Proxy | +| RDS | RDS Proxy | | Security Hub | Hubs | | Security Hub | Members | | Security Hub | Administrators | @@ -106,10 +108,10 @@ Cloud-nuke suppports 🔎 inspecting and 🔥💀 deleting the following AWS res | NetworkFirewall | Network Firewall Policy | | NetworkFirewall | Network Firewall Rule Group | | NetworkFirewall | Network Firewall TLS inspection configuration | -| NetworkFirewall | Network Firewall Resource Policy | -| VPCLattice | VPC Lattice Service | -| VPCLattice | VPC Lattice Service Network | -| VPCLattice | VPC Lattice Target Group | +| NetworkFirewall | Network Firewall Resource Policy | +| VPCLattice | VPC Lattice Service | +| VPCLattice | VPC Lattice Service Network | +| VPCLattice | VPC Lattice Target Group | > **WARNING:** The RDS APIs also interact with neptune and document db resources. > Running `cloud-nuke aws --resource-type rds` without a config file will remove any neptune and document db resources @@ -539,107 +541,108 @@ _Note: it doesn't support including resources by tags._ To find out what we options are supported in the config file today, consult this table. Resource types at the top level of the file that are supported are listed here. -| resource type | config key | names_regex | time | tags | timeout | -|-----------------------------|------------------------------|----------------------------------------|--------------------------------------|-------|---------| -| acm | ACM | ✅ (Domain Name) | ✅ (Created Time) | ❌ | ✅ | -| acmpca | ACMPCA | ❌ | ✅ (LastStateChange or Created Time) | ❌ | ✅ | -| ami | AMI | ✅ (Image Name) | ✅ (Creation Time) | ❌ | ✅ | -| apigateway | APIGateway | ✅ (API Name) | ✅ (Created Time) | ❌ | ✅ | -| apigatewayv2 | APIGatewayV2 | ✅ (API Name) | ✅ (Created Time) | ❌ | ✅ | -| accessanalyzer | AccessAnalyzer | ✅ (Analyzer Name) | ✅ (Created Time) | ❌ | ✅ | -| asg | AutoScalingGroup | ✅ (ASG Name) | ✅ (Created Time) | ✅ | ✅ | -| app-runner-service | AppRunnerService | ✅ (App Runner Service Name) | ✅ (Created Time) | ❌ | ✅ | -| backup-vault | BackupVault | ✅ (Backup Vault Name) | ✅ (Created Time) | ❌ | ✅ | -| cloudwatch-alarm | CloudWatchAlarm | ✅ (Alarm Name) | ✅ (AlarmConfigurationUpdated Time) | ❌ | ✅ | -| cloudwatch-dashboard | CloudWatchDashboard | ✅ (Dashboard Name) | ✅ (LastModified Time) | ❌ | ✅ | -| cloudwatch-loggroup | CloudWatchLogGroup | ✅ (Log Group Name) | ✅ (Creation Time) | ❌ | ✅ | -| cloudtrail | CloudtrailTrail | ✅ (Trail Name) | ❌ | ❌ | ✅ | -| codedeploy-application | CodeDeployApplications | ✅ (Application Name) | ✅ (Creation Time) | ❌ | ✅ | -| config-recorders | ConfigServiceRecorder | ✅ (Recorder Name) | ❌ | ❌ | ✅ | -| config-rules | ConfigServiceRule | ✅ (Rule Name) | ❌ | ❌ | ✅ | -| dynamodb | DynamoDB | ✅ (Table Name) | ✅ (Creation Time) | ❌ | ✅ | -| ebs | EBSVolume | ✅ (Volume Name) | ✅ (Creation Time) | ✅ | ✅ | -| elastic-beanstalk | ElasticBeanstalk | ✅ (Application Name) | ✅ (Creation Time) | ❌ | ✅ | -| ec2 | EC2 | ✅ (Instance Name) | ✅ (Launch Time) | ✅ | ✅ | -| ec2-dedicated-hosts | EC2DedicatedHosts | ✅ (EC2 Name Tag) | ✅ (Allocation Time) | ❌ | ✅ | -| ec2-dhcp-option | EC2DhcpOption | ❌ | ❌ | ❌ | ✅ | -| ec2-keypairs | EC2KeyPairs | ✅ (Key Pair Name) | ✅ (Creation Time) | ✅ | ✅ | -| ec2-ipam | EC2IPAM | ✅ (IPAM name) | ✅ (Creation Time) | ✅ | ✅ | -| ec2-ipam-pool | EC2IPAMPool | ✅ (IPAM Pool name) | ✅ (Creation Time) | ✅ | ✅ | -| ec2-ipam-resource-discovery | EC2IPAMResourceDiscovery | ✅ (IPAM Discovery Name) | ✅ (Creation Time) | ✅ | ✅ | -| ec2-ipam-scope | EC2IPAMScope | ✅ (IPAM Scope Name) | ✅ (Creation Time) | ✅ | ✅ | -| ec2-subnet | EC2Subnet | ✅ (Subnet Name) | ✅ (Creation Time) | ✅ | ❌ | -| ec2-endpoint | EC2Endpoint | ✅ (Endpoint Name) | ✅ (Creation Time) | ✅ | ✅ | -| ecr | ECRRepository | ✅ (Repository Name) | ✅ (Creation Time) | ❌ | ✅ | -| ecscluster | ECSCluster | ✅ (Cluster Name) | ❌ | ❌ | ✅ | -| ecsserv | ECSService | ✅ (Service Name) | ✅ (Creation Time) | ❌ | ✅ | -| ekscluster | EKSCluster | ✅ (Cluster Name) | ✅ (Creation Time) | ✅ | ✅ | -| elb | ELBv1 | ✅ (Load Balancer Name) | ✅ (Created Time) | ❌ | ✅ | -| elbv2 | ELBv2 | ✅ (Load Balancer Name) | ✅ (Created Time) | ❌ | ✅ | -| efs | ElasticFileSystem | ✅ (File System Name) | ✅ (Creation Time) | ❌ | ✅ | -| eip | ElasticIP | ✅ (Elastic IP Allocation Name) | ✅ (First Seen Tag Time) | ✅ | ✅ | -| elasticache | Elasticache | ✅ (Cluster ID & Replication Group ID) | ✅ (Creation Time) | ❌ | ✅ | -| elasticacheparametergroups | ElasticacheParameterGroups | ✅ (Parameter Group Name) | ❌ | ❌ | ✅ | -| elasticachesubnetgroups | ElasticacheSubnetGroups | ✅ (Subnet Group Name) | ❌ | ❌ | ✅ | -| guardduty | GuardDuty | ❌ | ✅ (Created Time) | ❌ | ✅ | -| iam-group | IAMGroups | ✅ (Group Name) | ✅ (Creation Time) | ❌ | ✅ | -| iam-policy | IAMPolicies | ✅ (Policy Name) | ✅ (Creation Time) | ❌ | ✅ | -| iam-role | IAMRoles | ✅ (Role Name) | ✅ (Creation Time) | ❌ | ✅ | -| iam-service-linked-role | IAMServiceLinkedRoles | ✅ (Service Linked Role Name) | ✅ (Creation Time) | ❌ | ✅ | -| iam | IAMUsers | ✅ (User Name) | ✅ (Creation Time) | ✅ | ✅ | -| internet-gateway | InternetGateway | ✅ (Gateway Name) | ✅ (Creation Time) | ✅ | ✅ | -| egress-only-internet-gateway| EgressOnlyInternetGateway | ✅ (Gateway name) | ✅ (Creation Time) | ✅ | ✅ | -| kmscustomerkeys | KMSCustomerKeys | ✅ (Key Name) | ✅ (Creation Time) | ❌ | ❌ | -| kinesis-stream | KinesisStream | ✅ (Stream Name) | ❌ | ❌ | ✅ | -| kinesis-firehose | KinesisFirehose | ✅ (Delivery Stream Name) | ❌ | ❌ | ✅ | -| lambda | LambdaFunction | ✅ (Function Name) | ✅ (Last Modified Time) | ❌ | ✅ | -| lc | LaunchConfiguration | ✅ (Launch Configuration Name) | ✅ (Created Time) | ❌ | ✅ | -| lt | LaunchTemplate | ✅ (Launch Template Name) | ✅ (Created Time) | ❌ | ✅ | -| macie-member | MacieMember | ❌ | ✅ (Creation Time) | ❌ | ✅ | -| msk-cluster | MSKCluster | ✅ (Cluster Name) | ✅ (Creation Time) | ❌ | ✅ | -| nat-gateway | NatGateway | ✅ (EC2 Name Tag) | ✅ (Creation Time) | ✅ | ✅ | -| network-acl | NetworkACL | ✅ (ACL Name Tag) | ✅ (Creation Time) | ✅ | ✅ | -| network-interface | NetworkInterface | ✅ (Interface Name Tag) | ✅ (Creation Time) | ✅ | ✅ | -| oidcprovider | OIDCProvider | ✅ (Provider URL) | ✅ (Creation Time) | ❌ | ✅ | -| opensearchdomain | OpenSearchDomain | ✅ (Domain Name) | ✅ (First Seen Tag Time) | ❌ | ✅ | -| redshift | Redshift | ✅ (Cluster Identifier) | ✅ (Creation Time) | ❌ | ✅ | -| rds-cluster | DBClusters | ✅ (DB Cluster Identifier ) | ✅ (Creation Time) | ✅ | ✅ | -| rds | DBInstances | ✅ (DB Name) | ✅ (Creation Time) | ✅ | ✅ | -| rds-parameter-group | RdsParameterGroup | ✅ (Group Name) | ❌ | ❌ | ✅ | -| rds-subnet-group | DBSubnetGroups | ✅ (DB Subnet Group Name) | ❌ | ❌ | ✅ | -| rds-proxy | RDSProxy | ✅ (proxy Name) | ✅ (Creation Time) | ❌ | ✅ | -| s3 | s3 | ✅ (Bucket Name) | ✅ (Creation Time) | ✅ | ✅ | -| s3-ap | s3AccessPoint | ✅ (Access point Name) | ❌ | ❌ | ✅ | -| s3-olap | S3ObjectLambdaAccessPoint | ✅ (Object Lambda Access point Name) | ❌ | ❌ | ✅ | -| s3-mrap | S3MultiRegionAccessPoint | ✅ (Multi region Access point Name) | ✅ (Creation Time) | ❌ | ✅ | -| security-group | SecurityGroup | ✅ (Security group name) | ✅ (Creation Time) | ✅ | ❌ | -| ses-configuration-set | SesConfigurationset | ✅ (Configuration set name) | ❌ | ❌ | ✅ | -| ses-email-template | SesEmailTemplates | ✅ (Template Name) | ✅ (Creation Time) | ❌ | ✅ | -| ses-identity | SesIdentity | ✅ (Identity -Mail/Domain) | ❌ | ❌ | ✅ | -| ses-receipt-rule-set | SesReceiptRuleSet | ✅ (Receipt Rule Set Name) | ✅ (Creation Time) | ❌ | ✅ | -| ses-receipt-filter | SesReceiptFilter | ✅ (Receipt Filter Name) | ❌ | ❌ | ✅ | -| snstopic | SNS | ✅ (Topic Name) | ✅ (First Seen Tag Time) | ❌ | ✅ | -| sqs | SQS | ✅ (Queue Name) | ✅ (Creation Time) | ❌ | ✅ | -| sagemaker-notebook-smni | SageMakerNotebook | ✅ (Notebook Instnace Name) | ✅ (Creation Time) | ❌ | ✅ | -| secretsmanager | SecretsManager | ✅ (Secret Name) | ✅ (Last Accessed or Creation Time) | ❌ | ✅ | -| security-hub | SecurityHub | ❌ | ✅ (Created Time) | ❌ | ✅ | -| snap | Snapshots | ❌ | ✅ (Creation Time) | ✅ | ✅ | -| transit-gateway | TransitGateway | ❌ | ✅ (Creation Time) | ❌ | ✅ | -| transit-gateway-route-table | TransitGatewayRouteTable | ❌ | ✅ (Creation Time) | ❌ | ✅ | -| transit-gateway-attachment | TransitGatewaysVpcAttachment | ❌ | ✅ (Creation Time) | ❌ | ✅ | -| vpc | VPC | ✅ (EC2 Name Tag) | ✅ (First Seen Tag Time) | ❌ | ❌ | -| route53-hosted-zone | Route53HostedZone | ✅ (Hosted zone name) | ❌ | ❌ | ❌ | -| route53-cidr-collection | Route53CIDRCollection | ✅ (Cidr collection name) | ❌ | ❌ | ❌ | -| route53-traffic-policy | Route53TrafficPolicy | ✅ (Traffic policy name) | ❌ | ❌ | ❌ | -| network-firewall | NetworkFirewall | ✅ (Firewall name) | ✅ (First Seen Tag Time) | ✅ | ❌ | -| network-firewall-policy | NetworkFirewallPolicy | ✅ (Firewall Policy name) | ✅ (First Seen Tag Time) | ✅ | ❌ | -| network-firewall-rule-group | NetworkFirewallRuleGroup | ✅ (Firewall Rule group name) | ✅ (First Seen Tag Time) | ✅ | ❌ | -| network-firewall-tls-config | NetworkFirewallTLSConfig | ✅ (Firewall TLS config name) | ✅ (First Seen Tag Time) | ✅ | ❌ | -| network-firewall-resource-policy | NetworkFirewallResourcePolicy | ✅ (Firewall Resource Policy ARN) | ❌ | ❌ | ❌ | -| vpc-lattice-service | VPCLatticeService | ✅ (VPC Lattice service ARN) | (Creation Time) | ❌ | ✅ | -| vpc-lattice-service-network | VPCLatticeServiceNetwork | ✅ (VPC Lattice service network ARN) | (Creation Time) | ❌ | ✅ | -| vpc-lattice-target-group | VPCLatticeTargetGroup | ✅ (VPC Lattice target group ARN) | (Creation Time) | ❌ | ✅ | - +| resource type | config key | names_regex | time | tags | timeout | +|----------------------------------|-------------------------------|---------------------------------------|-------------------------------------|------|---------| +| acm | ACM | ✅ (Domain Name) | ✅ (Created Time) | ❌ | ✅ | +| acmpca | ACMPCA | ❌ | ✅ (LastStateChange or Created Time) | ❌ | ✅ | +| ami | AMI | ✅ (Image Name) | ✅ (Creation Time) | ❌ | ✅ | +| apigateway | APIGateway | ✅ (API Name) | ✅ (Created Time) | ❌ | ✅ | +| apigatewayv2 | APIGatewayV2 | ✅ (API Name) | ✅ (Created Time) | ❌ | ✅ | +| accessanalyzer | AccessAnalyzer | ✅ (Analyzer Name) | ✅ (Created Time) | ❌ | ✅ | +| asg | AutoScalingGroup | ✅ (ASG Name) | ✅ (Created Time) | ✅ | ✅ | +| app-runner-service | AppRunnerService | ✅ (App Runner Service Name) | ✅ (Created Time) | ❌ | ✅ | +| backup-vault | BackupVault | ✅ (Backup Vault Name) | ✅ (Created Time) | ❌ | ✅ | +| cloudwatch-alarm | CloudWatchAlarm | ✅ (Alarm Name) | ✅ (AlarmConfigurationUpdated Time) | ❌ | ✅ | +| cloudwatch-dashboard | CloudWatchDashboard | ✅ (Dashboard Name) | ✅ (LastModified Time) | ❌ | ✅ | +| cloudwatch-loggroup | CloudWatchLogGroup | ✅ (Log Group Name) | ✅ (Creation Time) | ❌ | ✅ | +| cloudtrail | CloudtrailTrail | ✅ (Trail Name) | ❌ | ❌ | ✅ | +| codedeploy-application | CodeDeployApplications | ✅ (Application Name) | ✅ (Creation Time) | ❌ | ✅ | +| config-recorders | ConfigServiceRecorder | ✅ (Recorder Name) | ❌ | ❌ | ✅ | +| config-rules | ConfigServiceRule | ✅ (Rule Name) | ❌ | ❌ | ✅ | +| data-sync-location | DataSyncLocation | ❌ | ❌ | ❌ | ✅ | +| data-sync-task | DataSyncTask | ✅ (Task Name) | ❌ | ❌ | ✅ | +| dynamodb | DynamoDB | ✅ (Table Name) | ✅ (Creation Time) | ❌ | ✅ | +| ebs | EBSVolume | ✅ (Volume Name) | ✅ (Creation Time) | ✅ | ✅ | +| elastic-beanstalk | ElasticBeanstalk | ✅ (Application Name) | ✅ (Creation Time) | ❌ | ✅ | +| ec2 | EC2 | ✅ (Instance Name) | ✅ (Launch Time) | ✅ | ✅ | +| ec2-dedicated-hosts | EC2DedicatedHosts | ✅ (EC2 Name Tag) | ✅ (Allocation Time) | ❌ | ✅ | +| ec2-dhcp-option | EC2DhcpOption | ❌ | ❌ | ❌ | ✅ | +| ec2-keypairs | EC2KeyPairs | ✅ (Key Pair Name) | ✅ (Creation Time) | ✅ | ✅ | +| ec2-ipam | EC2IPAM | ✅ (IPAM name) | ✅ (Creation Time) | ✅ | ✅ | +| ec2-ipam-pool | EC2IPAMPool | ✅ (IPAM Pool name) | ✅ (Creation Time) | ✅ | ✅ | +| ec2-ipam-resource-discovery | EC2IPAMResourceDiscovery | ✅ (IPAM Discovery Name) | ✅ (Creation Time) | ✅ | ✅ | +| ec2-ipam-scope | EC2IPAMScope | ✅ (IPAM Scope Name) | ✅ (Creation Time) | ✅ | ✅ | +| ec2-subnet | EC2Subnet | ✅ (Subnet Name) | ✅ (Creation Time) | ✅ | ❌ | +| ec2-endpoint | EC2Endpoint | ✅ (Endpoint Name) | ✅ (Creation Time) | ✅ | ✅ | +| ecr | ECRRepository | ✅ (Repository Name) | ✅ (Creation Time) | ❌ | ✅ | +| ecscluster | ECSCluster | ✅ (Cluster Name) | ❌ | ❌ | ✅ | +| ecsserv | ECSService | ✅ (Service Name) | ✅ (Creation Time) | ❌ | ✅ | +| ekscluster | EKSCluster | ✅ (Cluster Name) | ✅ (Creation Time) | ✅ | ✅ | +| elb | ELBv1 | ✅ (Load Balancer Name) | ✅ (Created Time) | ❌ | ✅ | +| elbv2 | ELBv2 | ✅ (Load Balancer Name) | ✅ (Created Time) | ❌ | ✅ | +| efs | ElasticFileSystem | ✅ (File System Name) | ✅ (Creation Time) | ❌ | ✅ | +| eip | ElasticIP | ✅ (Elastic IP Allocation Name) | ✅ (First Seen Tag Time) | ✅ | ✅ | +| elasticache | Elasticache | ✅ (Cluster ID & Replication Group ID) | ✅ (Creation Time) | ❌ | ✅ | +| elasticacheparametergroups | ElasticacheParameterGroups | ✅ (Parameter Group Name) | ❌ | ❌ | ✅ | +| elasticachesubnetgroups | ElasticacheSubnetGroups | ✅ (Subnet Group Name) | ❌ | ❌ | ✅ | +| guardduty | GuardDuty | ❌ | ✅ (Created Time) | ❌ | ✅ | +| iam-group | IAMGroups | ✅ (Group Name) | ✅ (Creation Time) | ❌ | ✅ | +| iam-policy | IAMPolicies | ✅ (Policy Name) | ✅ (Creation Time) | ❌ | ✅ | +| iam-role | IAMRoles | ✅ (Role Name) | ✅ (Creation Time) | ❌ | ✅ | +| iam-service-linked-role | IAMServiceLinkedRoles | ✅ (Service Linked Role Name) | ✅ (Creation Time) | ❌ | ✅ | +| iam | IAMUsers | ✅ (User Name) | ✅ (Creation Time) | ✅ | ✅ | +| internet-gateway | InternetGateway | ✅ (Gateway Name) | ✅ (Creation Time) | ✅ | ✅ | +| egress-only-internet-gateway | EgressOnlyInternetGateway | ✅ (Gateway name) | ✅ (Creation Time) | ✅ | ✅ | +| kmscustomerkeys | KMSCustomerKeys | ✅ (Key Name) | ✅ (Creation Time) | ❌ | ❌ | +| kinesis-stream | KinesisStream | ✅ (Stream Name) | ❌ | ❌ | ✅ | +| kinesis-firehose | KinesisFirehose | ✅ (Delivery Stream Name) | ❌ | ❌ | ✅ | +| lambda | LambdaFunction | ✅ (Function Name) | ✅ (Last Modified Time) | ❌ | ✅ | +| lc | LaunchConfiguration | ✅ (Launch Configuration Name) | ✅ (Created Time) | ❌ | ✅ | +| lt | LaunchTemplate | ✅ (Launch Template Name) | ✅ (Created Time) | ❌ | ✅ | +| macie-member | MacieMember | ❌ | ✅ (Creation Time) | ❌ | ✅ | +| msk-cluster | MSKCluster | ✅ (Cluster Name) | ✅ (Creation Time) | ❌ | ✅ | +| nat-gateway | NatGateway | ✅ (EC2 Name Tag) | ✅ (Creation Time) | ✅ | ✅ | +| network-acl | NetworkACL | ✅ (ACL Name Tag) | ✅ (Creation Time) | ✅ | ✅ | +| network-interface | NetworkInterface | ✅ (Interface Name Tag) | ✅ (Creation Time) | ✅ | ✅ | +| oidcprovider | OIDCProvider | ✅ (Provider URL) | ✅ (Creation Time) | ❌ | ✅ | +| opensearchdomain | OpenSearchDomain | ✅ (Domain Name) | ✅ (First Seen Tag Time) | ❌ | ✅ | +| redshift | Redshift | ✅ (Cluster Identifier) | ✅ (Creation Time) | ❌ | ✅ | +| rds-cluster | DBClusters | ✅ (DB Cluster Identifier ) | ✅ (Creation Time) | ✅ | ✅ | +| rds | DBInstances | ✅ (DB Name) | ✅ (Creation Time) | ✅ | ✅ | +| rds-parameter-group | RdsParameterGroup | ✅ (Group Name) | ❌ | ❌ | ✅ | +| rds-subnet-group | DBSubnetGroups | ✅ (DB Subnet Group Name) | ❌ | ❌ | ✅ | +| rds-proxy | RDSProxy | ✅ (proxy Name) | ✅ (Creation Time) | ❌ | ✅ | +| s3 | s3 | ✅ (Bucket Name) | ✅ (Creation Time) | ✅ | ✅ | +| s3-ap | s3AccessPoint | ✅ (Access point Name) | ❌ | ❌ | ✅ | +| s3-olap | S3ObjectLambdaAccessPoint | ✅ (Object Lambda Access point Name) | ❌ | ❌ | ✅ | +| s3-mrap | S3MultiRegionAccessPoint | ✅ (Multi region Access point Name) | ✅ (Creation Time) | ❌ | ✅ | +| security-group | SecurityGroup | ✅ (Security group name) | ✅ (Creation Time) | ✅ | ❌ | +| ses-configuration-set | SesConfigurationset | ✅ (Configuration set name) | ❌ | ❌ | ✅ | +| ses-email-template | SesEmailTemplates | ✅ (Template Name) | ✅ (Creation Time) | ❌ | ✅ | +| ses-identity | SesIdentity | ✅ (Identity -Mail/Domain) | ❌ | ❌ | ✅ | +| ses-receipt-rule-set | SesReceiptRuleSet | ✅ (Receipt Rule Set Name) | ✅ (Creation Time) | ❌ | ✅ | +| ses-receipt-filter | SesReceiptFilter | ✅ (Receipt Filter Name) | ❌ | ❌ | ✅ | +| snstopic | SNS | ✅ (Topic Name) | ✅ (First Seen Tag Time) | ❌ | ✅ | +| sqs | SQS | ✅ (Queue Name) | ✅ (Creation Time) | ❌ | ✅ | +| sagemaker-notebook-smni | SageMakerNotebook | ✅ (Notebook Instnace Name) | ✅ (Creation Time) | ❌ | ✅ | +| secretsmanager | SecretsManager | ✅ (Secret Name) | ✅ (Last Accessed or Creation Time) | ❌ | ✅ | +| security-hub | SecurityHub | ❌ | ✅ (Created Time) | ❌ | ✅ | +| snap | Snapshots | ❌ | ✅ (Creation Time) | ✅ | ✅ | +| transit-gateway | TransitGateway | ❌ | ✅ (Creation Time) | ❌ | ✅ | +| transit-gateway-route-table | TransitGatewayRouteTable | ❌ | ✅ (Creation Time) | ❌ | ✅ | +| transit-gateway-attachment | TransitGatewaysVpcAttachment | ❌ | ✅ (Creation Time) | ❌ | ✅ | +| vpc | VPC | ✅ (EC2 Name Tag) | ✅ (First Seen Tag Time) | ❌ | ❌ | +| route53-hosted-zone | Route53HostedZone | ✅ (Hosted zone name) | ❌ | ❌ | ❌ | +| route53-cidr-collection | Route53CIDRCollection | ✅ (Cidr collection name) | ❌ | ❌ | ❌ | +| route53-traffic-policy | Route53TrafficPolicy | ✅ (Traffic policy name) | ❌ | ❌ | ❌ | +| network-firewall | NetworkFirewall | ✅ (Firewall name) | ✅ (First Seen Tag Time) | ✅ | ❌ | +| network-firewall-policy | NetworkFirewallPolicy | ✅ (Firewall Policy name) | ✅ (First Seen Tag Time) | ✅ | ❌ | +| network-firewall-rule-group | NetworkFirewallRuleGroup | ✅ (Firewall Rule group name) | ✅ (First Seen Tag Time) | ✅ | ❌ | +| network-firewall-tls-config | NetworkFirewallTLSConfig | ✅ (Firewall TLS config name) | ✅ (First Seen Tag Time) | ✅ | ❌ | +| network-firewall-resource-policy | NetworkFirewallResourcePolicy | ✅ (Firewall Resource Policy ARN) | ❌ | ❌ | ❌ | +| vpc-lattice-service | VPCLatticeService | ✅ (VPC Lattice service ARN) | ✅ (Creation Time) | ❌ | ✅ | +| vpc-lattice-service-network | VPCLatticeServiceNetwork | ✅ (VPC Lattice service network ARN) | ✅ (Creation Time) | ❌ | ✅ | +| vpc-lattice-target-group | VPCLatticeTargetGroup | ✅ (VPC Lattice target group ARN) | ✅ (Creation Time) | ❌ | ✅ | ### Resource Deletion and 'IsNukable' Check Option #### Supported Resources for 'IsNukable' Check diff --git a/aws/resource_registry.go b/aws/resource_registry.go index 5aeda874..fe1c4f48 100644 --- a/aws/resource_registry.go +++ b/aws/resource_registry.go @@ -67,6 +67,8 @@ func getRegisteredRegionalResources() []AwsResource { &resources.CodeDeployApplications{}, &resources.ConfigServiceRecorders{}, &resources.ConfigServiceRule{}, + &resources.DataSyncTask{}, + &resources.DataSyncLocation{}, &resources.DynamoDB{}, &resources.EBSVolumes{}, &resources.EBApplications{}, diff --git a/aws/resources/datasync_location.go b/aws/resources/datasync_location.go new file mode 100644 index 00000000..c0608af4 --- /dev/null +++ b/aws/resources/datasync_location.go @@ -0,0 +1,68 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/datasync" + "github.com/gruntwork-io/cloud-nuke/config" + "github.com/gruntwork-io/cloud-nuke/logging" + "github.com/gruntwork-io/cloud-nuke/report" + "github.com/gruntwork-io/go-commons/errors" +) + +func (dsl *DataSyncLocation) nukeAll(identifiers []*string) error { + if len(identifiers) == 0 { + logging.Debugf("[Data Sync Location] No Data Sync Locations found in region %s", dsl.Region) + return nil + } + + logging.Debugf("[Data Sync Location] Deleting all Data Sync Locations in region %s", dsl.Region) + var deleted []*string + + for _, identifier := range identifiers { + logging.Debugf("[Data Sync Location] Deleting Data Sync Location %s in region %s", *identifier, dsl.Region) + _, err := dsl.Client.DeleteLocationWithContext(dsl.Context, &datasync.DeleteLocationInput{ + LocationArn: identifier, + }) + if err != nil { + logging.Debugf("[Data Sync Location] Error deleting Data Sync Location %s in region %s", *identifier, dsl.Region) + return err + } else { + deleted = append(deleted, identifier) + logging.Debugf("[Data Sync Location] Deleted Data Sync Location %s in region %s", *identifier, dsl.Region) + } + + e := report.Entry{ + Identifier: aws.StringValue(identifier), + ResourceType: dsl.ResourceName(), + Error: err, + } + report.Record(e) + } + + logging.Debugf("[OK] %d Data Sync Location(s) nuked in %s", len(deleted), dsl.Region) + return nil +} + +func (dsl *DataSyncLocation) getAll(c context.Context, _ config.Config) ([]*string, error) { + var identifiers []*string + paginator := func(output *datasync.ListLocationsOutput, lastPage bool) bool { + for _, location := range output.Locations { + identifiers = append(identifiers, location.LocationArn) + } + + return !lastPage + } + + param := &datasync.ListLocationsInput{ + MaxResults: aws.Int64(100), + } + + if err := dsl.Client.ListLocationsPagesWithContext(c, param, paginator); err != nil { + logging.Debugf("[Data Sync Location] Failed to list Data Sync Locations: %s", err) + return nil, errors.WithStackTrace(err) + } + + return identifiers, nil +} diff --git a/aws/resources/datasync_location_test.go b/aws/resources/datasync_location_test.go new file mode 100644 index 00000000..2407d379 --- /dev/null +++ b/aws/resources/datasync_location_test.go @@ -0,0 +1,86 @@ +package resources + +import ( + "context" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/service/datasync" + "github.com/aws/aws-sdk-go/service/datasync/datasynciface" + "github.com/gruntwork-io/cloud-nuke/config" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type mockDatasyncLocation struct { + datasynciface.DataSyncAPI + ListLocationsOutput datasync.ListLocationsOutput + DeleteLocationOutput datasync.DeleteLocationOutput +} + +func (m mockDatasyncLocation) ListLocationsPagesWithContext(_ aws.Context, _ *datasync.ListLocationsInput, callback func(*datasync.ListLocationsOutput, bool) bool, _ ...request.Option) error { + callback(&m.ListLocationsOutput, true) + return nil +} + +func (m mockDatasyncLocation) DeleteLocationWithContext(aws.Context, *datasync.DeleteLocationInput, ...request.Option) (*datasync.DeleteLocationOutput, error) { + return &m.DeleteLocationOutput, nil +} + +func TestDataSyncLocation_NukeAll(t *testing.T) { + + t.Parallel() + + testName := "test-datasync-location" + service := DataSyncLocation{ + Client: mockDatasyncLocation{ + DeleteLocationOutput: datasync.DeleteLocationOutput{}, + }, + } + + err := service.nukeAll([]*string{&testName}) + assert.NoError(t, err) +} + +func TestDataSyncLocation_GetAll(t *testing.T) { + + t.Parallel() + + testName1 := "test-datasync-location-1" + testName2 := "test-datasync-location-2" + location := DataSyncLocation{ + Client: mockDatasyncLocation{ + ListLocationsOutput: datasync.ListLocationsOutput{ + Locations: []*datasync.LocationListEntry{ + { + LocationArn: aws.String(fmt.Sprintf("arn::location/%s", testName1)), + }, + { + LocationArn: aws.String(fmt.Sprintf("arn::location/%s", testName2)), + }, + }, + }, + }, + } + + tests := map[string]struct { + configObj config.ResourceType + expected []string + }{ + "emptyFilter": { + configObj: config.ResourceType{}, + expected: []string{fmt.Sprintf("arn::location/%s", testName1), fmt.Sprintf("arn::location/%s", testName2)}, + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + names, err := location.getAll(context.Background(), config.Config{ + DataSyncLocation: tc.configObj, + }) + require.NoError(t, err) + require.Equal(t, tc.expected, aws.StringValueSlice(names)) + }) + } +} diff --git a/aws/resources/datasync_location_types.go b/aws/resources/datasync_location_types.go new file mode 100644 index 00000000..c8292c91 --- /dev/null +++ b/aws/resources/datasync_location_types.go @@ -0,0 +1,51 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/datasync" + "github.com/aws/aws-sdk-go/service/datasync/datasynciface" + "github.com/gruntwork-io/cloud-nuke/config" + "github.com/gruntwork-io/go-commons/errors" +) + +type DataSyncLocation struct { + BaseAwsResource + Client datasynciface.DataSyncAPI + Region string + DataSyncLocations []string +} + +func (dsl *DataSyncLocation) GetAndSetResourceConfig(configObj config.Config) config.ResourceType { + return configObj.DataSyncLocation +} + +func (dsl *DataSyncLocation) Init(session *session.Session) { + dsl.Client = datasync.New(session) +} + +func (dsl *DataSyncLocation) ResourceName() string { return "data-sync-location" } + +func (dsl *DataSyncLocation) ResourceIdentifiers() []string { return dsl.DataSyncLocations } + +func (dsl *DataSyncLocation) MaxBatchSize() int { return 19 } + +func (dsl *DataSyncLocation) Nuke(identifiers []string) error { + if err := dsl.nukeAll(aws.StringSlice(identifiers)); err != nil { + return errors.WithStackTrace(err) + } + + return nil +} + +func (dsl *DataSyncLocation) GetAndSetIdentifiers(c context.Context, configObj config.Config) ([]string, error) { + identifiers, err := dsl.getAll(c, configObj) + if err != nil { + return nil, err + } + + dsl.DataSyncLocations = aws.StringValueSlice(identifiers) + return dsl.DataSyncLocations, nil +} diff --git a/aws/resources/datasync_task.go b/aws/resources/datasync_task.go new file mode 100644 index 00000000..4521d7dd --- /dev/null +++ b/aws/resources/datasync_task.go @@ -0,0 +1,72 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/datasync" + "github.com/gruntwork-io/cloud-nuke/config" + "github.com/gruntwork-io/cloud-nuke/logging" + "github.com/gruntwork-io/cloud-nuke/report" + "github.com/gruntwork-io/go-commons/errors" +) + +func (dst *DataSyncTask) nukeAll(identifiers []*string) error { + if len(identifiers) == 0 { + logging.Debugf("[Data Sync Task] No Data Sync Tasks found in region %s", dst.Region) + return nil + } + + logging.Debugf("[Data Sync Task] Deleting all Data Sync Tasks in region %s", dst.Region) + var deleted []*string + + for _, identifier := range identifiers { + logging.Debugf("[Data Sync Task] Deleting Data Sync Task %s in region %s", *identifier, dst.Region) + _, err := dst.Client.DeleteTaskWithContext(dst.Context, &datasync.DeleteTaskInput{ + TaskArn: identifier, + }) + if err != nil { + logging.Debugf("[Data Sync Task] Error deleting Data Sync Task %s in region %s", *identifier, dst.Region) + return err + } else { + deleted = append(deleted, identifier) + logging.Debugf("[Data Sync Task] Deleted Data Sync Task %s in region %s", *identifier, dst.Region) + } + + e := report.Entry{ + Identifier: aws.StringValue(identifier), + ResourceType: dst.ResourceName(), + Error: err, + } + report.Record(e) + } + + logging.Debugf("[OK] %d Data Sync Task(s) nuked in %s", len(deleted), dst.Region) + return nil +} + +func (dst *DataSyncTask) getAll(c context.Context, configObj config.Config) ([]*string, error) { + var identifiers []*string + paginator := func(output *datasync.ListTasksOutput, lastPage bool) bool { + for _, task := range output.Tasks { + if configObj.DataSyncTask.ShouldInclude(config.ResourceValue{ + Name: task.Name, + }) { + identifiers = append(identifiers, task.TaskArn) + } + } + + return !lastPage + } + + param := &datasync.ListTasksInput{ + MaxResults: aws.Int64(100), + } + + if err := dst.Client.ListTasksPagesWithContext(c, param, paginator); err != nil { + logging.Debugf("[Data Sync Task] Failed to list data sync tasks: %s", err) + return nil, errors.WithStackTrace(err) + } + + return identifiers, nil +} diff --git a/aws/resources/datasync_task_test.go b/aws/resources/datasync_task_test.go new file mode 100644 index 00000000..f0573af3 --- /dev/null +++ b/aws/resources/datasync_task_test.go @@ -0,0 +1,97 @@ +package resources + +import ( + "context" + "fmt" + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/service/datasync" + "github.com/aws/aws-sdk-go/service/datasync/datasynciface" + "github.com/gruntwork-io/cloud-nuke/config" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type mockDataSyncTask struct { + datasynciface.DataSyncAPI + ListTasksOutput datasync.ListTasksOutput + DeleteTaskOutput datasync.DeleteTaskOutput +} + +func (m mockDataSyncTask) ListTasksPagesWithContext(_ aws.Context, _ *datasync.ListTasksInput, callback func(*datasync.ListTasksOutput, bool) bool, _ ...request.Option) error { + callback(&m.ListTasksOutput, true) + return nil +} + +func (m mockDataSyncTask) DeleteTaskWithContext(aws.Context, *datasync.DeleteTaskInput, ...request.Option) (*datasync.DeleteTaskOutput, error) { + return &m.DeleteTaskOutput, nil +} + +func TestDataSyncTask_NukeAll(t *testing.T) { + + t.Parallel() + + testName := "test-datasync-task" + task := DataSyncTask{ + Client: mockDataSyncTask{ + DeleteTaskOutput: datasync.DeleteTaskOutput{}, + }, + } + + err := task.nukeAll([]*string{&testName}) + assert.NoError(t, err) +} + +func TestDataSyncTask_GetAll(t *testing.T) { + + t.Parallel() + + testName1 := "test-task-1" + testName2 := "test-task-2" + + task := DataSyncTask{Client: mockDataSyncTask{ + ListTasksOutput: datasync.ListTasksOutput{ + Tasks: []*datasync.TaskListEntry{ + { + Name: &testName1, + TaskArn: aws.String(fmt.Sprintf("arn::%s", testName1)), + }, + { + Name: &testName2, + TaskArn: aws.String(fmt.Sprintf("arn::%s", testName2)), + }, + }, + }, + }} + + tests := map[string]struct { + configObj config.ResourceType + expected []string + }{ + "emptyFilter": { + configObj: config.ResourceType{}, + expected: []string{fmt.Sprintf("arn::%s", testName1), fmt.Sprintf("arn::%s", testName2)}, + }, + "nameExclusionFilter": { + configObj: config.ResourceType{ + ExcludeRule: config.FilterRule{ + NamesRegExp: []config.Expression{{ + RE: *regexp.MustCompile(testName1), + }}, + }}, + expected: []string{fmt.Sprintf("arn::%s", testName2)}, + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + names, err := task.getAll(context.Background(), config.Config{ + DataSyncTask: tc.configObj, + }) + require.NoError(t, err) + require.Equal(t, tc.expected, aws.StringValueSlice(names)) + }) + } +} diff --git a/aws/resources/datasync_task_types.go b/aws/resources/datasync_task_types.go new file mode 100644 index 00000000..0827821d --- /dev/null +++ b/aws/resources/datasync_task_types.go @@ -0,0 +1,51 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/datasync" + "github.com/aws/aws-sdk-go/service/datasync/datasynciface" + "github.com/gruntwork-io/cloud-nuke/config" + "github.com/gruntwork-io/go-commons/errors" +) + +type DataSyncTask struct { + BaseAwsResource + Client datasynciface.DataSyncAPI + Region string + DataSyncTasks []string +} + +func (dst *DataSyncTask) GetAndSetResourceConfig(configObj config.Config) config.ResourceType { + return configObj.DataSyncTask +} + +func (dst *DataSyncTask) Init(session *session.Session) { + dst.Client = datasync.New(session) +} + +func (dst *DataSyncTask) ResourceName() string { return "data-sync-task" } + +func (dst *DataSyncTask) ResourceIdentifiers() []string { return dst.DataSyncTasks } + +func (dst *DataSyncTask) MaxBatchSize() int { return 19 } + +func (dst *DataSyncTask) Nuke(identifiers []string) error { + if err := dst.nukeAll(aws.StringSlice(identifiers)); err != nil { + return errors.WithStackTrace(err) + } + + return nil +} + +func (dst *DataSyncTask) GetAndSetIdentifiers(c context.Context, configObj config.Config) ([]string, error) { + identifiers, err := dst.getAll(c, configObj) + if err != nil { + return nil, err + } + + dst.DataSyncTasks = aws.StringValueSlice(identifiers) + return dst.DataSyncTasks, nil +} diff --git a/config/config.go b/config/config.go index e9733fa7..e8a4c05a 100644 --- a/config/config.go +++ b/config/config.go @@ -31,6 +31,8 @@ type Config struct { CodeDeployApplications ResourceType `yaml:"CodeDeployApplications"` ConfigServiceRecorder ResourceType `yaml:"ConfigServiceRecorder"` ConfigServiceRule ResourceType `yaml:"ConfigServiceRule"` + DataSyncLocation ResourceType `yaml:"DataSyncLocation"` + DataSyncTask ResourceType `yaml:"DataSyncTask"` DBGlobalClusters ResourceType `yaml:"DBGlobalClusters"` DBClusters ResourceType `yaml:"DBClusters"` DBInstances ResourceType `yaml:"DBInstances"` diff --git a/config/config_test.go b/config/config_test.go index 1d953e7a..df6d60c8 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -29,6 +29,8 @@ func emptyConfig() *Config { CodeDeployApplications: ResourceType{FilterRule{}, FilterRule{}, ""}, ConfigServiceRecorder: ResourceType{FilterRule{}, FilterRule{}, ""}, ConfigServiceRule: ResourceType{FilterRule{}, FilterRule{}, ""}, + DataSyncLocation: ResourceType{FilterRule{}, FilterRule{}, ""}, + DataSyncTask: ResourceType{FilterRule{}, FilterRule{}, ""}, DBGlobalClusters: ResourceType{FilterRule{}, FilterRule{}, ""}, DBClusters: ResourceType{FilterRule{}, FilterRule{}, ""}, DBInstances: ResourceType{FilterRule{}, FilterRule{}, ""},