1from moto.core.responses import BaseResponse 2from moto.ec2.models import ec2_backends 3from .models import rds_backends 4 5 6class RDSResponse(BaseResponse): 7 @property 8 def backend(self): 9 return rds_backends[self.region] 10 11 def _get_db_kwargs(self): 12 args = { 13 "auto_minor_version_upgrade": self._get_param("AutoMinorVersionUpgrade"), 14 "allocated_storage": self._get_int_param("AllocatedStorage"), 15 "availability_zone": self._get_param("AvailabilityZone"), 16 "backup_retention_period": self._get_param("BackupRetentionPeriod"), 17 "db_instance_class": self._get_param("DBInstanceClass"), 18 "db_instance_identifier": self._get_param("DBInstanceIdentifier"), 19 "db_name": self._get_param("DBName"), 20 # DBParameterGroupName 21 "db_subnet_group_name": self._get_param("DBSubnetGroupName"), 22 "engine": self._get_param("Engine"), 23 "engine_version": self._get_param("EngineVersion"), 24 "iops": self._get_int_param("Iops"), 25 "kms_key_id": self._get_param("KmsKeyId"), 26 "master_password": self._get_param("MasterUserPassword"), 27 "master_username": self._get_param("MasterUsername"), 28 "multi_az": self._get_bool_param("MultiAZ"), 29 # OptionGroupName 30 "port": self._get_param("Port"), 31 # PreferredBackupWindow 32 # PreferredMaintenanceWindow 33 "publicly_accessible": self._get_param("PubliclyAccessible"), 34 "region": self.region, 35 "security_groups": self._get_multi_param("DBSecurityGroups.member"), 36 "storage_encrypted": self._get_param("StorageEncrypted"), 37 "storage_type": self._get_param("StorageType"), 38 # VpcSecurityGroupIds.member.N 39 "tags": list(), 40 } 41 args["tags"] = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value")) 42 return args 43 44 def _get_db_replica_kwargs(self): 45 return { 46 "auto_minor_version_upgrade": self._get_param("AutoMinorVersionUpgrade"), 47 "availability_zone": self._get_param("AvailabilityZone"), 48 "db_instance_class": self._get_param("DBInstanceClass"), 49 "db_instance_identifier": self._get_param("DBInstanceIdentifier"), 50 "db_subnet_group_name": self._get_param("DBSubnetGroupName"), 51 "iops": self._get_int_param("Iops"), 52 # OptionGroupName 53 "port": self._get_param("Port"), 54 "publicly_accessible": self._get_param("PubliclyAccessible"), 55 "source_db_identifier": self._get_param("SourceDBInstanceIdentifier"), 56 "storage_type": self._get_param("StorageType"), 57 } 58 59 def unpack_complex_list_params(self, label, names): 60 unpacked_list = list() 61 count = 1 62 while self._get_param("{0}.{1}.{2}".format(label, count, names[0])): 63 param = dict() 64 for i in range(len(names)): 65 param[names[i]] = self._get_param( 66 "{0}.{1}.{2}".format(label, count, names[i]) 67 ) 68 unpacked_list.append(param) 69 count += 1 70 return unpacked_list 71 72 def create_db_instance(self): 73 db_kwargs = self._get_db_kwargs() 74 75 database = self.backend.create_database(db_kwargs) 76 template = self.response_template(CREATE_DATABASE_TEMPLATE) 77 return template.render(database=database) 78 79 def create_db_instance_read_replica(self): 80 db_kwargs = self._get_db_replica_kwargs() 81 82 database = self.backend.create_database_replica(db_kwargs) 83 template = self.response_template(CREATE_DATABASE_REPLICA_TEMPLATE) 84 return template.render(database=database) 85 86 def describe_db_instances(self): 87 db_instance_identifier = self._get_param("DBInstanceIdentifier") 88 all_instances = list(self.backend.describe_databases(db_instance_identifier)) 89 marker = self._get_param("Marker") 90 all_ids = [instance.db_instance_identifier for instance in all_instances] 91 if marker: 92 start = all_ids.index(marker) + 1 93 else: 94 start = 0 95 page_size = self._get_int_param( 96 "MaxRecords", 50 97 ) # the default is 100, but using 50 to make testing easier 98 instances_resp = all_instances[start : start + page_size] 99 next_marker = None 100 if len(all_instances) > start + page_size: 101 next_marker = instances_resp[-1].db_instance_identifier 102 103 template = self.response_template(DESCRIBE_DATABASES_TEMPLATE) 104 return template.render(databases=instances_resp, marker=next_marker) 105 106 def modify_db_instance(self): 107 db_instance_identifier = self._get_param("DBInstanceIdentifier") 108 db_kwargs = self._get_db_kwargs() 109 new_db_instance_identifier = self._get_param("NewDBInstanceIdentifier") 110 if new_db_instance_identifier: 111 db_kwargs["new_db_instance_identifier"] = new_db_instance_identifier 112 database = self.backend.modify_database(db_instance_identifier, db_kwargs) 113 template = self.response_template(MODIFY_DATABASE_TEMPLATE) 114 return template.render(database=database) 115 116 def delete_db_instance(self): 117 db_instance_identifier = self._get_param("DBInstanceIdentifier") 118 database = self.backend.delete_database(db_instance_identifier) 119 template = self.response_template(DELETE_DATABASE_TEMPLATE) 120 return template.render(database=database) 121 122 def create_db_security_group(self): 123 group_name = self._get_param("DBSecurityGroupName") 124 description = self._get_param("DBSecurityGroupDescription") 125 tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value")) 126 security_group = self.backend.create_security_group( 127 group_name, description, tags 128 ) 129 template = self.response_template(CREATE_SECURITY_GROUP_TEMPLATE) 130 return template.render(security_group=security_group) 131 132 def describe_db_security_groups(self): 133 security_group_name = self._get_param("DBSecurityGroupName") 134 security_groups = self.backend.describe_security_groups(security_group_name) 135 template = self.response_template(DESCRIBE_SECURITY_GROUPS_TEMPLATE) 136 return template.render(security_groups=security_groups) 137 138 def delete_db_security_group(self): 139 security_group_name = self._get_param("DBSecurityGroupName") 140 security_group = self.backend.delete_security_group(security_group_name) 141 template = self.response_template(DELETE_SECURITY_GROUP_TEMPLATE) 142 return template.render(security_group=security_group) 143 144 def authorize_db_security_group_ingress(self): 145 security_group_name = self._get_param("DBSecurityGroupName") 146 cidr_ip = self._get_param("CIDRIP") 147 security_group = self.backend.authorize_security_group( 148 security_group_name, cidr_ip 149 ) 150 template = self.response_template(AUTHORIZE_SECURITY_GROUP_TEMPLATE) 151 return template.render(security_group=security_group) 152 153 def create_db_subnet_group(self): 154 subnet_name = self._get_param("DBSubnetGroupName") 155 description = self._get_param("DBSubnetGroupDescription") 156 subnet_ids = self._get_multi_param("SubnetIds.member") 157 subnets = [ 158 ec2_backends[self.region].get_subnet(subnet_id) for subnet_id in subnet_ids 159 ] 160 tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value")) 161 subnet_group = self.backend.create_subnet_group( 162 subnet_name, description, subnets, tags 163 ) 164 template = self.response_template(CREATE_SUBNET_GROUP_TEMPLATE) 165 return template.render(subnet_group=subnet_group) 166 167 def describe_db_subnet_groups(self): 168 subnet_name = self._get_param("DBSubnetGroupName") 169 subnet_groups = self.backend.describe_subnet_groups(subnet_name) 170 template = self.response_template(DESCRIBE_SUBNET_GROUPS_TEMPLATE) 171 return template.render(subnet_groups=subnet_groups) 172 173 def delete_db_subnet_group(self): 174 subnet_name = self._get_param("DBSubnetGroupName") 175 subnet_group = self.backend.delete_subnet_group(subnet_name) 176 template = self.response_template(DELETE_SUBNET_GROUP_TEMPLATE) 177 return template.render(subnet_group=subnet_group) 178 179 180CREATE_DATABASE_TEMPLATE = """<CreateDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 181 <CreateDBInstanceResult> 182 {{ database.to_xml() }} 183 </CreateDBInstanceResult> 184 <ResponseMetadata> 185 <RequestId>523e3218-afc7-11c3-90f5-f90431260ab4</RequestId> 186 </ResponseMetadata> 187</CreateDBInstanceResponse>""" 188 189CREATE_DATABASE_REPLICA_TEMPLATE = """<CreateDBInstanceReadReplicaResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 190 <CreateDBInstanceReadReplicaResult> 191 {{ database.to_xml() }} 192 </CreateDBInstanceReadReplicaResult> 193 <ResponseMetadata> 194 <RequestId>ba8dedf0-bb9a-11d3-855b-576787000e19</RequestId> 195 </ResponseMetadata> 196</CreateDBInstanceReadReplicaResponse>""" 197 198DESCRIBE_DATABASES_TEMPLATE = """<DescribeDBInstancesResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 199 <DescribeDBInstancesResult> 200 <DBInstances> 201 {% for database in databases %} 202 {{ database.to_xml() }} 203 {% endfor %} 204 </DBInstances> 205 {% if marker %} 206 <Marker>{{ marker }}</Marker> 207 {% endif %} 208 </DescribeDBInstancesResult> 209 <ResponseMetadata> 210 <RequestId>01b2685a-b978-11d3-f272-7cd6cce12cc5</RequestId> 211 </ResponseMetadata> 212</DescribeDBInstancesResponse>""" 213 214MODIFY_DATABASE_TEMPLATE = """<ModifyDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 215 <ModifyDBInstanceResult> 216 {{ database.to_xml() }} 217 </ModifyDBInstanceResult> 218 <ResponseMetadata> 219 <RequestId>f643f1ac-bbfe-11d3-f4c6-37db295f7674</RequestId> 220 </ResponseMetadata> 221</ModifyDBInstanceResponse>""" 222 223DELETE_DATABASE_TEMPLATE = """<DeleteDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 224 <DeleteDBInstanceResult> 225 {{ database.to_xml() }} 226 </DeleteDBInstanceResult> 227 <ResponseMetadata> 228 <RequestId>7369556f-b70d-11c3-faca-6ba18376ea1b</RequestId> 229 </ResponseMetadata> 230</DeleteDBInstanceResponse>""" 231 232CREATE_SECURITY_GROUP_TEMPLATE = """<CreateDBSecurityGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 233 <CreateDBSecurityGroupResult> 234 {{ security_group.to_xml() }} 235 </CreateDBSecurityGroupResult> 236 <ResponseMetadata> 237 <RequestId>e68ef6fa-afc1-11c3-845a-476777009d19</RequestId> 238 </ResponseMetadata> 239</CreateDBSecurityGroupResponse>""" 240 241DESCRIBE_SECURITY_GROUPS_TEMPLATE = """<DescribeDBSecurityGroupsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 242 <DescribeDBSecurityGroupsResult> 243 <DBSecurityGroups> 244 {% for security_group in security_groups %} 245 {{ security_group.to_xml() }} 246 {% endfor %} 247 </DBSecurityGroups> 248 </DescribeDBSecurityGroupsResult> 249 <ResponseMetadata> 250 <RequestId>b76e692c-b98c-11d3-a907-5a2c468b9cb0</RequestId> 251 </ResponseMetadata> 252</DescribeDBSecurityGroupsResponse>""" 253 254DELETE_SECURITY_GROUP_TEMPLATE = """<DeleteDBSecurityGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 255 <ResponseMetadata> 256 <RequestId>7aec7454-ba25-11d3-855b-576787000e19</RequestId> 257 </ResponseMetadata> 258</DeleteDBSecurityGroupResponse>""" 259 260AUTHORIZE_SECURITY_GROUP_TEMPLATE = """<AuthorizeDBSecurityGroupIngressResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 261 <AuthorizeDBSecurityGroupIngressResult> 262 {{ security_group.to_xml() }} 263 </AuthorizeDBSecurityGroupIngressResult> 264 <ResponseMetadata> 265 <RequestId>6176b5f8-bfed-11d3-f92b-31fa5e8dbc99</RequestId> 266 </ResponseMetadata> 267</AuthorizeDBSecurityGroupIngressResponse>""" 268 269CREATE_SUBNET_GROUP_TEMPLATE = """<CreateDBSubnetGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 270 <CreateDBSubnetGroupResult> 271 {{ subnet_group.to_xml() }} 272 </CreateDBSubnetGroupResult> 273 <ResponseMetadata> 274 <RequestId>3a401b3f-bb9e-11d3-f4c6-37db295f7674</RequestId> 275 </ResponseMetadata> 276</CreateDBSubnetGroupResponse>""" 277 278DESCRIBE_SUBNET_GROUPS_TEMPLATE = """<DescribeDBSubnetGroupsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 279 <DescribeDBSubnetGroupsResult> 280 <DBSubnetGroups> 281 {% for subnet_group in subnet_groups %} 282 {{ subnet_group.to_xml() }} 283 {% endfor %} 284 </DBSubnetGroups> 285 </DescribeDBSubnetGroupsResult> 286 <ResponseMetadata> 287 <RequestId>b783db3b-b98c-11d3-fbc7-5c0aad74da7c</RequestId> 288 </ResponseMetadata> 289</DescribeDBSubnetGroupsResponse>""" 290 291DELETE_SUBNET_GROUP_TEMPLATE = """<DeleteDBSubnetGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/"> 292 <ResponseMetadata> 293 <RequestId>6295e5ab-bbf3-11d3-f4c6-37db295f7674</RequestId> 294 </ResponseMetadata> 295</DeleteDBSubnetGroupResponse>""" 296