RDS - improve tagging support (#4994)
This commit is contained in:
parent
e533b1a3ff
commit
15b49396ce
@ -4196,7 +4196,7 @@
|
|||||||
|
|
||||||
## rds
|
## rds
|
||||||
<details>
|
<details>
|
||||||
<summary>21% implemented</summary>
|
<summary>26% implemented</summary>
|
||||||
|
|
||||||
- [ ] add_role_to_db_cluster
|
- [ ] add_role_to_db_cluster
|
||||||
- [ ] add_role_to_db_instance
|
- [ ] add_role_to_db_instance
|
||||||
@ -4217,13 +4217,13 @@
|
|||||||
- [ ] create_db_cluster_endpoint
|
- [ ] create_db_cluster_endpoint
|
||||||
- [ ] create_db_cluster_parameter_group
|
- [ ] create_db_cluster_parameter_group
|
||||||
- [X] create_db_cluster_snapshot
|
- [X] create_db_cluster_snapshot
|
||||||
- [ ] create_db_instance
|
- [X] create_db_instance
|
||||||
- [ ] create_db_instance_read_replica
|
- [ ] create_db_instance_read_replica
|
||||||
- [X] create_db_parameter_group
|
- [X] create_db_parameter_group
|
||||||
- [ ] create_db_proxy
|
- [ ] create_db_proxy
|
||||||
- [ ] create_db_proxy_endpoint
|
- [ ] create_db_proxy_endpoint
|
||||||
- [ ] create_db_security_group
|
- [X] create_db_security_group
|
||||||
- [ ] create_db_snapshot
|
- [X] create_db_snapshot
|
||||||
- [ ] create_db_subnet_group
|
- [ ] create_db_subnet_group
|
||||||
- [X] create_event_subscription
|
- [X] create_event_subscription
|
||||||
- [ ] create_global_cluster
|
- [ ] create_global_cluster
|
||||||
@ -4234,13 +4234,13 @@
|
|||||||
- [ ] delete_db_cluster_endpoint
|
- [ ] delete_db_cluster_endpoint
|
||||||
- [ ] delete_db_cluster_parameter_group
|
- [ ] delete_db_cluster_parameter_group
|
||||||
- [X] delete_db_cluster_snapshot
|
- [X] delete_db_cluster_snapshot
|
||||||
- [ ] delete_db_instance
|
- [X] delete_db_instance
|
||||||
- [ ] delete_db_instance_automated_backup
|
- [ ] delete_db_instance_automated_backup
|
||||||
- [X] delete_db_parameter_group
|
- [X] delete_db_parameter_group
|
||||||
- [ ] delete_db_proxy
|
- [ ] delete_db_proxy
|
||||||
- [ ] delete_db_proxy_endpoint
|
- [ ] delete_db_proxy_endpoint
|
||||||
- [ ] delete_db_security_group
|
- [ ] delete_db_security_group
|
||||||
- [ ] delete_db_snapshot
|
- [X] delete_db_snapshot
|
||||||
- [ ] delete_db_subnet_group
|
- [ ] delete_db_subnet_group
|
||||||
- [X] delete_event_subscription
|
- [X] delete_event_subscription
|
||||||
- [ ] delete_global_cluster
|
- [ ] delete_global_cluster
|
||||||
@ -4299,7 +4299,7 @@
|
|||||||
- [ ] modify_db_cluster_endpoint
|
- [ ] modify_db_cluster_endpoint
|
||||||
- [ ] modify_db_cluster_parameter_group
|
- [ ] modify_db_cluster_parameter_group
|
||||||
- [ ] modify_db_cluster_snapshot_attribute
|
- [ ] modify_db_cluster_snapshot_attribute
|
||||||
- [ ] modify_db_instance
|
- [X] modify_db_instance
|
||||||
- [X] modify_db_parameter_group
|
- [X] modify_db_parameter_group
|
||||||
- [ ] modify_db_proxy
|
- [ ] modify_db_proxy
|
||||||
- [ ] modify_db_proxy_endpoint
|
- [ ] modify_db_proxy_endpoint
|
||||||
@ -4332,12 +4332,12 @@
|
|||||||
- [ ] revoke_db_security_group_ingress
|
- [ ] revoke_db_security_group_ingress
|
||||||
- [ ] start_activity_stream
|
- [ ] start_activity_stream
|
||||||
- [X] start_db_cluster
|
- [X] start_db_cluster
|
||||||
- [ ] start_db_instance
|
- [X] start_db_instance
|
||||||
- [ ] start_db_instance_automated_backups_replication
|
- [ ] start_db_instance_automated_backups_replication
|
||||||
- [X] start_export_task
|
- [X] start_export_task
|
||||||
- [ ] stop_activity_stream
|
- [ ] stop_activity_stream
|
||||||
- [X] stop_db_cluster
|
- [X] stop_db_cluster
|
||||||
- [ ] stop_db_instance
|
- [X] stop_db_instance
|
||||||
- [ ] stop_db_instance_automated_backups_replication
|
- [ ] stop_db_instance_automated_backups_replication
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@ -44,13 +44,13 @@ rds
|
|||||||
- [ ] create_db_cluster_endpoint
|
- [ ] create_db_cluster_endpoint
|
||||||
- [ ] create_db_cluster_parameter_group
|
- [ ] create_db_cluster_parameter_group
|
||||||
- [X] create_db_cluster_snapshot
|
- [X] create_db_cluster_snapshot
|
||||||
- [ ] create_db_instance
|
- [X] create_db_instance
|
||||||
- [ ] create_db_instance_read_replica
|
- [ ] create_db_instance_read_replica
|
||||||
- [X] create_db_parameter_group
|
- [X] create_db_parameter_group
|
||||||
- [ ] create_db_proxy
|
- [ ] create_db_proxy
|
||||||
- [ ] create_db_proxy_endpoint
|
- [ ] create_db_proxy_endpoint
|
||||||
- [ ] create_db_security_group
|
- [X] create_db_security_group
|
||||||
- [ ] create_db_snapshot
|
- [X] create_db_snapshot
|
||||||
- [ ] create_db_subnet_group
|
- [ ] create_db_subnet_group
|
||||||
- [X] create_event_subscription
|
- [X] create_event_subscription
|
||||||
- [ ] create_global_cluster
|
- [ ] create_global_cluster
|
||||||
@ -61,13 +61,13 @@ rds
|
|||||||
- [ ] delete_db_cluster_endpoint
|
- [ ] delete_db_cluster_endpoint
|
||||||
- [ ] delete_db_cluster_parameter_group
|
- [ ] delete_db_cluster_parameter_group
|
||||||
- [X] delete_db_cluster_snapshot
|
- [X] delete_db_cluster_snapshot
|
||||||
- [ ] delete_db_instance
|
- [X] delete_db_instance
|
||||||
- [ ] delete_db_instance_automated_backup
|
- [ ] delete_db_instance_automated_backup
|
||||||
- [X] delete_db_parameter_group
|
- [X] delete_db_parameter_group
|
||||||
- [ ] delete_db_proxy
|
- [ ] delete_db_proxy
|
||||||
- [ ] delete_db_proxy_endpoint
|
- [ ] delete_db_proxy_endpoint
|
||||||
- [ ] delete_db_security_group
|
- [ ] delete_db_security_group
|
||||||
- [ ] delete_db_snapshot
|
- [X] delete_db_snapshot
|
||||||
- [ ] delete_db_subnet_group
|
- [ ] delete_db_subnet_group
|
||||||
- [X] delete_event_subscription
|
- [X] delete_event_subscription
|
||||||
- [ ] delete_global_cluster
|
- [ ] delete_global_cluster
|
||||||
@ -126,7 +126,7 @@ rds
|
|||||||
- [ ] modify_db_cluster_endpoint
|
- [ ] modify_db_cluster_endpoint
|
||||||
- [ ] modify_db_cluster_parameter_group
|
- [ ] modify_db_cluster_parameter_group
|
||||||
- [ ] modify_db_cluster_snapshot_attribute
|
- [ ] modify_db_cluster_snapshot_attribute
|
||||||
- [ ] modify_db_instance
|
- [X] modify_db_instance
|
||||||
- [X] modify_db_parameter_group
|
- [X] modify_db_parameter_group
|
||||||
- [ ] modify_db_proxy
|
- [ ] modify_db_proxy
|
||||||
- [ ] modify_db_proxy_endpoint
|
- [ ] modify_db_proxy_endpoint
|
||||||
@ -159,11 +159,11 @@ rds
|
|||||||
- [ ] revoke_db_security_group_ingress
|
- [ ] revoke_db_security_group_ingress
|
||||||
- [ ] start_activity_stream
|
- [ ] start_activity_stream
|
||||||
- [X] start_db_cluster
|
- [X] start_db_cluster
|
||||||
- [ ] start_db_instance
|
- [X] start_db_instance
|
||||||
- [ ] start_db_instance_automated_backups_replication
|
- [ ] start_db_instance_automated_backups_replication
|
||||||
- [X] start_export_task
|
- [X] start_export_task
|
||||||
- [ ] stop_activity_stream
|
- [ ] stop_activity_stream
|
||||||
- [X] stop_db_cluster
|
- [X] stop_db_cluster
|
||||||
- [ ] stop_db_instance
|
- [X] stop_db_instance
|
||||||
- [ ] stop_db_instance_automated_backups_replication
|
- [ ] stop_db_instance_automated_backups_replication
|
||||||
|
|
||||||
|
@ -728,7 +728,7 @@ class Database(CloudFormationModel):
|
|||||||
db_kwargs["source_db_identifier"] = source_db_identifier
|
db_kwargs["source_db_identifier"] = source_db_identifier
|
||||||
database = rds_backend.create_database_replica(db_kwargs)
|
database = rds_backend.create_database_replica(db_kwargs)
|
||||||
else:
|
else:
|
||||||
database = rds_backend.create_database(db_kwargs)
|
database = rds_backend.create_db_instance(db_kwargs)
|
||||||
return database
|
return database
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
@ -820,7 +820,7 @@ class Database(CloudFormationModel):
|
|||||||
|
|
||||||
def delete(self, region_name):
|
def delete(self, region_name):
|
||||||
backend = rds_backends[region_name]
|
backend = rds_backends[region_name]
|
||||||
backend.delete_database(self.db_instance_identifier)
|
backend.delete_db_instance(self.db_instance_identifier)
|
||||||
|
|
||||||
|
|
||||||
class DatabaseSnapshot(BaseModel):
|
class DatabaseSnapshot(BaseModel):
|
||||||
@ -1094,7 +1094,7 @@ class SecurityGroup(CloudFormationModel):
|
|||||||
|
|
||||||
ec2_backend = ec2_backends[region_name]
|
ec2_backend = ec2_backends[region_name]
|
||||||
rds_backend = rds_backends[region_name]
|
rds_backend = rds_backends[region_name]
|
||||||
security_group = rds_backend.create_security_group(
|
security_group = rds_backend.create_db_security_group(
|
||||||
group_name, description, tags
|
group_name, description, tags
|
||||||
)
|
)
|
||||||
for security_group_ingress in security_group_ingress_rules:
|
for security_group_ingress in security_group_ingress_rules:
|
||||||
@ -1257,13 +1257,13 @@ class RDSBackend(BaseBackend):
|
|||||||
service_region, zones, "rds-data"
|
service_region, zones, "rds-data"
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_database(self, db_kwargs):
|
def create_db_instance(self, db_kwargs):
|
||||||
database_id = db_kwargs["db_instance_identifier"]
|
database_id = db_kwargs["db_instance_identifier"]
|
||||||
database = Database(**db_kwargs)
|
database = Database(**db_kwargs)
|
||||||
self.databases[database_id] = database
|
self.databases[database_id] = database
|
||||||
return database
|
return database
|
||||||
|
|
||||||
def create_database_snapshot(
|
def create_db_snapshot(
|
||||||
self, db_instance_identifier, db_snapshot_identifier, tags=None
|
self, db_instance_identifier, db_snapshot_identifier, tags=None
|
||||||
):
|
):
|
||||||
database = self.databases.get(db_instance_identifier)
|
database = self.databases.get(db_instance_identifier)
|
||||||
@ -1307,7 +1307,7 @@ class RDSBackend(BaseBackend):
|
|||||||
|
|
||||||
return target_snapshot
|
return target_snapshot
|
||||||
|
|
||||||
def delete_database_snapshot(self, db_snapshot_identifier):
|
def delete_db_snapshot(self, db_snapshot_identifier):
|
||||||
if db_snapshot_identifier not in self.database_snapshots:
|
if db_snapshot_identifier not in self.database_snapshots:
|
||||||
raise DBSnapshotNotFoundError(db_snapshot_identifier)
|
raise DBSnapshotNotFoundError(db_snapshot_identifier)
|
||||||
|
|
||||||
@ -1358,7 +1358,7 @@ class RDSBackend(BaseBackend):
|
|||||||
raise DBSnapshotNotFoundError(db_snapshot_identifier)
|
raise DBSnapshotNotFoundError(db_snapshot_identifier)
|
||||||
return list(snapshots.values())
|
return list(snapshots.values())
|
||||||
|
|
||||||
def modify_database(self, db_instance_identifier, db_kwargs):
|
def modify_db_instance(self, db_instance_identifier, db_kwargs):
|
||||||
database = self.describe_databases(db_instance_identifier)[0]
|
database = self.describe_databases(db_instance_identifier)[0]
|
||||||
if "new_db_instance_identifier" in db_kwargs:
|
if "new_db_instance_identifier" in db_kwargs:
|
||||||
del self.databases[db_instance_identifier]
|
del self.databases[db_instance_identifier]
|
||||||
@ -1388,9 +1388,9 @@ class RDSBackend(BaseBackend):
|
|||||||
if value:
|
if value:
|
||||||
new_instance_props[key] = value
|
new_instance_props[key] = value
|
||||||
|
|
||||||
return self.create_database(new_instance_props)
|
return self.create_db_instance(new_instance_props)
|
||||||
|
|
||||||
def stop_database(self, db_instance_identifier, db_snapshot_identifier=None):
|
def stop_db_instance(self, db_instance_identifier, db_snapshot_identifier=None):
|
||||||
database = self.describe_databases(db_instance_identifier)[0]
|
database = self.describe_databases(db_instance_identifier)[0]
|
||||||
# todo: certain rds types not allowed to be stopped at this time.
|
# todo: certain rds types not allowed to be stopped at this time.
|
||||||
# https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_StopInstance.html#USER_StopInstance.Limitations
|
# https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_StopInstance.html#USER_StopInstance.Limitations
|
||||||
@ -1402,13 +1402,11 @@ class RDSBackend(BaseBackend):
|
|||||||
if database.status != "available":
|
if database.status != "available":
|
||||||
raise InvalidDBInstanceStateError(db_instance_identifier, "stop")
|
raise InvalidDBInstanceStateError(db_instance_identifier, "stop")
|
||||||
if db_snapshot_identifier:
|
if db_snapshot_identifier:
|
||||||
self.create_database_snapshot(
|
self.create_db_snapshot(db_instance_identifier, db_snapshot_identifier)
|
||||||
db_instance_identifier, db_snapshot_identifier
|
|
||||||
)
|
|
||||||
database.status = "stopped"
|
database.status = "stopped"
|
||||||
return database
|
return database
|
||||||
|
|
||||||
def start_database(self, db_instance_identifier):
|
def start_db_instance(self, db_instance_identifier):
|
||||||
database = self.describe_databases(db_instance_identifier)[0]
|
database = self.describe_databases(db_instance_identifier)[0]
|
||||||
# todo: bunch of different error messages to be generated from this api call
|
# todo: bunch of different error messages to be generated from this api call
|
||||||
if database.status != "stopped":
|
if database.status != "stopped":
|
||||||
@ -1428,14 +1426,14 @@ class RDSBackend(BaseBackend):
|
|||||||
|
|
||||||
return backend.describe_databases(db_name)[0]
|
return backend.describe_databases(db_name)[0]
|
||||||
|
|
||||||
def delete_database(self, db_instance_identifier, db_snapshot_name=None):
|
def delete_db_instance(self, db_instance_identifier, db_snapshot_name=None):
|
||||||
if db_instance_identifier in self.databases:
|
if db_instance_identifier in self.databases:
|
||||||
if self.databases[db_instance_identifier].deletion_protection:
|
if self.databases[db_instance_identifier].deletion_protection:
|
||||||
raise InvalidParameterValue(
|
raise InvalidParameterValue(
|
||||||
"Can't delete Instance with protection enabled"
|
"Can't delete Instance with protection enabled"
|
||||||
)
|
)
|
||||||
if db_snapshot_name:
|
if db_snapshot_name:
|
||||||
self.create_database_snapshot(db_instance_identifier, db_snapshot_name)
|
self.create_db_snapshot(db_instance_identifier, db_snapshot_name)
|
||||||
database = self.databases.pop(db_instance_identifier)
|
database = self.databases.pop(db_instance_identifier)
|
||||||
if database.is_replica:
|
if database.is_replica:
|
||||||
primary = self.find_db_from_id(database.source_db_identifier)
|
primary = self.find_db_from_id(database.source_db_identifier)
|
||||||
@ -1445,7 +1443,7 @@ class RDSBackend(BaseBackend):
|
|||||||
else:
|
else:
|
||||||
raise DBInstanceNotFoundError(db_instance_identifier)
|
raise DBInstanceNotFoundError(db_instance_identifier)
|
||||||
|
|
||||||
def create_security_group(self, group_name, description, tags):
|
def create_db_security_group(self, group_name, description, tags):
|
||||||
security_group = SecurityGroup(group_name, description, tags)
|
security_group = SecurityGroup(group_name, description, tags)
|
||||||
self.security_groups[group_name] = security_group
|
self.security_groups[group_name] = security_group
|
||||||
return security_group
|
return security_group
|
||||||
@ -1985,6 +1983,9 @@ class RDSBackend(BaseBackend):
|
|||||||
elif resource_type == "snapshot": # DB Snapshot
|
elif resource_type == "snapshot": # DB Snapshot
|
||||||
if resource_name in self.database_snapshots:
|
if resource_name in self.database_snapshots:
|
||||||
return self.database_snapshots[resource_name].remove_tags(tag_keys)
|
return self.database_snapshots[resource_name].remove_tags(tag_keys)
|
||||||
|
elif resource_type == "cluster":
|
||||||
|
if resource_name in self.clusters:
|
||||||
|
return self.clusters[resource_name].remove_tags(tag_keys)
|
||||||
elif resource_type == "cluster-snapshot": # DB Cluster Snapshot
|
elif resource_type == "cluster-snapshot": # DB Cluster Snapshot
|
||||||
if resource_name in self.cluster_snapshots:
|
if resource_name in self.cluster_snapshots:
|
||||||
return self.cluster_snapshots[resource_name].remove_tags(tag_keys)
|
return self.cluster_snapshots[resource_name].remove_tags(tag_keys)
|
||||||
@ -1999,8 +2000,8 @@ class RDSBackend(BaseBackend):
|
|||||||
def add_tags_to_resource(self, arn, tags):
|
def add_tags_to_resource(self, arn, tags):
|
||||||
if self.arn_regex.match(arn):
|
if self.arn_regex.match(arn):
|
||||||
arn_breakdown = arn.split(":")
|
arn_breakdown = arn.split(":")
|
||||||
resource_type = arn_breakdown[len(arn_breakdown) - 2]
|
resource_type = arn_breakdown[-2]
|
||||||
resource_name = arn_breakdown[len(arn_breakdown) - 1]
|
resource_name = arn_breakdown[-1]
|
||||||
if resource_type == "db": # Database
|
if resource_type == "db": # Database
|
||||||
if resource_name in self.databases:
|
if resource_name in self.databases:
|
||||||
return self.databases[resource_name].add_tags(tags)
|
return self.databases[resource_name].add_tags(tags)
|
||||||
@ -2021,6 +2022,9 @@ class RDSBackend(BaseBackend):
|
|||||||
elif resource_type == "snapshot": # DB Snapshot
|
elif resource_type == "snapshot": # DB Snapshot
|
||||||
if resource_name in self.database_snapshots:
|
if resource_name in self.database_snapshots:
|
||||||
return self.database_snapshots[resource_name].add_tags(tags)
|
return self.database_snapshots[resource_name].add_tags(tags)
|
||||||
|
elif resource_type == "cluster":
|
||||||
|
if resource_name in self.clusters:
|
||||||
|
return self.clusters[resource_name].add_tags(tags)
|
||||||
elif resource_type == "cluster-snapshot": # DB Cluster Snapshot
|
elif resource_type == "cluster-snapshot": # DB Cluster Snapshot
|
||||||
if resource_name in self.cluster_snapshots:
|
if resource_name in self.cluster_snapshots:
|
||||||
return self.cluster_snapshots[resource_name].add_tags(tags)
|
return self.cluster_snapshots[resource_name].add_tags(tags)
|
||||||
@ -2113,95 +2117,6 @@ class OptionGroup(object):
|
|||||||
self.tags = [tag_set for tag_set in self.tags if tag_set["Key"] not in tag_keys]
|
self.tags = [tag_set for tag_set in self.tags if tag_set["Key"] not in tag_keys]
|
||||||
|
|
||||||
|
|
||||||
class OptionGroupOption(object):
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
self.default_port = kwargs.get("default_port")
|
|
||||||
self.description = kwargs.get("description")
|
|
||||||
self.engine_name = kwargs.get("engine_name")
|
|
||||||
self.major_engine_version = kwargs.get("major_engine_version")
|
|
||||||
self.name = kwargs.get("name")
|
|
||||||
self.option_group_option_settings = self._make_option_group_option_settings(
|
|
||||||
kwargs.get("option_group_option_settings", [])
|
|
||||||
)
|
|
||||||
self.options_depended_on = kwargs.get("options_depended_on", [])
|
|
||||||
self.permanent = kwargs.get("permanent")
|
|
||||||
self.persistent = kwargs.get("persistent")
|
|
||||||
self.port_required = kwargs.get("port_required")
|
|
||||||
|
|
||||||
def _make_option_group_option_settings(self, option_group_option_settings_kwargs):
|
|
||||||
return [
|
|
||||||
OptionGroupOptionSetting(**setting_kwargs)
|
|
||||||
for setting_kwargs in option_group_option_settings_kwargs
|
|
||||||
]
|
|
||||||
|
|
||||||
def to_json(self):
|
|
||||||
template = Template(
|
|
||||||
"""{ "MinimumRequiredMinorEngineVersion":
|
|
||||||
"2789.0.v1",
|
|
||||||
"OptionsDependedOn": [],
|
|
||||||
"MajorEngineVersion": "10.50",
|
|
||||||
"Persistent": false,
|
|
||||||
"DefaultPort": null,
|
|
||||||
"Permanent": false,
|
|
||||||
"OptionGroupOptionSettings": [],
|
|
||||||
"EngineName": "sqlserver-se",
|
|
||||||
"Name": "Mirroring",
|
|
||||||
"PortRequired": false,
|
|
||||||
"Description": "SQLServer Database Mirroring"
|
|
||||||
}"""
|
|
||||||
)
|
|
||||||
return template.render(option_group=self)
|
|
||||||
|
|
||||||
def to_xml(self):
|
|
||||||
template = Template(
|
|
||||||
"""<OptionGroupOption>
|
|
||||||
<MajorEngineVersion>{{ option_group.major_engine_version }}</MajorEngineVersion>
|
|
||||||
<DefaultPort>{{ option_group.default_port }}</DefaultPort>
|
|
||||||
<PortRequired>{{ option_group.port_required }}</PortRequired>
|
|
||||||
<Persistent>{{ option_group.persistent }}</Persistent>
|
|
||||||
<OptionsDependedOn>
|
|
||||||
{%- for option_name in option_group.options_depended_on -%}
|
|
||||||
<OptionName>{{ option_name }}</OptionName>
|
|
||||||
{%- endfor -%}
|
|
||||||
</OptionsDependedOn>
|
|
||||||
<Permanent>{{ option_group.permanent }}</Permanent>
|
|
||||||
<Description>{{ option_group.description }}</Description>
|
|
||||||
<Name>{{ option_group.name }}</Name>
|
|
||||||
<OptionGroupOptionSettings>
|
|
||||||
{%- for setting in option_group.option_group_option_settings -%}
|
|
||||||
{{ setting.to_xml() }}
|
|
||||||
{%- endfor -%}
|
|
||||||
</OptionGroupOptionSettings>
|
|
||||||
<EngineName>{{ option_group.engine_name }}</EngineName>
|
|
||||||
<MinimumRequiredMinorEngineVersion>{{ option_group.minimum_required_minor_engine_version }}</MinimumRequiredMinorEngineVersion>
|
|
||||||
</OptionGroupOption>"""
|
|
||||||
)
|
|
||||||
return template.render(option_group=self)
|
|
||||||
|
|
||||||
|
|
||||||
class OptionGroupOptionSetting(object):
|
|
||||||
def __init__(self, *kwargs):
|
|
||||||
self.allowed_values = kwargs.get("allowed_values")
|
|
||||||
self.apply_type = kwargs.get("apply_type")
|
|
||||||
self.default_value = kwargs.get("default_value")
|
|
||||||
self.is_modifiable = kwargs.get("is_modifiable")
|
|
||||||
self.setting_description = kwargs.get("setting_description")
|
|
||||||
self.setting_name = kwargs.get("setting_name")
|
|
||||||
|
|
||||||
def to_xml(self):
|
|
||||||
template = Template(
|
|
||||||
"""<OptionGroupOptionSetting>
|
|
||||||
<AllowedValues>{{ option_group_option_setting.allowed_values }}</AllowedValues>
|
|
||||||
<ApplyType>{{ option_group_option_setting.apply_type }}</ApplyType>
|
|
||||||
<DefaultValue>{{ option_group_option_setting.default_value }}</DefaultValue>
|
|
||||||
<IsModifiable>{{ option_group_option_setting.is_modifiable }}</IsModifiable>
|
|
||||||
<SettingDescription>{{ option_group_option_setting.setting_description }}</SettingDescription>
|
|
||||||
<SettingName>{{ option_group_option_setting.setting_name }}</SettingName>
|
|
||||||
</OptionGroupOptionSetting>"""
|
|
||||||
)
|
|
||||||
return template.render(option_group_option_setting=self)
|
|
||||||
|
|
||||||
|
|
||||||
def make_rds_arn(region, name):
|
def make_rds_arn(region, name):
|
||||||
return "arn:aws:rds:{0}:{1}:pg:{2}".format(region, ACCOUNT_ID, name)
|
return "arn:aws:rds:{0}:{1}:pg:{2}".format(region, ACCOUNT_ID, name)
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ class RDSResponse(BaseResponse):
|
|||||||
|
|
||||||
def create_db_instance(self):
|
def create_db_instance(self):
|
||||||
db_kwargs = self._get_db_kwargs()
|
db_kwargs = self._get_db_kwargs()
|
||||||
database = self.backend.create_database(db_kwargs)
|
database = self.backend.create_db_instance(db_kwargs)
|
||||||
template = self.response_template(CREATE_DATABASE_TEMPLATE)
|
template = self.response_template(CREATE_DATABASE_TEMPLATE)
|
||||||
return template.render(database=database)
|
return template.render(database=database)
|
||||||
|
|
||||||
@ -198,14 +198,14 @@ class RDSResponse(BaseResponse):
|
|||||||
new_db_instance_identifier = self._get_param("NewDBInstanceIdentifier")
|
new_db_instance_identifier = self._get_param("NewDBInstanceIdentifier")
|
||||||
if new_db_instance_identifier:
|
if new_db_instance_identifier:
|
||||||
db_kwargs["new_db_instance_identifier"] = new_db_instance_identifier
|
db_kwargs["new_db_instance_identifier"] = new_db_instance_identifier
|
||||||
database = self.backend.modify_database(db_instance_identifier, db_kwargs)
|
database = self.backend.modify_db_instance(db_instance_identifier, db_kwargs)
|
||||||
template = self.response_template(MODIFY_DATABASE_TEMPLATE)
|
template = self.response_template(MODIFY_DATABASE_TEMPLATE)
|
||||||
return template.render(database=database)
|
return template.render(database=database)
|
||||||
|
|
||||||
def delete_db_instance(self):
|
def delete_db_instance(self):
|
||||||
db_instance_identifier = self._get_param("DBInstanceIdentifier")
|
db_instance_identifier = self._get_param("DBInstanceIdentifier")
|
||||||
db_snapshot_name = self._get_param("FinalDBSnapshotIdentifier")
|
db_snapshot_name = self._get_param("FinalDBSnapshotIdentifier")
|
||||||
database = self.backend.delete_database(
|
database = self.backend.delete_db_instance(
|
||||||
db_instance_identifier, db_snapshot_name
|
db_instance_identifier, db_snapshot_name
|
||||||
)
|
)
|
||||||
template = self.response_template(DELETE_DATABASE_TEMPLATE)
|
template = self.response_template(DELETE_DATABASE_TEMPLATE)
|
||||||
@ -221,7 +221,7 @@ class RDSResponse(BaseResponse):
|
|||||||
db_instance_identifier = self._get_param("DBInstanceIdentifier")
|
db_instance_identifier = self._get_param("DBInstanceIdentifier")
|
||||||
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
|
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
|
||||||
tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value"))
|
tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value"))
|
||||||
snapshot = self.backend.create_database_snapshot(
|
snapshot = self.backend.create_db_snapshot(
|
||||||
db_instance_identifier, db_snapshot_identifier, tags
|
db_instance_identifier, db_snapshot_identifier, tags
|
||||||
)
|
)
|
||||||
template = self.response_template(CREATE_SNAPSHOT_TEMPLATE)
|
template = self.response_template(CREATE_SNAPSHOT_TEMPLATE)
|
||||||
@ -250,7 +250,7 @@ class RDSResponse(BaseResponse):
|
|||||||
|
|
||||||
def delete_db_snapshot(self):
|
def delete_db_snapshot(self):
|
||||||
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
|
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
|
||||||
snapshot = self.backend.delete_database_snapshot(db_snapshot_identifier)
|
snapshot = self.backend.delete_db_snapshot(db_snapshot_identifier)
|
||||||
template = self.response_template(DELETE_SNAPSHOT_TEMPLATE)
|
template = self.response_template(DELETE_SNAPSHOT_TEMPLATE)
|
||||||
return template.render(snapshot=snapshot)
|
return template.render(snapshot=snapshot)
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ class RDSResponse(BaseResponse):
|
|||||||
def stop_db_instance(self):
|
def stop_db_instance(self):
|
||||||
db_instance_identifier = self._get_param("DBInstanceIdentifier")
|
db_instance_identifier = self._get_param("DBInstanceIdentifier")
|
||||||
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
|
db_snapshot_identifier = self._get_param("DBSnapshotIdentifier")
|
||||||
database = self.backend.stop_database(
|
database = self.backend.stop_db_instance(
|
||||||
db_instance_identifier, db_snapshot_identifier
|
db_instance_identifier, db_snapshot_identifier
|
||||||
)
|
)
|
||||||
template = self.response_template(STOP_DATABASE_TEMPLATE)
|
template = self.response_template(STOP_DATABASE_TEMPLATE)
|
||||||
@ -294,7 +294,7 @@ class RDSResponse(BaseResponse):
|
|||||||
|
|
||||||
def start_db_instance(self):
|
def start_db_instance(self):
|
||||||
db_instance_identifier = self._get_param("DBInstanceIdentifier")
|
db_instance_identifier = self._get_param("DBInstanceIdentifier")
|
||||||
database = self.backend.start_database(db_instance_identifier)
|
database = self.backend.start_db_instance(db_instance_identifier)
|
||||||
template = self.response_template(START_DATABASE_TEMPLATE)
|
template = self.response_template(START_DATABASE_TEMPLATE)
|
||||||
return template.render(database=database)
|
return template.render(database=database)
|
||||||
|
|
||||||
@ -302,7 +302,7 @@ class RDSResponse(BaseResponse):
|
|||||||
group_name = self._get_param("DBSecurityGroupName")
|
group_name = self._get_param("DBSecurityGroupName")
|
||||||
description = self._get_param("DBSecurityGroupDescription")
|
description = self._get_param("DBSecurityGroupDescription")
|
||||||
tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value"))
|
tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value"))
|
||||||
security_group = self.backend.create_security_group(
|
security_group = self.backend.create_db_security_group(
|
||||||
group_name, description, tags
|
group_name, description, tags
|
||||||
)
|
)
|
||||||
template = self.response_template(CREATE_SECURITY_GROUP_TEMPLATE)
|
template = self.response_template(CREATE_SECURITY_GROUP_TEMPLATE)
|
||||||
|
@ -68,6 +68,10 @@ def test_create_dbinstance_via_cf():
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Outputs": {
|
||||||
|
"db_address": {"Value": {"Fn::GetAtt": ["db", "Endpoint.Address"]}},
|
||||||
|
"db_port": {"Value": {"Fn::GetAtt": ["db", "Endpoint.Port"]}},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
template_json = json.dumps(template)
|
template_json = json.dumps(template)
|
||||||
cf.create_stack(StackName="test_stack", TemplateBody=template_json)
|
cf.create_stack(StackName="test_stack", TemplateBody=template_json)
|
||||||
@ -85,6 +89,13 @@ def test_create_dbinstance_via_cf():
|
|||||||
created["Engine"].should.equal("mysql")
|
created["Engine"].should.equal("mysql")
|
||||||
created["DBInstanceStatus"].should.equal("available")
|
created["DBInstanceStatus"].should.equal("available")
|
||||||
|
|
||||||
|
# Verify the stack outputs are correct
|
||||||
|
o = _get_stack_outputs(cf, stack_name="test_stack")
|
||||||
|
o.should.have.key("db_address").equals(
|
||||||
|
f"{db_instance_identifier}.aaaaaaaaaa.us-west-2.rds.amazonaws.com"
|
||||||
|
)
|
||||||
|
o.should.have.key("db_port").equals("3307")
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
@mock_rds
|
@mock_rds
|
||||||
@ -248,3 +259,49 @@ def test_rds_mysql_with_read_replica_in_vpc():
|
|||||||
"DBSubnetGroups"
|
"DBSubnetGroups"
|
||||||
][0]
|
][0]
|
||||||
subnet_group.should.have.key("DBSubnetGroupDescription").equal("my db subnet group")
|
subnet_group.should.have.key("DBSubnetGroupDescription").equal("my db subnet group")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
@mock_rds
|
||||||
|
@mock_cloudformation
|
||||||
|
def test_delete_dbinstance_via_cf():
|
||||||
|
vpc_conn = boto3.client("ec2", "us-west-2")
|
||||||
|
vpc = vpc_conn.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
||||||
|
vpc_conn.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.1.0/24")
|
||||||
|
|
||||||
|
rds = boto3.client("rds", region_name="us-west-2")
|
||||||
|
cf = boto3.client("cloudformation", region_name="us-west-2")
|
||||||
|
|
||||||
|
template = {
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Resources": {
|
||||||
|
"db": {
|
||||||
|
"Type": "AWS::RDS::DBInstance",
|
||||||
|
"Properties": {
|
||||||
|
"Port": 3307,
|
||||||
|
"Engine": "mysql",
|
||||||
|
# Required - throws exception when describing an instance without tags
|
||||||
|
"Tags": [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
template_json = json.dumps(template)
|
||||||
|
cf.create_stack(StackName="test_stack", TemplateBody=template_json)
|
||||||
|
|
||||||
|
resp = rds.describe_db_instances()["DBInstances"]
|
||||||
|
resp.should.have.length_of(1)
|
||||||
|
|
||||||
|
cf.delete_stack(StackName="test_stack")
|
||||||
|
|
||||||
|
resp = rds.describe_db_instances()["DBInstances"]
|
||||||
|
resp.should.have.length_of(0)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_stack_outputs(cf_client, stack_name):
|
||||||
|
"""Returns the outputs for the first entry in describe_stacks."""
|
||||||
|
stack_description = cf_client.describe_stacks(StackName=stack_name)["Stacks"][0]
|
||||||
|
return {
|
||||||
|
output["OutputKey"]: output["OutputValue"]
|
||||||
|
for output in stack_description["Outputs"]
|
||||||
|
}
|
||||||
|
@ -620,3 +620,64 @@ def test_restore_db_cluster_from_snapshot_and_override_params():
|
|||||||
new_cluster["DBClusterParameterGroup"].should.equal("default.aurora8.0")
|
new_cluster["DBClusterParameterGroup"].should.equal("default.aurora8.0")
|
||||||
new_cluster["DBClusterInstanceClass"].should.equal("db.r6g.xlarge")
|
new_cluster["DBClusterInstanceClass"].should.equal("db.r6g.xlarge")
|
||||||
new_cluster["Port"].should.equal(10000)
|
new_cluster["Port"].should.equal(10000)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_rds
|
||||||
|
def test_add_tags_to_cluster():
|
||||||
|
conn = boto3.client("rds", region_name="us-west-2")
|
||||||
|
resp = conn.create_db_cluster(
|
||||||
|
DBClusterIdentifier="db-primary-1",
|
||||||
|
AllocatedStorage=10,
|
||||||
|
Engine="postgres",
|
||||||
|
DatabaseName="staging-postgres",
|
||||||
|
DBClusterInstanceClass="db.m1.small",
|
||||||
|
MasterUsername="root",
|
||||||
|
MasterUserPassword="hunter2000",
|
||||||
|
Port=1234,
|
||||||
|
Tags=[{"Key": "k1", "Value": "v1"}],
|
||||||
|
)
|
||||||
|
cluster_arn = resp["DBCluster"]["DBClusterArn"]
|
||||||
|
|
||||||
|
conn.add_tags_to_resource(
|
||||||
|
ResourceName=cluster_arn, Tags=[{"Key": "k2", "Value": "v2"}]
|
||||||
|
)
|
||||||
|
|
||||||
|
tags = conn.list_tags_for_resource(ResourceName=cluster_arn)["TagList"]
|
||||||
|
tags.should.equal([{"Key": "k1", "Value": "v1"}, {"Key": "k2", "Value": "v2"}])
|
||||||
|
|
||||||
|
conn.remove_tags_from_resource(ResourceName=cluster_arn, TagKeys=["k1"])
|
||||||
|
|
||||||
|
tags = conn.list_tags_for_resource(ResourceName=cluster_arn)["TagList"]
|
||||||
|
tags.should.equal([{"Key": "k2", "Value": "v2"}])
|
||||||
|
|
||||||
|
|
||||||
|
@mock_rds
|
||||||
|
def test_add_tags_to_cluster_snapshot():
|
||||||
|
conn = boto3.client("rds", region_name="us-west-2")
|
||||||
|
conn.create_db_cluster(
|
||||||
|
DBClusterIdentifier="db-primary-1",
|
||||||
|
AllocatedStorage=10,
|
||||||
|
Engine="postgres",
|
||||||
|
DatabaseName="staging-postgres",
|
||||||
|
DBClusterInstanceClass="db.m1.small",
|
||||||
|
MasterUsername="root",
|
||||||
|
MasterUserPassword="hunter2000",
|
||||||
|
Port=1234,
|
||||||
|
Tags=[{"Key": "k1", "Value": "v1"}],
|
||||||
|
)
|
||||||
|
resp = conn.create_db_cluster_snapshot(
|
||||||
|
DBClusterIdentifier="db-primary-1", DBClusterSnapshotIdentifier="snapshot-1"
|
||||||
|
)
|
||||||
|
snapshot_arn = resp["DBClusterSnapshot"]["DBClusterSnapshotArn"]
|
||||||
|
|
||||||
|
conn.add_tags_to_resource(
|
||||||
|
ResourceName=snapshot_arn, Tags=[{"Key": "k2", "Value": "v2"}]
|
||||||
|
)
|
||||||
|
|
||||||
|
tags = conn.list_tags_for_resource(ResourceName=snapshot_arn)["TagList"]
|
||||||
|
tags.should.equal([{"Key": "k1", "Value": "v1"}, {"Key": "k2", "Value": "v2"}])
|
||||||
|
|
||||||
|
conn.remove_tags_from_resource(ResourceName=snapshot_arn, TagKeys=["k1"])
|
||||||
|
|
||||||
|
tags = conn.list_tags_for_resource(ResourceName=snapshot_arn)["TagList"]
|
||||||
|
tags.should.equal([{"Key": "k2", "Value": "v2"}])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user