Run black on moto & test directories.
This commit is contained in:
parent
c820395dbf
commit
96e5b1993d
507 changed files with 52541 additions and 47814 deletions
|
|
@ -2,6 +2,6 @@ from __future__ import unicode_literals
|
|||
from .models import redshift_backends
|
||||
from ..core.models import base_decorator, deprecated_base_decorator
|
||||
|
||||
redshift_backend = redshift_backends['us-east-1']
|
||||
redshift_backend = redshift_backends["us-east-1"]
|
||||
mock_redshift = base_decorator(redshift_backends)
|
||||
mock_redshift_deprecated = deprecated_base_decorator(redshift_backends)
|
||||
|
|
|
|||
|
|
@ -5,94 +5,93 @@ from werkzeug.exceptions import BadRequest
|
|||
|
||||
|
||||
class RedshiftClientError(BadRequest):
|
||||
|
||||
def __init__(self, code, message):
|
||||
super(RedshiftClientError, self).__init__()
|
||||
self.description = json.dumps({
|
||||
"Error": {
|
||||
"Code": code,
|
||||
"Message": message,
|
||||
'Type': 'Sender',
|
||||
},
|
||||
'RequestId': '6876f774-7273-11e4-85dc-39e55ca848d1',
|
||||
})
|
||||
self.description = json.dumps(
|
||||
{
|
||||
"Error": {"Code": code, "Message": message, "Type": "Sender"},
|
||||
"RequestId": "6876f774-7273-11e4-85dc-39e55ca848d1",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class ClusterNotFoundError(RedshiftClientError):
|
||||
|
||||
def __init__(self, cluster_identifier):
|
||||
super(ClusterNotFoundError, self).__init__(
|
||||
'ClusterNotFound',
|
||||
"Cluster {0} not found.".format(cluster_identifier))
|
||||
"ClusterNotFound", "Cluster {0} not found.".format(cluster_identifier)
|
||||
)
|
||||
|
||||
|
||||
class ClusterSubnetGroupNotFoundError(RedshiftClientError):
|
||||
|
||||
def __init__(self, subnet_identifier):
|
||||
super(ClusterSubnetGroupNotFoundError, self).__init__(
|
||||
'ClusterSubnetGroupNotFound',
|
||||
"Subnet group {0} not found.".format(subnet_identifier))
|
||||
"ClusterSubnetGroupNotFound",
|
||||
"Subnet group {0} not found.".format(subnet_identifier),
|
||||
)
|
||||
|
||||
|
||||
class ClusterSecurityGroupNotFoundError(RedshiftClientError):
|
||||
|
||||
def __init__(self, group_identifier):
|
||||
super(ClusterSecurityGroupNotFoundError, self).__init__(
|
||||
'ClusterSecurityGroupNotFound',
|
||||
"Security group {0} not found.".format(group_identifier))
|
||||
"ClusterSecurityGroupNotFound",
|
||||
"Security group {0} not found.".format(group_identifier),
|
||||
)
|
||||
|
||||
|
||||
class ClusterParameterGroupNotFoundError(RedshiftClientError):
|
||||
|
||||
def __init__(self, group_identifier):
|
||||
super(ClusterParameterGroupNotFoundError, self).__init__(
|
||||
'ClusterParameterGroupNotFound',
|
||||
"Parameter group {0} not found.".format(group_identifier))
|
||||
"ClusterParameterGroupNotFound",
|
||||
"Parameter group {0} not found.".format(group_identifier),
|
||||
)
|
||||
|
||||
|
||||
class InvalidSubnetError(RedshiftClientError):
|
||||
|
||||
def __init__(self, subnet_identifier):
|
||||
super(InvalidSubnetError, self).__init__(
|
||||
'InvalidSubnet',
|
||||
"Subnet {0} not found.".format(subnet_identifier))
|
||||
"InvalidSubnet", "Subnet {0} not found.".format(subnet_identifier)
|
||||
)
|
||||
|
||||
|
||||
class SnapshotCopyGrantAlreadyExistsFaultError(RedshiftClientError):
|
||||
def __init__(self, snapshot_copy_grant_name):
|
||||
super(SnapshotCopyGrantAlreadyExistsFaultError, self).__init__(
|
||||
'SnapshotCopyGrantAlreadyExistsFault',
|
||||
"SnapshotCopyGrantAlreadyExistsFault",
|
||||
"Cannot create the snapshot copy grant because a grant "
|
||||
"with the identifier '{0}' already exists".format(snapshot_copy_grant_name))
|
||||
"with the identifier '{0}' already exists".format(snapshot_copy_grant_name),
|
||||
)
|
||||
|
||||
|
||||
class SnapshotCopyGrantNotFoundFaultError(RedshiftClientError):
|
||||
def __init__(self, snapshot_copy_grant_name):
|
||||
super(SnapshotCopyGrantNotFoundFaultError, self).__init__(
|
||||
'SnapshotCopyGrantNotFoundFault',
|
||||
"Snapshot copy grant not found: {0}".format(snapshot_copy_grant_name))
|
||||
"SnapshotCopyGrantNotFoundFault",
|
||||
"Snapshot copy grant not found: {0}".format(snapshot_copy_grant_name),
|
||||
)
|
||||
|
||||
|
||||
class ClusterSnapshotNotFoundError(RedshiftClientError):
|
||||
def __init__(self, snapshot_identifier):
|
||||
super(ClusterSnapshotNotFoundError, self).__init__(
|
||||
'ClusterSnapshotNotFound',
|
||||
"Snapshot {0} not found.".format(snapshot_identifier))
|
||||
"ClusterSnapshotNotFound",
|
||||
"Snapshot {0} not found.".format(snapshot_identifier),
|
||||
)
|
||||
|
||||
|
||||
class ClusterSnapshotAlreadyExistsError(RedshiftClientError):
|
||||
def __init__(self, snapshot_identifier):
|
||||
super(ClusterSnapshotAlreadyExistsError, self).__init__(
|
||||
'ClusterSnapshotAlreadyExists',
|
||||
"ClusterSnapshotAlreadyExists",
|
||||
"Cannot create the snapshot because a snapshot with the "
|
||||
"identifier {0} already exists".format(snapshot_identifier))
|
||||
"identifier {0} already exists".format(snapshot_identifier),
|
||||
)
|
||||
|
||||
|
||||
class InvalidParameterValueError(RedshiftClientError):
|
||||
def __init__(self, message):
|
||||
super(InvalidParameterValueError, self).__init__(
|
||||
'InvalidParameterValue',
|
||||
message)
|
||||
"InvalidParameterValue", message
|
||||
)
|
||||
|
||||
|
||||
class ResourceNotFoundFaultError(RedshiftClientError):
|
||||
|
|
@ -106,26 +105,34 @@ class ResourceNotFoundFaultError(RedshiftClientError):
|
|||
msg = "{0} ({1}) not found.".format(resource_type, resource_name)
|
||||
if message:
|
||||
msg = message
|
||||
super(ResourceNotFoundFaultError, self).__init__(
|
||||
'ResourceNotFoundFault', msg)
|
||||
super(ResourceNotFoundFaultError, self).__init__("ResourceNotFoundFault", msg)
|
||||
|
||||
|
||||
class SnapshotCopyDisabledFaultError(RedshiftClientError):
|
||||
def __init__(self, cluster_identifier):
|
||||
super(SnapshotCopyDisabledFaultError, self).__init__(
|
||||
'SnapshotCopyDisabledFault',
|
||||
"Cannot modify retention period because snapshot copy is disabled on Cluster {0}.".format(cluster_identifier))
|
||||
"SnapshotCopyDisabledFault",
|
||||
"Cannot modify retention period because snapshot copy is disabled on Cluster {0}.".format(
|
||||
cluster_identifier
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SnapshotCopyAlreadyDisabledFaultError(RedshiftClientError):
|
||||
def __init__(self, cluster_identifier):
|
||||
super(SnapshotCopyAlreadyDisabledFaultError, self).__init__(
|
||||
'SnapshotCopyAlreadyDisabledFault',
|
||||
"Snapshot Copy is already disabled on Cluster {0}.".format(cluster_identifier))
|
||||
"SnapshotCopyAlreadyDisabledFault",
|
||||
"Snapshot Copy is already disabled on Cluster {0}.".format(
|
||||
cluster_identifier
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SnapshotCopyAlreadyEnabledFaultError(RedshiftClientError):
|
||||
def __init__(self, cluster_identifier):
|
||||
super(SnapshotCopyAlreadyEnabledFaultError, self).__init__(
|
||||
'SnapshotCopyAlreadyEnabledFault',
|
||||
"Snapshot Copy is already enabled on Cluster {0}.".format(cluster_identifier))
|
||||
"SnapshotCopyAlreadyEnabledFault",
|
||||
"Snapshot Copy is already enabled on Cluster {0}.".format(
|
||||
cluster_identifier
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -48,59 +48,91 @@ class TaggableResourceMixin(object):
|
|||
region=self.region,
|
||||
account_id=ACCOUNT_ID,
|
||||
resource_type=self.resource_type,
|
||||
resource_id=self.resource_id)
|
||||
resource_id=self.resource_id,
|
||||
)
|
||||
|
||||
def create_tags(self, tags):
|
||||
new_keys = [tag_set['Key'] for tag_set in tags]
|
||||
self.tags = [tag_set for tag_set in self.tags
|
||||
if tag_set['Key'] not in new_keys]
|
||||
new_keys = [tag_set["Key"] for tag_set in tags]
|
||||
self.tags = [tag_set for tag_set in self.tags if tag_set["Key"] not in new_keys]
|
||||
self.tags.extend(tags)
|
||||
return self.tags
|
||||
|
||||
def delete_tags(self, tag_keys):
|
||||
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]
|
||||
return self.tags
|
||||
|
||||
|
||||
class Cluster(TaggableResourceMixin, BaseModel):
|
||||
|
||||
resource_type = 'cluster'
|
||||
resource_type = "cluster"
|
||||
|
||||
def __init__(self, redshift_backend, cluster_identifier, node_type, master_username,
|
||||
master_user_password, db_name, cluster_type, cluster_security_groups,
|
||||
vpc_security_group_ids, cluster_subnet_group_name, availability_zone,
|
||||
preferred_maintenance_window, cluster_parameter_group_name,
|
||||
automated_snapshot_retention_period, port, cluster_version,
|
||||
allow_version_upgrade, number_of_nodes, publicly_accessible,
|
||||
encrypted, region_name, tags=None, iam_roles_arn=None,
|
||||
enhanced_vpc_routing=None, restored_from_snapshot=False):
|
||||
def __init__(
|
||||
self,
|
||||
redshift_backend,
|
||||
cluster_identifier,
|
||||
node_type,
|
||||
master_username,
|
||||
master_user_password,
|
||||
db_name,
|
||||
cluster_type,
|
||||
cluster_security_groups,
|
||||
vpc_security_group_ids,
|
||||
cluster_subnet_group_name,
|
||||
availability_zone,
|
||||
preferred_maintenance_window,
|
||||
cluster_parameter_group_name,
|
||||
automated_snapshot_retention_period,
|
||||
port,
|
||||
cluster_version,
|
||||
allow_version_upgrade,
|
||||
number_of_nodes,
|
||||
publicly_accessible,
|
||||
encrypted,
|
||||
region_name,
|
||||
tags=None,
|
||||
iam_roles_arn=None,
|
||||
enhanced_vpc_routing=None,
|
||||
restored_from_snapshot=False,
|
||||
):
|
||||
super(Cluster, self).__init__(region_name, tags)
|
||||
self.redshift_backend = redshift_backend
|
||||
self.cluster_identifier = cluster_identifier
|
||||
self.create_time = iso_8601_datetime_with_milliseconds(datetime.datetime.utcnow())
|
||||
self.status = 'available'
|
||||
self.create_time = iso_8601_datetime_with_milliseconds(
|
||||
datetime.datetime.utcnow()
|
||||
)
|
||||
self.status = "available"
|
||||
self.node_type = node_type
|
||||
self.master_username = master_username
|
||||
self.master_user_password = master_user_password
|
||||
self.db_name = db_name if db_name else "dev"
|
||||
self.vpc_security_group_ids = vpc_security_group_ids
|
||||
self.enhanced_vpc_routing = enhanced_vpc_routing if enhanced_vpc_routing is not None else False
|
||||
self.enhanced_vpc_routing = (
|
||||
enhanced_vpc_routing if enhanced_vpc_routing is not None else False
|
||||
)
|
||||
self.cluster_subnet_group_name = cluster_subnet_group_name
|
||||
self.publicly_accessible = publicly_accessible
|
||||
self.encrypted = encrypted
|
||||
|
||||
self.allow_version_upgrade = allow_version_upgrade if allow_version_upgrade is not None else True
|
||||
self.allow_version_upgrade = (
|
||||
allow_version_upgrade if allow_version_upgrade is not None else True
|
||||
)
|
||||
self.cluster_version = cluster_version if cluster_version else "1.0"
|
||||
self.port = int(port) if port else 5439
|
||||
self.automated_snapshot_retention_period = int(
|
||||
automated_snapshot_retention_period) if automated_snapshot_retention_period else 1
|
||||
self.preferred_maintenance_window = preferred_maintenance_window if preferred_maintenance_window else "Mon:03:00-Mon:03:30"
|
||||
self.automated_snapshot_retention_period = (
|
||||
int(automated_snapshot_retention_period)
|
||||
if automated_snapshot_retention_period
|
||||
else 1
|
||||
)
|
||||
self.preferred_maintenance_window = (
|
||||
preferred_maintenance_window
|
||||
if preferred_maintenance_window
|
||||
else "Mon:03:00-Mon:03:30"
|
||||
)
|
||||
|
||||
if cluster_parameter_group_name:
|
||||
self.cluster_parameter_group_name = [cluster_parameter_group_name]
|
||||
else:
|
||||
self.cluster_parameter_group_name = ['default.redshift-1.0']
|
||||
self.cluster_parameter_group_name = ["default.redshift-1.0"]
|
||||
|
||||
if cluster_security_groups:
|
||||
self.cluster_security_groups = cluster_security_groups
|
||||
|
|
@ -114,7 +146,7 @@ class Cluster(TaggableResourceMixin, BaseModel):
|
|||
# way to pull AZs for a region in boto
|
||||
self.availability_zone = region_name + "a"
|
||||
|
||||
if cluster_type == 'single-node':
|
||||
if cluster_type == "single-node":
|
||||
self.number_of_nodes = 1
|
||||
elif number_of_nodes:
|
||||
self.number_of_nodes = int(number_of_nodes)
|
||||
|
|
@ -125,38 +157,39 @@ class Cluster(TaggableResourceMixin, BaseModel):
|
|||
self.restored_from_snapshot = restored_from_snapshot
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||
def create_from_cloudformation_json(
|
||||
cls, resource_name, cloudformation_json, region_name
|
||||
):
|
||||
redshift_backend = redshift_backends[region_name]
|
||||
properties = cloudformation_json['Properties']
|
||||
properties = cloudformation_json["Properties"]
|
||||
|
||||
if 'ClusterSubnetGroupName' in properties:
|
||||
if "ClusterSubnetGroupName" in properties:
|
||||
subnet_group_name = properties[
|
||||
'ClusterSubnetGroupName'].cluster_subnet_group_name
|
||||
"ClusterSubnetGroupName"
|
||||
].cluster_subnet_group_name
|
||||
else:
|
||||
subnet_group_name = None
|
||||
cluster = redshift_backend.create_cluster(
|
||||
cluster_identifier=resource_name,
|
||||
node_type=properties.get('NodeType'),
|
||||
master_username=properties.get('MasterUsername'),
|
||||
master_user_password=properties.get('MasterUserPassword'),
|
||||
db_name=properties.get('DBName'),
|
||||
cluster_type=properties.get('ClusterType'),
|
||||
cluster_security_groups=properties.get(
|
||||
'ClusterSecurityGroups', []),
|
||||
vpc_security_group_ids=properties.get('VpcSecurityGroupIds', []),
|
||||
node_type=properties.get("NodeType"),
|
||||
master_username=properties.get("MasterUsername"),
|
||||
master_user_password=properties.get("MasterUserPassword"),
|
||||
db_name=properties.get("DBName"),
|
||||
cluster_type=properties.get("ClusterType"),
|
||||
cluster_security_groups=properties.get("ClusterSecurityGroups", []),
|
||||
vpc_security_group_ids=properties.get("VpcSecurityGroupIds", []),
|
||||
cluster_subnet_group_name=subnet_group_name,
|
||||
availability_zone=properties.get('AvailabilityZone'),
|
||||
preferred_maintenance_window=properties.get(
|
||||
'PreferredMaintenanceWindow'),
|
||||
cluster_parameter_group_name=properties.get(
|
||||
'ClusterParameterGroupName'),
|
||||
availability_zone=properties.get("AvailabilityZone"),
|
||||
preferred_maintenance_window=properties.get("PreferredMaintenanceWindow"),
|
||||
cluster_parameter_group_name=properties.get("ClusterParameterGroupName"),
|
||||
automated_snapshot_retention_period=properties.get(
|
||||
'AutomatedSnapshotRetentionPeriod'),
|
||||
port=properties.get('Port'),
|
||||
cluster_version=properties.get('ClusterVersion'),
|
||||
allow_version_upgrade=properties.get('AllowVersionUpgrade'),
|
||||
enhanced_vpc_routing=properties.get('EnhancedVpcRouting'),
|
||||
number_of_nodes=properties.get('NumberOfNodes'),
|
||||
"AutomatedSnapshotRetentionPeriod"
|
||||
),
|
||||
port=properties.get("Port"),
|
||||
cluster_version=properties.get("ClusterVersion"),
|
||||
allow_version_upgrade=properties.get("AllowVersionUpgrade"),
|
||||
enhanced_vpc_routing=properties.get("EnhancedVpcRouting"),
|
||||
number_of_nodes=properties.get("NumberOfNodes"),
|
||||
publicly_accessible=properties.get("PubliclyAccessible"),
|
||||
encrypted=properties.get("Encrypted"),
|
||||
region_name=region_name,
|
||||
|
|
@ -165,41 +198,43 @@ class Cluster(TaggableResourceMixin, BaseModel):
|
|||
|
||||
def get_cfn_attribute(self, attribute_name):
|
||||
from moto.cloudformation.exceptions import UnformattedGetAttTemplateException
|
||||
if attribute_name == 'Endpoint.Address':
|
||||
|
||||
if attribute_name == "Endpoint.Address":
|
||||
return self.endpoint
|
||||
elif attribute_name == 'Endpoint.Port':
|
||||
elif attribute_name == "Endpoint.Port":
|
||||
return self.port
|
||||
raise UnformattedGetAttTemplateException()
|
||||
|
||||
@property
|
||||
def endpoint(self):
|
||||
return "{0}.cg034hpkmmjt.{1}.redshift.amazonaws.com".format(
|
||||
self.cluster_identifier,
|
||||
self.region,
|
||||
self.cluster_identifier, self.region
|
||||
)
|
||||
|
||||
@property
|
||||
def security_groups(self):
|
||||
return [
|
||||
security_group for security_group
|
||||
in self.redshift_backend.describe_cluster_security_groups()
|
||||
if security_group.cluster_security_group_name in self.cluster_security_groups
|
||||
security_group
|
||||
for security_group in self.redshift_backend.describe_cluster_security_groups()
|
||||
if security_group.cluster_security_group_name
|
||||
in self.cluster_security_groups
|
||||
]
|
||||
|
||||
@property
|
||||
def vpc_security_groups(self):
|
||||
return [
|
||||
security_group for security_group
|
||||
in self.redshift_backend.ec2_backend.describe_security_groups()
|
||||
security_group
|
||||
for security_group in self.redshift_backend.ec2_backend.describe_security_groups()
|
||||
if security_group.id in self.vpc_security_group_ids
|
||||
]
|
||||
|
||||
@property
|
||||
def parameter_groups(self):
|
||||
return [
|
||||
parameter_group for parameter_group
|
||||
in self.redshift_backend.describe_cluster_parameter_groups()
|
||||
if parameter_group.cluster_parameter_group_name in self.cluster_parameter_group_name
|
||||
parameter_group
|
||||
for parameter_group in self.redshift_backend.describe_cluster_parameter_groups()
|
||||
if parameter_group.cluster_parameter_group_name
|
||||
in self.cluster_parameter_group_name
|
||||
]
|
||||
|
||||
@property
|
||||
|
|
@ -211,10 +246,10 @@ class Cluster(TaggableResourceMixin, BaseModel):
|
|||
"MasterUsername": self.master_username,
|
||||
"MasterUserPassword": "****",
|
||||
"ClusterVersion": self.cluster_version,
|
||||
"VpcSecurityGroups": [{
|
||||
"Status": "active",
|
||||
"VpcSecurityGroupId": group.id
|
||||
} for group in self.vpc_security_groups],
|
||||
"VpcSecurityGroups": [
|
||||
{"Status": "active", "VpcSecurityGroupId": group.id}
|
||||
for group in self.vpc_security_groups
|
||||
],
|
||||
"ClusterSubnetGroupName": self.cluster_subnet_group_name,
|
||||
"AvailabilityZone": self.availability_zone,
|
||||
"ClusterStatus": self.status,
|
||||
|
|
@ -224,42 +259,47 @@ class Cluster(TaggableResourceMixin, BaseModel):
|
|||
"Encrypted": self.encrypted,
|
||||
"DBName": self.db_name,
|
||||
"PreferredMaintenanceWindow": self.preferred_maintenance_window,
|
||||
"ClusterParameterGroups": [{
|
||||
"ParameterApplyStatus": "in-sync",
|
||||
"ParameterGroupName": group.cluster_parameter_group_name,
|
||||
} for group in self.parameter_groups],
|
||||
"ClusterSecurityGroups": [{
|
||||
"Status": "active",
|
||||
"ClusterSecurityGroupName": group.cluster_security_group_name,
|
||||
} for group in self.security_groups],
|
||||
"ClusterParameterGroups": [
|
||||
{
|
||||
"ParameterApplyStatus": "in-sync",
|
||||
"ParameterGroupName": group.cluster_parameter_group_name,
|
||||
}
|
||||
for group in self.parameter_groups
|
||||
],
|
||||
"ClusterSecurityGroups": [
|
||||
{
|
||||
"Status": "active",
|
||||
"ClusterSecurityGroupName": group.cluster_security_group_name,
|
||||
}
|
||||
for group in self.security_groups
|
||||
],
|
||||
"Port": self.port,
|
||||
"NodeType": self.node_type,
|
||||
"ClusterIdentifier": self.cluster_identifier,
|
||||
"AllowVersionUpgrade": self.allow_version_upgrade,
|
||||
"Endpoint": {
|
||||
"Address": self.endpoint,
|
||||
"Port": self.port
|
||||
},
|
||||
'ClusterCreateTime': self.create_time,
|
||||
"Endpoint": {"Address": self.endpoint, "Port": self.port},
|
||||
"ClusterCreateTime": self.create_time,
|
||||
"PendingModifiedValues": [],
|
||||
"Tags": self.tags,
|
||||
"EnhancedVpcRouting": self.enhanced_vpc_routing,
|
||||
"IamRoles": [{
|
||||
"ApplyStatus": "in-sync",
|
||||
"IamRoleArn": iam_role_arn
|
||||
} for iam_role_arn in self.iam_roles_arn]
|
||||
"IamRoles": [
|
||||
{"ApplyStatus": "in-sync", "IamRoleArn": iam_role_arn}
|
||||
for iam_role_arn in self.iam_roles_arn
|
||||
],
|
||||
}
|
||||
if self.restored_from_snapshot:
|
||||
json_response['RestoreStatus'] = {
|
||||
'Status': 'completed',
|
||||
'CurrentRestoreRateInMegaBytesPerSecond': 123.0,
|
||||
'SnapshotSizeInMegaBytes': 123,
|
||||
'ProgressInMegaBytes': 123,
|
||||
'ElapsedTimeInSeconds': 123,
|
||||
'EstimatedTimeToCompletionInSeconds': 123
|
||||
json_response["RestoreStatus"] = {
|
||||
"Status": "completed",
|
||||
"CurrentRestoreRateInMegaBytesPerSecond": 123.0,
|
||||
"SnapshotSizeInMegaBytes": 123,
|
||||
"ProgressInMegaBytes": 123,
|
||||
"ElapsedTimeInSeconds": 123,
|
||||
"EstimatedTimeToCompletionInSeconds": 123,
|
||||
}
|
||||
try:
|
||||
json_response['ClusterSnapshotCopyStatus'] = self.cluster_snapshot_copy_status
|
||||
json_response[
|
||||
"ClusterSnapshotCopyStatus"
|
||||
] = self.cluster_snapshot_copy_status
|
||||
except AttributeError:
|
||||
pass
|
||||
return json_response
|
||||
|
|
@ -267,7 +307,7 @@ class Cluster(TaggableResourceMixin, BaseModel):
|
|||
|
||||
class SnapshotCopyGrant(TaggableResourceMixin, BaseModel):
|
||||
|
||||
resource_type = 'snapshotcopygrant'
|
||||
resource_type = "snapshotcopygrant"
|
||||
|
||||
def __init__(self, snapshot_copy_grant_name, kms_key_id):
|
||||
self.snapshot_copy_grant_name = snapshot_copy_grant_name
|
||||
|
|
@ -276,16 +316,23 @@ class SnapshotCopyGrant(TaggableResourceMixin, BaseModel):
|
|||
def to_json(self):
|
||||
return {
|
||||
"SnapshotCopyGrantName": self.snapshot_copy_grant_name,
|
||||
"KmsKeyId": self.kms_key_id
|
||||
"KmsKeyId": self.kms_key_id,
|
||||
}
|
||||
|
||||
|
||||
class SubnetGroup(TaggableResourceMixin, BaseModel):
|
||||
|
||||
resource_type = 'subnetgroup'
|
||||
resource_type = "subnetgroup"
|
||||
|
||||
def __init__(self, ec2_backend, cluster_subnet_group_name, description, subnet_ids,
|
||||
region_name, tags=None):
|
||||
def __init__(
|
||||
self,
|
||||
ec2_backend,
|
||||
cluster_subnet_group_name,
|
||||
description,
|
||||
subnet_ids,
|
||||
region_name,
|
||||
tags=None,
|
||||
):
|
||||
super(SubnetGroup, self).__init__(region_name, tags)
|
||||
self.ec2_backend = ec2_backend
|
||||
self.cluster_subnet_group_name = cluster_subnet_group_name
|
||||
|
|
@ -295,21 +342,23 @@ class SubnetGroup(TaggableResourceMixin, BaseModel):
|
|||
raise InvalidSubnetError(subnet_ids)
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||
def create_from_cloudformation_json(
|
||||
cls, resource_name, cloudformation_json, region_name
|
||||
):
|
||||
redshift_backend = redshift_backends[region_name]
|
||||
properties = cloudformation_json['Properties']
|
||||
properties = cloudformation_json["Properties"]
|
||||
|
||||
subnet_group = redshift_backend.create_cluster_subnet_group(
|
||||
cluster_subnet_group_name=resource_name,
|
||||
description=properties.get("Description"),
|
||||
subnet_ids=properties.get("SubnetIds", []),
|
||||
region_name=region_name
|
||||
region_name=region_name,
|
||||
)
|
||||
return subnet_group
|
||||
|
||||
@property
|
||||
def subnets(self):
|
||||
return self.ec2_backend.get_all_subnets(filters={'subnet-id': self.subnet_ids})
|
||||
return self.ec2_backend.get_all_subnets(filters={"subnet-id": self.subnet_ids})
|
||||
|
||||
@property
|
||||
def vpc_id(self):
|
||||
|
|
@ -325,22 +374,25 @@ class SubnetGroup(TaggableResourceMixin, BaseModel):
|
|||
"Description": self.description,
|
||||
"ClusterSubnetGroupName": self.cluster_subnet_group_name,
|
||||
"SubnetGroupStatus": "Complete",
|
||||
"Subnets": [{
|
||||
"SubnetStatus": "Active",
|
||||
"SubnetIdentifier": subnet.id,
|
||||
"SubnetAvailabilityZone": {
|
||||
"Name": subnet.availability_zone
|
||||
},
|
||||
} for subnet in self.subnets],
|
||||
"Tags": self.tags
|
||||
"Subnets": [
|
||||
{
|
||||
"SubnetStatus": "Active",
|
||||
"SubnetIdentifier": subnet.id,
|
||||
"SubnetAvailabilityZone": {"Name": subnet.availability_zone},
|
||||
}
|
||||
for subnet in self.subnets
|
||||
],
|
||||
"Tags": self.tags,
|
||||
}
|
||||
|
||||
|
||||
class SecurityGroup(TaggableResourceMixin, BaseModel):
|
||||
|
||||
resource_type = 'securitygroup'
|
||||
resource_type = "securitygroup"
|
||||
|
||||
def __init__(self, cluster_security_group_name, description, region_name, tags=None):
|
||||
def __init__(
|
||||
self, cluster_security_group_name, description, region_name, tags=None
|
||||
):
|
||||
super(SecurityGroup, self).__init__(region_name, tags)
|
||||
self.cluster_security_group_name = cluster_security_group_name
|
||||
self.description = description
|
||||
|
|
@ -355,30 +407,39 @@ class SecurityGroup(TaggableResourceMixin, BaseModel):
|
|||
"IPRanges": [],
|
||||
"Description": self.description,
|
||||
"ClusterSecurityGroupName": self.cluster_security_group_name,
|
||||
"Tags": self.tags
|
||||
"Tags": self.tags,
|
||||
}
|
||||
|
||||
|
||||
class ParameterGroup(TaggableResourceMixin, BaseModel):
|
||||
|
||||
resource_type = 'parametergroup'
|
||||
resource_type = "parametergroup"
|
||||
|
||||
def __init__(self, cluster_parameter_group_name, group_family, description, region_name, tags=None):
|
||||
def __init__(
|
||||
self,
|
||||
cluster_parameter_group_name,
|
||||
group_family,
|
||||
description,
|
||||
region_name,
|
||||
tags=None,
|
||||
):
|
||||
super(ParameterGroup, self).__init__(region_name, tags)
|
||||
self.cluster_parameter_group_name = cluster_parameter_group_name
|
||||
self.group_family = group_family
|
||||
self.description = description
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||
def create_from_cloudformation_json(
|
||||
cls, resource_name, cloudformation_json, region_name
|
||||
):
|
||||
redshift_backend = redshift_backends[region_name]
|
||||
properties = cloudformation_json['Properties']
|
||||
properties = cloudformation_json["Properties"]
|
||||
|
||||
parameter_group = redshift_backend.create_cluster_parameter_group(
|
||||
cluster_parameter_group_name=resource_name,
|
||||
description=properties.get("Description"),
|
||||
group_family=properties.get("ParameterGroupFamily"),
|
||||
region_name=region_name
|
||||
region_name=region_name,
|
||||
)
|
||||
return parameter_group
|
||||
|
||||
|
|
@ -391,78 +452,81 @@ class ParameterGroup(TaggableResourceMixin, BaseModel):
|
|||
"ParameterGroupFamily": self.group_family,
|
||||
"Description": self.description,
|
||||
"ParameterGroupName": self.cluster_parameter_group_name,
|
||||
"Tags": self.tags
|
||||
"Tags": self.tags,
|
||||
}
|
||||
|
||||
|
||||
class Snapshot(TaggableResourceMixin, BaseModel):
|
||||
|
||||
resource_type = 'snapshot'
|
||||
resource_type = "snapshot"
|
||||
|
||||
def __init__(self, cluster, snapshot_identifier, region_name, tags=None, iam_roles_arn=None):
|
||||
def __init__(
|
||||
self, cluster, snapshot_identifier, region_name, tags=None, iam_roles_arn=None
|
||||
):
|
||||
super(Snapshot, self).__init__(region_name, tags)
|
||||
self.cluster = copy.copy(cluster)
|
||||
self.snapshot_identifier = snapshot_identifier
|
||||
self.snapshot_type = 'manual'
|
||||
self.status = 'available'
|
||||
self.create_time = iso_8601_datetime_with_milliseconds(
|
||||
datetime.datetime.now())
|
||||
self.snapshot_type = "manual"
|
||||
self.status = "available"
|
||||
self.create_time = iso_8601_datetime_with_milliseconds(datetime.datetime.now())
|
||||
self.iam_roles_arn = iam_roles_arn or []
|
||||
|
||||
@property
|
||||
def resource_id(self):
|
||||
return "{cluster_id}/{snapshot_id}".format(
|
||||
cluster_id=self.cluster.cluster_identifier,
|
||||
snapshot_id=self.snapshot_identifier)
|
||||
snapshot_id=self.snapshot_identifier,
|
||||
)
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
'SnapshotIdentifier': self.snapshot_identifier,
|
||||
'ClusterIdentifier': self.cluster.cluster_identifier,
|
||||
'SnapshotCreateTime': self.create_time,
|
||||
'Status': self.status,
|
||||
'Port': self.cluster.port,
|
||||
'AvailabilityZone': self.cluster.availability_zone,
|
||||
'MasterUsername': self.cluster.master_username,
|
||||
'ClusterVersion': self.cluster.cluster_version,
|
||||
'SnapshotType': self.snapshot_type,
|
||||
'NodeType': self.cluster.node_type,
|
||||
'NumberOfNodes': self.cluster.number_of_nodes,
|
||||
'DBName': self.cluster.db_name,
|
||||
'Tags': self.tags,
|
||||
'EnhancedVpcRouting': self.cluster.enhanced_vpc_routing,
|
||||
"IamRoles": [{
|
||||
"ApplyStatus": "in-sync",
|
||||
"IamRoleArn": iam_role_arn
|
||||
} for iam_role_arn in self.iam_roles_arn]
|
||||
"SnapshotIdentifier": self.snapshot_identifier,
|
||||
"ClusterIdentifier": self.cluster.cluster_identifier,
|
||||
"SnapshotCreateTime": self.create_time,
|
||||
"Status": self.status,
|
||||
"Port": self.cluster.port,
|
||||
"AvailabilityZone": self.cluster.availability_zone,
|
||||
"MasterUsername": self.cluster.master_username,
|
||||
"ClusterVersion": self.cluster.cluster_version,
|
||||
"SnapshotType": self.snapshot_type,
|
||||
"NodeType": self.cluster.node_type,
|
||||
"NumberOfNodes": self.cluster.number_of_nodes,
|
||||
"DBName": self.cluster.db_name,
|
||||
"Tags": self.tags,
|
||||
"EnhancedVpcRouting": self.cluster.enhanced_vpc_routing,
|
||||
"IamRoles": [
|
||||
{"ApplyStatus": "in-sync", "IamRoleArn": iam_role_arn}
|
||||
for iam_role_arn in self.iam_roles_arn
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
class RedshiftBackend(BaseBackend):
|
||||
|
||||
def __init__(self, ec2_backend, region_name):
|
||||
self.region = region_name
|
||||
self.clusters = {}
|
||||
self.subnet_groups = {}
|
||||
self.security_groups = {
|
||||
"Default": SecurityGroup("Default", "Default Redshift Security Group", self.region)
|
||||
"Default": SecurityGroup(
|
||||
"Default", "Default Redshift Security Group", self.region
|
||||
)
|
||||
}
|
||||
self.parameter_groups = {
|
||||
"default.redshift-1.0": ParameterGroup(
|
||||
"default.redshift-1.0",
|
||||
"redshift-1.0",
|
||||
"Default Redshift parameter group",
|
||||
self.region
|
||||
self.region,
|
||||
)
|
||||
}
|
||||
self.ec2_backend = ec2_backend
|
||||
self.snapshots = OrderedDict()
|
||||
self.RESOURCE_TYPE_MAP = {
|
||||
'cluster': self.clusters,
|
||||
'parametergroup': self.parameter_groups,
|
||||
'securitygroup': self.security_groups,
|
||||
'snapshot': self.snapshots,
|
||||
'subnetgroup': self.subnet_groups
|
||||
"cluster": self.clusters,
|
||||
"parametergroup": self.parameter_groups,
|
||||
"securitygroup": self.security_groups,
|
||||
"snapshot": self.snapshots,
|
||||
"subnetgroup": self.subnet_groups,
|
||||
}
|
||||
self.snapshot_copy_grants = {}
|
||||
|
||||
|
|
@ -473,19 +537,22 @@ class RedshiftBackend(BaseBackend):
|
|||
self.__init__(ec2_backend, region_name)
|
||||
|
||||
def enable_snapshot_copy(self, **kwargs):
|
||||
cluster_identifier = kwargs['cluster_identifier']
|
||||
cluster_identifier = kwargs["cluster_identifier"]
|
||||
cluster = self.clusters[cluster_identifier]
|
||||
if not hasattr(cluster, 'cluster_snapshot_copy_status'):
|
||||
if cluster.encrypted == 'true' and kwargs['snapshot_copy_grant_name'] is None:
|
||||
if not hasattr(cluster, "cluster_snapshot_copy_status"):
|
||||
if (
|
||||
cluster.encrypted == "true"
|
||||
and kwargs["snapshot_copy_grant_name"] is None
|
||||
):
|
||||
raise ClientError(
|
||||
'InvalidParameterValue',
|
||||
'SnapshotCopyGrantName is required for Snapshot Copy '
|
||||
'on KMS encrypted clusters.'
|
||||
"InvalidParameterValue",
|
||||
"SnapshotCopyGrantName is required for Snapshot Copy "
|
||||
"on KMS encrypted clusters.",
|
||||
)
|
||||
status = {
|
||||
'DestinationRegion': kwargs['destination_region'],
|
||||
'RetentionPeriod': kwargs['retention_period'],
|
||||
'SnapshotCopyGrantName': kwargs['snapshot_copy_grant_name'],
|
||||
"DestinationRegion": kwargs["destination_region"],
|
||||
"RetentionPeriod": kwargs["retention_period"],
|
||||
"SnapshotCopyGrantName": kwargs["snapshot_copy_grant_name"],
|
||||
}
|
||||
cluster.cluster_snapshot_copy_status = status
|
||||
return cluster
|
||||
|
|
@ -493,24 +560,26 @@ class RedshiftBackend(BaseBackend):
|
|||
raise SnapshotCopyAlreadyEnabledFaultError(cluster_identifier)
|
||||
|
||||
def disable_snapshot_copy(self, **kwargs):
|
||||
cluster_identifier = kwargs['cluster_identifier']
|
||||
cluster_identifier = kwargs["cluster_identifier"]
|
||||
cluster = self.clusters[cluster_identifier]
|
||||
if hasattr(cluster, 'cluster_snapshot_copy_status'):
|
||||
if hasattr(cluster, "cluster_snapshot_copy_status"):
|
||||
del cluster.cluster_snapshot_copy_status
|
||||
return cluster
|
||||
else:
|
||||
raise SnapshotCopyAlreadyDisabledFaultError(cluster_identifier)
|
||||
|
||||
def modify_snapshot_copy_retention_period(self, cluster_identifier, retention_period):
|
||||
def modify_snapshot_copy_retention_period(
|
||||
self, cluster_identifier, retention_period
|
||||
):
|
||||
cluster = self.clusters[cluster_identifier]
|
||||
if hasattr(cluster, 'cluster_snapshot_copy_status'):
|
||||
cluster.cluster_snapshot_copy_status['RetentionPeriod'] = retention_period
|
||||
if hasattr(cluster, "cluster_snapshot_copy_status"):
|
||||
cluster.cluster_snapshot_copy_status["RetentionPeriod"] = retention_period
|
||||
return cluster
|
||||
else:
|
||||
raise SnapshotCopyDisabledFaultError(cluster_identifier)
|
||||
|
||||
def create_cluster(self, **cluster_kwargs):
|
||||
cluster_identifier = cluster_kwargs['cluster_identifier']
|
||||
cluster_identifier = cluster_kwargs["cluster_identifier"]
|
||||
cluster = Cluster(self, **cluster_kwargs)
|
||||
self.clusters[cluster_identifier] = cluster
|
||||
return cluster
|
||||
|
|
@ -525,9 +594,8 @@ class RedshiftBackend(BaseBackend):
|
|||
return clusters
|
||||
|
||||
def modify_cluster(self, **cluster_kwargs):
|
||||
cluster_identifier = cluster_kwargs.pop('cluster_identifier')
|
||||
new_cluster_identifier = cluster_kwargs.pop(
|
||||
'new_cluster_identifier', None)
|
||||
cluster_identifier = cluster_kwargs.pop("cluster_identifier")
|
||||
new_cluster_identifier = cluster_kwargs.pop("new_cluster_identifier", None)
|
||||
|
||||
cluster = self.describe_clusters(cluster_identifier)[0]
|
||||
|
||||
|
|
@ -538,7 +606,7 @@ class RedshiftBackend(BaseBackend):
|
|||
dic = {
|
||||
"cluster_identifier": cluster_identifier,
|
||||
"skip_final_snapshot": True,
|
||||
"final_cluster_snapshot_identifier": None
|
||||
"final_cluster_snapshot_identifier": None,
|
||||
}
|
||||
self.delete_cluster(**dic)
|
||||
cluster.cluster_identifier = new_cluster_identifier
|
||||
|
|
@ -549,30 +617,46 @@ class RedshiftBackend(BaseBackend):
|
|||
def delete_cluster(self, **cluster_kwargs):
|
||||
cluster_identifier = cluster_kwargs.pop("cluster_identifier")
|
||||
cluster_skip_final_snapshot = cluster_kwargs.pop("skip_final_snapshot")
|
||||
cluster_snapshot_identifer = cluster_kwargs.pop("final_cluster_snapshot_identifier")
|
||||
cluster_snapshot_identifer = cluster_kwargs.pop(
|
||||
"final_cluster_snapshot_identifier"
|
||||
)
|
||||
|
||||
if cluster_identifier in self.clusters:
|
||||
if cluster_skip_final_snapshot is False and cluster_snapshot_identifer is None:
|
||||
if (
|
||||
cluster_skip_final_snapshot is False
|
||||
and cluster_snapshot_identifer is None
|
||||
):
|
||||
raise ClientError(
|
||||
"InvalidParameterValue",
|
||||
'FinalSnapshotIdentifier is required for Snapshot copy '
|
||||
'when SkipFinalSnapshot is False'
|
||||
"FinalSnapshotIdentifier is required for Snapshot copy "
|
||||
"when SkipFinalSnapshot is False",
|
||||
)
|
||||
elif cluster_skip_final_snapshot is False and cluster_snapshot_identifer is not None: # create snapshot
|
||||
elif (
|
||||
cluster_skip_final_snapshot is False
|
||||
and cluster_snapshot_identifer is not None
|
||||
): # create snapshot
|
||||
cluster = self.describe_clusters(cluster_identifier)[0]
|
||||
self.create_cluster_snapshot(
|
||||
cluster_identifier,
|
||||
cluster_snapshot_identifer,
|
||||
cluster.region,
|
||||
cluster.tags)
|
||||
cluster.tags,
|
||||
)
|
||||
|
||||
return self.clusters.pop(cluster_identifier)
|
||||
raise ClusterNotFoundError(cluster_identifier)
|
||||
|
||||
def create_cluster_subnet_group(self, cluster_subnet_group_name, description, subnet_ids,
|
||||
region_name, tags=None):
|
||||
def create_cluster_subnet_group(
|
||||
self, cluster_subnet_group_name, description, subnet_ids, region_name, tags=None
|
||||
):
|
||||
subnet_group = SubnetGroup(
|
||||
self.ec2_backend, cluster_subnet_group_name, description, subnet_ids, region_name, tags)
|
||||
self.ec2_backend,
|
||||
cluster_subnet_group_name,
|
||||
description,
|
||||
subnet_ids,
|
||||
region_name,
|
||||
tags,
|
||||
)
|
||||
self.subnet_groups[cluster_subnet_group_name] = subnet_group
|
||||
return subnet_group
|
||||
|
||||
|
|
@ -590,9 +674,12 @@ class RedshiftBackend(BaseBackend):
|
|||
return self.subnet_groups.pop(subnet_identifier)
|
||||
raise ClusterSubnetGroupNotFoundError(subnet_identifier)
|
||||
|
||||
def create_cluster_security_group(self, cluster_security_group_name, description, region_name, tags=None):
|
||||
def create_cluster_security_group(
|
||||
self, cluster_security_group_name, description, region_name, tags=None
|
||||
):
|
||||
security_group = SecurityGroup(
|
||||
cluster_security_group_name, description, region_name, tags)
|
||||
cluster_security_group_name, description, region_name, tags
|
||||
)
|
||||
self.security_groups[cluster_security_group_name] = security_group
|
||||
return security_group
|
||||
|
||||
|
|
@ -610,10 +697,17 @@ class RedshiftBackend(BaseBackend):
|
|||
return self.security_groups.pop(security_group_identifier)
|
||||
raise ClusterSecurityGroupNotFoundError(security_group_identifier)
|
||||
|
||||
def create_cluster_parameter_group(self, cluster_parameter_group_name,
|
||||
group_family, description, region_name, tags=None):
|
||||
def create_cluster_parameter_group(
|
||||
self,
|
||||
cluster_parameter_group_name,
|
||||
group_family,
|
||||
description,
|
||||
region_name,
|
||||
tags=None,
|
||||
):
|
||||
parameter_group = ParameterGroup(
|
||||
cluster_parameter_group_name, group_family, description, region_name, tags)
|
||||
cluster_parameter_group_name, group_family, description, region_name, tags
|
||||
)
|
||||
self.parameter_groups[cluster_parameter_group_name] = parameter_group
|
||||
|
||||
return parameter_group
|
||||
|
|
@ -632,7 +726,9 @@ class RedshiftBackend(BaseBackend):
|
|||
return self.parameter_groups.pop(parameter_group_name)
|
||||
raise ClusterParameterGroupNotFoundError(parameter_group_name)
|
||||
|
||||
def create_cluster_snapshot(self, cluster_identifier, snapshot_identifier, region_name, tags):
|
||||
def create_cluster_snapshot(
|
||||
self, cluster_identifier, snapshot_identifier, region_name, tags
|
||||
):
|
||||
cluster = self.clusters.get(cluster_identifier)
|
||||
if not cluster:
|
||||
raise ClusterNotFoundError(cluster_identifier)
|
||||
|
|
@ -642,7 +738,9 @@ class RedshiftBackend(BaseBackend):
|
|||
self.snapshots[snapshot_identifier] = snapshot
|
||||
return snapshot
|
||||
|
||||
def describe_cluster_snapshots(self, cluster_identifier=None, snapshot_identifier=None):
|
||||
def describe_cluster_snapshots(
|
||||
self, cluster_identifier=None, snapshot_identifier=None
|
||||
):
|
||||
if cluster_identifier:
|
||||
cluster_snapshots = []
|
||||
for snapshot in self.snapshots.values():
|
||||
|
|
@ -664,18 +762,22 @@ class RedshiftBackend(BaseBackend):
|
|||
raise ClusterSnapshotNotFoundError(snapshot_identifier)
|
||||
|
||||
deleted_snapshot = self.snapshots.pop(snapshot_identifier)
|
||||
deleted_snapshot.status = 'deleted'
|
||||
deleted_snapshot.status = "deleted"
|
||||
return deleted_snapshot
|
||||
|
||||
def restore_from_cluster_snapshot(self, **kwargs):
|
||||
snapshot_identifier = kwargs.pop('snapshot_identifier')
|
||||
snapshot = self.describe_cluster_snapshots(snapshot_identifier=snapshot_identifier)[0]
|
||||
snapshot_identifier = kwargs.pop("snapshot_identifier")
|
||||
snapshot = self.describe_cluster_snapshots(
|
||||
snapshot_identifier=snapshot_identifier
|
||||
)[0]
|
||||
create_kwargs = {
|
||||
"node_type": snapshot.cluster.node_type,
|
||||
"master_username": snapshot.cluster.master_username,
|
||||
"master_user_password": snapshot.cluster.master_user_password,
|
||||
"db_name": snapshot.cluster.db_name,
|
||||
"cluster_type": 'multi-node' if snapshot.cluster.number_of_nodes > 1 else 'single-node',
|
||||
"cluster_type": "multi-node"
|
||||
if snapshot.cluster.number_of_nodes > 1
|
||||
else "single-node",
|
||||
"availability_zone": snapshot.cluster.availability_zone,
|
||||
"port": snapshot.cluster.port,
|
||||
"cluster_version": snapshot.cluster.cluster_version,
|
||||
|
|
@ -683,29 +785,31 @@ class RedshiftBackend(BaseBackend):
|
|||
"encrypted": snapshot.cluster.encrypted,
|
||||
"tags": snapshot.cluster.tags,
|
||||
"restored_from_snapshot": True,
|
||||
"enhanced_vpc_routing": snapshot.cluster.enhanced_vpc_routing
|
||||
"enhanced_vpc_routing": snapshot.cluster.enhanced_vpc_routing,
|
||||
}
|
||||
create_kwargs.update(kwargs)
|
||||
return self.create_cluster(**create_kwargs)
|
||||
|
||||
def create_snapshot_copy_grant(self, **kwargs):
|
||||
snapshot_copy_grant_name = kwargs['snapshot_copy_grant_name']
|
||||
kms_key_id = kwargs['kms_key_id']
|
||||
snapshot_copy_grant_name = kwargs["snapshot_copy_grant_name"]
|
||||
kms_key_id = kwargs["kms_key_id"]
|
||||
if snapshot_copy_grant_name not in self.snapshot_copy_grants:
|
||||
snapshot_copy_grant = SnapshotCopyGrant(snapshot_copy_grant_name, kms_key_id)
|
||||
snapshot_copy_grant = SnapshotCopyGrant(
|
||||
snapshot_copy_grant_name, kms_key_id
|
||||
)
|
||||
self.snapshot_copy_grants[snapshot_copy_grant_name] = snapshot_copy_grant
|
||||
return snapshot_copy_grant
|
||||
raise SnapshotCopyGrantAlreadyExistsFaultError(snapshot_copy_grant_name)
|
||||
|
||||
def delete_snapshot_copy_grant(self, **kwargs):
|
||||
snapshot_copy_grant_name = kwargs['snapshot_copy_grant_name']
|
||||
snapshot_copy_grant_name = kwargs["snapshot_copy_grant_name"]
|
||||
if snapshot_copy_grant_name in self.snapshot_copy_grants:
|
||||
return self.snapshot_copy_grants.pop(snapshot_copy_grant_name)
|
||||
raise SnapshotCopyGrantNotFoundFaultError(snapshot_copy_grant_name)
|
||||
|
||||
def describe_snapshot_copy_grants(self, **kwargs):
|
||||
copy_grants = self.snapshot_copy_grants.values()
|
||||
snapshot_copy_grant_name = kwargs['snapshot_copy_grant_name']
|
||||
snapshot_copy_grant_name = kwargs["snapshot_copy_grant_name"]
|
||||
if snapshot_copy_grant_name:
|
||||
if snapshot_copy_grant_name in self.snapshot_copy_grants:
|
||||
return [self.snapshot_copy_grants[snapshot_copy_grant_name]]
|
||||
|
|
@ -715,10 +819,10 @@ class RedshiftBackend(BaseBackend):
|
|||
|
||||
def _get_resource_from_arn(self, arn):
|
||||
try:
|
||||
arn_breakdown = arn.split(':')
|
||||
arn_breakdown = arn.split(":")
|
||||
resource_type = arn_breakdown[5]
|
||||
if resource_type == 'snapshot':
|
||||
resource_id = arn_breakdown[6].split('/')[1]
|
||||
if resource_type == "snapshot":
|
||||
resource_id = arn_breakdown[6].split("/")[1]
|
||||
else:
|
||||
resource_id = arn_breakdown[6]
|
||||
except IndexError:
|
||||
|
|
@ -728,7 +832,8 @@ class RedshiftBackend(BaseBackend):
|
|||
message = (
|
||||
"Tagging is not supported for this type of resource: '{0}' "
|
||||
"(the ARN is potentially malformed, please check the ARN "
|
||||
"documentation for more information)".format(resource_type))
|
||||
"documentation for more information)".format(resource_type)
|
||||
)
|
||||
raise ResourceNotFoundFaultError(message=message)
|
||||
try:
|
||||
resource = resources[resource_id]
|
||||
|
|
@ -743,12 +848,9 @@ class RedshiftBackend(BaseBackend):
|
|||
for resource in resources:
|
||||
for tag in resource.tags:
|
||||
data = {
|
||||
'ResourceName': resource.arn,
|
||||
'ResourceType': resource.resource_type,
|
||||
'Tag': {
|
||||
'Key': tag['Key'],
|
||||
'Value': tag['Value']
|
||||
}
|
||||
"ResourceName": resource.arn,
|
||||
"ResourceType": resource.resource_type,
|
||||
"Tag": {"Key": tag["Key"], "Value": tag["Value"]},
|
||||
}
|
||||
tagged_resources.append(data)
|
||||
return tagged_resources
|
||||
|
|
@ -773,7 +875,8 @@ class RedshiftBackend(BaseBackend):
|
|||
"You cannot filter a list of resources using an Amazon "
|
||||
"Resource Name (ARN) and a resource type together in the "
|
||||
"same request. Retry the request using either an ARN or "
|
||||
"a resource type, but not both.")
|
||||
"a resource type, but not both."
|
||||
)
|
||||
if resource_type:
|
||||
return self._describe_tags_for_resource_type(resource_type.lower())
|
||||
if resource_name:
|
||||
|
|
@ -795,4 +898,6 @@ class RedshiftBackend(BaseBackend):
|
|||
|
||||
redshift_backends = {}
|
||||
for region in boto.redshift.regions():
|
||||
redshift_backends[region.name] = RedshiftBackend(ec2_backends[region.name], region.name)
|
||||
redshift_backends[region.name] = RedshiftBackend(
|
||||
ec2_backends[region.name], region.name
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,9 +13,10 @@ from .models import redshift_backends
|
|||
|
||||
def convert_json_error_to_xml(json_error):
|
||||
error = json.loads(json_error)
|
||||
code = error['Error']['Code']
|
||||
message = error['Error']['Message']
|
||||
template = Template("""
|
||||
code = error["Error"]["Code"]
|
||||
message = error["Error"]["Message"]
|
||||
template = Template(
|
||||
"""
|
||||
<RedshiftClientError>
|
||||
<Error>
|
||||
<Code>{{ code }}</Code>
|
||||
|
|
@ -23,7 +24,8 @@ def convert_json_error_to_xml(json_error):
|
|||
<Type>Sender</Type>
|
||||
</Error>
|
||||
<RequestId>6876f774-7273-11e4-85dc-39e55ca848d1</RequestId>
|
||||
</RedshiftClientError>""")
|
||||
</RedshiftClientError>"""
|
||||
)
|
||||
return template.render(code=code, message=message)
|
||||
|
||||
|
||||
|
|
@ -40,13 +42,12 @@ def itemize(data):
|
|||
ret[key] = itemize(data[key])
|
||||
return ret
|
||||
elif isinstance(data, list):
|
||||
return {'item': [itemize(value) for value in data]}
|
||||
return {"item": [itemize(value) for value in data]}
|
||||
else:
|
||||
return data
|
||||
|
||||
|
||||
class RedshiftResponse(BaseResponse):
|
||||
|
||||
@property
|
||||
def redshift_backend(self):
|
||||
return redshift_backends[self.region]
|
||||
|
|
@ -56,8 +57,8 @@ class RedshiftResponse(BaseResponse):
|
|||
return json.dumps(response)
|
||||
else:
|
||||
xml = xmltodict.unparse(itemize(response), full_document=False)
|
||||
if hasattr(xml, 'decode'):
|
||||
xml = xml.decode('utf-8')
|
||||
if hasattr(xml, "decode"):
|
||||
xml = xml.decode("utf-8")
|
||||
return xml
|
||||
|
||||
def call_action(self):
|
||||
|
|
@ -69,11 +70,12 @@ class RedshiftResponse(BaseResponse):
|
|||
def unpack_complex_list_params(self, label, names):
|
||||
unpacked_list = list()
|
||||
count = 1
|
||||
while self._get_param('{0}.{1}.{2}'.format(label, count, names[0])):
|
||||
while self._get_param("{0}.{1}.{2}".format(label, count, names[0])):
|
||||
param = dict()
|
||||
for i in range(len(names)):
|
||||
param[names[i]] = self._get_param(
|
||||
'{0}.{1}.{2}'.format(label, count, names[i]))
|
||||
"{0}.{1}.{2}".format(label, count, names[i])
|
||||
)
|
||||
unpacked_list.append(param)
|
||||
count += 1
|
||||
return unpacked_list
|
||||
|
|
@ -81,148 +83,168 @@ class RedshiftResponse(BaseResponse):
|
|||
def unpack_list_params(self, label):
|
||||
unpacked_list = list()
|
||||
count = 1
|
||||
while self._get_param('{0}.{1}'.format(label, count)):
|
||||
unpacked_list.append(self._get_param(
|
||||
'{0}.{1}'.format(label, count)))
|
||||
while self._get_param("{0}.{1}".format(label, count)):
|
||||
unpacked_list.append(self._get_param("{0}.{1}".format(label, count)))
|
||||
count += 1
|
||||
return unpacked_list
|
||||
|
||||
def _get_cluster_security_groups(self):
|
||||
cluster_security_groups = self._get_multi_param('ClusterSecurityGroups.member')
|
||||
cluster_security_groups = self._get_multi_param("ClusterSecurityGroups.member")
|
||||
if not cluster_security_groups:
|
||||
cluster_security_groups = self._get_multi_param('ClusterSecurityGroups.ClusterSecurityGroupName')
|
||||
cluster_security_groups = self._get_multi_param(
|
||||
"ClusterSecurityGroups.ClusterSecurityGroupName"
|
||||
)
|
||||
return cluster_security_groups
|
||||
|
||||
def _get_vpc_security_group_ids(self):
|
||||
vpc_security_group_ids = self._get_multi_param('VpcSecurityGroupIds.member')
|
||||
vpc_security_group_ids = self._get_multi_param("VpcSecurityGroupIds.member")
|
||||
if not vpc_security_group_ids:
|
||||
vpc_security_group_ids = self._get_multi_param('VpcSecurityGroupIds.VpcSecurityGroupId')
|
||||
vpc_security_group_ids = self._get_multi_param(
|
||||
"VpcSecurityGroupIds.VpcSecurityGroupId"
|
||||
)
|
||||
return vpc_security_group_ids
|
||||
|
||||
def _get_iam_roles(self):
|
||||
iam_roles = self._get_multi_param('IamRoles.member')
|
||||
iam_roles = self._get_multi_param("IamRoles.member")
|
||||
if not iam_roles:
|
||||
iam_roles = self._get_multi_param('IamRoles.IamRoleArn')
|
||||
iam_roles = self._get_multi_param("IamRoles.IamRoleArn")
|
||||
return iam_roles
|
||||
|
||||
def _get_subnet_ids(self):
|
||||
subnet_ids = self._get_multi_param('SubnetIds.member')
|
||||
subnet_ids = self._get_multi_param("SubnetIds.member")
|
||||
if not subnet_ids:
|
||||
subnet_ids = self._get_multi_param('SubnetIds.SubnetIdentifier')
|
||||
subnet_ids = self._get_multi_param("SubnetIds.SubnetIdentifier")
|
||||
return subnet_ids
|
||||
|
||||
def create_cluster(self):
|
||||
cluster_kwargs = {
|
||||
"cluster_identifier": self._get_param('ClusterIdentifier'),
|
||||
"node_type": self._get_param('NodeType'),
|
||||
"master_username": self._get_param('MasterUsername'),
|
||||
"master_user_password": self._get_param('MasterUserPassword'),
|
||||
"db_name": self._get_param('DBName'),
|
||||
"cluster_type": self._get_param('ClusterType'),
|
||||
"cluster_identifier": self._get_param("ClusterIdentifier"),
|
||||
"node_type": self._get_param("NodeType"),
|
||||
"master_username": self._get_param("MasterUsername"),
|
||||
"master_user_password": self._get_param("MasterUserPassword"),
|
||||
"db_name": self._get_param("DBName"),
|
||||
"cluster_type": self._get_param("ClusterType"),
|
||||
"cluster_security_groups": self._get_cluster_security_groups(),
|
||||
"vpc_security_group_ids": self._get_vpc_security_group_ids(),
|
||||
"cluster_subnet_group_name": self._get_param('ClusterSubnetGroupName'),
|
||||
"availability_zone": self._get_param('AvailabilityZone'),
|
||||
"preferred_maintenance_window": self._get_param('PreferredMaintenanceWindow'),
|
||||
"cluster_parameter_group_name": self._get_param('ClusterParameterGroupName'),
|
||||
"automated_snapshot_retention_period": self._get_int_param('AutomatedSnapshotRetentionPeriod'),
|
||||
"port": self._get_int_param('Port'),
|
||||
"cluster_version": self._get_param('ClusterVersion'),
|
||||
"allow_version_upgrade": self._get_bool_param('AllowVersionUpgrade'),
|
||||
"number_of_nodes": self._get_int_param('NumberOfNodes'),
|
||||
"cluster_subnet_group_name": self._get_param("ClusterSubnetGroupName"),
|
||||
"availability_zone": self._get_param("AvailabilityZone"),
|
||||
"preferred_maintenance_window": self._get_param(
|
||||
"PreferredMaintenanceWindow"
|
||||
),
|
||||
"cluster_parameter_group_name": self._get_param(
|
||||
"ClusterParameterGroupName"
|
||||
),
|
||||
"automated_snapshot_retention_period": self._get_int_param(
|
||||
"AutomatedSnapshotRetentionPeriod"
|
||||
),
|
||||
"port": self._get_int_param("Port"),
|
||||
"cluster_version": self._get_param("ClusterVersion"),
|
||||
"allow_version_upgrade": self._get_bool_param("AllowVersionUpgrade"),
|
||||
"number_of_nodes": self._get_int_param("NumberOfNodes"),
|
||||
"publicly_accessible": self._get_param("PubliclyAccessible"),
|
||||
"encrypted": self._get_param("Encrypted"),
|
||||
"region_name": self.region,
|
||||
"tags": self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value')),
|
||||
"tags": self.unpack_complex_list_params("Tags.Tag", ("Key", "Value")),
|
||||
"iam_roles_arn": self._get_iam_roles(),
|
||||
"enhanced_vpc_routing": self._get_param('EnhancedVpcRouting'),
|
||||
"enhanced_vpc_routing": self._get_param("EnhancedVpcRouting"),
|
||||
}
|
||||
cluster = self.redshift_backend.create_cluster(**cluster_kwargs).to_json()
|
||||
cluster['ClusterStatus'] = 'creating'
|
||||
return self.get_response({
|
||||
"CreateClusterResponse": {
|
||||
"CreateClusterResult": {
|
||||
"Cluster": cluster,
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
cluster["ClusterStatus"] = "creating"
|
||||
return self.get_response(
|
||||
{
|
||||
"CreateClusterResponse": {
|
||||
"CreateClusterResult": {"Cluster": cluster},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def restore_from_cluster_snapshot(self):
|
||||
enhanced_vpc_routing = self._get_bool_param('EnhancedVpcRouting')
|
||||
enhanced_vpc_routing = self._get_bool_param("EnhancedVpcRouting")
|
||||
restore_kwargs = {
|
||||
"snapshot_identifier": self._get_param('SnapshotIdentifier'),
|
||||
"cluster_identifier": self._get_param('ClusterIdentifier'),
|
||||
"port": self._get_int_param('Port'),
|
||||
"availability_zone": self._get_param('AvailabilityZone'),
|
||||
"allow_version_upgrade": self._get_bool_param(
|
||||
'AllowVersionUpgrade'),
|
||||
"cluster_subnet_group_name": self._get_param(
|
||||
'ClusterSubnetGroupName'),
|
||||
"snapshot_identifier": self._get_param("SnapshotIdentifier"),
|
||||
"cluster_identifier": self._get_param("ClusterIdentifier"),
|
||||
"port": self._get_int_param("Port"),
|
||||
"availability_zone": self._get_param("AvailabilityZone"),
|
||||
"allow_version_upgrade": self._get_bool_param("AllowVersionUpgrade"),
|
||||
"cluster_subnet_group_name": self._get_param("ClusterSubnetGroupName"),
|
||||
"publicly_accessible": self._get_param("PubliclyAccessible"),
|
||||
"cluster_parameter_group_name": self._get_param(
|
||||
'ClusterParameterGroupName'),
|
||||
"ClusterParameterGroupName"
|
||||
),
|
||||
"cluster_security_groups": self._get_cluster_security_groups(),
|
||||
"vpc_security_group_ids": self._get_vpc_security_group_ids(),
|
||||
"preferred_maintenance_window": self._get_param(
|
||||
'PreferredMaintenanceWindow'),
|
||||
"PreferredMaintenanceWindow"
|
||||
),
|
||||
"automated_snapshot_retention_period": self._get_int_param(
|
||||
'AutomatedSnapshotRetentionPeriod'),
|
||||
"AutomatedSnapshotRetentionPeriod"
|
||||
),
|
||||
"region_name": self.region,
|
||||
"iam_roles_arn": self._get_iam_roles(),
|
||||
}
|
||||
if enhanced_vpc_routing is not None:
|
||||
restore_kwargs['enhanced_vpc_routing'] = enhanced_vpc_routing
|
||||
cluster = self.redshift_backend.restore_from_cluster_snapshot(**restore_kwargs).to_json()
|
||||
cluster['ClusterStatus'] = 'creating'
|
||||
return self.get_response({
|
||||
"RestoreFromClusterSnapshotResponse": {
|
||||
"RestoreFromClusterSnapshotResult": {
|
||||
"Cluster": cluster,
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
restore_kwargs["enhanced_vpc_routing"] = enhanced_vpc_routing
|
||||
cluster = self.redshift_backend.restore_from_cluster_snapshot(
|
||||
**restore_kwargs
|
||||
).to_json()
|
||||
cluster["ClusterStatus"] = "creating"
|
||||
return self.get_response(
|
||||
{
|
||||
"RestoreFromClusterSnapshotResponse": {
|
||||
"RestoreFromClusterSnapshotResult": {"Cluster": cluster},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def describe_clusters(self):
|
||||
cluster_identifier = self._get_param("ClusterIdentifier")
|
||||
clusters = self.redshift_backend.describe_clusters(cluster_identifier)
|
||||
|
||||
return self.get_response({
|
||||
"DescribeClustersResponse": {
|
||||
"DescribeClustersResult": {
|
||||
"Clusters": [cluster.to_json() for cluster in clusters]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DescribeClustersResponse": {
|
||||
"DescribeClustersResult": {
|
||||
"Clusters": [cluster.to_json() for cluster in clusters]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def modify_cluster(self):
|
||||
request_kwargs = {
|
||||
"cluster_identifier": self._get_param('ClusterIdentifier'),
|
||||
"new_cluster_identifier": self._get_param('NewClusterIdentifier'),
|
||||
"node_type": self._get_param('NodeType'),
|
||||
"master_user_password": self._get_param('MasterUserPassword'),
|
||||
"cluster_type": self._get_param('ClusterType'),
|
||||
"cluster_identifier": self._get_param("ClusterIdentifier"),
|
||||
"new_cluster_identifier": self._get_param("NewClusterIdentifier"),
|
||||
"node_type": self._get_param("NodeType"),
|
||||
"master_user_password": self._get_param("MasterUserPassword"),
|
||||
"cluster_type": self._get_param("ClusterType"),
|
||||
"cluster_security_groups": self._get_cluster_security_groups(),
|
||||
"vpc_security_group_ids": self._get_vpc_security_group_ids(),
|
||||
"cluster_subnet_group_name": self._get_param('ClusterSubnetGroupName'),
|
||||
"preferred_maintenance_window": self._get_param('PreferredMaintenanceWindow'),
|
||||
"cluster_parameter_group_name": self._get_param('ClusterParameterGroupName'),
|
||||
"automated_snapshot_retention_period": self._get_int_param('AutomatedSnapshotRetentionPeriod'),
|
||||
"cluster_version": self._get_param('ClusterVersion'),
|
||||
"allow_version_upgrade": self._get_bool_param('AllowVersionUpgrade'),
|
||||
"number_of_nodes": self._get_int_param('NumberOfNodes'),
|
||||
"cluster_subnet_group_name": self._get_param("ClusterSubnetGroupName"),
|
||||
"preferred_maintenance_window": self._get_param(
|
||||
"PreferredMaintenanceWindow"
|
||||
),
|
||||
"cluster_parameter_group_name": self._get_param(
|
||||
"ClusterParameterGroupName"
|
||||
),
|
||||
"automated_snapshot_retention_period": self._get_int_param(
|
||||
"AutomatedSnapshotRetentionPeriod"
|
||||
),
|
||||
"cluster_version": self._get_param("ClusterVersion"),
|
||||
"allow_version_upgrade": self._get_bool_param("AllowVersionUpgrade"),
|
||||
"number_of_nodes": self._get_int_param("NumberOfNodes"),
|
||||
"publicly_accessible": self._get_param("PubliclyAccessible"),
|
||||
"encrypted": self._get_param("Encrypted"),
|
||||
"iam_roles_arn": self._get_iam_roles(),
|
||||
"enhanced_vpc_routing": self._get_param("EnhancedVpcRouting")
|
||||
"enhanced_vpc_routing": self._get_param("EnhancedVpcRouting"),
|
||||
}
|
||||
cluster_kwargs = {}
|
||||
# We only want parameters that were actually passed in, otherwise
|
||||
|
|
@ -233,394 +255,442 @@ class RedshiftResponse(BaseResponse):
|
|||
|
||||
cluster = self.redshift_backend.modify_cluster(**cluster_kwargs)
|
||||
|
||||
return self.get_response({
|
||||
"ModifyClusterResponse": {
|
||||
"ModifyClusterResult": {
|
||||
"Cluster": cluster.to_json(),
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"ModifyClusterResponse": {
|
||||
"ModifyClusterResult": {"Cluster": cluster.to_json()},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def delete_cluster(self):
|
||||
request_kwargs = {
|
||||
"cluster_identifier": self._get_param("ClusterIdentifier"),
|
||||
"final_cluster_snapshot_identifier": self._get_param("FinalClusterSnapshotIdentifier"),
|
||||
"skip_final_snapshot": self._get_bool_param("SkipFinalClusterSnapshot")
|
||||
"final_cluster_snapshot_identifier": self._get_param(
|
||||
"FinalClusterSnapshotIdentifier"
|
||||
),
|
||||
"skip_final_snapshot": self._get_bool_param("SkipFinalClusterSnapshot"),
|
||||
}
|
||||
|
||||
cluster = self.redshift_backend.delete_cluster(**request_kwargs)
|
||||
|
||||
return self.get_response({
|
||||
"DeleteClusterResponse": {
|
||||
"DeleteClusterResult": {
|
||||
"Cluster": cluster.to_json()
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DeleteClusterResponse": {
|
||||
"DeleteClusterResult": {"Cluster": cluster.to_json()},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def create_cluster_subnet_group(self):
|
||||
cluster_subnet_group_name = self._get_param('ClusterSubnetGroupName')
|
||||
description = self._get_param('Description')
|
||||
cluster_subnet_group_name = self._get_param("ClusterSubnetGroupName")
|
||||
description = self._get_param("Description")
|
||||
subnet_ids = self._get_subnet_ids()
|
||||
tags = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
|
||||
tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value"))
|
||||
|
||||
subnet_group = self.redshift_backend.create_cluster_subnet_group(
|
||||
cluster_subnet_group_name=cluster_subnet_group_name,
|
||||
description=description,
|
||||
subnet_ids=subnet_ids,
|
||||
region_name=self.region,
|
||||
tags=tags
|
||||
tags=tags,
|
||||
)
|
||||
|
||||
return self.get_response({
|
||||
"CreateClusterSubnetGroupResponse": {
|
||||
"CreateClusterSubnetGroupResult": {
|
||||
"ClusterSubnetGroup": subnet_group.to_json(),
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"CreateClusterSubnetGroupResponse": {
|
||||
"CreateClusterSubnetGroupResult": {
|
||||
"ClusterSubnetGroup": subnet_group.to_json()
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def describe_cluster_subnet_groups(self):
|
||||
subnet_identifier = self._get_param("ClusterSubnetGroupName")
|
||||
subnet_groups = self.redshift_backend.describe_cluster_subnet_groups(
|
||||
subnet_identifier)
|
||||
subnet_identifier
|
||||
)
|
||||
|
||||
return self.get_response({
|
||||
"DescribeClusterSubnetGroupsResponse": {
|
||||
"DescribeClusterSubnetGroupsResult": {
|
||||
"ClusterSubnetGroups": [subnet_group.to_json() for subnet_group in subnet_groups]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DescribeClusterSubnetGroupsResponse": {
|
||||
"DescribeClusterSubnetGroupsResult": {
|
||||
"ClusterSubnetGroups": [
|
||||
subnet_group.to_json() for subnet_group in subnet_groups
|
||||
]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def delete_cluster_subnet_group(self):
|
||||
subnet_identifier = self._get_param("ClusterSubnetGroupName")
|
||||
self.redshift_backend.delete_cluster_subnet_group(subnet_identifier)
|
||||
|
||||
return self.get_response({
|
||||
"DeleteClusterSubnetGroupResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DeleteClusterSubnetGroupResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def create_cluster_security_group(self):
|
||||
cluster_security_group_name = self._get_param(
|
||||
'ClusterSecurityGroupName')
|
||||
description = self._get_param('Description')
|
||||
tags = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
|
||||
cluster_security_group_name = self._get_param("ClusterSecurityGroupName")
|
||||
description = self._get_param("Description")
|
||||
tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value"))
|
||||
|
||||
security_group = self.redshift_backend.create_cluster_security_group(
|
||||
cluster_security_group_name=cluster_security_group_name,
|
||||
description=description,
|
||||
region_name=self.region,
|
||||
tags=tags
|
||||
tags=tags,
|
||||
)
|
||||
|
||||
return self.get_response({
|
||||
"CreateClusterSecurityGroupResponse": {
|
||||
"CreateClusterSecurityGroupResult": {
|
||||
"ClusterSecurityGroup": security_group.to_json(),
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"CreateClusterSecurityGroupResponse": {
|
||||
"CreateClusterSecurityGroupResult": {
|
||||
"ClusterSecurityGroup": security_group.to_json()
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def describe_cluster_security_groups(self):
|
||||
cluster_security_group_name = self._get_param(
|
||||
"ClusterSecurityGroupName")
|
||||
cluster_security_group_name = self._get_param("ClusterSecurityGroupName")
|
||||
security_groups = self.redshift_backend.describe_cluster_security_groups(
|
||||
cluster_security_group_name)
|
||||
cluster_security_group_name
|
||||
)
|
||||
|
||||
return self.get_response({
|
||||
"DescribeClusterSecurityGroupsResponse": {
|
||||
"DescribeClusterSecurityGroupsResult": {
|
||||
"ClusterSecurityGroups": [security_group.to_json() for security_group in security_groups]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DescribeClusterSecurityGroupsResponse": {
|
||||
"DescribeClusterSecurityGroupsResult": {
|
||||
"ClusterSecurityGroups": [
|
||||
security_group.to_json()
|
||||
for security_group in security_groups
|
||||
]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def delete_cluster_security_group(self):
|
||||
security_group_identifier = self._get_param("ClusterSecurityGroupName")
|
||||
self.redshift_backend.delete_cluster_security_group(
|
||||
security_group_identifier)
|
||||
self.redshift_backend.delete_cluster_security_group(security_group_identifier)
|
||||
|
||||
return self.get_response({
|
||||
"DeleteClusterSecurityGroupResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DeleteClusterSecurityGroupResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
def create_cluster_parameter_group(self):
|
||||
cluster_parameter_group_name = self._get_param('ParameterGroupName')
|
||||
group_family = self._get_param('ParameterGroupFamily')
|
||||
description = self._get_param('Description')
|
||||
tags = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
|
||||
|
||||
parameter_group = self.redshift_backend.create_cluster_parameter_group(
|
||||
cluster_parameter_group_name,
|
||||
group_family,
|
||||
description,
|
||||
self.region,
|
||||
tags
|
||||
)
|
||||
|
||||
return self.get_response({
|
||||
"CreateClusterParameterGroupResponse": {
|
||||
"CreateClusterParameterGroupResult": {
|
||||
"ClusterParameterGroup": parameter_group.to_json(),
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
def create_cluster_parameter_group(self):
|
||||
cluster_parameter_group_name = self._get_param("ParameterGroupName")
|
||||
group_family = self._get_param("ParameterGroupFamily")
|
||||
description = self._get_param("Description")
|
||||
tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value"))
|
||||
|
||||
parameter_group = self.redshift_backend.create_cluster_parameter_group(
|
||||
cluster_parameter_group_name, group_family, description, self.region, tags
|
||||
)
|
||||
|
||||
return self.get_response(
|
||||
{
|
||||
"CreateClusterParameterGroupResponse": {
|
||||
"CreateClusterParameterGroupResult": {
|
||||
"ClusterParameterGroup": parameter_group.to_json()
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def describe_cluster_parameter_groups(self):
|
||||
cluster_parameter_group_name = self._get_param("ParameterGroupName")
|
||||
parameter_groups = self.redshift_backend.describe_cluster_parameter_groups(
|
||||
cluster_parameter_group_name)
|
||||
cluster_parameter_group_name
|
||||
)
|
||||
|
||||
return self.get_response({
|
||||
"DescribeClusterParameterGroupsResponse": {
|
||||
"DescribeClusterParameterGroupsResult": {
|
||||
"ParameterGroups": [parameter_group.to_json() for parameter_group in parameter_groups]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DescribeClusterParameterGroupsResponse": {
|
||||
"DescribeClusterParameterGroupsResult": {
|
||||
"ParameterGroups": [
|
||||
parameter_group.to_json()
|
||||
for parameter_group in parameter_groups
|
||||
]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def delete_cluster_parameter_group(self):
|
||||
cluster_parameter_group_name = self._get_param("ParameterGroupName")
|
||||
self.redshift_backend.delete_cluster_parameter_group(
|
||||
cluster_parameter_group_name)
|
||||
cluster_parameter_group_name
|
||||
)
|
||||
|
||||
return self.get_response({
|
||||
"DeleteClusterParameterGroupResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DeleteClusterParameterGroupResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def create_cluster_snapshot(self):
|
||||
cluster_identifier = self._get_param('ClusterIdentifier')
|
||||
snapshot_identifier = self._get_param('SnapshotIdentifier')
|
||||
tags = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
|
||||
cluster_identifier = self._get_param("ClusterIdentifier")
|
||||
snapshot_identifier = self._get_param("SnapshotIdentifier")
|
||||
tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value"))
|
||||
|
||||
snapshot = self.redshift_backend.create_cluster_snapshot(cluster_identifier,
|
||||
snapshot_identifier,
|
||||
self.region,
|
||||
tags)
|
||||
return self.get_response({
|
||||
'CreateClusterSnapshotResponse': {
|
||||
"CreateClusterSnapshotResult": {
|
||||
"Snapshot": snapshot.to_json(),
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
snapshot = self.redshift_backend.create_cluster_snapshot(
|
||||
cluster_identifier, snapshot_identifier, self.region, tags
|
||||
)
|
||||
return self.get_response(
|
||||
{
|
||||
"CreateClusterSnapshotResponse": {
|
||||
"CreateClusterSnapshotResult": {"Snapshot": snapshot.to_json()},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def describe_cluster_snapshots(self):
|
||||
cluster_identifier = self._get_param('ClusterIdentifier')
|
||||
snapshot_identifier = self._get_param('SnapshotIdentifier')
|
||||
snapshots = self.redshift_backend.describe_cluster_snapshots(cluster_identifier,
|
||||
snapshot_identifier)
|
||||
return self.get_response({
|
||||
"DescribeClusterSnapshotsResponse": {
|
||||
"DescribeClusterSnapshotsResult": {
|
||||
"Snapshots": [snapshot.to_json() for snapshot in snapshots]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
cluster_identifier = self._get_param("ClusterIdentifier")
|
||||
snapshot_identifier = self._get_param("SnapshotIdentifier")
|
||||
snapshots = self.redshift_backend.describe_cluster_snapshots(
|
||||
cluster_identifier, snapshot_identifier
|
||||
)
|
||||
return self.get_response(
|
||||
{
|
||||
"DescribeClusterSnapshotsResponse": {
|
||||
"DescribeClusterSnapshotsResult": {
|
||||
"Snapshots": [snapshot.to_json() for snapshot in snapshots]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def delete_cluster_snapshot(self):
|
||||
snapshot_identifier = self._get_param('SnapshotIdentifier')
|
||||
snapshot_identifier = self._get_param("SnapshotIdentifier")
|
||||
snapshot = self.redshift_backend.delete_cluster_snapshot(snapshot_identifier)
|
||||
|
||||
return self.get_response({
|
||||
"DeleteClusterSnapshotResponse": {
|
||||
"DeleteClusterSnapshotResult": {
|
||||
"Snapshot": snapshot.to_json()
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DeleteClusterSnapshotResponse": {
|
||||
"DeleteClusterSnapshotResult": {"Snapshot": snapshot.to_json()},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def create_snapshot_copy_grant(self):
|
||||
copy_grant_kwargs = {
|
||||
'snapshot_copy_grant_name': self._get_param('SnapshotCopyGrantName'),
|
||||
'kms_key_id': self._get_param('KmsKeyId'),
|
||||
'region_name': self._get_param('Region'),
|
||||
"snapshot_copy_grant_name": self._get_param("SnapshotCopyGrantName"),
|
||||
"kms_key_id": self._get_param("KmsKeyId"),
|
||||
"region_name": self._get_param("Region"),
|
||||
}
|
||||
|
||||
copy_grant = self.redshift_backend.create_snapshot_copy_grant(**copy_grant_kwargs)
|
||||
return self.get_response({
|
||||
"CreateSnapshotCopyGrantResponse": {
|
||||
"CreateSnapshotCopyGrantResult": {
|
||||
"SnapshotCopyGrant": copy_grant.to_json()
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
copy_grant = self.redshift_backend.create_snapshot_copy_grant(
|
||||
**copy_grant_kwargs
|
||||
)
|
||||
return self.get_response(
|
||||
{
|
||||
"CreateSnapshotCopyGrantResponse": {
|
||||
"CreateSnapshotCopyGrantResult": {
|
||||
"SnapshotCopyGrant": copy_grant.to_json()
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def delete_snapshot_copy_grant(self):
|
||||
copy_grant_kwargs = {
|
||||
'snapshot_copy_grant_name': self._get_param('SnapshotCopyGrantName'),
|
||||
"snapshot_copy_grant_name": self._get_param("SnapshotCopyGrantName")
|
||||
}
|
||||
self.redshift_backend.delete_snapshot_copy_grant(**copy_grant_kwargs)
|
||||
return self.get_response({
|
||||
"DeleteSnapshotCopyGrantResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DeleteSnapshotCopyGrantResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def describe_snapshot_copy_grants(self):
|
||||
copy_grant_kwargs = {
|
||||
'snapshot_copy_grant_name': self._get_param('SnapshotCopyGrantName'),
|
||||
"snapshot_copy_grant_name": self._get_param("SnapshotCopyGrantName")
|
||||
}
|
||||
|
||||
copy_grants = self.redshift_backend.describe_snapshot_copy_grants(**copy_grant_kwargs)
|
||||
return self.get_response({
|
||||
"DescribeSnapshotCopyGrantsResponse": {
|
||||
"DescribeSnapshotCopyGrantsResult": {
|
||||
"SnapshotCopyGrants": [copy_grant.to_json() for copy_grant in copy_grants]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
copy_grants = self.redshift_backend.describe_snapshot_copy_grants(
|
||||
**copy_grant_kwargs
|
||||
)
|
||||
return self.get_response(
|
||||
{
|
||||
"DescribeSnapshotCopyGrantsResponse": {
|
||||
"DescribeSnapshotCopyGrantsResult": {
|
||||
"SnapshotCopyGrants": [
|
||||
copy_grant.to_json() for copy_grant in copy_grants
|
||||
]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def create_tags(self):
|
||||
resource_name = self._get_param('ResourceName')
|
||||
tags = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
|
||||
resource_name = self._get_param("ResourceName")
|
||||
tags = self.unpack_complex_list_params("Tags.Tag", ("Key", "Value"))
|
||||
|
||||
self.redshift_backend.create_tags(resource_name, tags)
|
||||
|
||||
return self.get_response({
|
||||
"CreateTagsResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"CreateTagsResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def describe_tags(self):
|
||||
resource_name = self._get_param('ResourceName')
|
||||
resource_type = self._get_param('ResourceType')
|
||||
resource_name = self._get_param("ResourceName")
|
||||
resource_type = self._get_param("ResourceType")
|
||||
|
||||
tagged_resources = self.redshift_backend.describe_tags(resource_name,
|
||||
resource_type)
|
||||
return self.get_response({
|
||||
"DescribeTagsResponse": {
|
||||
"DescribeTagsResult": {
|
||||
"TaggedResources": tagged_resources
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
tagged_resources = self.redshift_backend.describe_tags(
|
||||
resource_name, resource_type
|
||||
)
|
||||
return self.get_response(
|
||||
{
|
||||
"DescribeTagsResponse": {
|
||||
"DescribeTagsResult": {"TaggedResources": tagged_resources},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def delete_tags(self):
|
||||
resource_name = self._get_param('ResourceName')
|
||||
tag_keys = self.unpack_list_params('TagKeys.TagKey')
|
||||
resource_name = self._get_param("ResourceName")
|
||||
tag_keys = self.unpack_list_params("TagKeys.TagKey")
|
||||
|
||||
self.redshift_backend.delete_tags(resource_name, tag_keys)
|
||||
|
||||
return self.get_response({
|
||||
"DeleteTagsResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DeleteTagsResponse": {
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def enable_snapshot_copy(self):
|
||||
snapshot_copy_kwargs = {
|
||||
'cluster_identifier': self._get_param('ClusterIdentifier'),
|
||||
'destination_region': self._get_param('DestinationRegion'),
|
||||
'retention_period': self._get_param('RetentionPeriod', 7),
|
||||
'snapshot_copy_grant_name': self._get_param('SnapshotCopyGrantName'),
|
||||
"cluster_identifier": self._get_param("ClusterIdentifier"),
|
||||
"destination_region": self._get_param("DestinationRegion"),
|
||||
"retention_period": self._get_param("RetentionPeriod", 7),
|
||||
"snapshot_copy_grant_name": self._get_param("SnapshotCopyGrantName"),
|
||||
}
|
||||
cluster = self.redshift_backend.enable_snapshot_copy(**snapshot_copy_kwargs)
|
||||
|
||||
return self.get_response({
|
||||
"EnableSnapshotCopyResponse": {
|
||||
"EnableSnapshotCopyResult": {
|
||||
"Cluster": cluster.to_json()
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"EnableSnapshotCopyResponse": {
|
||||
"EnableSnapshotCopyResult": {"Cluster": cluster.to_json()},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def disable_snapshot_copy(self):
|
||||
snapshot_copy_kwargs = {
|
||||
'cluster_identifier': self._get_param('ClusterIdentifier'),
|
||||
"cluster_identifier": self._get_param("ClusterIdentifier")
|
||||
}
|
||||
cluster = self.redshift_backend.disable_snapshot_copy(**snapshot_copy_kwargs)
|
||||
|
||||
return self.get_response({
|
||||
"DisableSnapshotCopyResponse": {
|
||||
"DisableSnapshotCopyResult": {
|
||||
"Cluster": cluster.to_json()
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"DisableSnapshotCopyResponse": {
|
||||
"DisableSnapshotCopyResult": {"Cluster": cluster.to_json()},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
def modify_snapshot_copy_retention_period(self):
|
||||
snapshot_copy_kwargs = {
|
||||
'cluster_identifier': self._get_param('ClusterIdentifier'),
|
||||
'retention_period': self._get_param('RetentionPeriod'),
|
||||
"cluster_identifier": self._get_param("ClusterIdentifier"),
|
||||
"retention_period": self._get_param("RetentionPeriod"),
|
||||
}
|
||||
cluster = self.redshift_backend.modify_snapshot_copy_retention_period(**snapshot_copy_kwargs)
|
||||
cluster = self.redshift_backend.modify_snapshot_copy_retention_period(
|
||||
**snapshot_copy_kwargs
|
||||
)
|
||||
|
||||
return self.get_response({
|
||||
"ModifySnapshotCopyRetentionPeriodResponse": {
|
||||
"ModifySnapshotCopyRetentionPeriodResult": {
|
||||
"Clusters": [cluster.to_json()]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||
return self.get_response(
|
||||
{
|
||||
"ModifySnapshotCopyRetentionPeriodResponse": {
|
||||
"ModifySnapshotCopyRetentionPeriodResult": {
|
||||
"Clusters": [cluster.to_json()]
|
||||
},
|
||||
"ResponseMetadata": {
|
||||
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a"
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
from __future__ import unicode_literals
|
||||
from .responses import RedshiftResponse
|
||||
|
||||
url_bases = [
|
||||
"https?://redshift.(.+).amazonaws.com",
|
||||
]
|
||||
url_bases = ["https?://redshift.(.+).amazonaws.com"]
|
||||
|
||||
url_paths = {
|
||||
'{0}/$': RedshiftResponse.dispatch,
|
||||
}
|
||||
url_paths = {"{0}/$": RedshiftResponse.dispatch}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue