RDS: add cluster engine validation when creating a rds cluster (#7001)
This commit is contained in:
parent
e43619ae07
commit
3ca46c3c24
@ -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."
|
||||
)
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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_",
|
||||
|
Loading…
Reference in New Issue
Block a user