RDS: detect rds instance / cluster engine mismatch (#6994)
This commit is contained in:
parent
3945decb60
commit
0a5e2d3e4d
@ -201,3 +201,11 @@ class InvalidDBInstanceIdentifier(InvalidParameterValue):
|
|||||||
"Identifiers must begin with a letter; must contain only ASCII letters, digits, and hyphens; "
|
"Identifiers must begin with a letter; must contain only ASCII letters, digits, and hyphens; "
|
||||||
"and must not end with a hyphen or contain two consecutive hyphens."
|
"and must not end with a hyphen or contain two consecutive hyphens."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidDBInstanceEngine(InvalidParameterCombination):
|
||||||
|
def __init__(self, instance_engine: str, cluster_engine: str) -> None:
|
||||||
|
super().__init__(
|
||||||
|
f"The engine name requested for your DB instance ({instance_engine}) doesn't match "
|
||||||
|
f"the engine name of your DB cluster ({cluster_engine})."
|
||||||
|
)
|
||||||
|
@ -27,6 +27,7 @@ from .exceptions import (
|
|||||||
DBClusterParameterGroupNotFoundError,
|
DBClusterParameterGroupNotFoundError,
|
||||||
OptionGroupNotFoundFaultError,
|
OptionGroupNotFoundFaultError,
|
||||||
InvalidDBClusterStateFaultError,
|
InvalidDBClusterStateFaultError,
|
||||||
|
InvalidDBInstanceEngine,
|
||||||
InvalidDBInstanceStateError,
|
InvalidDBInstanceStateError,
|
||||||
SnapshotQuotaExceededError,
|
SnapshotQuotaExceededError,
|
||||||
DBSnapshotAlreadyExistsError,
|
DBSnapshotAlreadyExistsError,
|
||||||
@ -1593,6 +1594,10 @@ class RDSBackend(BaseBackend):
|
|||||||
raise InvalidParameterValue(
|
raise InvalidParameterValue(
|
||||||
"Instances cannot be added to Aurora Serverless clusters."
|
"Instances cannot be added to Aurora Serverless clusters."
|
||||||
)
|
)
|
||||||
|
if database.engine != cluster.engine:
|
||||||
|
raise InvalidDBInstanceEngine(
|
||||||
|
str(database.engine), str(cluster.engine)
|
||||||
|
)
|
||||||
cluster.cluster_members.append(database_id)
|
cluster.cluster_members.append(database_id)
|
||||||
self.databases[database_id] = database
|
self.databases[database_id] = database
|
||||||
return database
|
return database
|
||||||
|
@ -7,10 +7,12 @@ import pytest
|
|||||||
from moto import mock_rds
|
from moto import mock_rds
|
||||||
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
||||||
|
|
||||||
|
RDS_REGION = "eu-north-1"
|
||||||
|
|
||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_describe_db_cluster_initial():
|
def test_describe_db_cluster_initial():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
resp = client.describe_db_clusters()
|
resp = client.describe_db_clusters()
|
||||||
assert len(resp["DBClusters"]) == 0
|
assert len(resp["DBClusters"]) == 0
|
||||||
@ -18,7 +20,7 @@ def test_describe_db_cluster_initial():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_describe_db_cluster_fails_for_non_existent_cluster():
|
def test_describe_db_cluster_fails_for_non_existent_cluster():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
resp = client.describe_db_clusters()
|
resp = client.describe_db_clusters()
|
||||||
assert len(resp["DBClusters"]) == 0
|
assert len(resp["DBClusters"]) == 0
|
||||||
@ -31,7 +33,7 @@ def test_describe_db_cluster_fails_for_non_existent_cluster():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_create_db_cluster_needs_master_username():
|
def test_create_db_cluster_needs_master_username():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
with pytest.raises(ClientError) as ex:
|
with pytest.raises(ClientError) as ex:
|
||||||
client.create_db_cluster(DBClusterIdentifier="cluster-id", Engine="aurora")
|
client.create_db_cluster(DBClusterIdentifier="cluster-id", Engine="aurora")
|
||||||
@ -44,7 +46,7 @@ def test_create_db_cluster_needs_master_username():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_create_db_cluster_needs_master_user_password():
|
def test_create_db_cluster_needs_master_user_password():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
with pytest.raises(ClientError) as ex:
|
with pytest.raises(ClientError) as ex:
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
@ -59,7 +61,7 @@ def test_create_db_cluster_needs_master_user_password():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_create_db_cluster_needs_long_master_user_password():
|
def test_create_db_cluster_needs_long_master_user_password():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
with pytest.raises(ClientError) as ex:
|
with pytest.raises(ClientError) as ex:
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
@ -78,7 +80,7 @@ def test_create_db_cluster_needs_long_master_user_password():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_modify_db_cluster_needs_long_master_user_password():
|
def test_modify_db_cluster_needs_long_master_user_password():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -102,7 +104,7 @@ def test_modify_db_cluster_needs_long_master_user_password():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_modify_db_cluster_new_cluster_identifier():
|
def test_modify_db_cluster_new_cluster_identifier():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
old_id = "cluster-id"
|
old_id = "cluster-id"
|
||||||
new_id = "new-cluster-id"
|
new_id = "new-cluster-id"
|
||||||
|
|
||||||
@ -131,7 +133,7 @@ def test_modify_db_cluster_new_cluster_identifier():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_create_db_cluster__verify_default_properties():
|
def test_create_db_cluster__verify_default_properties():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
resp = client.create_db_cluster(
|
resp = client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -198,7 +200,7 @@ def test_create_db_cluster__verify_default_properties():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_create_db_cluster_additional_parameters():
|
def test_create_db_cluster_additional_parameters():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
resp = client.create_db_cluster(
|
resp = client.create_db_cluster(
|
||||||
AvailabilityZones=["eu-north-1b"],
|
AvailabilityZones=["eu-north-1b"],
|
||||||
@ -253,7 +255,7 @@ def test_create_db_cluster_additional_parameters():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_describe_db_cluster_after_creation():
|
def test_describe_db_cluster_after_creation():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id1",
|
DBClusterIdentifier="cluster-id1",
|
||||||
@ -286,7 +288,7 @@ def test_describe_db_cluster_after_creation():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_delete_db_cluster():
|
def test_delete_db_cluster():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -302,7 +304,7 @@ def test_delete_db_cluster():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_delete_db_cluster_do_snapshot():
|
def test_delete_db_cluster_do_snapshot():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -323,7 +325,7 @@ def test_delete_db_cluster_do_snapshot():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_delete_db_cluster_that_is_protected():
|
def test_delete_db_cluster_that_is_protected():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -341,7 +343,7 @@ def test_delete_db_cluster_that_is_protected():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_delete_db_cluster_unknown_cluster():
|
def test_delete_db_cluster_unknown_cluster():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
with pytest.raises(ClientError) as ex:
|
with pytest.raises(ClientError) as ex:
|
||||||
client.delete_db_cluster(DBClusterIdentifier="cluster-unknown")
|
client.delete_db_cluster(DBClusterIdentifier="cluster-unknown")
|
||||||
@ -352,7 +354,7 @@ def test_delete_db_cluster_unknown_cluster():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_start_db_cluster_unknown_cluster():
|
def test_start_db_cluster_unknown_cluster():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
with pytest.raises(ClientError) as ex:
|
with pytest.raises(ClientError) as ex:
|
||||||
client.start_db_cluster(DBClusterIdentifier="cluster-unknown")
|
client.start_db_cluster(DBClusterIdentifier="cluster-unknown")
|
||||||
@ -363,7 +365,7 @@ def test_start_db_cluster_unknown_cluster():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_start_db_cluster_after_stopping():
|
def test_start_db_cluster_after_stopping():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -380,7 +382,7 @@ def test_start_db_cluster_after_stopping():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_start_db_cluster_without_stopping():
|
def test_start_db_cluster_without_stopping():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -398,7 +400,7 @@ def test_start_db_cluster_without_stopping():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_stop_db_cluster():
|
def test_stop_db_cluster():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -419,7 +421,7 @@ def test_stop_db_cluster():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_stop_db_cluster_already_stopped():
|
def test_stop_db_cluster_already_stopped():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -439,7 +441,7 @@ def test_stop_db_cluster_already_stopped():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_stop_db_cluster_unknown_cluster():
|
def test_stop_db_cluster_unknown_cluster():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
with pytest.raises(ClientError) as ex:
|
with pytest.raises(ClientError) as ex:
|
||||||
client.stop_db_cluster(DBClusterIdentifier="cluster-unknown")
|
client.stop_db_cluster(DBClusterIdentifier="cluster-unknown")
|
||||||
@ -807,7 +809,7 @@ def test_add_tags_to_cluster_snapshot():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_create_serverless_db_cluster():
|
def test_create_serverless_db_cluster():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
resp = client.create_db_cluster(
|
resp = client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -831,7 +833,7 @@ def test_create_serverless_db_cluster():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_create_db_cluster_with_enable_http_endpoint_invalid():
|
def test_create_db_cluster_with_enable_http_endpoint_invalid():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
resp = client.create_db_cluster(
|
resp = client.create_db_cluster(
|
||||||
DBClusterIdentifier="cluster-id",
|
DBClusterIdentifier="cluster-id",
|
||||||
@ -850,7 +852,7 @@ def test_create_db_cluster_with_enable_http_endpoint_invalid():
|
|||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
def test_describe_db_clusters_filter_by_engine():
|
def test_describe_db_clusters_filter_by_engine():
|
||||||
client = boto3.client("rds", region_name="eu-north-1")
|
client = boto3.client("rds", region_name=RDS_REGION)
|
||||||
|
|
||||||
client.create_db_cluster(
|
client.create_db_cluster(
|
||||||
DBClusterIdentifier="id1",
|
DBClusterIdentifier="id1",
|
||||||
@ -922,3 +924,37 @@ def test_replicate_cluster():
|
|||||||
replica = us_west.describe_db_clusters()["DBClusters"][0]
|
replica = us_west.describe_db_clusters()["DBClusters"][0]
|
||||||
assert "ReplicationSourceIdentifier" not in replica
|
assert "ReplicationSourceIdentifier" not in replica
|
||||||
assert replica["MultiAZ"] is False
|
assert replica["MultiAZ"] is False
|
||||||
|
|
||||||
|
|
||||||
|
@mock_rds
|
||||||
|
def test_createdb_instance_engine_mismatch_fail():
|
||||||
|
# Setup
|
||||||
|
client = boto3.client("rds", "us-east-1")
|
||||||
|
cluster_name = "test-cluster"
|
||||||
|
client.create_db_cluster(
|
||||||
|
DBClusterIdentifier=cluster_name,
|
||||||
|
Engine="aurora-postgresql",
|
||||||
|
EngineVersion="12.14",
|
||||||
|
MasterUsername="testuser",
|
||||||
|
MasterUserPassword="password",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Execute
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.create_db_instance(
|
||||||
|
DBClusterIdentifier=cluster_name,
|
||||||
|
Engine="mysql",
|
||||||
|
EngineVersion="12.14",
|
||||||
|
DBInstanceIdentifier="test-instance",
|
||||||
|
DBInstanceClass="db.t4g.medium",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
assert err["Code"] == "InvalidParameterCombination"
|
||||||
|
assert (
|
||||||
|
err["Message"]
|
||||||
|
== "The engine name requested for your DB instance (mysql) doesn't match "
|
||||||
|
"the engine name of your DB cluster (aurora-postgresql)."
|
||||||
|
)
|
||||||
|
@ -21,7 +21,7 @@ def test_add_instance_as_cluster_member():
|
|||||||
DBInstanceIdentifier="dbi",
|
DBInstanceIdentifier="dbi",
|
||||||
DBClusterIdentifier="dbci",
|
DBClusterIdentifier="dbci",
|
||||||
DBInstanceClass="db.r5.large",
|
DBInstanceClass="db.r5.large",
|
||||||
Engine="aurora-postgresql",
|
Engine="mysql",
|
||||||
)
|
)
|
||||||
|
|
||||||
cluster = client.describe_db_clusters()["DBClusters"][0]
|
cluster = client.describe_db_clusters()["DBClusters"][0]
|
||||||
@ -53,7 +53,7 @@ def test_remove_instance_from_cluster():
|
|||||||
DBInstanceIdentifier="dbi",
|
DBInstanceIdentifier="dbi",
|
||||||
DBClusterIdentifier="dbci",
|
DBClusterIdentifier="dbci",
|
||||||
DBInstanceClass="db.r5.large",
|
DBInstanceClass="db.r5.large",
|
||||||
Engine="aurora-postgresql",
|
Engine="mysql",
|
||||||
)
|
)
|
||||||
|
|
||||||
client.delete_db_instance(
|
client.delete_db_instance(
|
||||||
|
Loading…
Reference in New Issue
Block a user