RDS: add cluster engine validation when creating a rds cluster (#7001)

This commit is contained in:
Miki Watanabe 2023-11-09 15:26:49 -05:00 committed by GitHub
parent e43619ae07
commit 3ca46c3c24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 23 deletions

View File

@ -49,6 +49,7 @@ from .utils import (
merge_filters,
validate_filters,
valid_preferred_maintenance_window,
ClusterEngine,
)
@ -129,6 +130,17 @@ class Cluster:
self.db_cluster_instance_class = kwargs.get("db_cluster_instance_class")
self.deletion_protection = kwargs.get("deletion_protection")
self.engine = kwargs.get("engine")
if self.engine not in ClusterEngine.list_cluster_engines():
raise InvalidParameterValue(
(
"Engine '{engine}' is not supported "
"to satisfy constraint: Member must satisfy enum value set: "
"{valid_engines}"
).format(
engine=self.engine,
valid_engines=ClusterEngine.list_cluster_engines(),
)
)
self.engine_version = kwargs.get("engine_version") or Cluster.default_engine_version(self.engine) # type: ignore
self.engine_mode = kwargs.get("engine_mode") or "provisioned"
self.iops = kwargs.get("iops")
@ -1591,7 +1603,10 @@ class RDSBackend(BaseBackend):
if cluster_id is not None:
cluster = self.clusters.get(cluster_id)
if cluster is not None:
if cluster.engine == "aurora" and cluster.engine_mode == "serverless":
if (
cluster.engine in ClusterEngine.serverless_engines()
and cluster.engine_mode == "serverless"
):
raise InvalidParameterValue(
"Instances cannot be added to Aurora Serverless clusters."
)

View File

@ -1,6 +1,7 @@
import copy
from collections import namedtuple
from typing import Any, Dict, Tuple, Optional
from typing import Any, Dict, Tuple, Optional, List
from enum import Enum
from botocore.utils import merge_dicts
@ -22,6 +23,21 @@ FilterDef = namedtuple(
)
class ClusterEngine(str, Enum):
AURORA_POSTGRESQL = "aurora-postgresql"
AURORA_MYSQL = "aurora-mysql"
RDS_POSTGRESQL = "postgres"
RDS_MYSQL = "mysql"
@classmethod
def list_cluster_engines(self) -> List[str]:
return sorted([item.value for item in ClusterEngine])
@classmethod
def serverless_engines(self) -> List[str]:
return [ClusterEngine.AURORA_MYSQL, ClusterEngine.AURORA_POSTGRESQL]
def get_object_value(obj: Any, attr: str) -> Any:
"""Retrieves an arbitrary attribute value from an object.

View File

@ -31,12 +31,29 @@ def test_describe_db_cluster_fails_for_non_existent_cluster():
assert err["Message"] == "DBCluster cluster-id not found."
@mock_rds
def test_create_db_cluster_invalid_engine():
client = boto3.client("rds", region_name=RDS_REGION)
with pytest.raises(ClientError) as ex:
client.create_db_cluster(
DBClusterIdentifier="cluster-id", Engine="aurora-postgresql"
)
err = ex.value.response["Error"]
assert err["Code"] == "InvalidParameterValue"
assert err["Message"] == (
"The parameter MasterUsername must be provided and must not be blank."
)
@mock_rds
def test_create_db_cluster_needs_master_username():
client = boto3.client("rds", region_name=RDS_REGION)
with pytest.raises(ClientError) as ex:
client.create_db_cluster(DBClusterIdentifier="cluster-id", Engine="aurora")
client.create_db_cluster(
DBClusterIdentifier="cluster-id", Engine="aurora-postgresql"
)
err = ex.value.response["Error"]
assert err["Code"] == "InvalidParameterValue"
assert err["Message"] == (
@ -50,7 +67,9 @@ def test_create_db_cluster_needs_master_user_password():
with pytest.raises(ClientError) as ex:
client.create_db_cluster(
DBClusterIdentifier="cluster-id", Engine="aurora", MasterUsername="root"
DBClusterIdentifier="cluster-id",
Engine="aurora-postgresql",
MasterUsername="root",
)
err = ex.value.response["Error"]
assert err["Code"] == "InvalidParameterValue"
@ -66,7 +85,7 @@ def test_create_db_cluster_needs_long_master_user_password():
with pytest.raises(ClientError) as ex:
client.create_db_cluster(
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter2",
)
@ -84,7 +103,7 @@ def test_modify_db_cluster_needs_long_master_user_password():
client.create_db_cluster(
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter21",
)
@ -110,7 +129,7 @@ def test_modify_db_cluster_new_cluster_identifier():
client.create_db_cluster(
DBClusterIdentifier=old_id,
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter21",
)
@ -137,7 +156,7 @@ def test_create_db_cluster__verify_default_properties():
resp = client.create_db_cluster(
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-mysql",
MasterUsername="root",
MasterUserPassword="hunter2_",
)
@ -169,8 +188,8 @@ def test_create_db_cluster__verify_default_properties():
)
assert cluster["ReaderEndpoint"] == expected_readonly
assert cluster["MultiAZ"] is False
assert cluster["Engine"] == "aurora"
assert cluster["EngineVersion"] == "5.6.mysql_aurora.1.22.5"
assert cluster["Engine"] == "aurora-mysql"
assert cluster["EngineVersion"] == "5.7.mysql_aurora.2.07.2"
assert cluster["Port"] == 3306
assert cluster["MasterUsername"] == "root"
assert cluster["PreferredBackupWindow"] == "01:37-02:07"
@ -206,7 +225,7 @@ def test_create_db_cluster_additional_parameters():
AvailabilityZones=["eu-north-1b"],
DatabaseName="users",
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-postgresql",
EngineVersion="8.0.mysql_aurora.3.01.0",
EngineMode="serverless",
MasterUsername="root",
@ -232,7 +251,7 @@ def test_create_db_cluster_additional_parameters():
assert cluster["AvailabilityZones"] == ["eu-north-1b"]
assert cluster["DatabaseName"] == "users"
assert cluster["Engine"] == "aurora"
assert cluster["Engine"] == "aurora-postgresql"
assert cluster["EngineVersion"] == "8.0.mysql_aurora.3.01.0"
assert cluster["EngineMode"] == "serverless"
assert cluster["Port"] == 1234
@ -259,14 +278,14 @@ def test_describe_db_cluster_after_creation():
client.create_db_cluster(
DBClusterIdentifier="cluster-id1",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter2_",
)
cluster_arn = client.create_db_cluster(
DBClusterIdentifier="cluster-id2",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter2_",
)["DBCluster"]["DBClusterArn"]
@ -292,7 +311,7 @@ def test_delete_db_cluster():
client.create_db_cluster(
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter2_",
)
@ -308,7 +327,7 @@ def test_delete_db_cluster_do_snapshot():
client.create_db_cluster(
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter2_",
)
@ -329,7 +348,7 @@ def test_delete_db_cluster_that_is_protected():
client.create_db_cluster(
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter2_",
DeletionProtection=True,
@ -369,7 +388,7 @@ def test_start_db_cluster_after_stopping():
client.create_db_cluster(
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter2_",
)
@ -386,7 +405,7 @@ def test_start_db_cluster_without_stopping():
client.create_db_cluster(
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter2_",
)
@ -404,7 +423,7 @@ def test_stop_db_cluster():
client.create_db_cluster(
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter2_",
)
@ -425,7 +444,7 @@ def test_stop_db_cluster_already_stopped():
client.create_db_cluster(
DBClusterIdentifier="cluster-id",
Engine="aurora",
Engine="aurora-postgresql",
MasterUsername="root",
MasterUserPassword="hunter2_",
)
@ -838,7 +857,7 @@ def test_create_db_cluster_with_enable_http_endpoint_invalid():
resp = client.create_db_cluster(
DBClusterIdentifier="cluster-id",
DatabaseName="users",
Engine="aurora-mysql",
Engine="aurora-postgresql",
EngineMode="serverless",
EngineVersion="5.7.0",
MasterUsername="root",

View File

@ -74,7 +74,7 @@ def test_add_instance_to_serverless_cluster():
_ = client.create_db_cluster(
DBClusterIdentifier="dbci",
Engine="aurora",
Engine="aurora-postgresql",
EngineMode="serverless",
MasterUsername="masterusername",
MasterUserPassword="hunter2_",