moto/tests/test_redshift/test_redshift.py
2020-05-06 14:28:40 -07:00

1358 lines
48 KiB
Python

from __future__ import unicode_literals
import datetime
import boto
import boto3
from boto.redshift.exceptions import (
ClusterNotFound,
ClusterParameterGroupNotFound,
ClusterSecurityGroupNotFound,
ClusterSubnetGroupNotFound,
InvalidSubnet,
)
from botocore.exceptions import ClientError
import sure # noqa
from moto import mock_ec2
from moto import mock_ec2_deprecated
from moto import mock_redshift
from moto import mock_redshift_deprecated
from moto.core import ACCOUNT_ID
@mock_redshift
def test_create_cluster_boto3():
client = boto3.client("redshift", region_name="us-east-1")
response = client.create_cluster(
DBName="test",
ClusterIdentifier="test",
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="user",
MasterUserPassword="password",
)
response["Cluster"]["NodeType"].should.equal("ds2.xlarge")
create_time = response["Cluster"]["ClusterCreateTime"]
create_time.should.be.lower_than(datetime.datetime.now(create_time.tzinfo))
create_time.should.be.greater_than(
datetime.datetime.now(create_time.tzinfo) - datetime.timedelta(minutes=1)
)
response["Cluster"]["EnhancedVpcRouting"].should.equal(False)
@mock_redshift
def test_create_cluster_boto3():
client = boto3.client("redshift", region_name="us-east-1")
response = client.create_cluster(
DBName="test",
ClusterIdentifier="test",
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="user",
MasterUserPassword="password",
EnhancedVpcRouting=True,
)
response["Cluster"]["NodeType"].should.equal("ds2.xlarge")
create_time = response["Cluster"]["ClusterCreateTime"]
create_time.should.be.lower_than(datetime.datetime.now(create_time.tzinfo))
create_time.should.be.greater_than(
datetime.datetime.now(create_time.tzinfo) - datetime.timedelta(minutes=1)
)
response["Cluster"]["EnhancedVpcRouting"].should.equal(True)
@mock_redshift
def test_create_snapshot_copy_grant():
client = boto3.client("redshift", region_name="us-east-1")
grants = client.create_snapshot_copy_grant(
SnapshotCopyGrantName="test-us-east-1", KmsKeyId="fake"
)
grants["SnapshotCopyGrant"]["SnapshotCopyGrantName"].should.equal("test-us-east-1")
grants["SnapshotCopyGrant"]["KmsKeyId"].should.equal("fake")
client.delete_snapshot_copy_grant(SnapshotCopyGrantName="test-us-east-1")
client.describe_snapshot_copy_grants.when.called_with(
SnapshotCopyGrantName="test-us-east-1"
).should.throw(Exception)
@mock_redshift
def test_create_many_snapshot_copy_grants():
client = boto3.client("redshift", region_name="us-east-1")
for i in range(10):
client.create_snapshot_copy_grant(
SnapshotCopyGrantName="test-us-east-1-{0}".format(i), KmsKeyId="fake"
)
response = client.describe_snapshot_copy_grants()
len(response["SnapshotCopyGrants"]).should.equal(10)
@mock_redshift
def test_no_snapshot_copy_grants():
client = boto3.client("redshift", region_name="us-east-1")
response = client.describe_snapshot_copy_grants()
len(response["SnapshotCopyGrants"]).should.equal(0)
@mock_redshift_deprecated
def test_create_cluster():
conn = boto.redshift.connect_to_region("us-east-1")
cluster_identifier = "my_cluster"
cluster_response = conn.create_cluster(
cluster_identifier,
node_type="dw.hs1.xlarge",
master_username="username",
master_user_password="password",
db_name="my_db",
cluster_type="multi-node",
availability_zone="us-east-1d",
preferred_maintenance_window="Mon:03:00-Mon:11:00",
automated_snapshot_retention_period=10,
port=1234,
cluster_version="1.0",
allow_version_upgrade=True,
number_of_nodes=3,
)
cluster_response["CreateClusterResponse"]["CreateClusterResult"]["Cluster"][
"ClusterStatus"
].should.equal("creating")
cluster_response = conn.describe_clusters(cluster_identifier)
cluster = cluster_response["DescribeClustersResponse"]["DescribeClustersResult"][
"Clusters"
][0]
cluster["ClusterIdentifier"].should.equal(cluster_identifier)
cluster["NodeType"].should.equal("dw.hs1.xlarge")
cluster["MasterUsername"].should.equal("username")
cluster["DBName"].should.equal("my_db")
cluster["ClusterSecurityGroups"][0]["ClusterSecurityGroupName"].should.equal(
"Default"
)
cluster["VpcSecurityGroups"].should.equal([])
cluster["ClusterSubnetGroupName"].should.equal(None)
cluster["AvailabilityZone"].should.equal("us-east-1d")
cluster["PreferredMaintenanceWindow"].should.equal("Mon:03:00-Mon:11:00")
cluster["ClusterParameterGroups"][0]["ParameterGroupName"].should.equal(
"default.redshift-1.0"
)
cluster["AutomatedSnapshotRetentionPeriod"].should.equal(10)
cluster["Port"].should.equal(1234)
cluster["ClusterVersion"].should.equal("1.0")
cluster["AllowVersionUpgrade"].should.equal(True)
cluster["NumberOfNodes"].should.equal(3)
@mock_redshift_deprecated
def test_create_single_node_cluster():
conn = boto.redshift.connect_to_region("us-east-1")
cluster_identifier = "my_cluster"
conn.create_cluster(
cluster_identifier,
node_type="dw.hs1.xlarge",
master_username="username",
master_user_password="password",
db_name="my_db",
cluster_type="single-node",
)
cluster_response = conn.describe_clusters(cluster_identifier)
cluster = cluster_response["DescribeClustersResponse"]["DescribeClustersResult"][
"Clusters"
][0]
cluster["ClusterIdentifier"].should.equal(cluster_identifier)
cluster["NodeType"].should.equal("dw.hs1.xlarge")
cluster["MasterUsername"].should.equal("username")
cluster["DBName"].should.equal("my_db")
cluster["NumberOfNodes"].should.equal(1)
@mock_redshift_deprecated
def test_default_cluster_attributes():
conn = boto.redshift.connect_to_region("us-east-1")
cluster_identifier = "my_cluster"
conn.create_cluster(
cluster_identifier,
node_type="dw.hs1.xlarge",
master_username="username",
master_user_password="password",
)
cluster_response = conn.describe_clusters(cluster_identifier)
cluster = cluster_response["DescribeClustersResponse"]["DescribeClustersResult"][
"Clusters"
][0]
cluster["DBName"].should.equal("dev")
cluster["ClusterSubnetGroupName"].should.equal(None)
assert "us-east-" in cluster["AvailabilityZone"]
cluster["PreferredMaintenanceWindow"].should.equal("Mon:03:00-Mon:03:30")
cluster["ClusterParameterGroups"][0]["ParameterGroupName"].should.equal(
"default.redshift-1.0"
)
cluster["AutomatedSnapshotRetentionPeriod"].should.equal(1)
cluster["Port"].should.equal(5439)
cluster["ClusterVersion"].should.equal("1.0")
cluster["AllowVersionUpgrade"].should.equal(True)
cluster["NumberOfNodes"].should.equal(1)
@mock_redshift
@mock_ec2
def test_create_cluster_in_subnet_group():
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/24")
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster_subnet_group(
ClusterSubnetGroupName="my_subnet_group",
Description="This is my subnet group",
SubnetIds=[subnet.id],
)
client.create_cluster(
ClusterIdentifier="my_cluster",
NodeType="dw.hs1.xlarge",
MasterUsername="username",
MasterUserPassword="password",
ClusterSubnetGroupName="my_subnet_group",
)
cluster_response = client.describe_clusters(ClusterIdentifier="my_cluster")
cluster = cluster_response["Clusters"][0]
cluster["ClusterSubnetGroupName"].should.equal("my_subnet_group")
@mock_redshift
@mock_ec2
def test_create_cluster_in_subnet_group_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/24")
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster_subnet_group(
ClusterSubnetGroupName="my_subnet_group",
Description="This is my subnet group",
SubnetIds=[subnet.id],
)
client.create_cluster(
ClusterIdentifier="my_cluster",
NodeType="dw.hs1.xlarge",
MasterUsername="username",
MasterUserPassword="password",
ClusterSubnetGroupName="my_subnet_group",
)
cluster_response = client.describe_clusters(ClusterIdentifier="my_cluster")
cluster = cluster_response["Clusters"][0]
cluster["ClusterSubnetGroupName"].should.equal("my_subnet_group")
@mock_redshift_deprecated
def test_create_cluster_with_security_group():
conn = boto.redshift.connect_to_region("us-east-1")
conn.create_cluster_security_group("security_group1", "This is my security group")
conn.create_cluster_security_group("security_group2", "This is my security group")
cluster_identifier = "my_cluster"
conn.create_cluster(
cluster_identifier,
node_type="dw.hs1.xlarge",
master_username="username",
master_user_password="password",
cluster_security_groups=["security_group1", "security_group2"],
)
cluster_response = conn.describe_clusters(cluster_identifier)
cluster = cluster_response["DescribeClustersResponse"]["DescribeClustersResult"][
"Clusters"
][0]
group_names = [
group["ClusterSecurityGroupName"] for group in cluster["ClusterSecurityGroups"]
]
set(group_names).should.equal(set(["security_group1", "security_group2"]))
@mock_redshift
def test_create_cluster_with_security_group_boto3():
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster_security_group(
ClusterSecurityGroupName="security_group1",
Description="This is my security group",
)
client.create_cluster_security_group(
ClusterSecurityGroupName="security_group2",
Description="This is my security group",
)
cluster_identifier = "my_cluster"
client.create_cluster(
ClusterIdentifier=cluster_identifier,
NodeType="dw.hs1.xlarge",
MasterUsername="username",
MasterUserPassword="password",
ClusterSecurityGroups=["security_group1", "security_group2"],
)
response = client.describe_clusters(ClusterIdentifier=cluster_identifier)
cluster = response["Clusters"][0]
group_names = [
group["ClusterSecurityGroupName"] for group in cluster["ClusterSecurityGroups"]
]
set(group_names).should.equal({"security_group1", "security_group2"})
@mock_redshift_deprecated
@mock_ec2_deprecated
def test_create_cluster_with_vpc_security_groups():
vpc_conn = boto.connect_vpc()
ec2_conn = boto.connect_ec2()
redshift_conn = boto.connect_redshift()
vpc = vpc_conn.create_vpc("10.0.0.0/16")
security_group = ec2_conn.create_security_group(
"vpc_security_group", "a group", vpc_id=vpc.id
)
redshift_conn.create_cluster(
"my_cluster",
node_type="dw.hs1.xlarge",
master_username="username",
master_user_password="password",
vpc_security_group_ids=[security_group.id],
)
cluster_response = redshift_conn.describe_clusters("my_cluster")
cluster = cluster_response["DescribeClustersResponse"]["DescribeClustersResult"][
"Clusters"
][0]
group_ids = [group["VpcSecurityGroupId"] for group in cluster["VpcSecurityGroups"]]
list(group_ids).should.equal([security_group.id])
@mock_redshift
@mock_ec2
def test_create_cluster_with_vpc_security_groups_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
client = boto3.client("redshift", region_name="us-east-1")
cluster_id = "my_cluster"
security_group = ec2.create_security_group(
Description="vpc_security_group", GroupName="a group", VpcId=vpc.id
)
client.create_cluster(
ClusterIdentifier=cluster_id,
NodeType="dw.hs1.xlarge",
MasterUsername="username",
MasterUserPassword="password",
VpcSecurityGroupIds=[security_group.id],
)
response = client.describe_clusters(ClusterIdentifier=cluster_id)
cluster = response["Clusters"][0]
group_ids = [group["VpcSecurityGroupId"] for group in cluster["VpcSecurityGroups"]]
list(group_ids).should.equal([security_group.id])
@mock_redshift
def test_create_cluster_with_iam_roles():
iam_roles_arn = ["arn:aws:iam:::role/my-iam-role"]
client = boto3.client("redshift", region_name="us-east-1")
cluster_id = "my_cluster"
client.create_cluster(
ClusterIdentifier=cluster_id,
NodeType="dw.hs1.xlarge",
MasterUsername="username",
MasterUserPassword="password",
IamRoles=iam_roles_arn,
)
response = client.describe_clusters(ClusterIdentifier=cluster_id)
cluster = response["Clusters"][0]
iam_roles = [role["IamRoleArn"] for role in cluster["IamRoles"]]
iam_roles_arn.should.equal(iam_roles)
@mock_redshift_deprecated
def test_create_cluster_with_parameter_group():
conn = boto.connect_redshift()
conn.create_cluster_parameter_group(
"my_parameter_group", "redshift-1.0", "This is my parameter group"
)
conn.create_cluster(
"my_cluster",
node_type="dw.hs1.xlarge",
master_username="username",
master_user_password="password",
cluster_parameter_group_name="my_parameter_group",
)
cluster_response = conn.describe_clusters("my_cluster")
cluster = cluster_response["DescribeClustersResponse"]["DescribeClustersResult"][
"Clusters"
][0]
cluster["ClusterParameterGroups"][0]["ParameterGroupName"].should.equal(
"my_parameter_group"
)
@mock_redshift_deprecated
def test_describe_non_existent_cluster():
conn = boto.redshift.connect_to_region("us-east-1")
conn.describe_clusters.when.called_with("not-a-cluster").should.throw(
ClusterNotFound
)
@mock_redshift_deprecated
def test_delete_cluster():
conn = boto.connect_redshift()
cluster_identifier = "my_cluster"
snapshot_identifier = "my_snapshot"
conn.create_cluster(
cluster_identifier,
node_type="single-node",
master_username="username",
master_user_password="password",
)
conn.delete_cluster.when.called_with(cluster_identifier, False).should.throw(
AttributeError
)
clusters = conn.describe_clusters()["DescribeClustersResponse"][
"DescribeClustersResult"
]["Clusters"]
list(clusters).should.have.length_of(1)
conn.delete_cluster(
cluster_identifier=cluster_identifier,
skip_final_cluster_snapshot=False,
final_cluster_snapshot_identifier=snapshot_identifier,
)
clusters = conn.describe_clusters()["DescribeClustersResponse"][
"DescribeClustersResult"
]["Clusters"]
list(clusters).should.have.length_of(0)
snapshots = conn.describe_cluster_snapshots()["DescribeClusterSnapshotsResponse"][
"DescribeClusterSnapshotsResult"
]["Snapshots"]
list(snapshots).should.have.length_of(1)
assert snapshot_identifier in snapshots[0]["SnapshotIdentifier"]
# Delete invalid id
conn.delete_cluster.when.called_with("not-a-cluster").should.throw(ClusterNotFound)
@mock_redshift
def test_modify_cluster_vpc_routing():
iam_roles_arn = ["arn:aws:iam:::role/my-iam-role"]
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "my_cluster"
client.create_cluster(
ClusterIdentifier=cluster_identifier,
NodeType="single-node",
MasterUsername="username",
MasterUserPassword="password",
IamRoles=iam_roles_arn,
)
cluster_response = client.describe_clusters(ClusterIdentifier=cluster_identifier)
cluster = cluster_response["Clusters"][0]
cluster["EnhancedVpcRouting"].should.equal(False)
client.create_cluster_security_group(
ClusterSecurityGroupName="security_group", Description="security_group"
)
client.create_cluster_parameter_group(
ParameterGroupName="my_parameter_group",
ParameterGroupFamily="redshift-1.0",
Description="my_parameter_group",
)
client.modify_cluster(
ClusterIdentifier=cluster_identifier,
ClusterType="multi-node",
NodeType="ds2.8xlarge",
NumberOfNodes=3,
ClusterSecurityGroups=["security_group"],
MasterUserPassword="new_password",
ClusterParameterGroupName="my_parameter_group",
AutomatedSnapshotRetentionPeriod=7,
PreferredMaintenanceWindow="Tue:03:00-Tue:11:00",
AllowVersionUpgrade=False,
NewClusterIdentifier=cluster_identifier,
EnhancedVpcRouting=True,
)
cluster_response = client.describe_clusters(ClusterIdentifier=cluster_identifier)
cluster = cluster_response["Clusters"][0]
cluster["ClusterIdentifier"].should.equal(cluster_identifier)
cluster["NodeType"].should.equal("ds2.8xlarge")
cluster["PreferredMaintenanceWindow"].should.equal("Tue:03:00-Tue:11:00")
cluster["AutomatedSnapshotRetentionPeriod"].should.equal(7)
cluster["AllowVersionUpgrade"].should.equal(False)
# This one should remain unmodified.
cluster["NumberOfNodes"].should.equal(3)
cluster["EnhancedVpcRouting"].should.equal(True)
@mock_redshift_deprecated
def test_modify_cluster():
conn = boto.connect_redshift()
cluster_identifier = "my_cluster"
conn.create_cluster_security_group("security_group", "This is my security group")
conn.create_cluster_parameter_group(
"my_parameter_group", "redshift-1.0", "This is my parameter group"
)
conn.create_cluster(
cluster_identifier,
node_type="single-node",
master_username="username",
master_user_password="password",
)
cluster_response = conn.describe_clusters(cluster_identifier)
cluster = cluster_response["DescribeClustersResponse"]["DescribeClustersResult"][
"Clusters"
][0]
cluster["EnhancedVpcRouting"].should.equal(False)
conn.modify_cluster(
cluster_identifier,
cluster_type="multi-node",
node_type="dw.hs1.xlarge",
cluster_security_groups="security_group",
master_user_password="new_password",
cluster_parameter_group_name="my_parameter_group",
automated_snapshot_retention_period=7,
preferred_maintenance_window="Tue:03:00-Tue:11:00",
allow_version_upgrade=False,
new_cluster_identifier=cluster_identifier,
)
cluster_response = conn.describe_clusters(cluster_identifier)
cluster = cluster_response["DescribeClustersResponse"]["DescribeClustersResult"][
"Clusters"
][0]
cluster["ClusterIdentifier"].should.equal(cluster_identifier)
cluster["NodeType"].should.equal("dw.hs1.xlarge")
cluster["ClusterSecurityGroups"][0]["ClusterSecurityGroupName"].should.equal(
"security_group"
)
cluster["PreferredMaintenanceWindow"].should.equal("Tue:03:00-Tue:11:00")
cluster["ClusterParameterGroups"][0]["ParameterGroupName"].should.equal(
"my_parameter_group"
)
cluster["AutomatedSnapshotRetentionPeriod"].should.equal(7)
cluster["AllowVersionUpgrade"].should.equal(False)
# This one should remain unmodified.
cluster["NumberOfNodes"].should.equal(1)
@mock_redshift
@mock_ec2
def test_create_cluster_subnet_group():
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet1 = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/24")
subnet2 = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.1.0/24")
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster_subnet_group(
ClusterSubnetGroupName="my_subnet_group",
Description="This is my subnet group",
SubnetIds=[subnet1.id, subnet2.id],
)
subnets_response = client.describe_cluster_subnet_groups(
ClusterSubnetGroupName="my_subnet_group"
)
my_subnet = subnets_response["ClusterSubnetGroups"][0]
my_subnet["ClusterSubnetGroupName"].should.equal("my_subnet_group")
my_subnet["Description"].should.equal("This is my subnet group")
subnet_ids = [subnet["SubnetIdentifier"] for subnet in my_subnet["Subnets"]]
set(subnet_ids).should.equal(set([subnet1.id, subnet2.id]))
@mock_redshift_deprecated
@mock_ec2_deprecated
def test_create_invalid_cluster_subnet_group():
redshift_conn = boto.connect_redshift()
redshift_conn.create_cluster_subnet_group.when.called_with(
"my_subnet", "This is my subnet group", subnet_ids=["subnet-1234"]
).should.throw(InvalidSubnet)
@mock_redshift_deprecated
def test_describe_non_existent_subnet_group():
conn = boto.redshift.connect_to_region("us-east-1")
conn.describe_cluster_subnet_groups.when.called_with(
"not-a-subnet-group"
).should.throw(ClusterSubnetGroupNotFound)
@mock_redshift
@mock_ec2
def test_delete_cluster_subnet_group():
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/24")
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster_subnet_group(
ClusterSubnetGroupName="my_subnet_group",
Description="This is my subnet group",
SubnetIds=[subnet.id],
)
subnets_response = client.describe_cluster_subnet_groups()
subnets = subnets_response["ClusterSubnetGroups"]
subnets.should.have.length_of(1)
client.delete_cluster_subnet_group(ClusterSubnetGroupName="my_subnet_group")
subnets_response = client.describe_cluster_subnet_groups()
subnets = subnets_response["ClusterSubnetGroups"]
subnets.should.have.length_of(0)
# Delete invalid id
client.delete_cluster_subnet_group.when.called_with(
ClusterSubnetGroupName="not-a-subnet-group"
).should.throw(ClientError)
@mock_redshift_deprecated
def test_create_cluster_security_group():
conn = boto.connect_redshift()
conn.create_cluster_security_group("my_security_group", "This is my security group")
groups_response = conn.describe_cluster_security_groups("my_security_group")
my_group = groups_response["DescribeClusterSecurityGroupsResponse"][
"DescribeClusterSecurityGroupsResult"
]["ClusterSecurityGroups"][0]
my_group["ClusterSecurityGroupName"].should.equal("my_security_group")
my_group["Description"].should.equal("This is my security group")
list(my_group["IPRanges"]).should.equal([])
@mock_redshift_deprecated
def test_describe_non_existent_security_group():
conn = boto.redshift.connect_to_region("us-east-1")
conn.describe_cluster_security_groups.when.called_with(
"not-a-security-group"
).should.throw(ClusterSecurityGroupNotFound)
@mock_redshift_deprecated
def test_delete_cluster_security_group():
conn = boto.connect_redshift()
conn.create_cluster_security_group("my_security_group", "This is my security group")
groups_response = conn.describe_cluster_security_groups()
groups = groups_response["DescribeClusterSecurityGroupsResponse"][
"DescribeClusterSecurityGroupsResult"
]["ClusterSecurityGroups"]
groups.should.have.length_of(2) # The default group already exists
conn.delete_cluster_security_group("my_security_group")
groups_response = conn.describe_cluster_security_groups()
groups = groups_response["DescribeClusterSecurityGroupsResponse"][
"DescribeClusterSecurityGroupsResult"
]["ClusterSecurityGroups"]
groups.should.have.length_of(1)
# Delete invalid id
conn.delete_cluster_security_group.when.called_with(
"not-a-security-group"
).should.throw(ClusterSecurityGroupNotFound)
@mock_redshift_deprecated
def test_create_cluster_parameter_group():
conn = boto.connect_redshift()
conn.create_cluster_parameter_group(
"my_parameter_group", "redshift-1.0", "This is my parameter group"
)
groups_response = conn.describe_cluster_parameter_groups("my_parameter_group")
my_group = groups_response["DescribeClusterParameterGroupsResponse"][
"DescribeClusterParameterGroupsResult"
]["ParameterGroups"][0]
my_group["ParameterGroupName"].should.equal("my_parameter_group")
my_group["ParameterGroupFamily"].should.equal("redshift-1.0")
my_group["Description"].should.equal("This is my parameter group")
@mock_redshift_deprecated
def test_describe_non_existent_parameter_group():
conn = boto.redshift.connect_to_region("us-east-1")
conn.describe_cluster_parameter_groups.when.called_with(
"not-a-parameter-group"
).should.throw(ClusterParameterGroupNotFound)
@mock_redshift_deprecated
def test_delete_cluster_parameter_group():
conn = boto.connect_redshift()
conn.create_cluster_parameter_group(
"my_parameter_group", "redshift-1.0", "This is my parameter group"
)
groups_response = conn.describe_cluster_parameter_groups()
groups = groups_response["DescribeClusterParameterGroupsResponse"][
"DescribeClusterParameterGroupsResult"
]["ParameterGroups"]
groups.should.have.length_of(2) # The default group already exists
conn.delete_cluster_parameter_group("my_parameter_group")
groups_response = conn.describe_cluster_parameter_groups()
groups = groups_response["DescribeClusterParameterGroupsResponse"][
"DescribeClusterParameterGroupsResult"
]["ParameterGroups"]
groups.should.have.length_of(1)
# Delete invalid id
conn.delete_cluster_parameter_group.when.called_with(
"not-a-parameter-group"
).should.throw(ClusterParameterGroupNotFound)
@mock_redshift
def test_create_cluster_snapshot_of_non_existent_cluster():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "non-existent-cluster-id"
client.create_cluster_snapshot.when.called_with(
SnapshotIdentifier="snapshot-id", ClusterIdentifier=cluster_identifier
).should.throw(ClientError, "Cluster {} not found.".format(cluster_identifier))
@mock_redshift
def test_create_cluster_snapshot():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "my_cluster"
snapshot_identifier = "my_snapshot"
cluster_response = client.create_cluster(
DBName="test-db",
ClusterIdentifier=cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
EnhancedVpcRouting=True,
)
cluster_response["Cluster"]["NodeType"].should.equal("ds2.xlarge")
snapshot_response = client.create_cluster_snapshot(
SnapshotIdentifier=snapshot_identifier,
ClusterIdentifier=cluster_identifier,
Tags=[{"Key": "test-tag-key", "Value": "test-tag-value"}],
)
snapshot = snapshot_response["Snapshot"]
snapshot["SnapshotIdentifier"].should.equal(snapshot_identifier)
snapshot["ClusterIdentifier"].should.equal(cluster_identifier)
snapshot["NumberOfNodes"].should.equal(1)
snapshot["NodeType"].should.equal("ds2.xlarge")
snapshot["MasterUsername"].should.equal("username")
@mock_redshift
def test_describe_cluster_snapshots():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "my_cluster"
snapshot_identifier_1 = "my_snapshot_1"
snapshot_identifier_2 = "my_snapshot_2"
client.create_cluster(
DBName="test-db",
ClusterIdentifier=cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
)
client.create_cluster_snapshot(
SnapshotIdentifier=snapshot_identifier_1, ClusterIdentifier=cluster_identifier
)
client.create_cluster_snapshot(
SnapshotIdentifier=snapshot_identifier_2, ClusterIdentifier=cluster_identifier
)
resp_snap_1 = client.describe_cluster_snapshots(
SnapshotIdentifier=snapshot_identifier_1
)
snapshot_1 = resp_snap_1["Snapshots"][0]
snapshot_1["SnapshotIdentifier"].should.equal(snapshot_identifier_1)
snapshot_1["ClusterIdentifier"].should.equal(cluster_identifier)
snapshot_1["NumberOfNodes"].should.equal(1)
snapshot_1["NodeType"].should.equal("ds2.xlarge")
snapshot_1["MasterUsername"].should.equal("username")
resp_snap_2 = client.describe_cluster_snapshots(
SnapshotIdentifier=snapshot_identifier_2
)
snapshot_2 = resp_snap_2["Snapshots"][0]
snapshot_2["SnapshotIdentifier"].should.equal(snapshot_identifier_2)
snapshot_2["ClusterIdentifier"].should.equal(cluster_identifier)
snapshot_2["NumberOfNodes"].should.equal(1)
snapshot_2["NodeType"].should.equal("ds2.xlarge")
snapshot_2["MasterUsername"].should.equal("username")
resp_clust = client.describe_cluster_snapshots(ClusterIdentifier=cluster_identifier)
resp_clust["Snapshots"][0].should.equal(resp_snap_1["Snapshots"][0])
resp_clust["Snapshots"][1].should.equal(resp_snap_2["Snapshots"][0])
@mock_redshift
def test_describe_cluster_snapshots_not_found_error():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "my_cluster"
snapshot_identifier = "my_snapshot"
client.describe_cluster_snapshots.when.called_with(
ClusterIdentifier=cluster_identifier
).should.throw(ClientError, "Cluster {} not found.".format(cluster_identifier))
client.describe_cluster_snapshots.when.called_with(
SnapshotIdentifier=snapshot_identifier
).should.throw(ClientError, "Snapshot {} not found.".format(snapshot_identifier))
@mock_redshift
def test_delete_cluster_snapshot():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "my_cluster"
snapshot_identifier = "my_snapshot"
client.create_cluster(
ClusterIdentifier=cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
)
client.create_cluster_snapshot(
SnapshotIdentifier=snapshot_identifier, ClusterIdentifier=cluster_identifier
)
snapshots = client.describe_cluster_snapshots()["Snapshots"]
list(snapshots).should.have.length_of(1)
client.delete_cluster_snapshot(SnapshotIdentifier=snapshot_identifier)["Snapshot"][
"Status"
].should.equal("deleted")
snapshots = client.describe_cluster_snapshots()["Snapshots"]
list(snapshots).should.have.length_of(0)
# Delete invalid id
client.delete_cluster_snapshot.when.called_with(
SnapshotIdentifier="not-a-snapshot"
).should.throw(ClientError)
@mock_redshift
def test_cluster_snapshot_already_exists():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "my_cluster"
snapshot_identifier = "my_snapshot"
client.create_cluster(
DBName="test-db",
ClusterIdentifier=cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
)
client.create_cluster_snapshot(
SnapshotIdentifier=snapshot_identifier, ClusterIdentifier=cluster_identifier
)
client.create_cluster_snapshot.when.called_with(
SnapshotIdentifier=snapshot_identifier, ClusterIdentifier=cluster_identifier
).should.throw(ClientError)
@mock_redshift
def test_create_cluster_from_snapshot():
client = boto3.client("redshift", region_name="us-east-1")
original_cluster_identifier = "original-cluster"
original_snapshot_identifier = "original-snapshot"
new_cluster_identifier = "new-cluster"
client.create_cluster(
ClusterIdentifier=original_cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
EnhancedVpcRouting=True,
)
client.create_cluster_snapshot(
SnapshotIdentifier=original_snapshot_identifier,
ClusterIdentifier=original_cluster_identifier,
)
client.restore_from_cluster_snapshot.when.called_with(
ClusterIdentifier=original_cluster_identifier,
SnapshotIdentifier=original_snapshot_identifier,
).should.throw(ClientError, "ClusterAlreadyExists")
response = client.restore_from_cluster_snapshot(
ClusterIdentifier=new_cluster_identifier,
SnapshotIdentifier=original_snapshot_identifier,
Port=1234,
)
response["Cluster"]["ClusterStatus"].should.equal("creating")
response = client.describe_clusters(ClusterIdentifier=new_cluster_identifier)
new_cluster = response["Clusters"][0]
new_cluster["NodeType"].should.equal("ds2.xlarge")
new_cluster["MasterUsername"].should.equal("username")
new_cluster["Endpoint"]["Port"].should.equal(1234)
new_cluster["EnhancedVpcRouting"].should.equal(True)
@mock_redshift
def test_create_cluster_from_snapshot_with_waiter():
client = boto3.client("redshift", region_name="us-east-1")
original_cluster_identifier = "original-cluster"
original_snapshot_identifier = "original-snapshot"
new_cluster_identifier = "new-cluster"
client.create_cluster(
ClusterIdentifier=original_cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
EnhancedVpcRouting=True,
)
client.create_cluster_snapshot(
SnapshotIdentifier=original_snapshot_identifier,
ClusterIdentifier=original_cluster_identifier,
)
response = client.restore_from_cluster_snapshot(
ClusterIdentifier=new_cluster_identifier,
SnapshotIdentifier=original_snapshot_identifier,
Port=1234,
)
response["Cluster"]["ClusterStatus"].should.equal("creating")
client.get_waiter("cluster_restored").wait(
ClusterIdentifier=new_cluster_identifier,
WaiterConfig={"Delay": 1, "MaxAttempts": 2},
)
response = client.describe_clusters(ClusterIdentifier=new_cluster_identifier)
new_cluster = response["Clusters"][0]
new_cluster["NodeType"].should.equal("ds2.xlarge")
new_cluster["MasterUsername"].should.equal("username")
new_cluster["EnhancedVpcRouting"].should.equal(True)
new_cluster["Endpoint"]["Port"].should.equal(1234)
@mock_redshift
def test_create_cluster_from_non_existent_snapshot():
client = boto3.client("redshift", region_name="us-east-1")
client.restore_from_cluster_snapshot.when.called_with(
ClusterIdentifier="cluster-id", SnapshotIdentifier="non-existent-snapshot"
).should.throw(ClientError, "Snapshot non-existent-snapshot not found.")
@mock_redshift
def test_create_cluster_status_update():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "test-cluster"
response = client.create_cluster(
ClusterIdentifier=cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
)
response["Cluster"]["ClusterStatus"].should.equal("creating")
response = client.describe_clusters(ClusterIdentifier=cluster_identifier)
response["Clusters"][0]["ClusterStatus"].should.equal("available")
@mock_redshift
def test_describe_tags_with_resource_type():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "my_cluster"
cluster_arn = "arn:aws:redshift:us-east-1:{}:" "cluster:{}".format(
ACCOUNT_ID, cluster_identifier
)
snapshot_identifier = "my_snapshot"
snapshot_arn = "arn:aws:redshift:us-east-1:{}:" "snapshot:{}/{}".format(
ACCOUNT_ID, cluster_identifier, snapshot_identifier
)
tag_key = "test-tag-key"
tag_value = "test-tag-value"
client.create_cluster(
DBName="test-db",
ClusterIdentifier=cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
Tags=[{"Key": tag_key, "Value": tag_value}],
)
tags_response = client.describe_tags(ResourceType="cluster")
tagged_resources = tags_response["TaggedResources"]
list(tagged_resources).should.have.length_of(1)
tagged_resources[0]["ResourceType"].should.equal("cluster")
tagged_resources[0]["ResourceName"].should.equal(cluster_arn)
tag = tagged_resources[0]["Tag"]
tag["Key"].should.equal(tag_key)
tag["Value"].should.equal(tag_value)
client.create_cluster_snapshot(
SnapshotIdentifier=snapshot_identifier,
ClusterIdentifier=cluster_identifier,
Tags=[{"Key": tag_key, "Value": tag_value}],
)
tags_response = client.describe_tags(ResourceType="snapshot")
tagged_resources = tags_response["TaggedResources"]
list(tagged_resources).should.have.length_of(1)
tagged_resources[0]["ResourceType"].should.equal("snapshot")
tagged_resources[0]["ResourceName"].should.equal(snapshot_arn)
tag = tagged_resources[0]["Tag"]
tag["Key"].should.equal(tag_key)
tag["Value"].should.equal(tag_value)
@mock_redshift
def test_describe_tags_cannot_specify_resource_type_and_resource_name():
client = boto3.client("redshift", region_name="us-east-1")
resource_name = "arn:aws:redshift:us-east-1:{}:cluster:cluster-id".format(
ACCOUNT_ID
)
resource_type = "cluster"
client.describe_tags.when.called_with(
ResourceName=resource_name, ResourceType=resource_type
).should.throw(ClientError, "using either an ARN or a resource type")
@mock_redshift
def test_describe_tags_with_resource_name():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "cluster-id"
cluster_arn = "arn:aws:redshift:us-east-1:{}:" "cluster:{}".format(
ACCOUNT_ID, cluster_identifier
)
snapshot_identifier = "snapshot-id"
snapshot_arn = "arn:aws:redshift:us-east-1:{}:" "snapshot:{}/{}".format(
ACCOUNT_ID, cluster_identifier, snapshot_identifier
)
tag_key = "test-tag-key"
tag_value = "test-tag-value"
client.create_cluster(
DBName="test-db",
ClusterIdentifier=cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
Tags=[{"Key": tag_key, "Value": tag_value}],
)
tags_response = client.describe_tags(ResourceName=cluster_arn)
tagged_resources = tags_response["TaggedResources"]
list(tagged_resources).should.have.length_of(1)
tagged_resources[0]["ResourceType"].should.equal("cluster")
tagged_resources[0]["ResourceName"].should.equal(cluster_arn)
tag = tagged_resources[0]["Tag"]
tag["Key"].should.equal(tag_key)
tag["Value"].should.equal(tag_value)
client.create_cluster_snapshot(
SnapshotIdentifier=snapshot_identifier,
ClusterIdentifier=cluster_identifier,
Tags=[{"Key": tag_key, "Value": tag_value}],
)
tags_response = client.describe_tags(ResourceName=snapshot_arn)
tagged_resources = tags_response["TaggedResources"]
list(tagged_resources).should.have.length_of(1)
tagged_resources[0]["ResourceType"].should.equal("snapshot")
tagged_resources[0]["ResourceName"].should.equal(snapshot_arn)
tag = tagged_resources[0]["Tag"]
tag["Key"].should.equal(tag_key)
tag["Value"].should.equal(tag_value)
@mock_redshift
def test_create_tags():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "cluster-id"
cluster_arn = "arn:aws:redshift:us-east-1:{}:" "cluster:{}".format(
ACCOUNT_ID, cluster_identifier
)
tag_key = "test-tag-key"
tag_value = "test-tag-value"
num_tags = 5
tags = []
for i in range(0, num_tags):
tag = {"Key": "{}-{}".format(tag_key, i), "Value": "{}-{}".format(tag_value, i)}
tags.append(tag)
client.create_cluster(
DBName="test-db",
ClusterIdentifier=cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
)
client.create_tags(ResourceName=cluster_arn, Tags=tags)
response = client.describe_clusters(ClusterIdentifier=cluster_identifier)
cluster = response["Clusters"][0]
list(cluster["Tags"]).should.have.length_of(num_tags)
response = client.describe_tags(ResourceName=cluster_arn)
list(response["TaggedResources"]).should.have.length_of(num_tags)
@mock_redshift
def test_delete_tags():
client = boto3.client("redshift", region_name="us-east-1")
cluster_identifier = "cluster-id"
cluster_arn = "arn:aws:redshift:us-east-1:{}:" "cluster:{}".format(
ACCOUNT_ID, cluster_identifier
)
tag_key = "test-tag-key"
tag_value = "test-tag-value"
tags = []
for i in range(1, 2):
tag = {"Key": "{}-{}".format(tag_key, i), "Value": "{}-{}".format(tag_value, i)}
tags.append(tag)
client.create_cluster(
DBName="test-db",
ClusterIdentifier=cluster_identifier,
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="username",
MasterUserPassword="password",
Tags=tags,
)
client.delete_tags(
ResourceName=cluster_arn,
TagKeys=[tag["Key"] for tag in tags if tag["Key"] != "{}-1".format(tag_key)],
)
response = client.describe_clusters(ClusterIdentifier=cluster_identifier)
cluster = response["Clusters"][0]
list(cluster["Tags"]).should.have.length_of(1)
response = client.describe_tags(ResourceName=cluster_arn)
list(response["TaggedResources"]).should.have.length_of(1)
@mock_ec2
@mock_redshift
def test_describe_tags_all_resource_types():
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/24")
client = boto3.client("redshift", region_name="us-east-1")
response = client.describe_tags()
list(response["TaggedResources"]).should.have.length_of(0)
client.create_cluster_subnet_group(
ClusterSubnetGroupName="my_subnet_group",
Description="This is my subnet group",
SubnetIds=[subnet.id],
Tags=[{"Key": "tag_key", "Value": "tag_value"}],
)
client.create_cluster_security_group(
ClusterSecurityGroupName="security_group1",
Description="This is my security group",
Tags=[{"Key": "tag_key", "Value": "tag_value"}],
)
client.create_cluster(
DBName="test",
ClusterIdentifier="my_cluster",
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="user",
MasterUserPassword="password",
Tags=[{"Key": "tag_key", "Value": "tag_value"}],
)
client.create_cluster_snapshot(
SnapshotIdentifier="my_snapshot",
ClusterIdentifier="my_cluster",
Tags=[{"Key": "tag_key", "Value": "tag_value"}],
)
client.create_cluster_parameter_group(
ParameterGroupName="my_parameter_group",
ParameterGroupFamily="redshift-1.0",
Description="This is my parameter group",
Tags=[{"Key": "tag_key", "Value": "tag_value"}],
)
response = client.describe_tags()
expected_types = [
"cluster",
"parametergroup",
"securitygroup",
"snapshot",
"subnetgroup",
]
tagged_resources = response["TaggedResources"]
returned_types = [resource["ResourceType"] for resource in tagged_resources]
list(tagged_resources).should.have.length_of(len(expected_types))
set(returned_types).should.equal(set(expected_types))
@mock_redshift
def test_tagged_resource_not_found_error():
client = boto3.client("redshift", region_name="us-east-1")
cluster_arn = "arn:aws:redshift:us-east-1::cluster:fake"
client.describe_tags.when.called_with(ResourceName=cluster_arn).should.throw(
ClientError, "cluster (fake) not found."
)
snapshot_arn = "arn:aws:redshift:us-east-1::snapshot:cluster-id/snap-id"
client.delete_tags.when.called_with(
ResourceName=snapshot_arn, TagKeys=["test"]
).should.throw(ClientError, "snapshot (snap-id) not found.")
client.describe_tags.when.called_with(ResourceType="cluster").should.throw(
ClientError, "resource of type 'cluster' not found."
)
client.describe_tags.when.called_with(ResourceName="bad:arn").should.throw(
ClientError, "Tagging is not supported for this type of resource"
)
@mock_redshift
def test_enable_snapshot_copy():
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster(
ClusterIdentifier="test",
ClusterType="single-node",
DBName="test",
Encrypted=True,
MasterUsername="user",
MasterUserPassword="password",
NodeType="ds2.xlarge",
)
client.enable_snapshot_copy(
ClusterIdentifier="test",
DestinationRegion="us-west-2",
RetentionPeriod=3,
SnapshotCopyGrantName="copy-us-east-1-to-us-west-2",
)
response = client.describe_clusters(ClusterIdentifier="test")
cluster_snapshot_copy_status = response["Clusters"][0]["ClusterSnapshotCopyStatus"]
cluster_snapshot_copy_status["RetentionPeriod"].should.equal(3)
cluster_snapshot_copy_status["DestinationRegion"].should.equal("us-west-2")
cluster_snapshot_copy_status["SnapshotCopyGrantName"].should.equal(
"copy-us-east-1-to-us-west-2"
)
@mock_redshift
def test_enable_snapshot_copy_unencrypted():
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster(
ClusterIdentifier="test",
ClusterType="single-node",
DBName="test",
MasterUsername="user",
MasterUserPassword="password",
NodeType="ds2.xlarge",
)
client.enable_snapshot_copy(ClusterIdentifier="test", DestinationRegion="us-west-2")
response = client.describe_clusters(ClusterIdentifier="test")
cluster_snapshot_copy_status = response["Clusters"][0]["ClusterSnapshotCopyStatus"]
cluster_snapshot_copy_status["RetentionPeriod"].should.equal(7)
cluster_snapshot_copy_status["DestinationRegion"].should.equal("us-west-2")
@mock_redshift
def test_disable_snapshot_copy():
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster(
DBName="test",
ClusterIdentifier="test",
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="user",
MasterUserPassword="password",
)
client.enable_snapshot_copy(
ClusterIdentifier="test",
DestinationRegion="us-west-2",
RetentionPeriod=3,
SnapshotCopyGrantName="copy-us-east-1-to-us-west-2",
)
client.disable_snapshot_copy(ClusterIdentifier="test")
response = client.describe_clusters(ClusterIdentifier="test")
response["Clusters"][0].shouldnt.contain("ClusterSnapshotCopyStatus")
@mock_redshift
def test_modify_snapshot_copy_retention_period():
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster(
DBName="test",
ClusterIdentifier="test",
ClusterType="single-node",
NodeType="ds2.xlarge",
MasterUsername="user",
MasterUserPassword="password",
)
client.enable_snapshot_copy(
ClusterIdentifier="test",
DestinationRegion="us-west-2",
RetentionPeriod=3,
SnapshotCopyGrantName="copy-us-east-1-to-us-west-2",
)
client.modify_snapshot_copy_retention_period(
ClusterIdentifier="test", RetentionPeriod=5
)
response = client.describe_clusters(ClusterIdentifier="test")
cluster_snapshot_copy_status = response["Clusters"][0]["ClusterSnapshotCopyStatus"]
cluster_snapshot_copy_status["RetentionPeriod"].should.equal(5)
@mock_redshift
def test_create_duplicate_cluster_fails():
kwargs = {
"ClusterIdentifier": "test",
"ClusterType": "single-node",
"DBName": "test",
"MasterUsername": "user",
"MasterUserPassword": "password",
"NodeType": "ds2.xlarge",
}
client = boto3.client("redshift", region_name="us-east-1")
client.create_cluster(**kwargs)
client.create_cluster.when.called_with(**kwargs).should.throw(
ClientError, "ClusterAlreadyExists"
)