From 6e9960895e9e3f522e4e52695bb5899920ce7a84 Mon Sep 17 00:00:00 2001 From: Brian Pandola Date: Tue, 7 Nov 2023 02:36:36 -0800 Subject: [PATCH] RDS: Can't delete DBCluster with active DBInstances (#6998) --- moto/rds/exceptions.py | 8 ++++ moto/rds/models.py | 4 +- .../test_rds_clusters_with_instances.py | 39 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/moto/rds/exceptions.py b/moto/rds/exceptions.py index f6af07161..d6c015311 100644 --- a/moto/rds/exceptions.py +++ b/moto/rds/exceptions.py @@ -82,6 +82,14 @@ class InvalidDBClusterStateFaultError(RDSClientError): ) +class DBClusterToBeDeletedHasActiveMembers(RDSClientError): + def __init__(self) -> None: + super().__init__( + "InvalidDBClusterStateFault", + "Cluster cannot be deleted, it still contains DB instances in non-deleting state.", + ) + + class InvalidDBInstanceStateError(RDSClientError): def __init__(self, database_identifier: str, istate: str): estate = ( diff --git a/moto/rds/models.py b/moto/rds/models.py index 5e39aaef4..db0042cac 100644 --- a/moto/rds/models.py +++ b/moto/rds/models.py @@ -19,6 +19,7 @@ from .exceptions import ( DBClusterNotFoundError, DBClusterSnapshotAlreadyExistsError, DBClusterSnapshotNotFoundError, + DBClusterToBeDeletedHasActiveMembers, DBInstanceNotFoundError, DBSnapshotNotFoundError, DBSecurityGroupNotFoundError, @@ -2344,7 +2345,8 @@ class RDSBackend(BaseBackend): raise InvalidParameterValue( "Can't delete Cluster with protection enabled" ) - + if cluster.cluster_members: + raise DBClusterToBeDeletedHasActiveMembers() global_id = cluster.global_cluster_identifier or "" if global_id in self.global_clusters: self.remove_from_global_cluster(global_id, cluster_identifier) diff --git a/tests/test_rds/test_rds_clusters_with_instances.py b/tests/test_rds/test_rds_clusters_with_instances.py index 09dec8c56..66caeed7f 100644 --- a/tests/test_rds/test_rds_clusters_with_instances.py +++ b/tests/test_rds/test_rds_clusters_with_instances.py @@ -89,3 +89,42 @@ def test_add_instance_to_serverless_cluster(): err = exc.value.response["Error"] assert err["Code"] == "InvalidParameterValue" assert err["Message"] == "Instances cannot be added to Aurora Serverless clusters." + + +@mock_rds +def test_delete_db_cluster_fails_if_cluster_contains_db_instances(): + cluster_identifier = "test-cluster" + instance_identifier = "test-instance" + client = boto3.client("rds", "us-east-1") + client.create_db_cluster( + DBClusterIdentifier=cluster_identifier, + Engine="aurora-postgresql", + MasterUsername="test-user", + MasterUserPassword="password", + ) + client.create_db_instance( + DBClusterIdentifier=cluster_identifier, + Engine="aurora-postgresql", + DBInstanceIdentifier=instance_identifier, + DBInstanceClass="db.t4g.medium", + ) + with pytest.raises(ClientError) as exc: + client.delete_db_cluster( + DBClusterIdentifier=cluster_identifier, + SkipFinalSnapshot=True, + ) + err = exc.value.response["Error"] + assert err["Code"] == "InvalidDBClusterStateFault" + assert ( + err["Message"] + == "Cluster cannot be deleted, it still contains DB instances in non-deleting state." + ) + client.delete_db_instance( + DBInstanceIdentifier=instance_identifier, + SkipFinalSnapshot=True, + ) + cluster = client.delete_db_cluster( + DBClusterIdentifier=cluster_identifier, + SkipFinalSnapshot=True, + ).get("DBCluster") + assert cluster["DBClusterIdentifier"] == cluster_identifier