Redshift - Pause/Resume clusters (#4693)

This commit is contained in:
Bert Blommers 2021-12-15 19:00:19 -01:00 committed by GitHub
parent fb1a828fe3
commit 82588b2638
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 122 additions and 5 deletions

View File

@ -3770,7 +3770,7 @@
## redshift
<details>
<summary>23% implemented</summary>
<summary>25% implemented</summary>
- [ ] accept_reserved_node_exchange
- [ ] add_partner
@ -3876,7 +3876,7 @@
- [X] modify_snapshot_copy_retention_period
- [ ] modify_snapshot_schedule
- [ ] modify_usage_limit
- [ ] pause_cluster
- [X] pause_cluster
- [ ] purchase_reserved_node_offering
- [ ] reboot_cluster
- [ ] reject_data_share
@ -3884,7 +3884,7 @@
- [ ] resize_cluster
- [X] restore_from_cluster_snapshot
- [ ] restore_table_from_cluster_snapshot
- [ ] resume_cluster
- [X] resume_cluster
- [ ] revoke_cluster_security_group_ingress
- [ ] revoke_endpoint_access
- [ ] revoke_snapshot_access

View File

@ -129,7 +129,7 @@ redshift
- [X] modify_snapshot_copy_retention_period
- [ ] modify_snapshot_schedule
- [ ] modify_usage_limit
- [ ] pause_cluster
- [X] pause_cluster
- [ ] purchase_reserved_node_offering
- [ ] reboot_cluster
- [ ] reject_data_share
@ -137,7 +137,7 @@ redshift
- [ ] resize_cluster
- [X] restore_from_cluster_snapshot
- [ ] restore_table_from_cluster_snapshot
- [ ] resume_cluster
- [X] resume_cluster
- [ ] revoke_cluster_security_group_ingress
- [ ] revoke_endpoint_access
- [ ] revoke_snapshot_access

View File

@ -261,6 +261,12 @@ class Cluster(TaggableResourceMixin, CloudFormationModel):
def resource_id(self):
return self.cluster_identifier
def pause(self):
self.status = "paused"
def resume(self):
self.status = "available"
def to_json(self):
json_response = {
"MasterUsername": self.master_username,
@ -637,6 +643,18 @@ class RedshiftBackend(BaseBackend):
self.clusters[cluster_identifier] = cluster
return cluster
def pause_cluster(self, cluster_id):
if cluster_id not in self.clusters:
raise ClusterNotFoundError(cluster_identifier=cluster_id)
self.clusters[cluster_id].pause()
return self.clusters[cluster_id]
def resume_cluster(self, cluster_id):
if cluster_id not in self.clusters:
raise ClusterNotFoundError(cluster_identifier=cluster_id)
self.clusters[cluster_id].resume()
return self.clusters[cluster_id]
def describe_clusters(self, cluster_identifier=None):
clusters = self.clusters.values()
if cluster_identifier:

View File

@ -159,6 +159,34 @@ class RedshiftResponse(BaseResponse):
}
)
def pause_cluster(self):
cluster_id = self._get_param("ClusterIdentifier")
cluster = self.redshift_backend.pause_cluster(cluster_id).to_json()
return self.get_response(
{
"PauseClusterResponse": {
"PauseClusterResult": {"Cluster": cluster},
"ResponseMetadata": {
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
},
}
}
)
def resume_cluster(self):
cluster_id = self._get_param("ClusterIdentifier")
cluster = self.redshift_backend.resume_cluster(cluster_id).to_json()
return self.get_response(
{
"ResumeClusterResponse": {
"ResumeClusterResult": {"Cluster": cluster},
"ResponseMetadata": {
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
},
}
}
)
def restore_from_cluster_snapshot(self):
enhanced_vpc_routing = self._get_bool_param("EnhancedVpcRouting")
node_type = self._get_param("NodeType")

View File

@ -2137,3 +2137,74 @@ def test_get_cluster_credentials():
assert time.mktime(response["Expiration"].timetuple()) == pytest.approx(
expected_expiration
)
@mock_redshift
def test_pause_cluster():
client = boto3.client("redshift", region_name="us-east-1")
response = client.create_cluster(
DBName="test",
ClusterIdentifier="test",
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="user",
MasterUserPassword="password",
)
cluster = response["Cluster"]
cluster["ClusterIdentifier"].should.equal("test")
response = client.pause_cluster(ClusterIdentifier="test")
cluster = response["Cluster"]
cluster["ClusterIdentifier"].should.equal("test")
# Verify this call returns all properties
cluster["NodeType"].should.equal("ds2.xlarge")
cluster["ClusterStatus"].should.equal("paused")
cluster["ClusterVersion"].should.equal("1.0")
cluster["AllowVersionUpgrade"].should.equal(True)
cluster["Endpoint"]["Port"].should.equal(5439)
@mock_redshift
def test_pause_unknown_cluster():
client = boto3.client("redshift", region_name="us-east-1")
with pytest.raises(ClientError) as exc:
client.pause_cluster(ClusterIdentifier="test")
err = exc.value.response["Error"]
err["Code"].should.equal("ClusterNotFound")
err["Message"].should.equal("Cluster test not found.")
@mock_redshift
def test_resume_cluster():
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster(
DBName="test",
ClusterIdentifier="test",
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="user",
MasterUserPassword="password",
)
client.pause_cluster(ClusterIdentifier="test")
response = client.resume_cluster(ClusterIdentifier="test")
cluster = response["Cluster"]
cluster["ClusterIdentifier"].should.equal("test")
# Verify this call returns all properties
cluster["NodeType"].should.equal("ds2.xlarge")
cluster["ClusterStatus"].should.equal("available")
cluster["ClusterVersion"].should.equal("1.0")
cluster["AllowVersionUpgrade"].should.equal(True)
cluster["Endpoint"]["Port"].should.equal(5439)
@mock_redshift
def test_resume_unknown_cluster():
client = boto3.client("redshift", region_name="us-east-1")
with pytest.raises(ClientError) as exc:
client.resume_cluster(ClusterIdentifier="test")
err = exc.value.response["Error"]
err["Code"].should.equal("ClusterNotFound")
err["Message"].should.equal("Cluster test not found.")