|
49 | 49 | import java.time.ZoneId; |
50 | 50 | import java.time.ZonedDateTime; |
51 | 51 | import java.time.format.DateTimeFormatter; |
| 52 | +import java.time.temporal.ChronoUnit; |
52 | 53 | import java.util.ArrayList; |
53 | 54 | import java.util.Arrays; |
| 55 | +import java.util.Collection; |
| 56 | +import java.util.Collections; |
54 | 57 | import java.util.Comparator; |
55 | 58 | import java.util.List; |
56 | 59 | import java.util.Optional; |
|
71 | 74 | import java.util.logging.Logger; |
72 | 75 | import java.util.stream.Collectors; |
73 | 76 | import org.checkerframework.checker.nullness.qual.Nullable; |
| 77 | +import org.junit.jupiter.api.Test; |
74 | 78 | import org.testcontainers.shaded.org.apache.commons.lang3.NotImplementedException; |
75 | 79 | import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; |
76 | 80 | import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; |
|
81 | 85 | import software.amazon.awssdk.core.waiters.WaiterResponse; |
82 | 86 | import software.amazon.awssdk.regions.Region; |
83 | 87 | import software.amazon.awssdk.services.ec2.Ec2Client; |
| 88 | +import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupRulesRequest; |
| 89 | +import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupRulesResponse; |
| 90 | +import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupsRequest; |
84 | 91 | import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupsResponse; |
85 | 92 | import software.amazon.awssdk.services.ec2.model.Ec2Exception; |
86 | 93 | import software.amazon.awssdk.services.ec2.model.IpPermission; |
87 | 94 | import software.amazon.awssdk.services.ec2.model.IpRange; |
| 95 | +import software.amazon.awssdk.services.ec2.model.RevokeSecurityGroupIngressRequest; |
| 96 | +import software.amazon.awssdk.services.ec2.model.SecurityGroup; |
| 97 | +import software.amazon.awssdk.services.ec2.model.SecurityGroupRule; |
88 | 98 | import software.amazon.awssdk.services.rds.RdsClient; |
89 | 99 | import software.amazon.awssdk.services.rds.RdsClientBuilder; |
90 | 100 | import software.amazon.awssdk.services.rds.model.ApplyMethod; |
@@ -2172,4 +2182,151 @@ private Tag getTag() { |
2172 | 2182 | .key("created").value(timeStr) |
2173 | 2183 | .build(); |
2174 | 2184 | } |
| 2185 | + |
| 2186 | + public void testClustersCleanUp() { |
| 2187 | + try { |
| 2188 | + DescribeDbClustersResponse describeDbClustersResponse = rdsClient.describeDBClusters(); |
| 2189 | + for (DBCluster dbCluster : describeDbClustersResponse.dbClusters()) { |
| 2190 | + //LOGGER.finest(String.format("Test cluster: %s, status: %s, create time: %s, now: %s", |
| 2191 | + // dbCluster.dbClusterIdentifier(), dbCluster.status(), dbCluster.clusterCreateTime(), Instant.now())); |
| 2192 | + if (!dbCluster.dbClusterIdentifier().startsWith("test-")) { |
| 2193 | + continue; |
| 2194 | + } |
| 2195 | + if (!"available".equalsIgnoreCase(dbCluster.status()) |
| 2196 | + && !"rebooting".equalsIgnoreCase(dbCluster.status())) { |
| 2197 | + continue; |
| 2198 | + } |
| 2199 | + if (dbCluster.clusterCreateTime().plus(12, ChronoUnit.HOURS).isAfter(Instant.now())) { |
| 2200 | + // cluster is created less than 12 hours ago |
| 2201 | + continue; |
| 2202 | + } |
| 2203 | + |
| 2204 | + if (dbCluster.engine().startsWith("aurora-")) { |
| 2205 | + if (dbCluster.dbClusterMembers().isEmpty()) { |
| 2206 | + // empty cluster |
| 2207 | + LOGGER.finest("Deleting cluster " + dbCluster.dbClusterIdentifier()); |
| 2208 | + try { |
| 2209 | + rdsClient.deleteDBCluster(builder -> builder |
| 2210 | + .dbClusterIdentifier(dbCluster.dbClusterIdentifier()) |
| 2211 | + .skipFinalSnapshot(true) |
| 2212 | + .build()); |
| 2213 | + } catch (Exception ex) { |
| 2214 | + LOGGER.warning(ex.getMessage()); |
| 2215 | + } |
| 2216 | + } else { |
| 2217 | + for (DBClusterMember dbClusterMember : dbCluster.dbClusterMembers()) { |
| 2218 | + if (!dbClusterMember.dbInstanceIdentifier().startsWith("test-")) { |
| 2219 | + continue; |
| 2220 | + } |
| 2221 | + LOGGER.finest("Deleting instance " + dbClusterMember.dbInstanceIdentifier()); |
| 2222 | + try { |
| 2223 | + rdsClient.deleteDBInstance(builder -> builder |
| 2224 | + .dbInstanceIdentifier(dbClusterMember.dbInstanceIdentifier()) |
| 2225 | + .skipFinalSnapshot(true) |
| 2226 | + .build()); |
| 2227 | + } catch (Exception ex) { |
| 2228 | + LOGGER.warning(ex.getMessage()); |
| 2229 | + } |
| 2230 | + } |
| 2231 | + } |
| 2232 | + } else { |
| 2233 | + LOGGER.finest("Deleting cluster " + dbCluster.dbClusterIdentifier()); |
| 2234 | + try { |
| 2235 | + rdsClient.deleteDBCluster(builder -> builder |
| 2236 | + .dbClusterIdentifier(dbCluster.dbClusterIdentifier()) |
| 2237 | + .skipFinalSnapshot(true) |
| 2238 | + .build()); |
| 2239 | + } catch (Exception ex) { |
| 2240 | + LOGGER.warning(ex.getMessage()); |
| 2241 | + } |
| 2242 | + } |
| 2243 | + } |
| 2244 | + } catch (Exception ex) { |
| 2245 | + LOGGER.warning(ex.getMessage()); |
| 2246 | + } |
| 2247 | + } |
| 2248 | + |
| 2249 | + public void testInstancesCleanUp() { |
| 2250 | + try { |
| 2251 | + DescribeDbInstancesResponse describeDbInstancesResponse = rdsClient.describeDBInstances(); |
| 2252 | + for (DBInstance dbInstance : describeDbInstancesResponse.dbInstances()) { |
| 2253 | + //LOGGER.fine("Test instance: " + dbInstance.dbInstanceIdentifier()); |
| 2254 | + if (!dbInstance.dbInstanceIdentifier().startsWith("test-")) { |
| 2255 | + continue; |
| 2256 | + } |
| 2257 | + if (!"available".equalsIgnoreCase(dbInstance.dbInstanceStatus())) { |
| 2258 | + continue; |
| 2259 | + } |
| 2260 | + if (dbInstance.instanceCreateTime() != null |
| 2261 | + && dbInstance.instanceCreateTime().plus(12, ChronoUnit.HOURS).isAfter(Instant.now())) { |
| 2262 | + // cluster is created less than 12 hours ago |
| 2263 | + continue; |
| 2264 | + } |
| 2265 | + LOGGER.finest("Deleting instance " + dbInstance.dbInstanceIdentifier()); |
| 2266 | + try { |
| 2267 | + rdsClient.deleteDBInstance(builder -> builder |
| 2268 | + .dbInstanceIdentifier(dbInstance.dbInstanceIdentifier()) |
| 2269 | + .skipFinalSnapshot(true) |
| 2270 | + .build()); |
| 2271 | + } catch (Exception ex) { |
| 2272 | + LOGGER.warning(ex.getMessage()); |
| 2273 | + } |
| 2274 | + } |
| 2275 | + } catch (Exception ex) { |
| 2276 | + LOGGER.warning(ex.getMessage()); |
| 2277 | + } |
| 2278 | + } |
| 2279 | + |
| 2280 | + public void securityGroupRulesCleanUp() { |
| 2281 | + try { |
| 2282 | + DescribeSecurityGroupsResponse groupResponse = ec2Client.describeSecurityGroups( |
| 2283 | + DescribeSecurityGroupsRequest.builder().groupNames("default").build()); |
| 2284 | + |
| 2285 | + if (groupResponse.securityGroups().isEmpty()) { |
| 2286 | + return; |
| 2287 | + } |
| 2288 | + |
| 2289 | + SecurityGroup defaultSecurityGroup = groupResponse.securityGroups().get(0); |
| 2290 | + |
| 2291 | + final software.amazon.awssdk.services.ec2.model.Filter groupIdFilter = |
| 2292 | + software.amazon.awssdk.services.ec2.model.Filter.builder() |
| 2293 | + .name("group-id") |
| 2294 | + .values(defaultSecurityGroup.groupId()) |
| 2295 | + .build(); |
| 2296 | + DescribeSecurityGroupRulesResponse rulesResponse = ec2Client.describeSecurityGroupRules( |
| 2297 | + DescribeSecurityGroupRulesRequest.builder().filters(groupIdFilter).build()); |
| 2298 | + |
| 2299 | + if (rulesResponse.securityGroupRules().isEmpty()) { |
| 2300 | + return; |
| 2301 | + } |
| 2302 | + |
| 2303 | + for (SecurityGroupRule rule : rulesResponse.securityGroupRules()) { |
| 2304 | + if (!rule.isEgress() && rule.description() != null && rule.description().startsWith("Test run at ")) { |
| 2305 | + try { |
| 2306 | + String instantStr = rule.description().replaceAll("Test run at ", ""); |
| 2307 | + Instant createdAt = Instant.parse(instantStr); |
| 2308 | + if (createdAt.plus(12, ChronoUnit.HOURS).isAfter(Instant.now())) { |
| 2309 | + continue; |
| 2310 | + } |
| 2311 | + |
| 2312 | + LOGGER.finest("Deleting security group rule: " + rule.securityGroupRuleId()); |
| 2313 | + try { |
| 2314 | + ec2Client.revokeSecurityGroupIngress( |
| 2315 | + RevokeSecurityGroupIngressRequest.builder() |
| 2316 | + .groupId(rule.groupId()) |
| 2317 | + .securityGroupRuleIds(rule.securityGroupRuleId()) |
| 2318 | + .build()); |
| 2319 | + } catch (Exception ex) { |
| 2320 | + LOGGER.warning("Error deleting security group rule: " + ex.getMessage()); |
| 2321 | + } |
| 2322 | + |
| 2323 | + } catch (Exception ex) { |
| 2324 | + LOGGER.warning(ex.getMessage()); |
| 2325 | + } |
| 2326 | + } |
| 2327 | + } |
| 2328 | + } catch (Exception ex) { |
| 2329 | + LOGGER.warning(ex.getMessage()); |
| 2330 | + } |
| 2331 | + } |
2175 | 2332 | } |
0 commit comments