2023-08-17 07:42:19 +00:00
|
|
|
import datetime
|
|
|
|
|
2017-05-11 01:58:42 +00:00
|
|
|
import boto3
|
2023-08-17 07:42:19 +00:00
|
|
|
from botocore.exceptions import ClientError
|
2021-11-04 22:39:53 +00:00
|
|
|
import pytest
|
2023-08-17 07:42:19 +00:00
|
|
|
|
2022-03-09 11:05:18 +00:00
|
|
|
from moto import mock_ec2, mock_kms, mock_rds
|
2022-08-13 09:49:43 +00:00
|
|
|
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
2022-03-09 11:05:18 +00:00
|
|
|
|
2023-07-13 21:31:14 +00:00
|
|
|
DEFAULT_REGION = "us-west-2"
|
|
|
|
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
LicenseModel="license-included",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
VpcSecurityGroupIds=["sg-123456"],
|
2022-05-09 08:40:16 +00:00
|
|
|
EnableCloudwatchLogsExports=["audit", "error"],
|
2022-03-09 11:05:18 +00:00
|
|
|
)
|
|
|
|
db_instance = database["DBInstance"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_instance["AllocatedStorage"] == 10
|
|
|
|
assert db_instance["DBInstanceClass"] == "db.m1.small"
|
|
|
|
assert db_instance["LicenseModel"] == "license-included"
|
|
|
|
assert db_instance["MasterUsername"] == "root"
|
|
|
|
assert db_instance["DBSecurityGroups"][0]["DBSecurityGroupName"] == "my_sg"
|
|
|
|
assert db_instance["DBInstanceArn"] == (
|
2022-11-17 22:41:08 +00:00
|
|
|
f"arn:aws:rds:us-west-2:{ACCOUNT_ID}:db:db-master-1"
|
2022-03-09 11:05:18 +00:00
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_instance["DBInstanceStatus"] == "available"
|
|
|
|
assert db_instance["DBName"] == "staging-postgres"
|
|
|
|
assert db_instance["DBInstanceIdentifier"] == "db-master-1"
|
|
|
|
assert db_instance["IAMDatabaseAuthenticationEnabled"] is False
|
|
|
|
assert "db-" in db_instance["DbiResourceId"]
|
|
|
|
assert db_instance["CopyTagsToSnapshot"] is False
|
|
|
|
assert isinstance(db_instance["InstanceCreateTime"], datetime.datetime)
|
|
|
|
assert db_instance["VpcSecurityGroups"][0]["VpcSecurityGroupId"] == "sg-123456"
|
|
|
|
assert db_instance["DeletionProtection"] is False
|
|
|
|
assert db_instance["EnabledCloudwatchLogsExports"] == ["audit", "error"]
|
|
|
|
assert db_instance["Endpoint"]["Port"] == 1234
|
|
|
|
assert db_instance["DbInstancePort"] == 1234
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_database_with_deletion_protection_cannot_be_deleted():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
DeletionProtection=True,
|
|
|
|
)
|
|
|
|
db_instance = database["DBInstance"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_instance["DBInstanceClass"] == "db.m1.small"
|
|
|
|
assert db_instance["DeletionProtection"] is True
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_no_allocated_storage():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
)
|
|
|
|
db_instance = database["DBInstance"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_instance["Engine"] == "postgres"
|
|
|
|
assert db_instance["StorageType"] == "gp2"
|
|
|
|
assert db_instance["AllocatedStorage"] == 20
|
|
|
|
assert db_instance["PreferredMaintenanceWindow"] == "wed:06:38-wed:07:08"
|
2023-01-13 23:11:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_invalid_preferred_maintenance_window_more_24_hours():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
PreferredMaintenanceWindow="mon:16:00-tue:17:00",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert err["Message"] == "Maintenance window must be less than 24 hours."
|
2023-01-13 23:11:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_invalid_preferred_maintenance_window_less_30_mins():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
PreferredMaintenanceWindow="mon:16:00-mon:16:05",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert err["Message"] == "The maintenance window must be at least 30 minutes."
|
2023-01-13 23:11:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_invalid_preferred_maintenance_window_value():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
PreferredMaintenanceWindow="sim:16:00-mon:16:30",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert "Invalid day:hour:minute" in err["Message"]
|
2023-01-13 23:11:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_invalid_preferred_maintenance_window_format():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
PreferredMaintenanceWindow="mon:16tue:17:00",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert (
|
|
|
|
"Should be specified as a range ddd:hh24:mi-ddd:hh24:mi "
|
|
|
|
"(24H Clock UTC). Example: Sun:23:45-Mon:00:15"
|
|
|
|
) in err["Message"]
|
2023-01-13 23:11:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_preferred_backup_window_overlap_no_spill():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
PreferredMaintenanceWindow="wed:18:00-wed:22:00",
|
|
|
|
PreferredBackupWindow="20:00-20:30",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert (
|
|
|
|
"The backup window and maintenance window must not overlap." in err["Message"]
|
2023-01-13 23:11:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_preferred_backup_window_overlap_maintenance_window_spill():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
PreferredMaintenanceWindow="wed:18:00-thu:01:00",
|
|
|
|
PreferredBackupWindow="00:00-00:30",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert (
|
|
|
|
"The backup window and maintenance window must not overlap." in err["Message"]
|
2023-01-13 23:11:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_preferred_backup_window_overlap_backup_window_spill():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
PreferredMaintenanceWindow="thu:00:00-thu:14:00",
|
|
|
|
PreferredBackupWindow="23:50-00:20",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert (
|
|
|
|
"The backup window and maintenance window must not overlap." in err["Message"]
|
2023-01-13 23:11:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_preferred_backup_window_overlap_both_spill():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
PreferredMaintenanceWindow="wed:18:00-thu:01:00",
|
|
|
|
PreferredBackupWindow="23:50-00:20",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert (
|
|
|
|
"The backup window and maintenance window must not overlap." in err["Message"]
|
2023-01-13 23:11:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_valid_preferred_maintenance_window_format():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
PreferredMaintenanceWindow="sun:16:00-sun:16:30",
|
|
|
|
)
|
|
|
|
db_instance = database["DBInstance"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_instance["DBInstanceClass"] == "db.m1.small"
|
|
|
|
assert db_instance["PreferredMaintenanceWindow"] == "sun:16:00-sun:16:30"
|
2023-01-13 23:11:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_valid_preferred_maintenance_window_uppercase_format():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
PreferredMaintenanceWindow="MON:16:00-TUE:01:30",
|
|
|
|
)
|
|
|
|
db_instance = database["DBInstance"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_instance["DBInstanceClass"] == "db.m1.small"
|
|
|
|
assert db_instance["PreferredMaintenanceWindow"] == "mon:16:00-tue:01:30"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_non_existing_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
OptionGroupName="non-existing",
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_with_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="my-og",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test option group",
|
|
|
|
)
|
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
OptionGroupName="my-og",
|
|
|
|
)
|
|
|
|
db_instance = database["DBInstance"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_instance["AllocatedStorage"] == 10
|
|
|
|
assert db_instance["DBInstanceClass"] == "db.m1.small"
|
|
|
|
assert db_instance["DBName"] == "staging-postgres"
|
|
|
|
assert db_instance["OptionGroupMemberships"][0]["OptionGroupName"] == "my-og"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_stop_database():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
LicenseModel="license-included",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
mydb = conn.describe_db_instances(
|
|
|
|
DBInstanceIdentifier=database["DBInstance"]["DBInstanceIdentifier"]
|
|
|
|
)["DBInstances"][0]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert mydb["DBInstanceStatus"] == "available"
|
2022-03-09 11:05:18 +00:00
|
|
|
# test stopping database should shutdown
|
|
|
|
response = conn.stop_db_instance(DBInstanceIdentifier=mydb["DBInstanceIdentifier"])
|
2023-08-17 07:42:19 +00:00
|
|
|
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
|
|
|
|
assert response["DBInstance"]["DBInstanceStatus"] == "stopped"
|
2022-03-09 11:05:18 +00:00
|
|
|
# test rdsclient error when trying to stop an already stopped database
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.stop_db_instance(DBInstanceIdentifier=mydb["DBInstanceIdentifier"])
|
|
|
|
# test stopping a stopped database with snapshot should error and no
|
|
|
|
# snapshot should exist for that call
|
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.stop_db_instance(
|
|
|
|
DBInstanceIdentifier=mydb["DBInstanceIdentifier"],
|
|
|
|
DBSnapshotIdentifier="rocky4570-rds-snap",
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
response = conn.describe_db_snapshots()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert response["DBSnapshots"] == []
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_start_database():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
LicenseModel="license-included",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
mydb = conn.describe_db_instances(
|
|
|
|
DBInstanceIdentifier=database["DBInstance"]["DBInstanceIdentifier"]
|
|
|
|
)["DBInstances"][0]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert mydb["DBInstanceStatus"] == "available"
|
2022-03-09 11:05:18 +00:00
|
|
|
# test starting an already started database should error
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.start_db_instance(DBInstanceIdentifier=mydb["DBInstanceIdentifier"])
|
|
|
|
# stop and test start - should go from stopped to available, create
|
|
|
|
# snapshot and check snapshot
|
2022-03-09 11:05:18 +00:00
|
|
|
response = conn.stop_db_instance(
|
|
|
|
DBInstanceIdentifier=mydb["DBInstanceIdentifier"],
|
|
|
|
DBSnapshotIdentifier="rocky4570-rds-snap",
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
|
|
|
|
assert response["DBInstance"]["DBInstanceStatus"] == "stopped"
|
2022-03-09 11:05:18 +00:00
|
|
|
response = conn.describe_db_snapshots()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert response["DBSnapshots"][0]["DBSnapshotIdentifier"] == "rocky4570-rds-snap"
|
2022-03-09 11:05:18 +00:00
|
|
|
response = conn.start_db_instance(DBInstanceIdentifier=mydb["DBInstanceIdentifier"])
|
2023-08-17 07:42:19 +00:00
|
|
|
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
|
|
|
|
assert response["DBInstance"]["DBInstanceStatus"] == "available"
|
2022-03-09 11:05:18 +00:00
|
|
|
# starting database should not remove snapshot
|
|
|
|
response = conn.describe_db_snapshots()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert response["DBSnapshots"][0]["DBSnapshotIdentifier"] == "rocky4570-rds-snap"
|
|
|
|
# test stopping database, create snapshot with existing snapshot already
|
|
|
|
# created should throw error
|
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.stop_db_instance(
|
|
|
|
DBInstanceIdentifier=mydb["DBInstanceIdentifier"],
|
|
|
|
DBSnapshotIdentifier="rocky4570-rds-snap",
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
# test stopping database not invoking snapshot should succeed.
|
|
|
|
response = conn.stop_db_instance(DBInstanceIdentifier=mydb["DBInstanceIdentifier"])
|
2023-08-17 07:42:19 +00:00
|
|
|
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
|
|
|
|
assert response["DBInstance"]["DBInstanceStatus"] == "stopped"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_fail_to_stop_multi_az_and_sqlserver():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="sqlserver-ee",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
LicenseModel="license-included",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
MultiAZ=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
mydb = conn.describe_db_instances(
|
|
|
|
DBInstanceIdentifier=database["DBInstance"]["DBInstanceIdentifier"]
|
|
|
|
)["DBInstances"][0]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert mydb["DBInstanceStatus"] == "available"
|
2022-03-09 11:05:18 +00:00
|
|
|
# multi-az databases arent allowed to be shutdown at this time.
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.stop_db_instance(DBInstanceIdentifier=mydb["DBInstanceIdentifier"])
|
2022-03-09 11:05:18 +00:00
|
|
|
# multi-az databases arent allowed to be started up at this time.
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.start_db_instance(DBInstanceIdentifier=mydb["DBInstanceIdentifier"])
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_stop_multi_az_postgres():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
LicenseModel="license-included",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
MultiAZ=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
mydb = conn.describe_db_instances(
|
|
|
|
DBInstanceIdentifier=database["DBInstance"]["DBInstanceIdentifier"]
|
|
|
|
)["DBInstances"][0]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert mydb["DBInstanceStatus"] == "available"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
response = conn.stop_db_instance(DBInstanceIdentifier=mydb["DBInstanceIdentifier"])
|
2023-08-17 07:42:19 +00:00
|
|
|
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
|
|
|
|
assert response["DBInstance"]["DBInstanceStatus"] == "stopped"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_fail_to_stop_readreplica():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
LicenseModel="license-included",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
|
|
|
|
replica = conn.create_db_instance_read_replica(
|
|
|
|
DBInstanceIdentifier="db-replica-1",
|
|
|
|
SourceDBInstanceIdentifier="db-master-1",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
)
|
|
|
|
|
|
|
|
mydb = conn.describe_db_instances(
|
|
|
|
DBInstanceIdentifier=replica["DBInstance"]["DBInstanceIdentifier"]
|
|
|
|
)["DBInstances"][0]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert mydb["DBInstanceStatus"] == "available"
|
2022-03-09 11:05:18 +00:00
|
|
|
# read-replicas are not allowed to be stopped at this time.
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.stop_db_instance(DBInstanceIdentifier=mydb["DBInstanceIdentifier"])
|
2022-03-09 11:05:18 +00:00
|
|
|
# read-replicas are not allowed to be started at this time.
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.start_db_instance(DBInstanceIdentifier=mydb["DBInstanceIdentifier"])
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_get_databases():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2015-01-09 03:18:06 +00:00
|
|
|
|
2022-03-09 11:05:18 +00:00
|
|
|
instances = conn.describe_db_instances()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(instances["DBInstances"])) == 0
|
2015-01-09 03:18:06 +00:00
|
|
|
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-2",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
DeletionProtection=True,
|
|
|
|
)
|
|
|
|
instances = conn.describe_db_instances()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(instances["DBInstances"])) == 2
|
2015-01-09 03:18:06 +00:00
|
|
|
|
2022-03-09 11:05:18 +00:00
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(instances["DBInstances"])) == 1
|
|
|
|
assert instances["DBInstances"][0]["DBInstanceIdentifier"] == "db-master-1"
|
|
|
|
assert instances["DBInstances"][0]["DeletionProtection"] is False
|
|
|
|
assert instances["DBInstances"][0]["DBInstanceArn"] == (
|
2022-11-17 22:41:08 +00:00
|
|
|
f"arn:aws:rds:us-west-2:{ACCOUNT_ID}:db:db-master-1"
|
2021-11-04 22:39:53 +00:00
|
|
|
)
|
|
|
|
|
2022-03-09 11:05:18 +00:00
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-2")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert instances["DBInstances"][0]["DeletionProtection"] is True
|
|
|
|
assert instances["DBInstances"][0]["Endpoint"]["Port"] == 1234
|
|
|
|
assert instances["DBInstances"][0]["DbInstancePort"] == 1234
|
2022-03-09 11:05:18 +00:00
|
|
|
|
2021-11-04 22:39:53 +00:00
|
|
|
|
2017-05-11 01:58:42 +00:00
|
|
|
@mock_rds
|
|
|
|
def test_get_databases_paginated():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2017-05-11 01:58:42 +00:00
|
|
|
|
|
|
|
for i in range(51):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
AllocatedStorage=5,
|
|
|
|
Port=5432,
|
2022-11-17 22:41:08 +00:00
|
|
|
DBInstanceIdentifier=f"rds{i}",
|
2019-10-31 15:44:26 +00:00
|
|
|
DBInstanceClass="db.t1.micro",
|
|
|
|
Engine="postgres",
|
|
|
|
)
|
2017-05-11 01:58:42 +00:00
|
|
|
|
|
|
|
resp = conn.describe_db_instances()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(resp["DBInstances"]) == 50
|
|
|
|
assert resp["Marker"] == resp["DBInstances"][-1]["DBInstanceIdentifier"]
|
2017-05-11 01:58:42 +00:00
|
|
|
|
|
|
|
resp2 = conn.describe_db_instances(Marker=resp["Marker"])
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(resp2["DBInstances"]) == 1
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
resp3 = conn.describe_db_instances(MaxRecords=100)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(resp3["DBInstances"]) == 51
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_describe_non_existent_database():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.describe_db_instances(DBInstanceIdentifier="not-a-db")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert instances["DBInstances"][0]["AllocatedStorage"] == 10
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=20,
|
|
|
|
ApplyImmediately=True,
|
|
|
|
VpcSecurityGroupIds=["sg-123456"],
|
|
|
|
)
|
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert instances["DBInstances"][0]["AllocatedStorage"] == 20
|
|
|
|
assert instances["DBInstances"][0]["PreferredMaintenanceWindow"] == (
|
2023-01-13 23:11:03 +00:00
|
|
|
"wed:06:38-wed:07:08"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert (
|
|
|
|
instances["DBInstances"][0]["VpcSecurityGroups"][0]["VpcSecurityGroupId"]
|
|
|
|
== "sg-123456"
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_not_existent_db_parameter_group_name():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert instances["DBInstances"][0]["AllocatedStorage"] == 10
|
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
DBParameterGroupName="test-sqlserver-se-2017",
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
2023-01-13 23:11:03 +00:00
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_valid_preferred_maintenance_window():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
PreferredMaintenanceWindow="sun:16:00-sun:16:30",
|
|
|
|
)
|
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert instances["DBInstances"][0]["PreferredMaintenanceWindow"] == (
|
2023-01-13 23:11:03 +00:00
|
|
|
"sun:16:00-sun:16:30"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_valid_preferred_maintenance_window_uppercase():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
PreferredMaintenanceWindow="SUN:16:00-SUN:16:30",
|
|
|
|
)
|
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert instances["DBInstances"][0]["PreferredMaintenanceWindow"] == (
|
2023-01-13 23:11:03 +00:00
|
|
|
"sun:16:00-sun:16:30"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_invalid_preferred_maintenance_window_more_than_24_hours():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
PreferredMaintenanceWindow="sun:16:00-sat:16:30",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert err["Message"] == "Maintenance window must be less than 24 hours."
|
2023-01-13 23:11:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_invalid_preferred_maintenance_window_less_than_30_mins():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
PreferredMaintenanceWindow="sun:16:00-sun:16:10",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert err["Message"] == "The maintenance window must be at least 30 minutes."
|
2023-01-13 23:11:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_invalid_preferred_maintenance_window_value():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
PreferredMaintenanceWindow="sin:16:00-sun:16:30",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert "Invalid day:hour:minute value" in err["Message"]
|
2023-01-13 23:11:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_invalid_preferred_maintenance_window_format():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
PreferredMaintenanceWindow="sun:16:00sun:16:30",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert (
|
|
|
|
"Should be specified as a range ddd:hh24:mi-ddd:hh24:mi "
|
|
|
|
"(24H Clock UTC). Example: Sun:23:45-Mon:00:15"
|
|
|
|
) in err["Message"]
|
2023-01-13 23:11:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_maintenance_backup_window_no_spill():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
PreferredMaintenanceWindow="sun:16:00-sun:16:30",
|
|
|
|
PreferredBackupWindow="15:50-16:20",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert (
|
|
|
|
err["Message"] == "The backup window and maintenance window must not overlap."
|
2023-01-13 23:11:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_maintenance_backup_window_maintenance_spill():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
PreferredMaintenanceWindow="sun:16:00-mon:15:00",
|
|
|
|
PreferredBackupWindow="00:00-00:30",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert err["Message"] == (
|
2023-01-13 23:11:03 +00:00
|
|
|
"The backup window and maintenance window must not overlap."
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_maintenance_backup_window_backup_spill():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
PreferredMaintenanceWindow="mon:00:00-mon:15:00",
|
|
|
|
PreferredBackupWindow="23:50-00:20",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert err["Message"] == (
|
2023-01-13 23:11:03 +00:00
|
|
|
"The backup window and maintenance window must not overlap."
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_maintenance_backup_window_both_spill():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-01-13 23:11:03 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
PreferredMaintenanceWindow="sun:16:00-mon:15:00",
|
|
|
|
PreferredBackupWindow="23:20-00:20",
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert err["Message"] == (
|
2023-01-13 23:11:03 +00:00
|
|
|
"The backup window and maintenance window must not overlap."
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-03-09 11:05:18 +00:00
|
|
|
@mock_rds
|
|
|
|
def test_rename_db_instance():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(instances["DBInstances"])) == 1
|
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.describe_db_instances(DBInstanceIdentifier="db-master-2")
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
NewDBInstanceIdentifier="db-master-2",
|
|
|
|
ApplyImmediately=True,
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2022-03-09 11:05:18 +00:00
|
|
|
instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-2")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(instances["DBInstances"])) == 1
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_non_existent_database():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="not-a-db", AllocatedStorage=20, ApplyImmediately=True
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_reboot_db_instance():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
database = conn.reboot_db_instance(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert database["DBInstance"]["DBInstanceIdentifier"] == "db-master-1"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_reboot_non_existent_database():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.reboot_db_instance(DBInstanceIdentifier="not-a-db")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_delete_database():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
instances = conn.describe_db_instances()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(instances["DBInstances"])) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
2023-06-25 17:36:42 +00:00
|
|
|
DBInstanceIdentifier="db-1",
|
2022-03-09 11:05:18 +00:00
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
instances = conn.describe_db_instances()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(instances["DBInstances"])) == 1
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.delete_db_instance(
|
2023-06-25 17:36:42 +00:00
|
|
|
DBInstanceIdentifier="db-1",
|
2022-03-09 11:05:18 +00:00
|
|
|
FinalDBSnapshotIdentifier="primary-1-snapshot",
|
|
|
|
)
|
|
|
|
|
|
|
|
instances = conn.describe_db_instances()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(instances["DBInstances"])) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
# Saved the snapshot
|
2023-06-25 17:36:42 +00:00
|
|
|
snapshot = conn.describe_db_snapshots(DBInstanceIdentifier="db-1")["DBSnapshots"][0]
|
|
|
|
assert snapshot["Engine"] == "postgres"
|
|
|
|
assert snapshot["SnapshotType"] == "automated"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_db_snapshots():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-1"
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
|
|
|
|
snapshot = conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="g-1"
|
|
|
|
).get("DBSnapshot")
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
assert snapshot.get("Engine") == "postgres"
|
|
|
|
assert snapshot.get("DBInstanceIdentifier") == "db-primary-1"
|
|
|
|
assert snapshot.get("DBSnapshotIdentifier") == "g-1"
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.list_tags_for_resource(ResourceName=snapshot["DBSnapshotArn"])
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == []
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_db_snapshots_copy_tags():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-1"
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
CopyTagsToSnapshot=True,
|
|
|
|
Tags=[{"Key": "foo", "Value": "bar"}, {"Key": "foo1", "Value": "bar1"}],
|
|
|
|
)
|
|
|
|
|
|
|
|
snapshot = conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="g-1"
|
|
|
|
).get("DBSnapshot")
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
assert snapshot.get("Engine") == "postgres"
|
|
|
|
assert snapshot.get("DBInstanceIdentifier") == "db-primary-1"
|
|
|
|
assert snapshot.get("DBSnapshotIdentifier") == "g-1"
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.list_tags_for_resource(ResourceName=snapshot["DBSnapshotArn"])
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == [
|
|
|
|
{"Value": "bar", "Key": "foo"},
|
|
|
|
{"Value": "bar1", "Key": "foo1"},
|
|
|
|
]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
2023-03-20 16:58:24 +00:00
|
|
|
@mock_rds
|
|
|
|
def test_create_db_snapshots_with_tags():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-03-20 16:58:24 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
|
|
|
|
conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
DBSnapshotIdentifier="g-1",
|
|
|
|
Tags=[{"Key": "foo", "Value": "bar"}, {"Key": "foo1", "Value": "bar1"}],
|
|
|
|
)
|
|
|
|
|
|
|
|
snapshots = conn.describe_db_snapshots(DBInstanceIdentifier="db-primary-1").get(
|
|
|
|
"DBSnapshots"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert snapshots[0].get("DBSnapshotIdentifier") == "g-1"
|
|
|
|
assert snapshots[0].get("TagList") == [
|
|
|
|
{"Value": "bar", "Key": "foo"},
|
|
|
|
{"Value": "bar1", "Key": "foo1"},
|
|
|
|
]
|
2023-03-20 16:58:24 +00:00
|
|
|
|
|
|
|
|
2022-03-09 11:05:18 +00:00
|
|
|
@mock_rds
|
|
|
|
def test_copy_db_snapshots():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
|
|
|
|
conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-1"
|
|
|
|
).get("DBSnapshot")
|
|
|
|
|
|
|
|
target_snapshot = conn.copy_db_snapshot(
|
|
|
|
SourceDBSnapshotIdentifier="snapshot-1", TargetDBSnapshotIdentifier="snapshot-2"
|
|
|
|
).get("DBSnapshot")
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
assert target_snapshot.get("Engine") == "postgres"
|
|
|
|
assert target_snapshot.get("DBInstanceIdentifier") == "db-primary-1"
|
|
|
|
assert target_snapshot.get("DBSnapshotIdentifier") == "snapshot-2"
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.list_tags_for_resource(ResourceName=target_snapshot["DBSnapshotArn"])
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == []
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_describe_db_snapshots():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
|
|
|
|
created = conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-1"
|
|
|
|
).get("DBSnapshot")
|
|
|
|
|
2023-06-25 17:36:42 +00:00
|
|
|
assert created["Engine"] == "postgres"
|
|
|
|
assert created["SnapshotType"] == "manual"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
by_database_id = conn.describe_db_snapshots(
|
|
|
|
DBInstanceIdentifier="db-primary-1"
|
|
|
|
).get("DBSnapshots")
|
|
|
|
by_snapshot_id = conn.describe_db_snapshots(DBSnapshotIdentifier="snapshot-1").get(
|
|
|
|
"DBSnapshots"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert by_snapshot_id == by_database_id
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
snapshot = by_snapshot_id[0]
|
2023-06-25 17:36:42 +00:00
|
|
|
assert snapshot == created
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-2"
|
|
|
|
)
|
|
|
|
snapshots = conn.describe_db_snapshots(DBInstanceIdentifier="db-primary-1").get(
|
|
|
|
"DBSnapshots"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(snapshots) == 2
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
2022-12-08 12:03:32 +00:00
|
|
|
@mock_rds
|
|
|
|
def test_promote_read_replica():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-12-08 12:03:32 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
|
|
|
|
conn.create_db_instance_read_replica(
|
|
|
|
DBInstanceIdentifier="db-replica-1",
|
|
|
|
SourceDBInstanceIdentifier="db-primary-1",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
)
|
|
|
|
conn.promote_read_replica(DBInstanceIdentifier="db-replica-1")
|
|
|
|
|
|
|
|
replicas = conn.describe_db_instances(DBInstanceIdentifier="db-primary-1").get(
|
|
|
|
"ReadReplicaDBInstanceIdentifiers"
|
|
|
|
)
|
|
|
|
assert replicas is None
|
|
|
|
|
|
|
|
|
2022-03-09 11:05:18 +00:00
|
|
|
@mock_rds
|
|
|
|
def test_delete_db_snapshot():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-1"
|
|
|
|
)
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
_ = conn.describe_db_snapshots(DBSnapshotIdentifier="snapshot-1").get(
|
|
|
|
"DBSnapshots"
|
|
|
|
)[0]
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.delete_db_snapshot(DBSnapshotIdentifier="snapshot-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.describe_db_snapshots(DBSnapshotIdentifier="snapshot-1")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_restore_db_instance_from_db_snapshot():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(conn.describe_db_instances()["DBInstances"]) == 1
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-1"
|
|
|
|
)
|
|
|
|
|
|
|
|
# restore
|
|
|
|
new_instance = conn.restore_db_instance_from_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-restore-1", DBSnapshotIdentifier="snapshot-1"
|
|
|
|
)["DBInstance"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert new_instance["DBInstanceIdentifier"] == "db-restore-1"
|
|
|
|
assert new_instance["DBInstanceClass"] == "db.m1.small"
|
|
|
|
assert new_instance["StorageType"] == "gp2"
|
|
|
|
assert new_instance["Engine"] == "postgres"
|
|
|
|
assert new_instance["DBName"] == "staging-postgres"
|
|
|
|
assert new_instance["DBParameterGroups"][0]["DBParameterGroupName"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"default.postgres9.3"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert new_instance["DBSecurityGroups"] == [
|
|
|
|
{"DBSecurityGroupName": "my_sg", "Status": "active"}
|
|
|
|
]
|
|
|
|
assert new_instance["Endpoint"]["Port"] == 5432
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
# Verify it exists
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(conn.describe_db_instances()["DBInstances"]) == 2
|
|
|
|
assert (
|
|
|
|
len(
|
|
|
|
conn.describe_db_instances(DBInstanceIdentifier="db-restore-1")[
|
|
|
|
"DBInstances"
|
|
|
|
]
|
|
|
|
)
|
|
|
|
== 1
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_restore_db_instance_from_db_snapshot_and_override_params():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(conn.describe_db_instances()["DBInstances"]) == 1
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-1"
|
|
|
|
)
|
|
|
|
|
|
|
|
# restore with some updated attributes
|
|
|
|
new_instance = conn.restore_db_instance_from_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-restore-1",
|
|
|
|
DBSnapshotIdentifier="snapshot-1",
|
|
|
|
Port=10000,
|
|
|
|
VpcSecurityGroupIds=["new_vpc"],
|
|
|
|
)["DBInstance"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert new_instance["DBInstanceIdentifier"] == "db-restore-1"
|
|
|
|
assert new_instance["DBParameterGroups"][0]["DBParameterGroupName"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"default.postgres9.3"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert new_instance["DBSecurityGroups"] == [
|
|
|
|
{"DBSecurityGroupName": "my_sg", "Status": "active"}
|
|
|
|
]
|
|
|
|
assert new_instance["VpcSecurityGroups"] == [
|
|
|
|
{"VpcSecurityGroupId": "new_vpc", "Status": "active"}
|
|
|
|
]
|
|
|
|
assert new_instance["Endpoint"]["Port"] == 10000
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
option_group = conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test option group",
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert option_group["OptionGroup"]["OptionGroupName"] == "test"
|
|
|
|
assert option_group["OptionGroup"]["EngineName"] == "mysql"
|
|
|
|
assert option_group["OptionGroup"]["OptionGroupDescription"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"test option group"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert option_group["OptionGroup"]["MajorEngineVersion"] == "5.6"
|
|
|
|
assert option_group["OptionGroup"]["OptionGroupArn"] == (
|
2023-02-21 16:07:19 +00:00
|
|
|
f"arn:aws:rds:us-west-2:{ACCOUNT_ID}:og:test"
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_option_group_bad_engine_name():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="invalid_engine",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test invalid engine",
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_option_group_bad_engine_major_version():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="6.6.6",
|
|
|
|
OptionGroupDescription="test invalid engine version",
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_option_group_empty_description():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="",
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_option_group_duplicate():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test option group",
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test option group",
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_describe_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test option group",
|
|
|
|
)
|
|
|
|
option_groups = conn.describe_option_groups(OptionGroupName="test")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert option_groups["OptionGroupsList"][0]["OptionGroupName"] == "test"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_describe_non_existent_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.describe_option_groups(OptionGroupName="not-a-option-group")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_delete_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test option group",
|
|
|
|
)
|
|
|
|
option_groups = conn.describe_option_groups(OptionGroupName="test")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert option_groups["OptionGroupsList"][0]["OptionGroupName"] == "test"
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.delete_option_group(OptionGroupName="test")
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.describe_option_groups(OptionGroupName="test")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_delete_non_existent_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.delete_option_group(OptionGroupName="non-existent")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_describe_option_group_options():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
option_group_options = conn.describe_option_group_options(EngineName="sqlserver-ee")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(option_group_options["OptionGroupOptions"]) == 4
|
2022-03-09 11:05:18 +00:00
|
|
|
option_group_options = conn.describe_option_group_options(
|
|
|
|
EngineName="sqlserver-ee", MajorEngineVersion="11.00"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(option_group_options["OptionGroupOptions"]) == 2
|
2022-03-09 11:05:18 +00:00
|
|
|
option_group_options = conn.describe_option_group_options(
|
|
|
|
EngineName="mysql", MajorEngineVersion="5.6"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(option_group_options["OptionGroupOptions"]) == 1
|
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.describe_option_group_options(EngineName="non-existent")
|
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.describe_option_group_options(
|
|
|
|
EngineName="mysql", MajorEngineVersion="non-existent"
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test option group",
|
|
|
|
)
|
|
|
|
# TODO: create option and validate before deleting.
|
|
|
|
# if Someone can tell me how the hell to use this function
|
|
|
|
# to add options to an option_group, I can finish coding this.
|
|
|
|
result = conn.modify_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
OptionsToInclude=[],
|
|
|
|
OptionsToRemove=["MEMCACHED"],
|
|
|
|
ApplyImmediately=True,
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["OptionGroup"]["EngineName"] == "mysql"
|
|
|
|
assert result["OptionGroup"]["Options"] == []
|
|
|
|
assert result["OptionGroup"]["OptionGroupName"] == "test"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_option_group_no_options():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test option group",
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.modify_option_group(OptionGroupName="test")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_non_existent_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError) as client_err:
|
|
|
|
conn.modify_option_group(
|
|
|
|
OptionGroupName="non-existent",
|
|
|
|
OptionsToInclude=[{"OptionName": "test-option"}],
|
|
|
|
)
|
|
|
|
assert client_err.value.response["Error"]["Message"] == (
|
|
|
|
"Specified OptionGroupName: non-existent not found."
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_delete_database_with_protection():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
DeletionProtection=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
conn.delete_db_instance(DBInstanceIdentifier="db-primary-1")
|
|
|
|
err = exc.value.response["Error"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert err["Message"] == "Can't delete Instance with protection enabled"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_delete_non_existent_database():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.delete_db_instance(DBInstanceIdentifier="non-existent")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert ex.value.response["Error"]["Code"] == "DBInstanceNotFound"
|
|
|
|
assert ex.value.response["Error"]["Message"] == "DBInstance non-existent not found."
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_list_tags_invalid_arn():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.list_tags_for_resource(ResourceName="arn:aws:rds:bad-arn")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_list_tags_db():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:db:foo"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == []
|
2022-03-09 11:05:18 +00:00
|
|
|
test_instance = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-with-tags",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
Tags=[{"Key": "foo", "Value": "bar"}, {"Key": "foo1", "Value": "bar1"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName=test_instance["DBInstance"]["DBInstanceArn"]
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == [
|
|
|
|
{"Value": "bar", "Key": "foo"},
|
|
|
|
{"Value": "bar1", "Key": "foo1"},
|
|
|
|
]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_add_tags_db():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-without-tags",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
Tags=[{"Key": "foo", "Value": "bar"}, {"Key": "foo1", "Value": "bar1"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:db:db-without-tags"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(result["TagList"])) == 2
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.add_tags_to_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:db:db-without-tags",
|
|
|
|
Tags=[{"Key": "foo", "Value": "fish"}, {"Key": "foo2", "Value": "bar2"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:db:db-without-tags"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(result["TagList"])) == 3
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_remove_tags_db():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-with-tags",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
Tags=[{"Key": "foo", "Value": "bar"}, {"Key": "foo1", "Value": "bar1"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:db:db-with-tags"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(result["TagList"])) == 2
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.remove_tags_from_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:db:db-with-tags", TagKeys=["foo"]
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:db:db-with-tags"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["TagList"]) == 1
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_list_tags_snapshot():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:snapshot:foo"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == []
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
snapshot = conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
DBSnapshotIdentifier="snapshot-with-tags",
|
|
|
|
Tags=[{"Key": "foo", "Value": "bar"}, {"Key": "foo1", "Value": "bar1"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName=snapshot["DBSnapshot"]["DBSnapshotArn"]
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == [
|
|
|
|
{"Value": "bar", "Key": "foo"},
|
|
|
|
{"Value": "bar1", "Key": "foo1"},
|
|
|
|
]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_add_tags_snapshot():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
DBSnapshotIdentifier="snapshot-without-tags",
|
|
|
|
Tags=[{"Key": "foo", "Value": "bar"}, {"Key": "foo1", "Value": "bar1"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:snapshot:snapshot-without-tags"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(result["TagList"])) == 2
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.add_tags_to_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:snapshot:snapshot-without-tags",
|
|
|
|
Tags=[{"Key": "foo", "Value": "fish"}, {"Key": "foo2", "Value": "bar2"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:snapshot:snapshot-without-tags"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(result["TagList"])) == 3
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_remove_tags_snapshot():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="db-primary-1",
|
|
|
|
DBSnapshotIdentifier="snapshot-with-tags",
|
|
|
|
Tags=[{"Key": "foo", "Value": "bar"}, {"Key": "foo1", "Value": "bar1"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:snapshot:snapshot-with-tags"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(result["TagList"])) == 2
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.remove_tags_from_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:snapshot:snapshot-with-tags",
|
|
|
|
TagKeys=["foo"],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:snapshot:snapshot-with-tags"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["TagList"]) == 1
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_add_tags_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test option group",
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:og:test"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(result["TagList"])) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.add_tags_to_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:og:test",
|
|
|
|
Tags=[{"Key": "foo", "Value": "fish"}, {"Key": "foo2", "Value": "bar2"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:og:test"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(result["TagList"])) == 2
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_remove_tags_option_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_option_group(
|
|
|
|
OptionGroupName="test",
|
|
|
|
EngineName="mysql",
|
|
|
|
MajorEngineVersion="5.6",
|
|
|
|
OptionGroupDescription="test option group",
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:og:test"
|
|
|
|
)
|
|
|
|
conn.add_tags_to_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:og:test",
|
|
|
|
Tags=[{"Key": "foo", "Value": "fish"}, {"Key": "foo2", "Value": "bar2"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:og:test"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(result["TagList"])) == 2
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.remove_tags_from_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:og:test", TagKeys=["foo"]
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:og:test"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(list(result["TagList"])) == 1
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_security_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
result = conn.create_db_security_group(
|
|
|
|
DBSecurityGroupName="db_sg", DBSecurityGroupDescription="DB Security Group"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["DBSecurityGroup"]["DBSecurityGroupName"] == "db_sg"
|
|
|
|
assert (
|
|
|
|
result["DBSecurityGroup"]["DBSecurityGroupDescription"] == "DB Security Group"
|
2022-03-09 11:05:18 +00:00
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["DBSecurityGroup"]["IPRanges"] == []
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_get_security_groups():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
result = conn.describe_db_security_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSecurityGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.create_db_security_group(
|
|
|
|
DBSecurityGroupName="db_sg1", DBSecurityGroupDescription="DB Security Group"
|
|
|
|
)
|
|
|
|
conn.create_db_security_group(
|
|
|
|
DBSecurityGroupName="db_sg2", DBSecurityGroupDescription="DB Security Group"
|
|
|
|
)
|
|
|
|
|
|
|
|
result = conn.describe_db_security_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSecurityGroups"]) == 2
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
result = conn.describe_db_security_groups(DBSecurityGroupName="db_sg1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSecurityGroups"]) == 1
|
|
|
|
assert result["DBSecurityGroups"][0]["DBSecurityGroupName"] == "db_sg1"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_get_non_existent_security_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.describe_db_security_groups(DBSecurityGroupName="not-a-sg")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_delete_database_security_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_security_group(
|
|
|
|
DBSecurityGroupName="db_sg", DBSecurityGroupDescription="DB Security Group"
|
|
|
|
)
|
|
|
|
|
|
|
|
result = conn.describe_db_security_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSecurityGroups"]) == 1
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.delete_db_security_group(DBSecurityGroupName="db_sg")
|
|
|
|
result = conn.describe_db_security_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSecurityGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_delete_non_existent_security_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.delete_db_security_group(DBSecurityGroupName="not-a-db")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_security_group_authorize():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
security_group = conn.create_db_security_group(
|
|
|
|
DBSecurityGroupName="db_sg", DBSecurityGroupDescription="DB Security Group"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert security_group["DBSecurityGroup"]["IPRanges"] == []
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.authorize_db_security_group_ingress(
|
|
|
|
DBSecurityGroupName="db_sg", CIDRIP="10.3.2.45/32"
|
|
|
|
)
|
|
|
|
|
|
|
|
result = conn.describe_db_security_groups(DBSecurityGroupName="db_sg")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSecurityGroups"][0]["IPRanges"]) == 1
|
|
|
|
assert result["DBSecurityGroups"][0]["IPRanges"] == [
|
|
|
|
{"Status": "authorized", "CIDRIP": "10.3.2.45/32"}
|
|
|
|
]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.authorize_db_security_group_ingress(
|
|
|
|
DBSecurityGroupName="db_sg", CIDRIP="10.3.2.46/32"
|
|
|
|
)
|
|
|
|
result = conn.describe_db_security_groups(DBSecurityGroupName="db_sg")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSecurityGroups"][0]["IPRanges"]) == 2
|
|
|
|
assert result["DBSecurityGroups"][0]["IPRanges"] == [
|
|
|
|
{"Status": "authorized", "CIDRIP": "10.3.2.45/32"},
|
|
|
|
{"Status": "authorized", "CIDRIP": "10.3.2.46/32"},
|
|
|
|
]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_add_security_group_to_database():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
DBInstanceClass="postgres",
|
|
|
|
Engine="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
)
|
|
|
|
|
|
|
|
result = conn.describe_db_instances()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["DBInstances"][0]["DBSecurityGroups"] == []
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_security_group(
|
|
|
|
DBSecurityGroupName="db_sg", DBSecurityGroupDescription="DB Security Group"
|
|
|
|
)
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1", DBSecurityGroups=["db_sg"]
|
|
|
|
)
|
|
|
|
result = conn.describe_db_instances()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert (
|
|
|
|
result["DBInstances"][0]["DBSecurityGroups"][0]["DBSecurityGroupName"]
|
|
|
|
== "db_sg"
|
2022-03-09 11:05:18 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_list_tags_security_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.describe_db_subnet_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSubnetGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
security_group = conn.create_db_security_group(
|
|
|
|
DBSecurityGroupName="db_sg",
|
|
|
|
DBSecurityGroupDescription="DB Security Group",
|
|
|
|
Tags=[{"Value": "bar", "Key": "foo"}, {"Value": "bar1", "Key": "foo1"}],
|
|
|
|
)["DBSecurityGroup"]["DBSecurityGroupName"]
|
2022-11-17 22:41:08 +00:00
|
|
|
resource = f"arn:aws:rds:us-west-2:1234567890:secgrp:{security_group}"
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == [
|
|
|
|
{"Value": "bar", "Key": "foo"},
|
|
|
|
{"Value": "bar1", "Key": "foo1"},
|
|
|
|
]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_add_tags_security_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.describe_db_subnet_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSubnetGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
security_group = conn.create_db_security_group(
|
|
|
|
DBSecurityGroupName="db_sg", DBSecurityGroupDescription="DB Security Group"
|
|
|
|
)["DBSecurityGroup"]["DBSecurityGroupName"]
|
|
|
|
|
2022-11-17 22:41:08 +00:00
|
|
|
resource = f"arn:aws:rds:us-west-2:1234567890:secgrp:{security_group}"
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.add_tags_to_resource(
|
|
|
|
ResourceName=resource,
|
|
|
|
Tags=[{"Value": "bar", "Key": "foo"}, {"Value": "bar1", "Key": "foo1"}],
|
|
|
|
)
|
|
|
|
|
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == [
|
|
|
|
{"Value": "bar", "Key": "foo"},
|
|
|
|
{"Value": "bar1", "Key": "foo1"},
|
|
|
|
]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_remove_tags_security_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.describe_db_subnet_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSubnetGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
security_group = conn.create_db_security_group(
|
|
|
|
DBSecurityGroupName="db_sg",
|
|
|
|
DBSecurityGroupDescription="DB Security Group",
|
|
|
|
Tags=[{"Value": "bar", "Key": "foo"}, {"Value": "bar1", "Key": "foo1"}],
|
|
|
|
)["DBSecurityGroup"]["DBSecurityGroupName"]
|
|
|
|
|
2022-11-17 22:41:08 +00:00
|
|
|
resource = f"arn:aws:rds:us-west-2:1234567890:secgrp:{security_group}"
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.remove_tags_from_resource(ResourceName=resource, TagKeys=["foo"])
|
|
|
|
|
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == [{"Value": "bar1", "Key": "foo1"}]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_subnet_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
vpc_conn = boto3.client("ec2", DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
vpc = vpc_conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
|
|
|
subnet1 = vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.1.0/24")[
|
|
|
|
"Subnet"
|
|
|
|
]
|
|
|
|
subnet2 = vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.2.0/24")[
|
|
|
|
"Subnet"
|
|
|
|
]
|
|
|
|
|
|
|
|
subnet_ids = [subnet1["SubnetId"], subnet2["SubnetId"]]
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.create_db_subnet_group(
|
|
|
|
DBSubnetGroupName="db_subnet",
|
|
|
|
DBSubnetGroupDescription="my db subnet",
|
|
|
|
SubnetIds=subnet_ids,
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["DBSubnetGroup"]["DBSubnetGroupName"] == "db_subnet"
|
|
|
|
assert result["DBSubnetGroup"]["DBSubnetGroupDescription"] == "my db subnet"
|
2022-03-09 11:05:18 +00:00
|
|
|
subnets = result["DBSubnetGroup"]["Subnets"]
|
|
|
|
subnet_group_ids = [subnets[0]["SubnetIdentifier"], subnets[1]["SubnetIdentifier"]]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert list(subnet_group_ids) == subnet_ids
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_database_subnet_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
vpc_conn = boto3.client("ec2", DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
vpc = vpc_conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
|
|
|
subnet1 = vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.1.0/24")[
|
|
|
|
"Subnet"
|
|
|
|
]
|
|
|
|
subnet2 = vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.2.0/24")[
|
|
|
|
"Subnet"
|
|
|
|
]
|
|
|
|
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_subnet_group(
|
|
|
|
DBSubnetGroupName="db_subnet",
|
|
|
|
DBSubnetGroupDescription="my db subnet",
|
|
|
|
SubnetIds=[subnet1["SubnetId"]],
|
|
|
|
)
|
|
|
|
|
|
|
|
conn.modify_db_subnet_group(
|
|
|
|
DBSubnetGroupName="db_subnet",
|
|
|
|
DBSubnetGroupDescription="my updated desc",
|
|
|
|
SubnetIds=[subnet1["SubnetId"], subnet2["SubnetId"]],
|
|
|
|
)
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
_ = conn.describe_db_subnet_groups()["DBSubnetGroups"]
|
2022-03-09 11:05:18 +00:00
|
|
|
# FIXME: Group is deleted atm
|
|
|
|
# TODO: we should check whether all attrs are persisted
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_in_subnet_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
vpc_conn = boto3.client("ec2", DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
vpc = vpc_conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
|
|
|
subnet = vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.1.0/24")[
|
|
|
|
"Subnet"
|
|
|
|
]
|
|
|
|
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_subnet_group(
|
|
|
|
DBSubnetGroupName="db_subnet1",
|
|
|
|
DBSubnetGroupDescription="my db subnet",
|
|
|
|
SubnetIds=[subnet["SubnetId"]],
|
|
|
|
)
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSubnetGroupName="db_subnet1",
|
|
|
|
)
|
|
|
|
result = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["DBInstances"][0]["DBSubnetGroup"]["DBSubnetGroupName"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"db_subnet1"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_rds
|
|
|
|
def test_describe_database_subnet_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
vpc_conn = boto3.client("ec2", DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
vpc = vpc_conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
|
|
|
subnet = vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.1.0/24")[
|
|
|
|
"Subnet"
|
|
|
|
]
|
|
|
|
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_subnet_group(
|
|
|
|
DBSubnetGroupName="db_subnet1",
|
|
|
|
DBSubnetGroupDescription="my db subnet",
|
|
|
|
SubnetIds=[subnet["SubnetId"]],
|
|
|
|
)
|
|
|
|
conn.create_db_subnet_group(
|
|
|
|
DBSubnetGroupName="db_subnet2",
|
|
|
|
DBSubnetGroupDescription="my db subnet",
|
|
|
|
SubnetIds=[subnet["SubnetId"]],
|
|
|
|
)
|
|
|
|
|
|
|
|
resp = conn.describe_db_subnet_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(resp["DBSubnetGroups"]) == 2
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
subnets = resp["DBSubnetGroups"][0]["Subnets"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(subnets) == 1
|
|
|
|
|
|
|
|
assert (
|
|
|
|
len(
|
|
|
|
list(
|
|
|
|
conn.describe_db_subnet_groups(DBSubnetGroupName="db_subnet1")[
|
|
|
|
"DBSubnetGroups"
|
|
|
|
]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
== 1
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.describe_db_subnet_groups(DBSubnetGroupName="not-a-subnet")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_rds
|
|
|
|
def test_delete_database_subnet_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
vpc_conn = boto3.client("ec2", DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
vpc = vpc_conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
|
|
|
subnet = vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.1.0/24")[
|
|
|
|
"Subnet"
|
|
|
|
]
|
|
|
|
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.describe_db_subnet_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSubnetGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.create_db_subnet_group(
|
|
|
|
DBSubnetGroupName="db_subnet1",
|
|
|
|
DBSubnetGroupDescription="my db subnet",
|
|
|
|
SubnetIds=[subnet["SubnetId"]],
|
|
|
|
)
|
|
|
|
result = conn.describe_db_subnet_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSubnetGroups"]) == 1
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.delete_db_subnet_group(DBSubnetGroupName="db_subnet1")
|
|
|
|
result = conn.describe_db_subnet_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSubnetGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.delete_db_subnet_group(DBSubnetGroupName="db_subnet1")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_rds
|
|
|
|
def test_list_tags_database_subnet_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
vpc_conn = boto3.client("ec2", DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
vpc = vpc_conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
|
|
|
subnet = vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.1.0/24")[
|
|
|
|
"Subnet"
|
|
|
|
]
|
|
|
|
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.describe_db_subnet_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSubnetGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
subnet = conn.create_db_subnet_group(
|
|
|
|
DBSubnetGroupName="db_subnet1",
|
|
|
|
DBSubnetGroupDescription="my db subnet",
|
|
|
|
SubnetIds=[subnet["SubnetId"]],
|
|
|
|
Tags=[{"Value": "bar", "Key": "foo"}, {"Value": "bar1", "Key": "foo1"}],
|
|
|
|
)["DBSubnetGroup"]["DBSubnetGroupName"]
|
|
|
|
result = conn.list_tags_for_resource(
|
2022-11-17 22:41:08 +00:00
|
|
|
ResourceName=f"arn:aws:rds:us-west-2:1234567890:subgrp:{subnet}"
|
2022-03-09 11:05:18 +00:00
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == [
|
|
|
|
{"Value": "bar", "Key": "foo"},
|
|
|
|
{"Value": "bar1", "Key": "foo1"},
|
|
|
|
]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_tags_parameter_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
client_tags = [{"Key": "character_set_client", "Value": "utf-8"}]
|
|
|
|
result = conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName="test-sqlserver-2017",
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="MySQL Group",
|
|
|
|
Tags=client_tags,
|
|
|
|
)
|
|
|
|
resource = result["DBParameterGroup"]["DBParameterGroupArn"]
|
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == client_tags
|
2022-03-09 11:05:18 +00:00
|
|
|
server_tags = [{"Key": "character_set_server", "Value": "utf-8"}]
|
|
|
|
conn.add_tags_to_resource(ResourceName=resource, Tags=server_tags)
|
|
|
|
combined_tags = client_tags + server_tags
|
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == combined_tags
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.remove_tags_from_resource(
|
|
|
|
ResourceName=resource, TagKeys=["character_set_client"]
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == server_tags
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_tags_event_subscription():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
tags = [{"Key": "hello", "Value": "world"}]
|
|
|
|
result = conn.create_event_subscription(
|
|
|
|
SubscriptionName="my-instance-events",
|
|
|
|
SourceType="db-instance",
|
|
|
|
EventCategories=["backup", "recovery"],
|
|
|
|
SnsTopicArn="arn:aws:sns:us-east-1:123456789012:interesting-events",
|
|
|
|
Tags=tags,
|
|
|
|
)
|
|
|
|
resource = result["EventSubscription"]["EventSubscriptionArn"]
|
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == tags
|
2022-03-09 11:05:18 +00:00
|
|
|
new_tags = [{"Key": "new_key", "Value": "new_value"}]
|
|
|
|
conn.add_tags_to_resource(ResourceName=resource, Tags=new_tags)
|
|
|
|
combined_tags = tags + new_tags
|
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == combined_tags
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.remove_tags_from_resource(ResourceName=resource, TagKeys=["new_key"])
|
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == tags
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_rds
|
|
|
|
def test_add_tags_database_subnet_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
vpc_conn = boto3.client("ec2", DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
vpc = vpc_conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
|
|
|
subnet = vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.1.0/24")[
|
|
|
|
"Subnet"
|
|
|
|
]
|
|
|
|
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.describe_db_subnet_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSubnetGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
subnet = conn.create_db_subnet_group(
|
|
|
|
DBSubnetGroupName="db_subnet1",
|
|
|
|
DBSubnetGroupDescription="my db subnet",
|
|
|
|
SubnetIds=[subnet["SubnetId"]],
|
|
|
|
Tags=[],
|
|
|
|
)["DBSubnetGroup"]["DBSubnetGroupName"]
|
2022-11-17 22:41:08 +00:00
|
|
|
resource = f"arn:aws:rds:us-west-2:1234567890:subgrp:{subnet}"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.add_tags_to_resource(
|
|
|
|
ResourceName=resource,
|
|
|
|
Tags=[{"Value": "bar", "Key": "foo"}, {"Value": "bar1", "Key": "foo1"}],
|
|
|
|
)
|
|
|
|
|
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == [
|
|
|
|
{"Value": "bar", "Key": "foo"},
|
|
|
|
{"Value": "bar1", "Key": "foo1"},
|
|
|
|
]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_rds
|
|
|
|
def test_remove_tags_database_subnet_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
vpc_conn = boto3.client("ec2", DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
vpc = vpc_conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
|
|
|
subnet = vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.1.0/24")[
|
|
|
|
"Subnet"
|
|
|
|
]
|
|
|
|
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
result = conn.describe_db_subnet_groups()
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(result["DBSubnetGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
subnet = conn.create_db_subnet_group(
|
|
|
|
DBSubnetGroupName="db_subnet1",
|
|
|
|
DBSubnetGroupDescription="my db subnet",
|
|
|
|
SubnetIds=[subnet["SubnetId"]],
|
|
|
|
Tags=[{"Value": "bar", "Key": "foo"}, {"Value": "bar1", "Key": "foo1"}],
|
|
|
|
)["DBSubnetGroup"]["DBSubnetGroupName"]
|
2022-11-17 22:41:08 +00:00
|
|
|
resource = f"arn:aws:rds:us-west-2:1234567890:subgrp:{subnet}"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.remove_tags_from_resource(ResourceName=resource, TagKeys=["foo"])
|
|
|
|
|
|
|
|
result = conn.list_tags_for_resource(ResourceName=resource)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == [{"Value": "bar1", "Key": "foo1"}]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_replica():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
|
|
|
|
|
|
|
replica = conn.create_db_instance_read_replica(
|
|
|
|
DBInstanceIdentifier="db-replica-1",
|
|
|
|
SourceDBInstanceIdentifier="db-master-1",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert replica["DBInstance"]["ReadReplicaSourceDBInstanceIdentifier"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"db-master-1"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert replica["DBInstance"]["DBInstanceClass"] == "db.m1.small"
|
|
|
|
assert replica["DBInstance"]["DBInstanceIdentifier"] == "db-replica-1"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
master = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert master["DBInstances"][0]["ReadReplicaDBInstanceIdentifiers"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
["db-replica-1"]
|
|
|
|
)
|
2022-09-28 22:07:29 +00:00
|
|
|
replica = conn.describe_db_instances(DBInstanceIdentifier="db-replica-1")[
|
|
|
|
"DBInstances"
|
|
|
|
][0]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert replica["ReadReplicaSourceDBInstanceIdentifier"] == "db-master-1"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
conn.delete_db_instance(DBInstanceIdentifier="db-replica-1", SkipFinalSnapshot=True)
|
|
|
|
|
|
|
|
master = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert master["DBInstances"][0]["ReadReplicaDBInstanceIdentifiers"] == []
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
2022-09-28 22:07:29 +00:00
|
|
|
@mock_rds
|
|
|
|
def test_create_database_replica_cross_region():
|
|
|
|
us1 = boto3.client("rds", region_name="us-east-1")
|
2023-07-13 21:31:14 +00:00
|
|
|
us2 = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-09-28 22:07:29 +00:00
|
|
|
|
|
|
|
source_id = "db-master-1"
|
|
|
|
source_arn = us1.create_db_instance(
|
|
|
|
DBInstanceIdentifier=source_id,
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
)["DBInstance"]["DBInstanceArn"]
|
|
|
|
|
|
|
|
target_id = "db-replica-1"
|
|
|
|
target_arn = us2.create_db_instance_read_replica(
|
|
|
|
DBInstanceIdentifier=target_id,
|
|
|
|
SourceDBInstanceIdentifier=source_arn,
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
)["DBInstance"]["DBInstanceArn"]
|
|
|
|
|
|
|
|
source_db = us1.describe_db_instances(DBInstanceIdentifier=source_id)[
|
|
|
|
"DBInstances"
|
|
|
|
][0]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert source_db["ReadReplicaDBInstanceIdentifiers"] == [target_arn]
|
2022-09-28 22:07:29 +00:00
|
|
|
|
|
|
|
target_db = us2.describe_db_instances(DBInstanceIdentifier=target_id)[
|
|
|
|
"DBInstances"
|
|
|
|
][0]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert target_db["ReadReplicaSourceDBInstanceIdentifier"] == source_arn
|
2022-09-28 22:07:29 +00:00
|
|
|
|
|
|
|
|
2022-03-09 11:05:18 +00:00
|
|
|
@mock_rds
|
|
|
|
@mock_kms
|
|
|
|
def test_create_database_with_encrypted_storage():
|
2023-07-13 21:31:14 +00:00
|
|
|
kms_conn = boto3.client("kms", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
key = kms_conn.create_key(
|
|
|
|
Policy="my RDS encryption policy",
|
|
|
|
Description="RDS encryption key",
|
|
|
|
KeyUsage="ENCRYPT_DECRYPT",
|
|
|
|
)
|
|
|
|
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
StorageEncrypted=True,
|
|
|
|
KmsKeyId=key["KeyMetadata"]["KeyId"],
|
|
|
|
)
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
assert database["DBInstance"]["StorageEncrypted"] is True
|
|
|
|
assert database["DBInstance"]["KmsKeyId"] == key["KeyMetadata"]["KeyId"]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_db_parameter_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
region = DEFAULT_REGION
|
2022-03-09 11:05:18 +00:00
|
|
|
pg_name = "test"
|
|
|
|
conn = boto3.client("rds", region_name=region)
|
|
|
|
db_parameter_group = conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="test parameter group",
|
|
|
|
)
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_parameter_group["DBParameterGroup"]["DBParameterGroupName"] == "test"
|
|
|
|
assert db_parameter_group["DBParameterGroup"]["DBParameterGroupFamily"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"mysql5.6"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_parameter_group["DBParameterGroup"]["Description"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"test parameter group"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_parameter_group["DBParameterGroup"]["DBParameterGroupArn"] == (
|
2022-11-17 22:41:08 +00:00
|
|
|
f"arn:aws:rds:{region}:{ACCOUNT_ID}:pg:{pg_name}"
|
2022-03-09 11:05:18 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_db_instance_with_parameter_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="test parameter group",
|
|
|
|
)
|
|
|
|
|
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="mysql",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
)
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(database["DBInstance"]["DBParameterGroups"]) == 1
|
|
|
|
assert database["DBInstance"]["DBParameterGroups"][0]["DBParameterGroupName"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"test"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert database["DBInstance"]["DBParameterGroups"][0]["ParameterApplyStatus"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"in-sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_database_with_default_port():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
DBSecurityGroups=["my_sg"],
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert database["DBInstance"]["Endpoint"]["Port"] == 5432
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_instance_with_parameter_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
AllocatedStorage=10,
|
|
|
|
Engine="mysql",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
MasterUsername="root",
|
|
|
|
MasterUserPassword="hunter2",
|
|
|
|
Port=1234,
|
|
|
|
)
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(database["DBInstance"]["DBParameterGroups"]) == 1
|
|
|
|
assert database["DBInstance"]["DBParameterGroups"][0]["DBParameterGroupName"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"default.mysql5.6"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert database["DBInstance"]["DBParameterGroups"][0]["ParameterApplyStatus"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"in-sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="test parameter group",
|
|
|
|
)
|
|
|
|
conn.modify_db_instance(
|
|
|
|
DBInstanceIdentifier="db-master-1",
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
ApplyImmediately=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
database = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")[
|
|
|
|
"DBInstances"
|
|
|
|
][0]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(database["DBParameterGroups"]) == 1
|
|
|
|
assert database["DBParameterGroups"][0]["DBParameterGroupName"] == "test"
|
|
|
|
assert database["DBParameterGroups"][0]["ParameterApplyStatus"] == "in-sync"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_db_parameter_group_empty_description():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="",
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_db_parameter_group_duplicate():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="test parameter group",
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="test parameter group",
|
|
|
|
)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_describe_db_parameter_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
region = DEFAULT_REGION
|
2022-03-09 11:05:18 +00:00
|
|
|
pg_name = "test"
|
|
|
|
conn = boto3.client("rds", region_name=region)
|
|
|
|
conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName=pg_name,
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="test parameter group",
|
|
|
|
)
|
|
|
|
db_parameter_groups = conn.describe_db_parameter_groups(DBParameterGroupName="test")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_parameter_groups["DBParameterGroups"][0]["DBParameterGroupName"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"test"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_parameter_groups["DBParameterGroups"][0]["DBParameterGroupArn"] == (
|
2022-11-17 22:41:08 +00:00
|
|
|
f"arn:aws:rds:{region}:{ACCOUNT_ID}:pg:{pg_name}"
|
2022-03-09 11:05:18 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_describe_non_existent_db_parameter_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
db_parameter_groups = conn.describe_db_parameter_groups(DBParameterGroupName="test")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(db_parameter_groups["DBParameterGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_delete_db_parameter_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="test parameter group",
|
|
|
|
)
|
|
|
|
db_parameter_groups = conn.describe_db_parameter_groups(DBParameterGroupName="test")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_parameter_groups["DBParameterGroups"][0]["DBParameterGroupName"] == (
|
2022-03-09 11:05:18 +00:00
|
|
|
"test"
|
|
|
|
)
|
|
|
|
conn.delete_db_parameter_group(DBParameterGroupName="test")
|
|
|
|
db_parameter_groups = conn.describe_db_parameter_groups(DBParameterGroupName="test")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert len(db_parameter_groups["DBParameterGroups"]) == 0
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_modify_db_parameter_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="test parameter group",
|
|
|
|
)
|
|
|
|
|
|
|
|
modify_result = conn.modify_db_parameter_group(
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
Parameters=[
|
|
|
|
{
|
|
|
|
"ParameterName": "foo",
|
|
|
|
"ParameterValue": "foo_val",
|
|
|
|
"Description": "test param",
|
|
|
|
"ApplyMethod": "immediate",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
assert modify_result["DBParameterGroupName"] == "test"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
db_parameters = conn.describe_db_parameters(DBParameterGroupName="test")
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_parameters["Parameters"][0]["ParameterName"] == "foo"
|
|
|
|
assert db_parameters["Parameters"][0]["ParameterValue"] == "foo_val"
|
|
|
|
assert db_parameters["Parameters"][0]["Description"] == "test param"
|
|
|
|
assert db_parameters["Parameters"][0]["ApplyMethod"] == "immediate"
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_delete_non_existent_db_parameter_group():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2023-08-17 07:42:19 +00:00
|
|
|
with pytest.raises(ClientError):
|
|
|
|
conn.delete_db_parameter_group(DBParameterGroupName="non-existent")
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_parameter_group_with_tags():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
conn.create_db_parameter_group(
|
|
|
|
DBParameterGroupName="test",
|
|
|
|
DBParameterGroupFamily="mysql5.6",
|
|
|
|
Description="test parameter group",
|
|
|
|
Tags=[{"Key": "foo", "Value": "bar"}],
|
|
|
|
)
|
|
|
|
result = conn.list_tags_for_resource(
|
|
|
|
ResourceName="arn:aws:rds:us-west-2:1234567890:pg:test"
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert result["TagList"] == [{"Value": "bar", "Key": "foo"}]
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_db_with_iam_authentication():
|
2023-07-13 21:31:14 +00:00
|
|
|
conn = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
database = conn.create_db_instance(
|
|
|
|
DBInstanceIdentifier="rds",
|
|
|
|
DBInstanceClass="db.t1.micro",
|
|
|
|
Engine="postgres",
|
|
|
|
EnableIAMDatabaseAuthentication=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
db_instance = database["DBInstance"]
|
2023-08-17 07:42:19 +00:00
|
|
|
assert db_instance["IAMDatabaseAuthenticationEnabled"] is True
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
snapshot = conn.create_db_snapshot(
|
|
|
|
DBInstanceIdentifier="rds", DBSnapshotIdentifier="snapshot"
|
|
|
|
).get("DBSnapshot")
|
|
|
|
|
2023-08-17 07:42:19 +00:00
|
|
|
assert snapshot.get("IAMDatabaseAuthenticationEnabled") is True
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_db_instance_with_tags():
|
2023-07-13 21:31:14 +00:00
|
|
|
client = boto3.client("rds", region_name=DEFAULT_REGION)
|
2022-03-09 11:05:18 +00:00
|
|
|
tags = [{"Key": "foo", "Value": "bar"}, {"Key": "foo1", "Value": "bar1"}]
|
|
|
|
db_instance_identifier = "test-db-instance"
|
|
|
|
resp = client.create_db_instance(
|
|
|
|
DBInstanceIdentifier=db_instance_identifier,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
Tags=tags,
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert resp["DBInstance"]["TagList"] == tags
|
2022-03-09 11:05:18 +00:00
|
|
|
|
|
|
|
resp = client.describe_db_instances(DBInstanceIdentifier=db_instance_identifier)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert resp["DBInstances"][0]["TagList"] == tags
|
2022-08-10 20:49:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_db_instance_without_availability_zone():
|
|
|
|
region = "us-east-1"
|
|
|
|
client = boto3.client("rds", region_name=region)
|
|
|
|
db_instance_identifier = "test-db-instance"
|
|
|
|
resp = client.create_db_instance(
|
|
|
|
DBInstanceIdentifier=db_instance_identifier,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert region in resp["DBInstance"]["AvailabilityZone"]
|
2022-08-10 20:49:07 +00:00
|
|
|
|
|
|
|
resp = client.describe_db_instances(DBInstanceIdentifier=db_instance_identifier)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert region in resp["DBInstances"][0]["AvailabilityZone"]
|
2022-08-10 20:49:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_create_db_instance_with_availability_zone():
|
|
|
|
region = "us-east-1"
|
|
|
|
availability_zone = f"{region}c"
|
|
|
|
client = boto3.client("rds", region_name=region)
|
|
|
|
db_instance_identifier = "test-db-instance"
|
|
|
|
resp = client.create_db_instance(
|
|
|
|
DBInstanceIdentifier=db_instance_identifier,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
AvailabilityZone=availability_zone,
|
|
|
|
)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert resp["DBInstance"]["AvailabilityZone"] == availability_zone
|
2022-08-10 20:49:07 +00:00
|
|
|
|
|
|
|
resp = client.describe_db_instances(DBInstanceIdentifier=db_instance_identifier)
|
2023-08-17 07:42:19 +00:00
|
|
|
assert resp["DBInstances"][0]["AvailabilityZone"] == availability_zone
|
2023-07-13 21:31:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_rds
|
|
|
|
def test_validate_db_identifier():
|
|
|
|
client = boto3.client("rds", region_name=DEFAULT_REGION)
|
|
|
|
invalid_db_instance_identifier = "arn:aws:rds:eu-west-1:123456789012:db:mydb"
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.create_db_instance(
|
|
|
|
DBInstanceIdentifier=invalid_db_instance_identifier,
|
|
|
|
Engine="postgres",
|
|
|
|
DBName="staging-postgres",
|
|
|
|
DBInstanceClass="db.m1.small",
|
|
|
|
)
|
|
|
|
validation_helper(exc)
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.start_db_instance(
|
|
|
|
DBInstanceIdentifier=invalid_db_instance_identifier,
|
|
|
|
)
|
|
|
|
validation_helper(exc)
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.stop_db_instance(
|
|
|
|
DBInstanceIdentifier=invalid_db_instance_identifier,
|
|
|
|
)
|
|
|
|
validation_helper(exc)
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.delete_db_instance(
|
|
|
|
DBInstanceIdentifier=invalid_db_instance_identifier,
|
|
|
|
)
|
|
|
|
validation_helper(exc)
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.delete_db_instance(
|
|
|
|
DBInstanceIdentifier="valid-1-id" * 10,
|
|
|
|
)
|
|
|
|
validation_helper(exc)
|
|
|
|
|
|
|
|
|
|
|
|
def validation_helper(exc):
|
|
|
|
err = exc.value.response["Error"]
|
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert err["Message"] == (
|
|
|
|
"The parameter DBInstanceIdentifier is not a valid identifier. "
|
2023-08-17 07:42:19 +00:00
|
|
|
"Identifiers must begin with a letter; must contain only ASCII "
|
|
|
|
"letters, digits, and hyphens; "
|
2023-07-13 21:31:14 +00:00
|
|
|
"and must not end with a hyphen or contain two consecutive hyphens."
|
|
|
|
)
|