Run black on moto & test directories.

This commit is contained in:
Asher Foa 2019-10-31 08:44:26 -07:00
commit 96e5b1993d
507 changed files with 52541 additions and 47814 deletions

View file

@ -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)

View file

@ -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
),
)

View file

@ -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
)

View file

@ -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"
},
}
}
})
)

View file

@ -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}