RDS: Snapshot attributes, cluster parameters (#7232)
This commit is contained in:
		
							parent
							
								
									5de7d4df38
								
							
						
					
					
						commit
						792956e959
					
				@ -229,6 +229,15 @@ class Cluster:
 | 
				
			|||||||
        self.replication_source_identifier = kwargs.get("replication_source_identifier")
 | 
					        self.replication_source_identifier = kwargs.get("replication_source_identifier")
 | 
				
			||||||
        self.read_replica_identifiers: List[str] = list()
 | 
					        self.read_replica_identifiers: List[str] = list()
 | 
				
			||||||
        self.is_writer: bool = False
 | 
					        self.is_writer: bool = False
 | 
				
			||||||
 | 
					        self.storage_encrypted = kwargs.get("storage_encrypted", False)
 | 
				
			||||||
 | 
					        if self.storage_encrypted:
 | 
				
			||||||
 | 
					            self.kms_key_id = kwargs.get("kms_key_id", "default_kms_key_id")
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.kms_key_id = kwargs.get("kms_key_id")
 | 
				
			||||||
 | 
					        if self.engine == "aurora-mysql" or self.engine == "aurora-postgresql":
 | 
				
			||||||
 | 
					            self.global_write_forwarding_requested = kwargs.get(
 | 
				
			||||||
 | 
					                "enable_global_write_forwarding"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_multi_az(self) -> bool:
 | 
					    def is_multi_az(self) -> bool:
 | 
				
			||||||
@ -361,7 +370,8 @@ class Cluster:
 | 
				
			|||||||
              {% endfor %}
 | 
					              {% endfor %}
 | 
				
			||||||
              </VpcSecurityGroups>
 | 
					              </VpcSecurityGroups>
 | 
				
			||||||
              <HostedZoneId>{{ cluster.hosted_zone_id }}</HostedZoneId>
 | 
					              <HostedZoneId>{{ cluster.hosted_zone_id }}</HostedZoneId>
 | 
				
			||||||
              <StorageEncrypted>false</StorageEncrypted>
 | 
					              <StorageEncrypted>{{ 'true' if cluster.storage_encrypted else 'false' }}</StorageEncrypted>
 | 
				
			||||||
 | 
					              <GlobalWriteForwardingRequested>{{ cluster.global_write_forwarding_requested }}</GlobalWriteForwardingRequested>
 | 
				
			||||||
              <DbClusterResourceId>{{ cluster.resource_id }}</DbClusterResourceId>
 | 
					              <DbClusterResourceId>{{ cluster.resource_id }}</DbClusterResourceId>
 | 
				
			||||||
              <DBClusterArn>{{ cluster.db_cluster_arn }}</DBClusterArn>
 | 
					              <DBClusterArn>{{ cluster.db_cluster_arn }}</DBClusterArn>
 | 
				
			||||||
              <AssociatedRoles></AssociatedRoles>
 | 
					              <AssociatedRoles></AssociatedRoles>
 | 
				
			||||||
@ -485,6 +495,7 @@ class ClusterSnapshot(BaseModel):
 | 
				
			|||||||
        self.tags = tags
 | 
					        self.tags = tags
 | 
				
			||||||
        self.status = "available"
 | 
					        self.status = "available"
 | 
				
			||||||
        self.created_at = iso_8601_datetime_with_milliseconds()
 | 
					        self.created_at = iso_8601_datetime_with_milliseconds()
 | 
				
			||||||
 | 
					        self.attributes: List[Dict[str, Any]] = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def arn(self) -> str:
 | 
					    def arn(self) -> str:
 | 
				
			||||||
@ -1122,6 +1133,7 @@ class DatabaseSnapshot(BaseModel):
 | 
				
			|||||||
        self.tags = tags
 | 
					        self.tags = tags
 | 
				
			||||||
        self.status = "available"
 | 
					        self.status = "available"
 | 
				
			||||||
        self.created_at = iso_8601_datetime_with_milliseconds()
 | 
					        self.created_at = iso_8601_datetime_with_milliseconds()
 | 
				
			||||||
 | 
					        self.attributes: List[Dict[str, Any]] = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def arn(self) -> str:
 | 
					    def arn(self) -> str:
 | 
				
			||||||
@ -2803,6 +2815,92 @@ class RDSBackend(BaseBackend):
 | 
				
			|||||||
            pass
 | 
					            pass
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def describe_db_snapshot_attributes(
 | 
				
			||||||
 | 
					        self, db_snapshot_identifier: str
 | 
				
			||||||
 | 
					    ) -> List[Dict[str, Any]]:
 | 
				
			||||||
 | 
					        snapshot = self.describe_db_snapshots(
 | 
				
			||||||
 | 
					            db_instance_identifier=None, db_snapshot_identifier=db_snapshot_identifier
 | 
				
			||||||
 | 
					        )[0]
 | 
				
			||||||
 | 
					        return snapshot.attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def modify_db_snapshot_attribute(
 | 
				
			||||||
 | 
					        self,
 | 
				
			||||||
 | 
					        db_snapshot_identifier: str,
 | 
				
			||||||
 | 
					        attribute_name: str,
 | 
				
			||||||
 | 
					        values_to_add: Optional[Dict[str, Dict[str, str]]] = None,
 | 
				
			||||||
 | 
					        values_to_remove: Optional[Dict[str, Dict[str, str]]] = None,
 | 
				
			||||||
 | 
					    ) -> List[Dict[str, Any]]:
 | 
				
			||||||
 | 
					        snapshot = self.describe_db_snapshots(
 | 
				
			||||||
 | 
					            db_instance_identifier=None, db_snapshot_identifier=db_snapshot_identifier
 | 
				
			||||||
 | 
					        )[0]
 | 
				
			||||||
 | 
					        attribute_present = False
 | 
				
			||||||
 | 
					        for attribute in snapshot.attributes:
 | 
				
			||||||
 | 
					            if attribute["AttributeName"] == attribute_name:
 | 
				
			||||||
 | 
					                attribute_present = True
 | 
				
			||||||
 | 
					                if values_to_add:
 | 
				
			||||||
 | 
					                    attribute["AttributeValues"] = (
 | 
				
			||||||
 | 
					                        values_to_add["AttributeValue"].values()
 | 
				
			||||||
 | 
					                        + attribute["AttributeValues"]
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                if values_to_remove:
 | 
				
			||||||
 | 
					                    attribute["AttributeValues"] = [
 | 
				
			||||||
 | 
					                        i
 | 
				
			||||||
 | 
					                        for i in attribute["AttributeValues"]
 | 
				
			||||||
 | 
					                        if i not in values_to_remove["AttributeValue"].values()
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					        if not attribute_present and values_to_add:
 | 
				
			||||||
 | 
					            snapshot.attributes.append(
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "AttributeName": attribute_name,
 | 
				
			||||||
 | 
					                    "AttributeValues": values_to_add["AttributeValue"].values(),
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        return snapshot.attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def describe_db_cluster_snapshot_attributes(
 | 
				
			||||||
 | 
					        self, db_cluster_snapshot_identifier: str
 | 
				
			||||||
 | 
					    ) -> List[Dict[str, Any]]:
 | 
				
			||||||
 | 
					        snapshot = self.describe_db_cluster_snapshots(
 | 
				
			||||||
 | 
					            db_cluster_identifier=None,
 | 
				
			||||||
 | 
					            db_snapshot_identifier=db_cluster_snapshot_identifier,
 | 
				
			||||||
 | 
					        )[0]
 | 
				
			||||||
 | 
					        return snapshot.attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def modify_db_cluster_snapshot_attribute(
 | 
				
			||||||
 | 
					        self,
 | 
				
			||||||
 | 
					        db_cluster_snapshot_identifier: str,
 | 
				
			||||||
 | 
					        attribute_name: str,
 | 
				
			||||||
 | 
					        values_to_add: Optional[Dict[str, Dict[str, str]]] = None,
 | 
				
			||||||
 | 
					        values_to_remove: Optional[Dict[str, Dict[str, str]]] = None,
 | 
				
			||||||
 | 
					    ) -> List[Dict[str, Any]]:
 | 
				
			||||||
 | 
					        snapshot = self.describe_db_cluster_snapshots(
 | 
				
			||||||
 | 
					            db_cluster_identifier=None,
 | 
				
			||||||
 | 
					            db_snapshot_identifier=db_cluster_snapshot_identifier,
 | 
				
			||||||
 | 
					        )[0]
 | 
				
			||||||
 | 
					        attribute_present = False
 | 
				
			||||||
 | 
					        for attribute in snapshot.attributes:
 | 
				
			||||||
 | 
					            if attribute["AttributeName"] == attribute_name:
 | 
				
			||||||
 | 
					                attribute_present = True
 | 
				
			||||||
 | 
					                if values_to_add:
 | 
				
			||||||
 | 
					                    attribute["AttributeValues"] = (
 | 
				
			||||||
 | 
					                        values_to_add["AttributeValue"].values()
 | 
				
			||||||
 | 
					                        + attribute["AttributeValues"]
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                if values_to_remove:
 | 
				
			||||||
 | 
					                    attribute["AttributeValues"] = [
 | 
				
			||||||
 | 
					                        i
 | 
				
			||||||
 | 
					                        for i in attribute["AttributeValues"]
 | 
				
			||||||
 | 
					                        if i not in values_to_remove["AttributeValue"].values()
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					        if not attribute_present and values_to_add:
 | 
				
			||||||
 | 
					            snapshot.attributes.append(
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "AttributeName": attribute_name,
 | 
				
			||||||
 | 
					                    "AttributeValues": values_to_add["AttributeValue"].values(),
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        return snapshot.attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OptionGroup:
 | 
					class OptionGroup:
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
 | 
				
			|||||||
@ -195,6 +195,10 @@ class RDSResponse(BaseResponse):
 | 
				
			|||||||
            "allocated_storage": self._get_param("AllocatedStorage"),
 | 
					            "allocated_storage": self._get_param("AllocatedStorage"),
 | 
				
			||||||
            "global_cluster_identifier": self._get_param("GlobalClusterIdentifier"),
 | 
					            "global_cluster_identifier": self._get_param("GlobalClusterIdentifier"),
 | 
				
			||||||
            "iops": self._get_param("Iops"),
 | 
					            "iops": self._get_param("Iops"),
 | 
				
			||||||
 | 
					            "storage_encrypted": self._get_param("StorageEncrypted"),
 | 
				
			||||||
 | 
					            "enable_global_write_forwarding": self._get_param(
 | 
				
			||||||
 | 
					                "EnableGlobalWriteForwarding"
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
            "storage_type": self._get_param("StorageType"),
 | 
					            "storage_type": self._get_param("StorageType"),
 | 
				
			||||||
            "kms_key_id": self._get_param("KmsKeyId"),
 | 
					            "kms_key_id": self._get_param("KmsKeyId"),
 | 
				
			||||||
            "master_username": self._get_param("MasterUsername"),
 | 
					            "master_username": self._get_param("MasterUsername"),
 | 
				
			||||||
@ -818,6 +822,66 @@ class RDSResponse(BaseResponse):
 | 
				
			|||||||
        template = self.response_template(PROMOTE_READ_REPLICA_DB_CLUSTER_TEMPLATE)
 | 
					        template = self.response_template(PROMOTE_READ_REPLICA_DB_CLUSTER_TEMPLATE)
 | 
				
			||||||
        return template.render(cluster=cluster)
 | 
					        return template.render(cluster=cluster)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def describe_db_snapshot_attributes(self) -> str:
 | 
				
			||||||
 | 
					        params = self._get_params()
 | 
				
			||||||
 | 
					        db_snapshot_identifier = params["DBSnapshotIdentifier"]
 | 
				
			||||||
 | 
					        db_snapshot_attributes_result = self.backend.describe_db_snapshot_attributes(
 | 
				
			||||||
 | 
					            db_snapshot_identifier=db_snapshot_identifier,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        template = self.response_template(DESCRIBE_DB_SNAPSHOT_ATTRIBUTES_TEMPLATE)
 | 
				
			||||||
 | 
					        return template.render(
 | 
				
			||||||
 | 
					            db_snapshot_attributes_result=db_snapshot_attributes_result,
 | 
				
			||||||
 | 
					            db_snapshot_identifier=db_snapshot_identifier,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def modify_db_snapshot_attribute(self) -> str:
 | 
				
			||||||
 | 
					        params = self._get_params()
 | 
				
			||||||
 | 
					        db_snapshot_identifier = params["DBSnapshotIdentifier"]
 | 
				
			||||||
 | 
					        db_snapshot_attributes_result = self.backend.modify_db_snapshot_attribute(
 | 
				
			||||||
 | 
					            db_snapshot_identifier=db_snapshot_identifier,
 | 
				
			||||||
 | 
					            attribute_name=params["AttributeName"],
 | 
				
			||||||
 | 
					            values_to_add=params.get("ValuesToAdd"),
 | 
				
			||||||
 | 
					            values_to_remove=params.get("ValuesToRemove"),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        template = self.response_template(MODIFY_DB_SNAPSHOT_ATTRIBUTE_TEMPLATE)
 | 
				
			||||||
 | 
					        return template.render(
 | 
				
			||||||
 | 
					            db_snapshot_attributes_result=db_snapshot_attributes_result,
 | 
				
			||||||
 | 
					            db_snapshot_identifier=db_snapshot_identifier,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def describe_db_cluster_snapshot_attributes(self) -> str:
 | 
				
			||||||
 | 
					        params = self._get_params()
 | 
				
			||||||
 | 
					        db_cluster_snapshot_identifier = params["DBClusterSnapshotIdentifier"]
 | 
				
			||||||
 | 
					        db_cluster_snapshot_attributes_result = (
 | 
				
			||||||
 | 
					            self.backend.describe_db_cluster_snapshot_attributes(
 | 
				
			||||||
 | 
					                db_cluster_snapshot_identifier=db_cluster_snapshot_identifier,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        template = self.response_template(
 | 
				
			||||||
 | 
					            DESCRIBE_DB_CLUSTER_SNAPSHOT_ATTRIBUTES_TEMPLATE
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return template.render(
 | 
				
			||||||
 | 
					            db_cluster_snapshot_attributes_result=db_cluster_snapshot_attributes_result,
 | 
				
			||||||
 | 
					            db_cluster_snapshot_identifier=db_cluster_snapshot_identifier,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def modify_db_cluster_snapshot_attribute(self) -> str:
 | 
				
			||||||
 | 
					        params = self._get_params()
 | 
				
			||||||
 | 
					        db_cluster_snapshot_identifier = params["DBClusterSnapshotIdentifier"]
 | 
				
			||||||
 | 
					        db_cluster_snapshot_attributes_result = (
 | 
				
			||||||
 | 
					            self.backend.modify_db_cluster_snapshot_attribute(
 | 
				
			||||||
 | 
					                db_cluster_snapshot_identifier=db_cluster_snapshot_identifier,
 | 
				
			||||||
 | 
					                attribute_name=params["AttributeName"],
 | 
				
			||||||
 | 
					                values_to_add=params.get("ValuesToAdd"),
 | 
				
			||||||
 | 
					                values_to_remove=params.get("ValuesToRemove"),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        template = self.response_template(MODIFY_DB_CLUSTER_SNAPSHOT_ATTRIBUTE_TEMPLATE)
 | 
				
			||||||
 | 
					        return template.render(
 | 
				
			||||||
 | 
					            db_cluster_snapshot_attributes_result=db_cluster_snapshot_attributes_result,
 | 
				
			||||||
 | 
					            db_cluster_snapshot_identifier=db_cluster_snapshot_identifier,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CREATE_DATABASE_TEMPLATE = """<CreateDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
 | 
					CREATE_DATABASE_TEMPLATE = """<CreateDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
 | 
				
			||||||
  <CreateDBInstanceResult>
 | 
					  <CreateDBInstanceResult>
 | 
				
			||||||
@ -1474,3 +1538,95 @@ PROMOTE_READ_REPLICA_DB_CLUSTER_TEMPLATE = """<PromoteReadReplicaDBClusterRespon
 | 
				
			|||||||
    <RequestId>7369556f-b70d-11c3-faca-6ba18376ea1b</RequestId>
 | 
					    <RequestId>7369556f-b70d-11c3-faca-6ba18376ea1b</RequestId>
 | 
				
			||||||
  </ResponseMetadata>
 | 
					  </ResponseMetadata>
 | 
				
			||||||
</PromoteReadReplicaDBClusterResponse>"""
 | 
					</PromoteReadReplicaDBClusterResponse>"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DESCRIBE_DB_SNAPSHOT_ATTRIBUTES_TEMPLATE = """<DescribeDBSnapshotAttributesResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
 | 
				
			||||||
 | 
					  <DescribeDBSnapshotAttributesResult>
 | 
				
			||||||
 | 
					    <DBSnapshotAttributesResult>
 | 
				
			||||||
 | 
					      <DBSnapshotAttributes>
 | 
				
			||||||
 | 
					        {%- for attribute in db_snapshot_attributes_result -%}
 | 
				
			||||||
 | 
					          <DBSnapshotAttribute>
 | 
				
			||||||
 | 
					            <AttributeName>{{ attribute["AttributeName"] }}</AttributeName>
 | 
				
			||||||
 | 
					            <AttributeValues>
 | 
				
			||||||
 | 
					              {%- for value in attribute["AttributeValues"] -%}
 | 
				
			||||||
 | 
					                <AttributeValue>{{ value }}</AttributeValue>
 | 
				
			||||||
 | 
					              {%- endfor -%}
 | 
				
			||||||
 | 
					            </AttributeValues>
 | 
				
			||||||
 | 
					          </DBSnapshotAttribute>
 | 
				
			||||||
 | 
					        {%- endfor -%}
 | 
				
			||||||
 | 
					      </DBSnapshotAttributes>
 | 
				
			||||||
 | 
					      <DBSnapshotIdentifier>{{ db_snapshot_identifier }}</DBSnapshotIdentifier>
 | 
				
			||||||
 | 
					    </DBSnapshotAttributesResult>
 | 
				
			||||||
 | 
					  </DescribeDBSnapshotAttributesResult>
 | 
				
			||||||
 | 
					  <ResponseMetadata>
 | 
				
			||||||
 | 
					    <RequestId>1549581b-12b7-11e3-895e-1334a</RequestId>
 | 
				
			||||||
 | 
					  </ResponseMetadata>
 | 
				
			||||||
 | 
					</DescribeDBSnapshotAttributesResponse>"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODIFY_DB_SNAPSHOT_ATTRIBUTE_TEMPLATE = """<ModifyDBSnapshotAttributeResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
 | 
				
			||||||
 | 
					  <ModifyDBSnapshotAttributeResult>
 | 
				
			||||||
 | 
					    <DBSnapshotAttributesResult>
 | 
				
			||||||
 | 
					      <DBSnapshotAttributes>
 | 
				
			||||||
 | 
					        {%- for attribute in db_snapshot_attributes_result -%}
 | 
				
			||||||
 | 
					          <DBSnapshotAttribute>
 | 
				
			||||||
 | 
					            <AttributeName>{{ attribute["AttributeName"] }}</AttributeName>
 | 
				
			||||||
 | 
					            <AttributeValues>
 | 
				
			||||||
 | 
					              {%- for value in attribute["AttributeValues"] -%}
 | 
				
			||||||
 | 
					                <AttributeValue>{{ value }}</AttributeValue>
 | 
				
			||||||
 | 
					              {%- endfor -%}
 | 
				
			||||||
 | 
					            </AttributeValues>
 | 
				
			||||||
 | 
					          </DBSnapshotAttribute>
 | 
				
			||||||
 | 
					        {%- endfor -%}
 | 
				
			||||||
 | 
					      </DBSnapshotAttributes>
 | 
				
			||||||
 | 
					      <DBSnapshotIdentifier>{{ db_snapshot_identifier }}</DBSnapshotIdentifier>
 | 
				
			||||||
 | 
					    </DBSnapshotAttributesResult>
 | 
				
			||||||
 | 
					  </ModifyDBSnapshotAttributeResult>
 | 
				
			||||||
 | 
					  <ResponseMetadata>
 | 
				
			||||||
 | 
					    <RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>
 | 
				
			||||||
 | 
					  </ResponseMetadata>
 | 
				
			||||||
 | 
					</ModifyDBSnapshotAttributeResponse>"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODIFY_DB_CLUSTER_SNAPSHOT_ATTRIBUTE_TEMPLATE = """<ModifyDBClusterSnapshotAttributeResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
 | 
				
			||||||
 | 
					  <ModifyDBClusterSnapshotAttributeResult>
 | 
				
			||||||
 | 
					    <DBClusterSnapshotAttributesResult>
 | 
				
			||||||
 | 
					      <DBClusterSnapshotAttributes>
 | 
				
			||||||
 | 
					        {%- for attribute in db_cluster_snapshot_attributes_result -%}
 | 
				
			||||||
 | 
					          <DBClusterSnapshotAttribute>
 | 
				
			||||||
 | 
					            <AttributeName>{{ attribute["AttributeName"] }}</AttributeName>
 | 
				
			||||||
 | 
					            <AttributeValues>
 | 
				
			||||||
 | 
					              {%- for value in attribute["AttributeValues"] -%}
 | 
				
			||||||
 | 
					                <AttributeValue>{{ value }}</AttributeValue>
 | 
				
			||||||
 | 
					              {%- endfor -%}
 | 
				
			||||||
 | 
					            </AttributeValues>
 | 
				
			||||||
 | 
					          </DBClusterSnapshotAttribute>
 | 
				
			||||||
 | 
					        {%- endfor -%}
 | 
				
			||||||
 | 
					      </DBClusterSnapshotAttributes>
 | 
				
			||||||
 | 
					      <DBClusterSnapshotIdentifier>{{ db_cluster_snapshot_identifier }}</DBClusterSnapshotIdentifier>
 | 
				
			||||||
 | 
					    </DBClusterSnapshotAttributesResult>
 | 
				
			||||||
 | 
					  </ModifyDBClusterSnapshotAttributeResult>
 | 
				
			||||||
 | 
					  <ResponseMetadata>
 | 
				
			||||||
 | 
					    <RequestId>1549581b-12b7-11e3-895e-1334a</RequestId>
 | 
				
			||||||
 | 
					  </ResponseMetadata>
 | 
				
			||||||
 | 
					</ModifyDBClusterSnapshotAttributeResponse>"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DESCRIBE_DB_CLUSTER_SNAPSHOT_ATTRIBUTES_TEMPLATE = """<DescribeDBClusterSnapshotAttributesResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">
 | 
				
			||||||
 | 
					  <DescribeDBClusterSnapshotAttributesResult>
 | 
				
			||||||
 | 
					    <DBClusterSnapshotAttributesResult>
 | 
				
			||||||
 | 
					      <DBClusterSnapshotAttributes>
 | 
				
			||||||
 | 
					        {%- for attribute in db_cluster_snapshot_attributes_result -%}
 | 
				
			||||||
 | 
					          <DBClusterSnapshotAttribute>
 | 
				
			||||||
 | 
					            <AttributeName>{{ attribute["AttributeName"] }}</AttributeName>
 | 
				
			||||||
 | 
					            <AttributeValues>
 | 
				
			||||||
 | 
					              {%- for value in attribute["AttributeValues"] -%}
 | 
				
			||||||
 | 
					                <AttributeValue>{{ value }}</AttributeValue>
 | 
				
			||||||
 | 
					              {%- endfor -%}
 | 
				
			||||||
 | 
					            </AttributeValues>
 | 
				
			||||||
 | 
					          </DBClusterSnapshotAttribute> 
 | 
				
			||||||
 | 
					        {%- endfor -%}
 | 
				
			||||||
 | 
					      </DBClusterSnapshotAttributes>
 | 
				
			||||||
 | 
					      <DBClusterSnapshotIdentifier>{{ db_cluster_snapshot_identifier }}</DBClusterSnapshotIdentifier>
 | 
				
			||||||
 | 
					    </DBClusterSnapshotAttributesResult>
 | 
				
			||||||
 | 
					  </DescribeDBClusterSnapshotAttributesResult>
 | 
				
			||||||
 | 
					  <ResponseMetadata>
 | 
				
			||||||
 | 
					    <RequestId>1549581b-12b7-11e3-895e-1334a</RequestId>
 | 
				
			||||||
 | 
					  </ResponseMetadata>
 | 
				
			||||||
 | 
					</DescribeDBClusterSnapshotAttributesResponse>"""
 | 
				
			||||||
 | 
				
			|||||||
@ -2694,6 +2694,106 @@ def test_createdb_instance_engine_with_invalid_value():
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mock_rds
 | 
				
			||||||
 | 
					def test_describe_db_snapshot_attributes_default():
 | 
				
			||||||
 | 
					    client = boto3.client("rds", region_name="us-east-2")
 | 
				
			||||||
 | 
					    client.create_db_instance(
 | 
				
			||||||
 | 
					        DBInstanceIdentifier="db-primary-1",
 | 
				
			||||||
 | 
					        AllocatedStorage=10,
 | 
				
			||||||
 | 
					        Engine="postgres",
 | 
				
			||||||
 | 
					        DBName="staging-postgres",
 | 
				
			||||||
 | 
					        DBInstanceClass="db.m1.small",
 | 
				
			||||||
 | 
					        MasterUsername="root",
 | 
				
			||||||
 | 
					        MasterUserPassword="hunter2",
 | 
				
			||||||
 | 
					        Port=1234,
 | 
				
			||||||
 | 
					        DBSecurityGroups=["my_sg"],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    client.create_db_snapshot(
 | 
				
			||||||
 | 
					        DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-1"
 | 
				
			||||||
 | 
					    ).get("DBSnapshot")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resp = client.describe_db_snapshot_attributes(DBSnapshotIdentifier="snapshot-1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert resp["DBSnapshotAttributesResult"]["DBSnapshotIdentifier"] == "snapshot-1"
 | 
				
			||||||
 | 
					    assert resp["DBSnapshotAttributesResult"]["DBSnapshotAttributes"] == []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mock_rds
 | 
				
			||||||
 | 
					def test_describe_db_snapshot_attributes():
 | 
				
			||||||
 | 
					    client = boto3.client("rds", region_name="us-east-2")
 | 
				
			||||||
 | 
					    client.create_db_instance(
 | 
				
			||||||
 | 
					        DBInstanceIdentifier="db-primary-1",
 | 
				
			||||||
 | 
					        AllocatedStorage=10,
 | 
				
			||||||
 | 
					        Engine="postgres",
 | 
				
			||||||
 | 
					        DBName="staging-postgres",
 | 
				
			||||||
 | 
					        DBInstanceClass="db.m1.small",
 | 
				
			||||||
 | 
					        MasterUsername="root",
 | 
				
			||||||
 | 
					        MasterUserPassword="hunter2",
 | 
				
			||||||
 | 
					        Port=1234,
 | 
				
			||||||
 | 
					        DBSecurityGroups=["my_sg"],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    client.create_db_snapshot(
 | 
				
			||||||
 | 
					        DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-1"
 | 
				
			||||||
 | 
					    ).get("DBSnapshot")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resp = client.modify_db_snapshot_attribute(
 | 
				
			||||||
 | 
					        DBSnapshotIdentifier="snapshot-1",
 | 
				
			||||||
 | 
					        AttributeName="restore",
 | 
				
			||||||
 | 
					        ValuesToAdd=["Test", "Test2"],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resp = client.describe_db_snapshot_attributes(DBSnapshotIdentifier="snapshot-1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert (
 | 
				
			||||||
 | 
					        resp["DBSnapshotAttributesResult"]["DBSnapshotAttributes"][0]["AttributeName"]
 | 
				
			||||||
 | 
					        == "restore"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert resp["DBSnapshotAttributesResult"]["DBSnapshotAttributes"][0][
 | 
				
			||||||
 | 
					        "AttributeValues"
 | 
				
			||||||
 | 
					    ] == ["Test", "Test2"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mock_rds
 | 
				
			||||||
 | 
					def test_modify_db_snapshot_attribute():
 | 
				
			||||||
 | 
					    client = boto3.client("rds", region_name="us-east-2")
 | 
				
			||||||
 | 
					    client.create_db_instance(
 | 
				
			||||||
 | 
					        DBInstanceIdentifier="db-primary-1",
 | 
				
			||||||
 | 
					        AllocatedStorage=10,
 | 
				
			||||||
 | 
					        Engine="postgres",
 | 
				
			||||||
 | 
					        DBName="staging-postgres",
 | 
				
			||||||
 | 
					        DBInstanceClass="db.m1.small",
 | 
				
			||||||
 | 
					        MasterUsername="root",
 | 
				
			||||||
 | 
					        MasterUserPassword="hunter2",
 | 
				
			||||||
 | 
					        Port=1234,
 | 
				
			||||||
 | 
					        DBSecurityGroups=["my_sg"],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    client.create_db_snapshot(
 | 
				
			||||||
 | 
					        DBInstanceIdentifier="db-primary-1", DBSnapshotIdentifier="snapshot-1"
 | 
				
			||||||
 | 
					    ).get("DBSnapshot")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resp = client.modify_db_snapshot_attribute(
 | 
				
			||||||
 | 
					        DBSnapshotIdentifier="snapshot-1",
 | 
				
			||||||
 | 
					        AttributeName="restore",
 | 
				
			||||||
 | 
					        ValuesToAdd=["Test", "Test2"],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    resp = client.modify_db_snapshot_attribute(
 | 
				
			||||||
 | 
					        DBSnapshotIdentifier="snapshot-1",
 | 
				
			||||||
 | 
					        AttributeName="restore",
 | 
				
			||||||
 | 
					        ValuesToRemove=["Test"],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert (
 | 
				
			||||||
 | 
					        resp["DBSnapshotAttributesResult"]["DBSnapshotAttributes"][0]["AttributeName"]
 | 
				
			||||||
 | 
					        == "restore"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert resp["DBSnapshotAttributesResult"]["DBSnapshotAttributes"][0][
 | 
				
			||||||
 | 
					        "AttributeValues"
 | 
				
			||||||
 | 
					    ] == ["Test2"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def validation_helper(exc):
 | 
					def validation_helper(exc):
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    assert err["Code"] == "InvalidParameterValue"
 | 
					    assert err["Code"] == "InvalidParameterValue"
 | 
				
			||||||
 | 
				
			|||||||
@ -215,6 +215,8 @@ def test_create_db_cluster__verify_default_properties():
 | 
				
			|||||||
    assert cluster["TagList"] == []
 | 
					    assert cluster["TagList"] == []
 | 
				
			||||||
    assert "ClusterCreateTime" in cluster
 | 
					    assert "ClusterCreateTime" in cluster
 | 
				
			||||||
    assert cluster["EarliestRestorableTime"] >= cluster["ClusterCreateTime"]
 | 
					    assert cluster["EarliestRestorableTime"] >= cluster["ClusterCreateTime"]
 | 
				
			||||||
 | 
					    assert cluster["StorageEncrypted"] is False
 | 
				
			||||||
 | 
					    assert cluster["GlobalWriteForwardingRequested"] is False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_rds
 | 
					@mock_rds
 | 
				
			||||||
@ -236,6 +238,8 @@ def test_create_db_cluster_additional_parameters():
 | 
				
			|||||||
        KmsKeyId="some:kms:arn",
 | 
					        KmsKeyId="some:kms:arn",
 | 
				
			||||||
        NetworkType="IPV4",
 | 
					        NetworkType="IPV4",
 | 
				
			||||||
        DBSubnetGroupName="subnetgroupname",
 | 
					        DBSubnetGroupName="subnetgroupname",
 | 
				
			||||||
 | 
					        StorageEncrypted=True,
 | 
				
			||||||
 | 
					        EnableGlobalWriteForwarding=True,
 | 
				
			||||||
        ScalingConfiguration={
 | 
					        ScalingConfiguration={
 | 
				
			||||||
            "MinCapacity": 5,
 | 
					            "MinCapacity": 5,
 | 
				
			||||||
            "AutoPause": True,
 | 
					            "AutoPause": True,
 | 
				
			||||||
@ -260,6 +264,8 @@ def test_create_db_cluster_additional_parameters():
 | 
				
			|||||||
    assert cluster["KmsKeyId"] == "some:kms:arn"
 | 
					    assert cluster["KmsKeyId"] == "some:kms:arn"
 | 
				
			||||||
    assert cluster["NetworkType"] == "IPV4"
 | 
					    assert cluster["NetworkType"] == "IPV4"
 | 
				
			||||||
    assert cluster["DBSubnetGroup"] == "subnetgroupname"
 | 
					    assert cluster["DBSubnetGroup"] == "subnetgroupname"
 | 
				
			||||||
 | 
					    assert cluster["StorageEncrypted"] is True
 | 
				
			||||||
 | 
					    assert cluster["GlobalWriteForwardingRequested"] is True
 | 
				
			||||||
    assert cluster["ScalingConfigurationInfo"] == {"MinCapacity": 5, "AutoPause": True}
 | 
					    assert cluster["ScalingConfigurationInfo"] == {"MinCapacity": 5, "AutoPause": True}
 | 
				
			||||||
    assert cluster["ServerlessV2ScalingConfiguration"] == {
 | 
					    assert cluster["ServerlessV2ScalingConfiguration"] == {
 | 
				
			||||||
        "MaxCapacity": 4.0,
 | 
					        "MaxCapacity": 4.0,
 | 
				
			||||||
@ -977,3 +983,120 @@ def test_createdb_instance_engine_mismatch_fail():
 | 
				
			|||||||
        == "The engine name requested for your DB instance (mysql) doesn't match "
 | 
					        == "The engine name requested for your DB instance (mysql) doesn't match "
 | 
				
			||||||
        "the engine name of your DB cluster (aurora-postgresql)."
 | 
					        "the engine name of your DB cluster (aurora-postgresql)."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mock_rds
 | 
				
			||||||
 | 
					def test_describe_db_cluster_snapshot_attributes_default():
 | 
				
			||||||
 | 
					    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,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    conn.create_db_cluster_snapshot(
 | 
				
			||||||
 | 
					        DBClusterIdentifier="db-primary-1", DBClusterSnapshotIdentifier="g-1"
 | 
				
			||||||
 | 
					    ).get("DBClusterSnapshot")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resp = conn.describe_db_cluster_snapshot_attributes(
 | 
				
			||||||
 | 
					        DBClusterSnapshotIdentifier="g-1"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert (
 | 
				
			||||||
 | 
					        resp["DBClusterSnapshotAttributesResult"]["DBClusterSnapshotIdentifier"]
 | 
				
			||||||
 | 
					        == "g-1"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert (
 | 
				
			||||||
 | 
					        resp["DBClusterSnapshotAttributesResult"]["DBClusterSnapshotAttributes"] == []
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mock_rds
 | 
				
			||||||
 | 
					def test_describe_db_cluster_snapshot_attributes():
 | 
				
			||||||
 | 
					    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,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    conn.create_db_cluster_snapshot(
 | 
				
			||||||
 | 
					        DBClusterIdentifier="db-primary-1", DBClusterSnapshotIdentifier="g-1"
 | 
				
			||||||
 | 
					    ).get("DBClusterSnapshot")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    conn.modify_db_cluster_snapshot_attribute(
 | 
				
			||||||
 | 
					        DBClusterSnapshotIdentifier="g-1",
 | 
				
			||||||
 | 
					        AttributeName="restore",
 | 
				
			||||||
 | 
					        ValuesToAdd=["test", "test2"],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resp = conn.describe_db_cluster_snapshot_attributes(
 | 
				
			||||||
 | 
					        DBClusterSnapshotIdentifier="g-1"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert (
 | 
				
			||||||
 | 
					        resp["DBClusterSnapshotAttributesResult"]["DBClusterSnapshotIdentifier"]
 | 
				
			||||||
 | 
					        == "g-1"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert (
 | 
				
			||||||
 | 
					        resp["DBClusterSnapshotAttributesResult"]["DBClusterSnapshotAttributes"][0][
 | 
				
			||||||
 | 
					            "AttributeName"
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        == "restore"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert resp["DBClusterSnapshotAttributesResult"]["DBClusterSnapshotAttributes"][0][
 | 
				
			||||||
 | 
					        "AttributeValues"
 | 
				
			||||||
 | 
					    ] == ["test", "test2"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mock_rds
 | 
				
			||||||
 | 
					def test_modify_db_cluster_snapshot_attribute():
 | 
				
			||||||
 | 
					    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,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    conn.create_db_cluster_snapshot(
 | 
				
			||||||
 | 
					        DBClusterIdentifier="db-primary-1", DBClusterSnapshotIdentifier="g-1"
 | 
				
			||||||
 | 
					    ).get("DBClusterSnapshot")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resp = conn.modify_db_cluster_snapshot_attribute(
 | 
				
			||||||
 | 
					        DBClusterSnapshotIdentifier="g-1",
 | 
				
			||||||
 | 
					        AttributeName="restore",
 | 
				
			||||||
 | 
					        ValuesToAdd=["test", "test2"],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    resp = conn.modify_db_cluster_snapshot_attribute(
 | 
				
			||||||
 | 
					        DBClusterSnapshotIdentifier="g-1",
 | 
				
			||||||
 | 
					        AttributeName="restore",
 | 
				
			||||||
 | 
					        ValuesToRemove=["test"],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert (
 | 
				
			||||||
 | 
					        resp["DBClusterSnapshotAttributesResult"]["DBClusterSnapshotIdentifier"]
 | 
				
			||||||
 | 
					        == "g-1"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert (
 | 
				
			||||||
 | 
					        resp["DBClusterSnapshotAttributesResult"]["DBClusterSnapshotAttributes"][0][
 | 
				
			||||||
 | 
					            "AttributeName"
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        == "restore"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert resp["DBClusterSnapshotAttributesResult"]["DBClusterSnapshotAttributes"][0][
 | 
				
			||||||
 | 
					        "AttributeValues"
 | 
				
			||||||
 | 
					    ] == ["test2"]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user