moto/moto/rds/responses.py

1450 lines
63 KiB
Python

from collections import defaultdict
from typing import Any, Dict, List, Iterable
from moto.core.common_types import TYPE_RESPONSE
from moto.core.responses import BaseResponse
from moto.ec2.models import ec2_backends
from moto.neptune.responses import NeptuneResponse
from moto.neptune.responses import (
CREATE_GLOBAL_CLUSTER_TEMPLATE,
DESCRIBE_GLOBAL_CLUSTERS_TEMPLATE,
DELETE_GLOBAL_CLUSTER_TEMPLATE,
REMOVE_FROM_GLOBAL_CLUSTER_TEMPLATE,
)
from .models import rds_backends, RDSBackend
from .exceptions import DBParameterGroupNotFoundError
class RDSResponse(BaseResponse):
def __init__(self) -> None:
super().__init__(service_name="rds")
# Neptune and RDS share a HTTP endpoint RDS is the lucky guy that catches all requests
# So we have to determine whether we can handle an incoming request here, or whether it needs redirecting to Neptune
self.neptune = NeptuneResponse()
@property
def backend(self) -> RDSBackend:
return rds_backends[self.current_account][self.region]
def _dispatch(self, request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE:
# Because some requests are send through to Neptune, we have to prepare the NeptuneResponse-class
self.neptune.setup_class(request, full_url, headers)
return super()._dispatch(request, full_url, headers)
def __getattribute__(self, name: str) -> Any:
if name in ["create_db_cluster", "create_global_cluster"]:
if self._get_param("Engine") == "neptune":
return object.__getattribute__(self.neptune, name)
return object.__getattribute__(self, name)
def _get_db_kwargs(self) -> Dict[str, Any]:
args = {
"auto_minor_version_upgrade": self._get_param("AutoMinorVersionUpgrade"),
"allocated_storage": self._get_int_param("AllocatedStorage"),
"availability_zone": self._get_param("AvailabilityZone"),
"backup_retention_period": self._get_param("BackupRetentionPeriod"),
"copy_tags_to_snapshot": self._get_param("CopyTagsToSnapshot"),
"db_instance_class": self._get_param("DBInstanceClass"),
"db_cluster_identifier": self._get_param("DBClusterIdentifier"),
"db_instance_identifier": self._get_param("DBInstanceIdentifier"),
"db_name": self._get_param("DBName"),
"db_parameter_group_name": self._get_param("DBParameterGroupName"),
"db_snapshot_identifier": self._get_param("DBSnapshotIdentifier"),
"db_subnet_group_name": self._get_param("DBSubnetGroupName"),
"engine": self._get_param("Engine"),
"engine_version": self._get_param("EngineVersion"),
"enable_cloudwatch_logs_exports": self._get_params().get(
"EnableCloudwatchLogsExports"
),
"enable_iam_database_authentication": self._get_bool_param(
"EnableIAMDatabaseAuthentication"
),
"license_model": self._get_param("LicenseModel"),
"iops": self._get_int_param("Iops"),
"kms_key_id": self._get_param("KmsKeyId"),
"master_user_password": self._get_param("MasterUserPassword"),
"master_username": self._get_param("MasterUsername"),
"multi_az": self._get_bool_param("MultiAZ"),
"option_group_name": self._get_param("OptionGroupName"),
"port": self._get_param("Port"),
"preferred_backup_window": self._get_param(
"PreferredBackupWindow", "13:14-13:44"
),
"preferred_maintenance_window": self._get_param(
"PreferredMaintenanceWindow", "wed:06:38-wed:07:08"
).lower(),
"publicly_accessible": self._get_param("PubliclyAccessible"),
"account_id": self.current_account,
"region": self.region,
"security_groups": self._get_multi_param(
"DBSecurityGroups.DBSecurityGroupName"
),
"storage_encrypted": self._get_param("StorageEncrypted"),
"storage_type": self._get_param("StorageType", None),
"vpc_security_group_ids": self._get_multi_param(
"VpcSecurityGroupIds.VpcSecurityGroupId"
),
"tags": list(),
"deletion_protection": self._get_bool_param("DeletionProtection"),
}
args["tags"] = self.unpack_list_params("Tags", "Tag")
return args
def _get_modify_db_cluster_kwargs(self) -> Dict[str, Any]:
args = {
"auto_minor_version_upgrade": self._get_param("AutoMinorVersionUpgrade"),
"allocated_storage": self._get_int_param("AllocatedStorage"),
"availability_zone": self._get_param("AvailabilityZone"),
"backup_retention_period": self._get_param("BackupRetentionPeriod"),
"copy_tags_to_snapshot": self._get_param("CopyTagsToSnapshot"),
"db_instance_class": self._get_param("DBInstanceClass"),
"db_cluster_identifier": self._get_param("DBClusterIdentifier"),
"new_db_cluster_identifier": self._get_param("NewDBClusterIdentifier"),
"db_instance_identifier": self._get_param("DBInstanceIdentifier"),
"db_name": self._get_param("DBName"),
"db_parameter_group_name": self._get_param("DBParameterGroupName"),
"db_cluster_parameter_group_name": self._get_param(
"DBClusterParameterGroupName"
),
"db_snapshot_identifier": self._get_param("DBSnapshotIdentifier"),
"db_subnet_group_name": self._get_param("DBSubnetGroupName"),
"engine": self._get_param("Engine"),
"engine_version": self._get_param("EngineVersion"),
"enable_cloudwatch_logs_exports": self._get_params().get(
"CloudwatchLogsExportConfiguration"
),
"enable_iam_database_authentication": self._get_bool_param(
"EnableIAMDatabaseAuthentication"
),
"enable_http_endpoint": self._get_param("EnableHttpEndpoint"),
"license_model": self._get_param("LicenseModel"),
"iops": self._get_int_param("Iops"),
"kms_key_id": self._get_param("KmsKeyId"),
"master_user_password": self._get_param("MasterUserPassword"),
"master_username": self._get_param("MasterUsername"),
"multi_az": self._get_bool_param("MultiAZ"),
"option_group_name": self._get_param("OptionGroupName"),
"port": self._get_param("Port"),
"preferred_backup_window": self._get_param("PreferredBackupWindow"),
"preferred_maintenance_window": self._get_param(
"PreferredMaintenanceWindow"
),
"publicly_accessible": self._get_param("PubliclyAccessible"),
"account_id": self.current_account,
"region": self.region,
"security_groups": self._get_multi_param(
"DBSecurityGroups.DBSecurityGroupName"
),
"storage_encrypted": self._get_param("StorageEncrypted"),
"storage_type": self._get_param("StorageType", None),
"vpc_security_group_ids": self._get_multi_param(
"VpcSecurityGroupIds.VpcSecurityGroupId"
),
"tags": list(),
"deletion_protection": self._get_bool_param("DeletionProtection"),
}
args["tags"] = self.unpack_list_params("Tags", "Tag")
return args
def _get_db_replica_kwargs(self) -> Dict[str, Any]:
return {
"auto_minor_version_upgrade": self._get_param("AutoMinorVersionUpgrade"),
"availability_zone": self._get_param("AvailabilityZone"),
"db_instance_class": self._get_param("DBInstanceClass"),
"db_instance_identifier": self._get_param("DBInstanceIdentifier"),
"db_subnet_group_name": self._get_param("DBSubnetGroupName"),
"iops": self._get_int_param("Iops"),
# OptionGroupName
"port": self._get_param("Port"),
"publicly_accessible": self._get_param("PubliclyAccessible"),
"source_db_identifier": self._get_param("SourceDBInstanceIdentifier"),
"storage_type": self._get_param("StorageType"),
}
def _get_option_group_kwargs(self) -> Dict[str, Any]:
return {
"major_engine_version": self._get_param("MajorEngineVersion"),
"description": self._get_param("OptionGroupDescription"),
"engine_name": self._get_param("EngineName"),
"name": self._get_param("OptionGroupName"),
}
def _get_db_parameter_group_kwargs(self) -> Dict[str, Any]:
return {
"description": self._get_param("Description"),
"family": self._get_param("DBParameterGroupFamily"),
"name": self._get_param("DBParameterGroupName"),
"tags": self.unpack_list_params("Tags", "Tag"),
}
def _get_db_cluster_kwargs(self) -> Dict[str, Any]:
return {
"availability_zones": self._get_multi_param(
"AvailabilityZones.AvailabilityZone"
),
"enable_cloudwatch_logs_exports": self._get_params().get(
"EnableCloudwatchLogsExports"
),
"db_name": self._get_param("DatabaseName"),
"db_cluster_identifier": self._get_param("DBClusterIdentifier"),
"db_subnet_group_name": self._get_param("DBSubnetGroupName"),
"deletion_protection": self._get_bool_param("DeletionProtection"),
"engine": self._get_param("Engine"),
"engine_version": self._get_param("EngineVersion"),
"engine_mode": self._get_param("EngineMode"),
"allocated_storage": self._get_param("AllocatedStorage"),
"global_cluster_identifier": self._get_param("GlobalClusterIdentifier"),
"iops": self._get_param("Iops"),
"storage_type": self._get_param("StorageType"),
"kms_key_id": self._get_param("KmsKeyId"),
"master_username": self._get_param("MasterUsername"),
"master_user_password": self._get_param("MasterUserPassword"),
"network_type": self._get_param("NetworkType"),
"port": self._get_param("Port"),
"parameter_group": self._get_param("DBClusterParameterGroupName"),
"region": self.region,
"db_cluster_instance_class": self._get_param("DBClusterInstanceClass"),
"enable_http_endpoint": self._get_param("EnableHttpEndpoint"),
"copy_tags_to_snapshot": self._get_param("CopyTagsToSnapshot"),
"tags": self.unpack_list_params("Tags", "Tag"),
"scaling_configuration": self._get_dict_param("ScalingConfiguration."),
"replication_source_identifier": self._get_param(
"ReplicationSourceIdentifier"
),
}
def _get_export_task_kwargs(self) -> Dict[str, Any]:
return {
"export_task_identifier": self._get_param("ExportTaskIdentifier"),
"source_arn": self._get_param("SourceArn"),
"s3_bucket_name": self._get_param("S3BucketName"),
"iam_role_arn": self._get_param("IamRoleArn"),
"kms_key_id": self._get_param("KmsKeyId"),
"s3_prefix": self._get_param("S3Prefix"),
"export_only": self.unpack_list_params("ExportOnly", "member"),
}
def _get_event_subscription_kwargs(self) -> Dict[str, Any]:
return {
"subscription_name": self._get_param("SubscriptionName"),
"sns_topic_arn": self._get_param("SnsTopicArn"),
"source_type": self._get_param("SourceType"),
"event_categories": self.unpack_list_params(
"EventCategories", "EventCategory"
),
"source_ids": self.unpack_list_params("SourceIds", "SourceId"),
"enabled": self._get_param("Enabled"),
"tags": self.unpack_list_params("Tags", "Tag"),
}
def unpack_list_params(self, label: str, child_label: str) -> List[Dict[str, Any]]:
root = self._get_multi_param_dict(label) or {}
return root.get(child_label, [])
def create_db_instance(self) -> str:
db_kwargs = self._get_db_kwargs()
database = self.backend.create_db_instance(db_kwargs)
template = self.response_template(CREATE_DATABASE_TEMPLATE)
return template.render(database=database)
def create_db_instance_read_replica(self) -> str:
db_kwargs = self._get_db_replica_kwargs()
database = self.backend.create_db_instance_read_replica(db_kwargs)
template = self.response_template(CREATE_DATABASE_REPLICA_TEMPLATE)
return template.render(database=database)
def describe_db_instances(self) -> str:
db_instance_identifier = self._get_param("DBInstanceIdentifier")
filters = self._get_multi_param("Filters.Filter.")
filter_dict = {f["Name"]: f["Values"] for f in filters}
all_instances = list(
self.backend.describe_db_instances(
db_instance_identifier, filters=filter_dict
)
)
marker = self._get_param("Marker")
all_ids = [instance.db_instance_identifier for instance in all_instances]
if marker:
start = all_ids.index(marker) + 1
else:
start = 0
page_size = self._get_int_param(
"MaxRecords", 50
) # the default is 100, but using 50 to make testing easier
instances_resp = all_instances[start : start + page_size]
next_marker = None
if len(all_instances) > start + page_size:
next_marker = instances_resp[-1].db_instance_identifier
template = self.response_template(DESCRIBE_DATABASES_TEMPLATE)
return template.render(databases=instances_resp, marker=next_marker)
def modify_db_instance(self) -> str:
db_instance_identifier = self._get_param("DBInstanceIdentifier")
db_kwargs = self._get_db_kwargs()
# NOTE modify_db_instance does not support tags
del db_kwargs["tags"]
new_db_instance_identifier = self._get_param("NewDBInstanceIdentifier")
if new_db_instance_identifier:
db_kwargs["new_db_instance_identifier"] = new_db_instance_identifier
database = self.backend.modify_db_instance(db_instance_identifier, db_kwargs)
template = self.response_template(MODIFY_DATABASE_TEMPLATE)
return template.render(database=database)
def delete_db_instance(self) -> str:
db_instance_identifier = self._get_param("DBInstanceIdentifier")
db_snapshot_name = self._get_param("FinalDBSnapshotIdentifier")
database = self.backend.delete_db_instance(
db_instance_identifier, db_snapshot_name
)
template = self.response_template(DELETE_DATABASE_TEMPLATE)
return template.render(database=database)
def reboot_db_instance(self) -> str:
db_instance_identifier = self._get_param("DBInstanceIdentifier")
database = self.backend.reboot_db_instance(db_instance_identifier)
template = self.response_template(REBOOT_DATABASE_TEMPLATE)
return template.render(database=database)
def create_db_snapshot(self) -> str:
db_instance_identifier = self._get_param("DBInstanceIdentifier")
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
tags = self.unpack_list_params("Tags", "Tag")
snapshot = self.backend.create_db_snapshot(
db_instance_identifier, db_snapshot_identifier, tags=tags
)
template = self.response_template(CREATE_SNAPSHOT_TEMPLATE)
return template.render(snapshot=snapshot)
def copy_db_snapshot(self) -> str:
source_snapshot_identifier = self._get_param("SourceDBSnapshotIdentifier")
target_snapshot_identifier = self._get_param("TargetDBSnapshotIdentifier")
tags = self.unpack_list_params("Tags", "Tag")
snapshot = self.backend.copy_db_snapshot(
source_snapshot_identifier, target_snapshot_identifier, tags
)
template = self.response_template(COPY_SNAPSHOT_TEMPLATE)
return template.render(snapshot=snapshot)
def describe_db_snapshots(self) -> str:
db_instance_identifier = self._get_param("DBInstanceIdentifier")
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
filters = self._get_multi_param("Filters.Filter.")
filter_dict = {f["Name"]: f["Values"] for f in filters}
snapshots = self.backend.describe_db_snapshots(
db_instance_identifier, db_snapshot_identifier, filter_dict
)
template = self.response_template(DESCRIBE_SNAPSHOTS_TEMPLATE)
return template.render(snapshots=snapshots)
def promote_read_replica(self) -> str:
db_instance_identifier = self._get_param("DBInstanceIdentifier")
db_kwargs = self._get_db_kwargs()
database = self.backend.promote_read_replica(db_kwargs)
database = self.backend.modify_db_instance(db_instance_identifier, db_kwargs)
template = self.response_template(PROMOTE_REPLICA_TEMPLATE)
return template.render(database=database)
def delete_db_snapshot(self) -> str:
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
snapshot = self.backend.delete_db_snapshot(db_snapshot_identifier)
template = self.response_template(DELETE_SNAPSHOT_TEMPLATE)
return template.render(snapshot=snapshot)
def restore_db_instance_from_db_snapshot(self) -> str:
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
db_kwargs = self._get_db_kwargs()
new_instance = self.backend.restore_db_instance_from_db_snapshot(
db_snapshot_identifier, db_kwargs
)
template = self.response_template(RESTORE_INSTANCE_FROM_SNAPSHOT_TEMPLATE)
return template.render(database=new_instance)
def list_tags_for_resource(self) -> str:
arn = self._get_param("ResourceName")
template = self.response_template(LIST_TAGS_FOR_RESOURCE_TEMPLATE)
tags = self.backend.list_tags_for_resource(arn)
return template.render(tags=tags)
def add_tags_to_resource(self) -> str:
arn = self._get_param("ResourceName")
tags = self.unpack_list_params("Tags", "Tag")
tags = self.backend.add_tags_to_resource(arn, tags)
template = self.response_template(ADD_TAGS_TO_RESOURCE_TEMPLATE)
return template.render(tags=tags)
def remove_tags_from_resource(self) -> str:
arn = self._get_param("ResourceName")
tag_keys = self.unpack_list_params("TagKeys", "member")
self.backend.remove_tags_from_resource(arn, tag_keys) # type: ignore
template = self.response_template(REMOVE_TAGS_FROM_RESOURCE_TEMPLATE)
return template.render()
def stop_db_instance(self) -> str:
db_instance_identifier = self._get_param("DBInstanceIdentifier")
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
database = self.backend.stop_db_instance(
db_instance_identifier, db_snapshot_identifier
)
template = self.response_template(STOP_DATABASE_TEMPLATE)
return template.render(database=database)
def start_db_instance(self) -> str:
db_instance_identifier = self._get_param("DBInstanceIdentifier")
database = self.backend.start_db_instance(db_instance_identifier)
template = self.response_template(START_DATABASE_TEMPLATE)
return template.render(database=database)
def create_db_security_group(self) -> str:
group_name = self._get_param("DBSecurityGroupName")
description = self._get_param("DBSecurityGroupDescription")
tags = self.unpack_list_params("Tags", "Tag")
security_group = self.backend.create_db_security_group(
group_name, description, tags
)
template = self.response_template(CREATE_SECURITY_GROUP_TEMPLATE)
return template.render(security_group=security_group)
def describe_db_security_groups(self) -> str:
security_group_name = self._get_param("DBSecurityGroupName")
security_groups = self.backend.describe_security_groups(security_group_name)
template = self.response_template(DESCRIBE_SECURITY_GROUPS_TEMPLATE)
return template.render(security_groups=security_groups)
def delete_db_security_group(self) -> str:
security_group_name = self._get_param("DBSecurityGroupName")
security_group = self.backend.delete_security_group(security_group_name)
template = self.response_template(DELETE_SECURITY_GROUP_TEMPLATE)
return template.render(security_group=security_group)
def authorize_db_security_group_ingress(self) -> str:
security_group_name = self._get_param("DBSecurityGroupName")
cidr_ip = self._get_param("CIDRIP")
security_group = self.backend.authorize_security_group(
security_group_name, cidr_ip
)
template = self.response_template(AUTHORIZE_SECURITY_GROUP_TEMPLATE)
return template.render(security_group=security_group)
def create_db_subnet_group(self) -> str:
subnet_name = self._get_param("DBSubnetGroupName")
description = self._get_param("DBSubnetGroupDescription")
subnet_ids = self._get_multi_param("SubnetIds.SubnetIdentifier")
tags = self.unpack_list_params("Tags", "Tag")
subnets = [
ec2_backends[self.current_account][self.region].get_subnet(subnet_id)
for subnet_id in subnet_ids
]
subnet_group = self.backend.create_subnet_group(
subnet_name, description, subnets, tags
)
template = self.response_template(CREATE_SUBNET_GROUP_TEMPLATE)
return template.render(subnet_group=subnet_group)
def describe_db_subnet_groups(self) -> str:
subnet_name = self._get_param("DBSubnetGroupName")
subnet_groups = self.backend.describe_db_subnet_groups(subnet_name)
template = self.response_template(DESCRIBE_SUBNET_GROUPS_TEMPLATE)
return template.render(subnet_groups=subnet_groups)
def modify_db_subnet_group(self) -> str:
subnet_name = self._get_param("DBSubnetGroupName")
description = self._get_param("DBSubnetGroupDescription")
subnet_ids = self._get_multi_param("SubnetIds.SubnetIdentifier")
subnets = [
ec2_backends[self.current_account][self.region].get_subnet(subnet_id)
for subnet_id in subnet_ids
]
subnet_group = self.backend.modify_db_subnet_group(
subnet_name, description, subnets
)
template = self.response_template(MODIFY_SUBNET_GROUPS_TEMPLATE)
return template.render(subnet_group=subnet_group)
def delete_db_subnet_group(self) -> str:
subnet_name = self._get_param("DBSubnetGroupName")
subnet_group = self.backend.delete_subnet_group(subnet_name)
template = self.response_template(DELETE_SUBNET_GROUP_TEMPLATE)
return template.render(subnet_group=subnet_group)
def create_option_group(self) -> str:
kwargs = self._get_option_group_kwargs()
option_group = self.backend.create_option_group(kwargs)
template = self.response_template(CREATE_OPTION_GROUP_TEMPLATE)
return template.render(option_group=option_group)
def delete_option_group(self) -> str:
kwargs = self._get_option_group_kwargs()
option_group = self.backend.delete_option_group(kwargs["name"])
template = self.response_template(DELETE_OPTION_GROUP_TEMPLATE)
return template.render(option_group=option_group)
def describe_option_groups(self) -> str:
kwargs = self._get_option_group_kwargs()
kwargs["max_records"] = self._get_int_param("MaxRecords")
kwargs["marker"] = self._get_param("Marker")
option_groups = self.backend.describe_option_groups(kwargs)
template = self.response_template(DESCRIBE_OPTION_GROUP_TEMPLATE)
return template.render(option_groups=option_groups)
def describe_option_group_options(self) -> str:
engine_name = self._get_param("EngineName")
major_engine_version = self._get_param("MajorEngineVersion")
return self.backend.describe_option_group_options(
engine_name, major_engine_version
)
def modify_option_group(self) -> str:
option_group_name = self._get_param("OptionGroupName")
count = 1
options_to_include = []
# TODO: This can probably be refactored with a single call to super.get_multi_param, but there are not enough tests (yet) to verify this
while self._get_param(f"OptionsToInclude.member.{count}.OptionName"):
options_to_include.append(
{
"Port": self._get_param(f"OptionsToInclude.member.{count}.Port"),
"OptionName": self._get_param(
f"OptionsToInclude.member.{count}.OptionName"
),
"DBSecurityGroupMemberships": self._get_param(
f"OptionsToInclude.member.{count}.DBSecurityGroupMemberships"
),
"OptionSettings": self._get_param(
f"OptionsToInclude.member.{count}.OptionSettings"
),
"VpcSecurityGroupMemberships": self._get_param(
f"OptionsToInclude.member.{count}.VpcSecurityGroupMemberships"
),
}
)
count += 1
count = 1
options_to_remove = []
while self._get_param(f"OptionsToRemove.member.{count}"):
options_to_remove.append(self._get_param(f"OptionsToRemove.member.{count}"))
count += 1
option_group = self.backend.modify_option_group(
option_group_name, options_to_include, options_to_remove
)
template = self.response_template(MODIFY_OPTION_GROUP_TEMPLATE)
return template.render(option_group=option_group)
def create_db_parameter_group(self) -> str:
kwargs = self._get_db_parameter_group_kwargs()
db_parameter_group = self.backend.create_db_parameter_group(kwargs)
template = self.response_template(CREATE_DB_PARAMETER_GROUP_TEMPLATE)
return template.render(db_parameter_group=db_parameter_group)
def describe_db_parameter_groups(self) -> str:
kwargs = self._get_db_parameter_group_kwargs()
kwargs["max_records"] = self._get_int_param("MaxRecords")
kwargs["marker"] = self._get_param("Marker")
db_parameter_groups = self.backend.describe_db_parameter_groups(kwargs)
template = self.response_template(DESCRIBE_DB_PARAMETER_GROUPS_TEMPLATE)
return template.render(db_parameter_groups=db_parameter_groups)
def modify_db_parameter_group(self) -> str:
db_parameter_group_name = self._get_param("DBParameterGroupName")
db_parameter_group_parameters = self._get_db_parameter_group_parameters()
db_parameter_group = self.backend.modify_db_parameter_group(
db_parameter_group_name, db_parameter_group_parameters
)
template = self.response_template(MODIFY_DB_PARAMETER_GROUP_TEMPLATE)
return template.render(db_parameter_group=db_parameter_group)
def _get_db_parameter_group_parameters(self) -> Iterable[Dict[str, Any]]:
parameter_group_parameters: Dict[str, Any] = defaultdict(dict)
for param_name, value in self.querystring.items():
if not param_name.startswith("Parameters.Parameter"):
continue
split_param_name = param_name.split(".")
param_id = split_param_name[2]
param_setting = split_param_name[3]
parameter_group_parameters[param_id][param_setting] = value[0]
return parameter_group_parameters.values()
def describe_db_parameters(self) -> str:
db_parameter_group_name = self._get_param("DBParameterGroupName")
db_parameter_groups = self.backend.describe_db_parameter_groups(
{"name": db_parameter_group_name}
)
if not db_parameter_groups:
raise DBParameterGroupNotFoundError(db_parameter_group_name)
template = self.response_template(DESCRIBE_DB_PARAMETERS_TEMPLATE)
return template.render(db_parameter_group=db_parameter_groups[0])
def delete_db_parameter_group(self) -> str:
kwargs = self._get_db_parameter_group_kwargs()
db_parameter_group = self.backend.delete_db_parameter_group(kwargs["name"])
template = self.response_template(DELETE_DB_PARAMETER_GROUP_TEMPLATE)
return template.render(db_parameter_group=db_parameter_group)
def describe_db_cluster_parameters(self) -> str:
db_parameter_group_name = self._get_param("DBParameterGroupName")
db_parameter_groups = self.backend.describe_db_cluster_parameters()
if db_parameter_groups is None:
raise DBParameterGroupNotFoundError(db_parameter_group_name)
template = self.response_template(DESCRIBE_DB_CLUSTER_PARAMETERS_TEMPLATE)
return template.render(db_parameter_group=db_parameter_groups)
def create_db_cluster(self) -> str:
kwargs = self._get_db_cluster_kwargs()
cluster = self.backend.create_db_cluster(kwargs)
template = self.response_template(CREATE_DB_CLUSTER_TEMPLATE)
return template.render(cluster=cluster)
def modify_db_cluster(self) -> str:
kwargs = self._get_modify_db_cluster_kwargs()
cluster = self.backend.modify_db_cluster(kwargs)
template = self.response_template(MODIFY_DB_CLUSTER_TEMPLATE)
return template.render(cluster=cluster)
def describe_db_clusters(self) -> str:
_id = self._get_param("DBClusterIdentifier")
filters = self._get_multi_param("Filters.Filter.")
filter_dict = {f["Name"]: f["Values"] for f in filters}
clusters = self.backend.describe_db_clusters(
cluster_identifier=_id, filters=filter_dict
)
template = self.response_template(DESCRIBE_CLUSTERS_TEMPLATE)
return template.render(clusters=clusters)
def delete_db_cluster(self) -> str:
_id = self._get_param("DBClusterIdentifier")
snapshot_name = self._get_param("FinalDBSnapshotIdentifier")
cluster = self.backend.delete_db_cluster(
cluster_identifier=_id, snapshot_name=snapshot_name
)
template = self.response_template(DELETE_CLUSTER_TEMPLATE)
return template.render(cluster=cluster)
def start_db_cluster(self) -> str:
_id = self._get_param("DBClusterIdentifier")
cluster = self.backend.start_db_cluster(cluster_identifier=_id)
template = self.response_template(START_CLUSTER_TEMPLATE)
return template.render(cluster=cluster)
def stop_db_cluster(self) -> str:
_id = self._get_param("DBClusterIdentifier")
cluster = self.backend.stop_db_cluster(cluster_identifier=_id)
template = self.response_template(STOP_CLUSTER_TEMPLATE)
return template.render(cluster=cluster)
def create_db_cluster_snapshot(self) -> str:
db_cluster_identifier = self._get_param("DBClusterIdentifier")
db_snapshot_identifier = self._get_param("DBClusterSnapshotIdentifier")
tags = self.unpack_list_params("Tags", "Tag")
snapshot = self.backend.create_db_cluster_snapshot(
db_cluster_identifier, db_snapshot_identifier, tags=tags
)
template = self.response_template(CREATE_CLUSTER_SNAPSHOT_TEMPLATE)
return template.render(snapshot=snapshot)
def copy_db_cluster_snapshot(self) -> str:
source_snapshot_identifier = self._get_param(
"SourceDBClusterSnapshotIdentifier"
)
target_snapshot_identifier = self._get_param(
"TargetDBClusterSnapshotIdentifier"
)
tags = self.unpack_list_params("Tags", "Tag")
snapshot = self.backend.copy_db_cluster_snapshot(
source_snapshot_identifier, target_snapshot_identifier, tags
)
template = self.response_template(COPY_CLUSTER_SNAPSHOT_TEMPLATE)
return template.render(snapshot=snapshot)
def describe_db_cluster_snapshots(self) -> str:
db_cluster_identifier = self._get_param("DBClusterIdentifier")
db_snapshot_identifier = self._get_param("DBClusterSnapshotIdentifier")
filters = self._get_multi_param("Filters.Filter.")
filter_dict = {f["Name"]: f["Values"] for f in filters}
snapshots = self.backend.describe_db_cluster_snapshots(
db_cluster_identifier, db_snapshot_identifier, filter_dict
)
template = self.response_template(DESCRIBE_CLUSTER_SNAPSHOTS_TEMPLATE)
return template.render(snapshots=snapshots)
def delete_db_cluster_snapshot(self) -> str:
db_snapshot_identifier = self._get_param("DBClusterSnapshotIdentifier")
snapshot = self.backend.delete_db_cluster_snapshot(db_snapshot_identifier)
template = self.response_template(DELETE_CLUSTER_SNAPSHOT_TEMPLATE)
return template.render(snapshot=snapshot)
def restore_db_cluster_from_snapshot(self) -> str:
db_snapshot_identifier = self._get_param("SnapshotIdentifier")
db_kwargs = self._get_db_cluster_kwargs()
new_cluster = self.backend.restore_db_cluster_from_snapshot(
db_snapshot_identifier, db_kwargs
)
template = self.response_template(RESTORE_CLUSTER_FROM_SNAPSHOT_TEMPLATE)
return template.render(cluster=new_cluster)
def start_export_task(self) -> str:
kwargs = self._get_export_task_kwargs()
export_task = self.backend.start_export_task(kwargs)
template = self.response_template(START_EXPORT_TASK_TEMPLATE)
return template.render(task=export_task)
def cancel_export_task(self) -> str:
export_task_identifier = self._get_param("ExportTaskIdentifier")
export_task = self.backend.cancel_export_task(export_task_identifier)
template = self.response_template(CANCEL_EXPORT_TASK_TEMPLATE)
return template.render(task=export_task)
def describe_export_tasks(self) -> str:
export_task_identifier = self._get_param("ExportTaskIdentifier")
tasks = self.backend.describe_export_tasks(export_task_identifier)
template = self.response_template(DESCRIBE_EXPORT_TASKS_TEMPLATE)
return template.render(tasks=tasks)
def create_event_subscription(self) -> str:
kwargs = self._get_event_subscription_kwargs()
subscription = self.backend.create_event_subscription(kwargs)
template = self.response_template(CREATE_EVENT_SUBSCRIPTION_TEMPLATE)
return template.render(subscription=subscription)
def delete_event_subscription(self) -> str:
subscription_name = self._get_param("SubscriptionName")
subscription = self.backend.delete_event_subscription(subscription_name)
template = self.response_template(DELETE_EVENT_SUBSCRIPTION_TEMPLATE)
return template.render(subscription=subscription)
def describe_event_subscriptions(self) -> str:
subscription_name = self._get_param("SubscriptionName")
subscriptions = self.backend.describe_event_subscriptions(subscription_name)
template = self.response_template(DESCRIBE_EVENT_SUBSCRIPTIONS_TEMPLATE)
return template.render(subscriptions=subscriptions)
def describe_orderable_db_instance_options(self) -> str:
engine = self._get_param("Engine")
engine_version = self._get_param("EngineVersion")
options = self.backend.describe_orderable_db_instance_options(
engine, engine_version
)
template = self.response_template(DESCRIBE_ORDERABLE_CLUSTER_OPTIONS)
return template.render(options=options, marker=None)
def describe_global_clusters(self) -> str:
clusters = self.backend.describe_global_clusters()
template = self.response_template(DESCRIBE_GLOBAL_CLUSTERS_TEMPLATE)
return template.render(clusters=clusters)
def create_global_cluster(self) -> str:
params = self._get_params()
cluster = self.backend.create_global_cluster(
global_cluster_identifier=params["GlobalClusterIdentifier"],
source_db_cluster_identifier=params.get("SourceDBClusterIdentifier"),
engine=params.get("Engine"),
engine_version=params.get("EngineVersion"),
storage_encrypted=params.get("StorageEncrypted"),
deletion_protection=params.get("DeletionProtection"),
)
template = self.response_template(CREATE_GLOBAL_CLUSTER_TEMPLATE)
return template.render(cluster=cluster)
def delete_global_cluster(self) -> str:
params = self._get_params()
cluster = self.backend.delete_global_cluster(
global_cluster_identifier=params["GlobalClusterIdentifier"],
)
template = self.response_template(DELETE_GLOBAL_CLUSTER_TEMPLATE)
return template.render(cluster=cluster)
def remove_from_global_cluster(self) -> str:
params = self._get_params()
global_cluster = self.backend.remove_from_global_cluster(
global_cluster_identifier=params["GlobalClusterIdentifier"],
db_cluster_identifier=params["DbClusterIdentifier"],
)
template = self.response_template(REMOVE_FROM_GLOBAL_CLUSTER_TEMPLATE)
return template.render(cluster=global_cluster)
def create_db_cluster_parameter_group(self) -> str:
group_name = self._get_param("DBClusterParameterGroupName")
family = self._get_param("DBParameterGroupFamily")
desc = self._get_param("Description")
db_cluster_parameter_group = self.backend.create_db_cluster_parameter_group(
group_name=group_name,
family=family,
description=desc,
)
template = self.response_template(CREATE_DB_CLUSTER_PARAMETER_GROUP_TEMPLATE)
return template.render(db_cluster_parameter_group=db_cluster_parameter_group)
def describe_db_cluster_parameter_groups(self) -> str:
group_name = self._get_param("DBClusterParameterGroupName")
db_parameter_groups = self.backend.describe_db_cluster_parameter_groups(
group_name=group_name,
)
template = self.response_template(DESCRIBE_DB_CLUSTER_PARAMETER_GROUPS_TEMPLATE)
return template.render(db_parameter_groups=db_parameter_groups)
def delete_db_cluster_parameter_group(self) -> str:
group_name = self._get_param("DBClusterParameterGroupName")
self.backend.delete_db_cluster_parameter_group(
group_name=group_name,
)
template = self.response_template(DELETE_DB_CLUSTER_PARAMETER_GROUP_TEMPLATE)
return template.render()
def promote_read_replica_db_cluster(self) -> str:
db_cluster_identifier = self._get_param("DBClusterIdentifier")
cluster = self.backend.promote_read_replica_db_cluster(db_cluster_identifier)
template = self.response_template(PROMOTE_READ_REPLICA_DB_CLUSTER_TEMPLATE)
return template.render(cluster=cluster)
CREATE_DATABASE_TEMPLATE = """<CreateDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateDBInstanceResult>
{{ database.to_xml() }}
</CreateDBInstanceResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</CreateDBInstanceResponse>"""
CREATE_DATABASE_REPLICA_TEMPLATE = """<CreateDBInstanceReadReplicaResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateDBInstanceReadReplicaResult>
{{ database.to_xml() }}
</CreateDBInstanceReadReplicaResult>
<ResponseMetadata>
<RequestId>5e60c46d-a844-11e4-bb68-17f36418e58f</RequestId>
</ResponseMetadata>
</CreateDBInstanceReadReplicaResponse>"""
DESCRIBE_DATABASES_TEMPLATE = """<DescribeDBInstancesResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeDBInstancesResult>
<DBInstances>
{%- for database in databases -%}
{{ database.to_xml() }}
{%- endfor -%}
</DBInstances>
{% if marker %}
<Marker>{{ marker }}</Marker>
{% endif %}
</DescribeDBInstancesResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</DescribeDBInstancesResponse>"""
MODIFY_DATABASE_TEMPLATE = """<ModifyDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<ModifyDBInstanceResult>
{{ database.to_xml() }}
</ModifyDBInstanceResult>
<ResponseMetadata>
<RequestId>bb58476c-a1a8-11e4-99cf-55e92d4bbada</RequestId>
</ResponseMetadata>
</ModifyDBInstanceResponse>"""
PROMOTE_REPLICA_TEMPLATE = """<PromoteReadReplicaResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<PromoteReadReplicaResult>
{{ database.to_xml() }}
</PromoteReadReplicaResult>
<ResponseMetadata>
<RequestId>8e8c0d64-be21-11d3-a71c-13dc2f771e41</RequestId>
</ResponseMetadata>
</PromoteReadReplicaResponse>"""
REBOOT_DATABASE_TEMPLATE = """<RebootDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<RebootDBInstanceResult>
{{ database.to_xml() }}
</RebootDBInstanceResult>
<ResponseMetadata>
<RequestId>d55711cb-a1ab-11e4-99cf-55e92d4bbada</RequestId>
</ResponseMetadata>
</RebootDBInstanceResponse>"""
START_DATABASE_TEMPLATE = """<StartDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
<StartDBInstanceResult>
{{ database.to_xml() }}
</StartDBInstanceResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab9</RequestId>
</ResponseMetadata>
</StartDBInstanceResponse>"""
STOP_DATABASE_TEMPLATE = """<StopDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
<StopDBInstanceResult>
{{ database.to_xml() }}
</StopDBInstanceResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab8</RequestId>
</ResponseMetadata>
</StopDBInstanceResponse>"""
DELETE_DATABASE_TEMPLATE = """<DeleteDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DeleteDBInstanceResult>
{{ database.to_xml() }}
</DeleteDBInstanceResult>
<ResponseMetadata>
<RequestId>7369556f-b70d-11c3-faca-6ba18376ea1b</RequestId>
</ResponseMetadata>
</DeleteDBInstanceResponse>"""
DELETE_CLUSTER_TEMPLATE = """<DeleteDBClusterResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DeleteDBClusterResult>
{{ cluster.to_xml() }}
</DeleteDBClusterResult>
<ResponseMetadata>
<RequestId>7369556f-b70d-11c3-faca-6ba18376ea1b</RequestId>
</ResponseMetadata>
</DeleteDBClusterResponse>"""
RESTORE_INSTANCE_FROM_SNAPSHOT_TEMPLATE = """<RestoreDBInstanceFromDBSnapshotResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<RestoreDBInstanceFromDBSnapshotResult>
{{ database.to_xml() }}
</RestoreDBInstanceFromDBSnapshotResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</RestoreDBInstanceFromDBSnapshotResponse>"""
CREATE_SNAPSHOT_TEMPLATE = """<CreateDBSnapshotResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateDBSnapshotResult>
{{ snapshot.to_xml() }}
</CreateDBSnapshotResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</CreateDBSnapshotResponse>
"""
COPY_SNAPSHOT_TEMPLATE = """<CopyDBSnapshotResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CopyDBSnapshotResult>
{{ snapshot.to_xml() }}
</CopyDBSnapshotResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</CopyDBSnapshotResponse>
"""
DESCRIBE_SNAPSHOTS_TEMPLATE = """<DescribeDBSnapshotsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeDBSnapshotsResult>
<DBSnapshots>
{%- for snapshot in snapshots -%}
{{ snapshot.to_xml() }}
{%- endfor -%}
</DBSnapshots>
{% if marker %}
<Marker>{{ marker }}</Marker>
{% endif %}
</DescribeDBSnapshotsResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</DescribeDBSnapshotsResponse>"""
DELETE_SNAPSHOT_TEMPLATE = """<DeleteDBSnapshotResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DeleteDBSnapshotResult>
{{ snapshot.to_xml() }}
</DeleteDBSnapshotResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</DeleteDBSnapshotResponse>
"""
CREATE_SECURITY_GROUP_TEMPLATE = """<CreateDBSecurityGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateDBSecurityGroupResult>
{{ security_group.to_xml() }}
</CreateDBSecurityGroupResult>
<ResponseMetadata>
<RequestId>462165d0-a77a-11e4-a5fa-75b30c556f97</RequestId>
</ResponseMetadata>
</CreateDBSecurityGroupResponse>"""
DESCRIBE_SECURITY_GROUPS_TEMPLATE = """<DescribeDBSecurityGroupsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeDBSecurityGroupsResult>
<DBSecurityGroups>
{% for security_group in security_groups %}
{{ security_group.to_xml() }}
{% endfor %}
</DBSecurityGroups>
</DescribeDBSecurityGroupsResult>
<ResponseMetadata>
<RequestId>5df2014e-a779-11e4-bdb0-594def064d0c</RequestId>
</ResponseMetadata>
</DescribeDBSecurityGroupsResponse>"""
DELETE_SECURITY_GROUP_TEMPLATE = """<DeleteDBSecurityGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<ResponseMetadata>
<RequestId>97e846bd-a77d-11e4-ac58-91351c0f3426</RequestId>
</ResponseMetadata>
</DeleteDBSecurityGroupResponse>"""
AUTHORIZE_SECURITY_GROUP_TEMPLATE = """<AuthorizeDBSecurityGroupIngressResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<AuthorizeDBSecurityGroupIngressResult>
{{ security_group.to_xml() }}
</AuthorizeDBSecurityGroupIngressResult>
<ResponseMetadata>
<RequestId>75d32fd5-a77e-11e4-8892-b10432f7a87d</RequestId>
</ResponseMetadata>
</AuthorizeDBSecurityGroupIngressResponse>"""
CREATE_SUBNET_GROUP_TEMPLATE = """<CreateDBSubnetGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateDBSubnetGroupResult>
{{ subnet_group.to_xml() }}
</CreateDBSubnetGroupResult>
<ResponseMetadata>
<RequestId>3a401b3f-bb9e-11d3-f4c6-37db295f7674</RequestId>
</ResponseMetadata>
</CreateDBSubnetGroupResponse>"""
DESCRIBE_SUBNET_GROUPS_TEMPLATE = """<DescribeDBSubnetGroupsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeDBSubnetGroupsResult>
<DBSubnetGroups>
{% for subnet_group in subnet_groups %}
{{ subnet_group.to_xml() }}
{% endfor %}
</DBSubnetGroups>
</DescribeDBSubnetGroupsResult>
<ResponseMetadata>
<RequestId>b783db3b-b98c-11d3-fbc7-5c0aad74da7c</RequestId>
</ResponseMetadata>
</DescribeDBSubnetGroupsResponse>"""
MODIFY_SUBNET_GROUPS_TEMPLATE = """<ModifyDBSubnetGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<ModifyDBSubnetGroupResult>
{{ subnet_group.to_xml() }}
</ModifyDBSubnetGroupResult>
<ResponseMetadata>
<RequestId>b783db3b-b98c-11d3-fbc7-5c0aad74da7c</RequestId>
</ResponseMetadata>
</ModifyDBSubnetGroupResponse>"""
DELETE_SUBNET_GROUP_TEMPLATE = """<DeleteDBSubnetGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<ResponseMetadata>
<RequestId>13785dd5-a7fc-11e4-bb9c-7f371d0859b0</RequestId>
</ResponseMetadata>
</DeleteDBSubnetGroupResponse>"""
CREATE_OPTION_GROUP_TEMPLATE = """<CreateOptionGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateOptionGroupResult>
{{ option_group.to_xml() }}
</CreateOptionGroupResult>
<ResponseMetadata>
<RequestId>1e38dad4-9f50-11e4-87ea-a31c60ed2e36</RequestId>
</ResponseMetadata>
</CreateOptionGroupResponse>"""
DELETE_OPTION_GROUP_TEMPLATE = """<DeleteOptionGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<ResponseMetadata>
<RequestId>e2590367-9fa2-11e4-99cf-55e92d41c60e</RequestId>
</ResponseMetadata>
</DeleteOptionGroupResponse>"""
DESCRIBE_OPTION_GROUP_TEMPLATE = """<DescribeOptionGroupsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeOptionGroupsResult>
<OptionGroupsList>
{%- for option_group in option_groups -%}
{{ option_group.to_xml() }}
{%- endfor -%}
</OptionGroupsList>
</DescribeOptionGroupsResult>
<ResponseMetadata>
<RequestId>4caf445d-9fbc-11e4-87ea-a31c60ed2e36</RequestId>
</ResponseMetadata>
</DescribeOptionGroupsResponse>"""
DESCRIBE_OPTION_GROUP_OPTIONS_TEMPLATE = """<DescribeOptionGroupOptionsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeOptionGroupOptionsResult>
<OptionGroupOptions>
{%- for option_group_option in option_group_options -%}
{{ option_group_option.to_xml() }}
{%- endfor -%}
</OptionGroupOptions>
</DescribeOptionGroupOptionsResult>
<ResponseMetadata>
<RequestId>457f7bb8-9fbf-11e4-9084-5754f80d5144</RequestId>
</ResponseMetadata>
</DescribeOptionGroupOptionsResponse>"""
MODIFY_OPTION_GROUP_TEMPLATE = """<ModifyOptionGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<ModifyOptionGroupResult>
{{ option_group.to_xml() }}
</ModifyOptionGroupResult>
<ResponseMetadata>
<RequestId>ce9284a5-a0de-11e4-b984-a11a53e1f328</RequestId>
</ResponseMetadata>
</ModifyOptionGroupResponse>"""
CREATE_DB_PARAMETER_GROUP_TEMPLATE = """<CreateDBParameterGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateDBParameterGroupResult>
{{ db_parameter_group.to_xml() }}
</CreateDBParameterGroupResult>
<ResponseMetadata>
<RequestId>7805c127-af22-11c3-96ac-6999cc5f7e72</RequestId>
</ResponseMetadata>
</CreateDBParameterGroupResponse>"""
DESCRIBE_DB_PARAMETER_GROUPS_TEMPLATE = """<DescribeDBParameterGroupsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeDBParameterGroupsResult>
<DBParameterGroups>
{%- for db_parameter_group in db_parameter_groups -%}
{{ db_parameter_group.to_xml() }}
{%- endfor -%}
</DBParameterGroups>
</DescribeDBParameterGroupsResult>
<ResponseMetadata>
<RequestId>b75d527a-b98c-11d3-f272-7cd6cce12cc5</RequestId>
</ResponseMetadata>
</DescribeDBParameterGroupsResponse>"""
MODIFY_DB_PARAMETER_GROUP_TEMPLATE = """<ModifyDBParameterGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<ModifyDBParameterGroupResult>
<DBParameterGroupName>{{ db_parameter_group.name }}</DBParameterGroupName>
</ModifyDBParameterGroupResult>
<ResponseMetadata>
<RequestId>12d7435e-bba0-11d3-fe11-33d33a9bb7e3</RequestId>
</ResponseMetadata>
</ModifyDBParameterGroupResponse>"""
DELETE_DB_PARAMETER_GROUP_TEMPLATE = """<DeleteDBParameterGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<ResponseMetadata>
<RequestId>cad6c267-ba25-11d3-fe11-33d33a9bb7e3</RequestId>
</ResponseMetadata>
</DeleteDBParameterGroupResponse>"""
DESCRIBE_DB_PARAMETERS_TEMPLATE = """<DescribeDBParametersResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeDBParametersResult>
<Parameters>
{%- for db_parameter_name, db_parameter in db_parameter_group.parameters.items() -%}
<Parameter>
{%- for parameter_name, parameter_value in db_parameter.items() -%}
<{{ parameter_name }}>{{ parameter_value }}</{{ parameter_name }}>
{%- endfor -%}
</Parameter>
{%- endfor -%}
</Parameters>
</DescribeDBParametersResult>
<ResponseMetadata>
<RequestId>8c40488f-b9ff-11d3-a15e-7ac49293f4fa</RequestId>
</ResponseMetadata>
</DescribeDBParametersResponse>
"""
DESCRIBE_DB_CLUSTER_PARAMETERS_TEMPLATE = """<DescribeDBClusterParametersResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeDBClusterParametersResult>
<Parameters>
{%- for param in db_parameter_group -%}
<Parameter>
{%- for parameter_name, parameter_value in db_parameter.items() -%}
<{{ parameter_name }}>{{ parameter_value }}</{{ parameter_name }}>
{%- endfor -%}
</Parameter>
{%- endfor -%}
</Parameters>
</DescribeDBClusterParametersResult>
<ResponseMetadata>
<RequestId>8c40488f-b9ff-11d3-a15e-7ac49293f4fa</RequestId>
</ResponseMetadata>
</DescribeDBClusterParametersResponse>
"""
LIST_TAGS_FOR_RESOURCE_TEMPLATE = """<ListTagsForResourceResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
<ListTagsForResourceResult>
<TagList>
{%- for tag in tags -%}
<Tag>
<Key>{{ tag['Key'] }}</Key>
<Value>{{ tag['Value'] }}</Value>
</Tag>
{%- endfor -%}
</TagList>
</ListTagsForResourceResult>
<ResponseMetadata>
<RequestId>8c21ba39-a598-11e4-b688-194eaf8658fa</RequestId>
</ResponseMetadata>
</ListTagsForResourceResponse>"""
ADD_TAGS_TO_RESOURCE_TEMPLATE = """<AddTagsToResourceResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
<ResponseMetadata>
<RequestId>b194d9ca-a664-11e4-b688-194eaf8658fa</RequestId>
</ResponseMetadata>
</AddTagsToResourceResponse>"""
REMOVE_TAGS_FROM_RESOURCE_TEMPLATE = """<RemoveTagsFromResourceResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
<ResponseMetadata>
<RequestId>b194d9ca-a664-11e4-b688-194eaf8658fa</RequestId>
</ResponseMetadata>
</RemoveTagsFromResourceResponse>"""
CREATE_DB_CLUSTER_TEMPLATE = """<CreateDBClusterResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateDBClusterResult>
{{ cluster.to_xml() }}
</CreateDBClusterResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</CreateDBClusterResponse>"""
MODIFY_DB_CLUSTER_TEMPLATE = """<ModifyDBClusterResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
<ModifyDBClusterResult>
{{ cluster.to_xml() }}
</ModifyDBClusterResult>
<ResponseMetadata>
<RequestId>69673d54-e48e-4ba4-9333-c5a6c1e7526a</RequestId>
</ResponseMetadata>
</ModifyDBClusterResponse>"""
DESCRIBE_CLUSTERS_TEMPLATE = """<DescribeDBClustersResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeDBClustersResult>
<DBClusters>
{%- for cluster in clusters -%}
{{ cluster.to_xml() }}
{%- endfor -%}
</DBClusters>
{% if marker %}
<Marker>{{ marker }}</Marker>
{% endif %}
</DescribeDBClustersResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</DescribeDBClustersResponse>"""
START_CLUSTER_TEMPLATE = """<StartDBClusterResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
<StartDBClusterResult>
{{ cluster.to_xml() }}
</StartDBClusterResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab9</RequestId>
</ResponseMetadata>
</StartDBClusterResponse>"""
STOP_CLUSTER_TEMPLATE = """<StopDBClusterResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
<StopDBClusterResult>
{{ cluster.to_xml() }}
</StopDBClusterResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab8</RequestId>
</ResponseMetadata>
</StopDBClusterResponse>"""
RESTORE_CLUSTER_FROM_SNAPSHOT_TEMPLATE = """<RestoreDBClusterFromDBSnapshotResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<RestoreDBClusterFromSnapshotResult>
{{ cluster.to_xml() }}
</RestoreDBClusterFromSnapshotResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</RestoreDBClusterFromDBSnapshotResponse>
"""
CREATE_CLUSTER_SNAPSHOT_TEMPLATE = """<CreateDBClusterSnapshotResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateDBClusterSnapshotResult>
{{ snapshot.to_xml() }}
</CreateDBClusterSnapshotResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</CreateDBClusterSnapshotResponse>
"""
COPY_CLUSTER_SNAPSHOT_TEMPLATE = """<CopyDBClusterSnapshotResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CopyDBClusterSnapshotResult>
{{ snapshot.to_xml() }}
</CopyDBClusterSnapshotResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</CopyDBClusterSnapshotResponse>
"""
DESCRIBE_CLUSTER_SNAPSHOTS_TEMPLATE = """<DescribeDBClusterSnapshotsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeDBClusterSnapshotsResult>
<DBClusterSnapshots>
{%- for snapshot in snapshots -%}
{{ snapshot.to_xml() }}
{%- endfor -%}
</DBClusterSnapshots>
{% if marker %}
<Marker>{{ marker }}</Marker>
{% endif %}
</DescribeDBClusterSnapshotsResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</DescribeDBClusterSnapshotsResponse>"""
DELETE_CLUSTER_SNAPSHOT_TEMPLATE = """<DeleteDBClusterSnapshotResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DeleteDBClusterSnapshotResult>
{{ snapshot.to_xml() }}
</DeleteDBClusterSnapshotResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</DeleteDBClusterSnapshotResponse>
"""
START_EXPORT_TASK_TEMPLATE = """<StartExportTaskResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<StartExportTaskResult>
{{ task.to_xml() }}
</StartExportTaskResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</StartExportTaskResponse>
"""
CANCEL_EXPORT_TASK_TEMPLATE = """<CancelExportTaskResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CancelExportTaskResult>
{{ task.to_xml() }}
</CancelExportTaskResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</CancelExportTaskResponse>
"""
DESCRIBE_EXPORT_TASKS_TEMPLATE = """<DescribeExportTasksResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeExportTasksResult>
<ExportTasks>
{%- for task in tasks -%}
<ExportTask>{{ task.to_xml() }}</ExportTask>
{%- endfor -%}
</ExportTasks>
{% if marker %}
<Marker>{{ marker }}</Marker>
{% endif %}
</DescribeExportTasksResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</DescribeExportTasksResponse>
"""
CREATE_EVENT_SUBSCRIPTION_TEMPLATE = """<CreateEventSubscriptionResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateEventSubscriptionResult>
{{ subscription.to_xml() }}
</CreateEventSubscriptionResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</CreateEventSubscriptionResponse>
"""
DELETE_EVENT_SUBSCRIPTION_TEMPLATE = """<DeleteEventSubscriptionResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DeleteEventSubscriptionResult>
{{ subscription.to_xml() }}
</DeleteEventSubscriptionResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</DeleteEventSubscriptionResponse>
"""
DESCRIBE_EVENT_SUBSCRIPTIONS_TEMPLATE = """<DescribeEventSubscriptionsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeEventSubscriptionsResult>
<EventSubscriptionsList>
{%- for subscription in subscriptions -%}
{{ subscription.to_xml() }}
{%- endfor -%}
</EventSubscriptionsList>
</DescribeEventSubscriptionsResult>
<ResponseMetadata>
<RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId>
</ResponseMetadata>
</DescribeEventSubscriptionsResponse>
"""
DESCRIBE_ORDERABLE_CLUSTER_OPTIONS = """<DescribeOrderableDBInstanceOptionsResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
<DescribeOrderableDBInstanceOptionsResult>
<OrderableDBInstanceOptions>
{% for option in options %}
<OrderableDBInstanceOption>
<OutpostCapable>false</OutpostCapable>
<AvailabilityZones>
{% for zone in option["AvailabilityZones"] %}
<AvailabilityZone>
<Name>{{ zone["Name"] }}</Name>
</AvailabilityZone>
{% endfor %}
</AvailabilityZones>
<SupportsStorageThroughput>{{ option["SupportsStorageThroughput"] }}</SupportsStorageThroughput>
<SupportedEngineModes>
<member>provisioned</member>
</SupportedEngineModes>
<SupportsGlobalDatabases>{{ option["SupportsGlobalDatabases"] }}</SupportsGlobalDatabases>
<SupportsClusters>{{ option["SupportsClusters"] }}</SupportsClusters>
<Engine>{{ option["Engine"] }}</Engine>
<SupportedActivityStreamModes/>
<SupportsEnhancedMonitoring>false</SupportsEnhancedMonitoring>
<EngineVersion>{{ option["EngineVersion"] }}</EngineVersion>
<ReadReplicaCapable>false</ReadReplicaCapable>
<Vpc>true</Vpc>
<DBInstanceClass>{{ option["DBInstanceClass"] }}</DBInstanceClass>
<SupportsStorageEncryption>{{ option["SupportsStorageEncryption"] }}</SupportsStorageEncryption>
<SupportsKerberosAuthentication>{{ option["SupportsKerberosAuthentication"] }}</SupportsKerberosAuthentication>
<SupportedNetworkTypes>
<member>IPV4</member>
</SupportedNetworkTypes>
<AvailableProcessorFeatures/>
<SupportsPerformanceInsights>{{ option["SupportsPerformanceInsights"] }}</SupportsPerformanceInsights>
<LicenseModel>{{ option["LicenseModel"] }}</LicenseModel>
<MultiAZCapable>{{ option["MultiAZCapable"] }}</MultiAZCapable>
<RequiresCustomProcessorFeatures>{{ option["RequiresCustomProcessorFeatures"] }}</RequiresCustomProcessorFeatures>
<StorageType>{{ option["StorageType"] }}</StorageType>
<SupportsIops>{{ option["SupportsIops"] }}</SupportsIops>
<SupportsIAMDatabaseAuthentication>{{ option["SupportsIAMDatabaseAuthentication"] }}</SupportsIAMDatabaseAuthentication>
</OrderableDBInstanceOption>
{% endfor %}
</OrderableDBInstanceOptions>
{% if marker %}
<Marker>{{ marker }}</Marker>
{% endif %}
</DescribeOrderableDBInstanceOptionsResult>
<ResponseMetadata>
<RequestId>54212dc5-16c4-4eb8-a88e-448691e877ab</RequestId>
</ResponseMetadata>
</DescribeOrderableDBInstanceOptionsResponse>"""
CREATE_DB_CLUSTER_PARAMETER_GROUP_TEMPLATE = """<CreateDBClusterParameterGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateDBClusterParameterGroupResult>
{{ db_cluster_parameter_group.to_xml() }}
</CreateDBClusterParameterGroupResult>
<ResponseMetadata>
<RequestId>7805c127-af22-11c3-96ac-6999cc5f7e72</RequestId>
</ResponseMetadata>
</CreateDBClusterParameterGroupResponse>"""
DESCRIBE_DB_CLUSTER_PARAMETER_GROUPS_TEMPLATE = """<DescribeDBClusterParameterGroupsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<DescribeDBClusterParameterGroupsResult>
<DBClusterParameterGroups>
{%- for db_parameter_group in db_parameter_groups -%}
{{ db_parameter_group.to_xml() }}
{%- endfor -%}
</DBClusterParameterGroups>
</DescribeDBClusterParameterGroupsResult>
<ResponseMetadata>
<RequestId>b75d527a-b98c-11d3-f272-7cd6cce12cc5</RequestId>
</ResponseMetadata>
</DescribeDBClusterParameterGroupsResponse>"""
DELETE_DB_CLUSTER_PARAMETER_GROUP_TEMPLATE = """<DeleteDBClusterParameterGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<ResponseMetadata>
<RequestId>cad6c267-ba25-11d3-fe11-33d33a9bb7e3</RequestId>
</ResponseMetadata>
</DeleteDBClusterParameterGroupResponse>"""
PROMOTE_READ_REPLICA_DB_CLUSTER_TEMPLATE = """<PromoteReadReplicaDBClusterResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<PromoteReadReplicaDBClusterResult>
{{ cluster.to_xml() }}
</PromoteReadReplicaDBClusterResult>
<ResponseMetadata>
<RequestId>7369556f-b70d-11c3-faca-6ba18376ea1b</RequestId>
</ResponseMetadata>
</PromoteReadReplicaDBClusterResponse>"""