Add redshift support for cloudformation.
This commit is contained in:
parent
323f720cb5
commit
73f03d1ccf
@ -8,6 +8,7 @@ from moto.ec2 import models as ec2_models
|
|||||||
from moto.elb import models as elb_models
|
from moto.elb import models as elb_models
|
||||||
from moto.iam import models as iam_models
|
from moto.iam import models as iam_models
|
||||||
from moto.rds import models as rds_models
|
from moto.rds import models as rds_models
|
||||||
|
from moto.redshift import models as redshift_models
|
||||||
from moto.route53 import models as route53_models
|
from moto.route53 import models as route53_models
|
||||||
from moto.sns import models as sns_models
|
from moto.sns import models as sns_models
|
||||||
from moto.sqs import models as sqs_models
|
from moto.sqs import models as sqs_models
|
||||||
@ -40,6 +41,9 @@ MODEL_MAP = {
|
|||||||
"AWS::RDS::DBInstance": rds_models.Database,
|
"AWS::RDS::DBInstance": rds_models.Database,
|
||||||
"AWS::RDS::DBSecurityGroup": rds_models.SecurityGroup,
|
"AWS::RDS::DBSecurityGroup": rds_models.SecurityGroup,
|
||||||
"AWS::RDS::DBSubnetGroup": rds_models.SubnetGroup,
|
"AWS::RDS::DBSubnetGroup": rds_models.SubnetGroup,
|
||||||
|
"AWS::Redshift::Cluster": redshift_models.Cluster,
|
||||||
|
"AWS::Redshift::ClusterParameterGroup": redshift_models.ParameterGroup,
|
||||||
|
"AWS::Redshift::ClusterSubnetGroup": redshift_models.SubnetGroup,
|
||||||
"AWS::Route53::HealthCheck": route53_models.HealthCheck,
|
"AWS::Route53::HealthCheck": route53_models.HealthCheck,
|
||||||
"AWS::Route53::HostedZone": route53_models.FakeZone,
|
"AWS::Route53::HostedZone": route53_models.FakeZone,
|
||||||
"AWS::Route53::RecordSet": route53_models.RecordSet,
|
"AWS::Route53::RecordSet": route53_models.RecordSet,
|
||||||
|
@ -33,8 +33,8 @@ class Cluster(object):
|
|||||||
|
|
||||||
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.cluster_version = cluster_version if cluster_version else "1.0"
|
||||||
self.port = port if port else 5439
|
self.port = int(port) if port else 5439
|
||||||
self.automated_snapshot_retention_period = automated_snapshot_retention_period if automated_snapshot_retention_period else 1
|
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.preferred_maintenance_window = preferred_maintenance_window if preferred_maintenance_window else "Mon:03:00-Mon:03:30"
|
||||||
|
|
||||||
if cluster_parameter_group_name:
|
if cluster_parameter_group_name:
|
||||||
@ -47,6 +47,7 @@ class Cluster(object):
|
|||||||
else:
|
else:
|
||||||
self.cluster_security_groups = ["Default"]
|
self.cluster_security_groups = ["Default"]
|
||||||
|
|
||||||
|
self.region = region
|
||||||
if availability_zone:
|
if availability_zone:
|
||||||
self.availability_zone = availability_zone
|
self.availability_zone = availability_zone
|
||||||
else:
|
else:
|
||||||
@ -57,10 +58,58 @@ class Cluster(object):
|
|||||||
if cluster_type == 'single-node':
|
if cluster_type == 'single-node':
|
||||||
self.number_of_nodes = 1
|
self.number_of_nodes = 1
|
||||||
elif number_of_nodes:
|
elif number_of_nodes:
|
||||||
self.number_of_nodes = number_of_nodes
|
self.number_of_nodes = int(number_of_nodes)
|
||||||
else:
|
else:
|
||||||
self.number_of_nodes = 1
|
self.number_of_nodes = 1
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||||
|
redshift_backend = redshift_backends[region_name]
|
||||||
|
properties = cloudformation_json['Properties']
|
||||||
|
|
||||||
|
if 'ClusterSubnetGroupName' in properties:
|
||||||
|
subnet_group_name = properties['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', []),
|
||||||
|
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'),
|
||||||
|
automated_snapshot_retention_period=properties.get('AutomatedSnapshotRetentionPeriod'),
|
||||||
|
port=properties.get('Port'),
|
||||||
|
cluster_version=properties.get('ClusterVersion'),
|
||||||
|
allow_version_upgrade=properties.get('AllowVersionUpgrade'),
|
||||||
|
number_of_nodes=properties.get('NumberOfNodes'),
|
||||||
|
publicly_accessible=properties.get("PubliclyAccessible"),
|
||||||
|
encrypted=properties.get("Encrypted"),
|
||||||
|
region=region_name,
|
||||||
|
)
|
||||||
|
return cluster
|
||||||
|
|
||||||
|
def get_cfn_attribute(self, attribute_name):
|
||||||
|
from moto.cloudformation.exceptions import UnformattedGetAttTemplateException
|
||||||
|
if attribute_name == 'Endpoint.Address':
|
||||||
|
return self.endpoint
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def security_groups(self):
|
def security_groups(self):
|
||||||
return [
|
return [
|
||||||
@ -128,6 +177,18 @@ class SubnetGroup(object):
|
|||||||
if not self.subnets:
|
if not self.subnets:
|
||||||
raise InvalidSubnetError(subnet_ids)
|
raise InvalidSubnetError(subnet_ids)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||||
|
redshift_backend = redshift_backends[region_name]
|
||||||
|
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", []),
|
||||||
|
)
|
||||||
|
return subnet_group
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def subnets(self):
|
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})
|
||||||
@ -173,6 +234,18 @@ class ParameterGroup(object):
|
|||||||
self.group_family = group_family
|
self.group_family = group_family
|
||||||
self.description = description
|
self.description = description
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||||
|
redshift_backend = redshift_backends[region_name]
|
||||||
|
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"),
|
||||||
|
)
|
||||||
|
return parameter_group
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
return {
|
return {
|
||||||
"ParameterGroupFamily": self.group_family,
|
"ParameterGroupFamily": self.group_family,
|
||||||
|
187
tests/test_cloudformation/fixtures/redshift.py
Normal file
187
tests/test_cloudformation/fixtures/redshift.py
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
template = {
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Parameters" : {
|
||||||
|
"DatabaseName" : {
|
||||||
|
"Description" : "The name of the first database to be created when the cluster is created",
|
||||||
|
"Type" : "String",
|
||||||
|
"Default" : "dev",
|
||||||
|
"AllowedPattern" : "([a-z]|[0-9])+"
|
||||||
|
},
|
||||||
|
"ClusterType" : {
|
||||||
|
"Description" : "The type of cluster",
|
||||||
|
"Type" : "String",
|
||||||
|
"Default" : "single-node",
|
||||||
|
"AllowedValues" : [ "single-node", "multi-node" ]
|
||||||
|
},
|
||||||
|
"NumberOfNodes" : {
|
||||||
|
"Description" : "The number of compute nodes in the cluster. For multi-node clusters, the NumberOfNodes parameter must be greater than 1",
|
||||||
|
"Type" : "Number",
|
||||||
|
"Default" : "1"
|
||||||
|
},
|
||||||
|
"NodeType" : {
|
||||||
|
"Description" : "The type of node to be provisioned",
|
||||||
|
"Type" : "String",
|
||||||
|
"Default" : "dw1.xlarge",
|
||||||
|
"AllowedValues" : [ "dw1.xlarge", "dw1.8xlarge", "dw2.large", "dw2.8xlarge" ]
|
||||||
|
},
|
||||||
|
"MasterUsername" : {
|
||||||
|
"Description" : "The user name that is associated with the master user account for the cluster that is being created",
|
||||||
|
"Type" : "String",
|
||||||
|
"Default" : "defaultuser",
|
||||||
|
"AllowedPattern" : "([a-z])([a-z]|[0-9])*"
|
||||||
|
},
|
||||||
|
"MasterUserPassword" : {
|
||||||
|
"Description" : "The password that is associated with the master user account for the cluster that is being created.",
|
||||||
|
"Type" : "String",
|
||||||
|
"NoEcho" : "true"
|
||||||
|
},
|
||||||
|
"InboundTraffic" : {
|
||||||
|
"Description" : "Allow inbound traffic to the cluster from this CIDR range.",
|
||||||
|
"Type" : "String",
|
||||||
|
"MinLength": "9",
|
||||||
|
"MaxLength": "18",
|
||||||
|
"Default" : "0.0.0.0/0",
|
||||||
|
"AllowedPattern" : "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
|
||||||
|
"ConstraintDescription" : "must be a valid CIDR range of the form x.x.x.x/x."
|
||||||
|
},
|
||||||
|
"PortNumber" : {
|
||||||
|
"Description" : "The port number on which the cluster accepts incoming connections.",
|
||||||
|
"Type" : "Number",
|
||||||
|
"Default" : "5439"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Conditions" : {
|
||||||
|
"IsMultiNodeCluster" : {
|
||||||
|
"Fn::Equals" : [{ "Ref" : "ClusterType" }, "multi-node" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Resources" : {
|
||||||
|
"RedshiftCluster" : {
|
||||||
|
"Type" : "AWS::Redshift::Cluster",
|
||||||
|
"DependsOn" : "AttachGateway",
|
||||||
|
"Properties" : {
|
||||||
|
"ClusterType" : { "Ref" : "ClusterType" },
|
||||||
|
"NumberOfNodes" : { "Fn::If" : [ "IsMultiNodeCluster", { "Ref" : "NumberOfNodes" }, { "Ref" : "AWS::NoValue" }]},
|
||||||
|
"NodeType" : { "Ref" : "NodeType" },
|
||||||
|
"DBName" : { "Ref" : "DatabaseName" },
|
||||||
|
"MasterUsername" : { "Ref" : "MasterUsername" },
|
||||||
|
"MasterUserPassword" : { "Ref" : "MasterUserPassword" },
|
||||||
|
"ClusterParameterGroupName" : { "Ref" : "RedshiftClusterParameterGroup" },
|
||||||
|
"VpcSecurityGroupIds" : [ { "Ref" : "SecurityGroup" } ],
|
||||||
|
"ClusterSubnetGroupName" : { "Ref" : "RedshiftClusterSubnetGroup" },
|
||||||
|
"PubliclyAccessible" : "true",
|
||||||
|
"Port" : { "Ref" : "PortNumber" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"RedshiftClusterParameterGroup" : {
|
||||||
|
"Type" : "AWS::Redshift::ClusterParameterGroup",
|
||||||
|
"Properties" : {
|
||||||
|
"Description" : "Cluster parameter group",
|
||||||
|
"ParameterGroupFamily" : "redshift-1.0",
|
||||||
|
"Parameters" : [{
|
||||||
|
"ParameterName" : "enable_user_activity_logging",
|
||||||
|
"ParameterValue" : "true"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"RedshiftClusterSubnetGroup" : {
|
||||||
|
"Type" : "AWS::Redshift::ClusterSubnetGroup",
|
||||||
|
"Properties" : {
|
||||||
|
"Description" : "Cluster subnet group",
|
||||||
|
"SubnetIds" : [ { "Ref" : "PublicSubnet" } ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"VPC" : {
|
||||||
|
"Type" : "AWS::EC2::VPC",
|
||||||
|
"Properties" : {
|
||||||
|
"CidrBlock" : "10.0.0.0/16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PublicSubnet" : {
|
||||||
|
"Type" : "AWS::EC2::Subnet",
|
||||||
|
"Properties" : {
|
||||||
|
"CidrBlock" : "10.0.0.0/24",
|
||||||
|
"VpcId" : { "Ref" : "VPC" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SecurityGroup" : {
|
||||||
|
"Type" : "AWS::EC2::SecurityGroup",
|
||||||
|
"Properties" : {
|
||||||
|
"GroupDescription" : "Security group",
|
||||||
|
"SecurityGroupIngress" : [ {
|
||||||
|
"CidrIp" : { "Ref": "InboundTraffic" },
|
||||||
|
"FromPort" : { "Ref" : "PortNumber" },
|
||||||
|
"ToPort" : { "Ref" : "PortNumber" },
|
||||||
|
"IpProtocol" : "tcp"
|
||||||
|
} ],
|
||||||
|
"VpcId" : { "Ref" : "VPC" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"myInternetGateway" : {
|
||||||
|
"Type" : "AWS::EC2::InternetGateway"
|
||||||
|
},
|
||||||
|
"AttachGateway" : {
|
||||||
|
"Type" : "AWS::EC2::VPCGatewayAttachment",
|
||||||
|
"Properties" : {
|
||||||
|
"VpcId" : { "Ref" : "VPC" },
|
||||||
|
"InternetGatewayId" : { "Ref" : "myInternetGateway" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PublicRouteTable" : {
|
||||||
|
"Type" : "AWS::EC2::RouteTable",
|
||||||
|
"Properties" : {
|
||||||
|
"VpcId" : {
|
||||||
|
"Ref" : "VPC"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PublicRoute" : {
|
||||||
|
"Type" : "AWS::EC2::Route",
|
||||||
|
"DependsOn" : "AttachGateway",
|
||||||
|
"Properties" : {
|
||||||
|
"RouteTableId" : {
|
||||||
|
"Ref" : "PublicRouteTable"
|
||||||
|
},
|
||||||
|
"DestinationCidrBlock" : "0.0.0.0/0",
|
||||||
|
"GatewayId" : {
|
||||||
|
"Ref" : "myInternetGateway"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PublicSubnetRouteTableAssociation" : {
|
||||||
|
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
|
||||||
|
"Properties" : {
|
||||||
|
"SubnetId" : {
|
||||||
|
"Ref" : "PublicSubnet"
|
||||||
|
},
|
||||||
|
"RouteTableId" : {
|
||||||
|
"Ref" : "PublicRouteTable"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Outputs" : {
|
||||||
|
"ClusterEndpoint" : {
|
||||||
|
"Description" : "Cluster endpoint",
|
||||||
|
"Value" : { "Fn::Join" : [ ":", [ { "Fn::GetAtt" : [ "RedshiftCluster", "Endpoint.Address" ] }, { "Fn::GetAtt" : [ "RedshiftCluster", "Endpoint.Port" ] } ] ] }
|
||||||
|
},
|
||||||
|
"ClusterName" : {
|
||||||
|
"Description" : "Name of cluster",
|
||||||
|
"Value" : { "Ref" : "RedshiftCluster" }
|
||||||
|
},
|
||||||
|
"ParameterGroupName" : {
|
||||||
|
"Description" : "Name of parameter group",
|
||||||
|
"Value" : { "Ref" : "RedshiftClusterParameterGroup" }
|
||||||
|
},
|
||||||
|
"RedshiftClusterSubnetGroupName" : {
|
||||||
|
"Description" : "Name of cluster subnet group",
|
||||||
|
"Value" : { "Ref" : "RedshiftClusterSubnetGroup" }
|
||||||
|
},
|
||||||
|
"RedshiftClusterSecurityGroupName" : {
|
||||||
|
"Description" : "Name of cluster security group",
|
||||||
|
"Value" : { "Ref" : "SecurityGroup" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import boto.ec2.autoscale
|
|||||||
import boto.ec2.elb
|
import boto.ec2.elb
|
||||||
from boto.exception import BotoServerError
|
from boto.exception import BotoServerError
|
||||||
import boto.iam
|
import boto.iam
|
||||||
|
import boto.redshift
|
||||||
import boto.sns
|
import boto.sns
|
||||||
import boto.sqs
|
import boto.sqs
|
||||||
import boto.vpc
|
import boto.vpc
|
||||||
@ -20,6 +21,7 @@ from moto import (
|
|||||||
mock_elb,
|
mock_elb,
|
||||||
mock_iam,
|
mock_iam,
|
||||||
mock_rds,
|
mock_rds,
|
||||||
|
mock_redshift,
|
||||||
mock_route53,
|
mock_route53,
|
||||||
mock_sns,
|
mock_sns,
|
||||||
mock_sqs,
|
mock_sqs,
|
||||||
@ -29,6 +31,7 @@ from .fixtures import (
|
|||||||
ec2_classic_eip,
|
ec2_classic_eip,
|
||||||
fn_join,
|
fn_join,
|
||||||
rds_mysql_with_read_replica,
|
rds_mysql_with_read_replica,
|
||||||
|
redshift,
|
||||||
route53_ec2_instance_with_public_ip,
|
route53_ec2_instance_with_public_ip,
|
||||||
route53_health_check,
|
route53_health_check,
|
||||||
route53_roundrobin,
|
route53_roundrobin,
|
||||||
@ -288,20 +291,50 @@ def test_stack_elb_integration_with_attached_ec2_instances():
|
|||||||
|
|
||||||
load_balancer.instances[0].id.should.equal(ec2_instance.id)
|
load_balancer.instances[0].id.should.equal(ec2_instance.id)
|
||||||
list(load_balancer.availability_zones).should.equal(['us-east1'])
|
list(load_balancer.availability_zones).should.equal(['us-east1'])
|
||||||
load_balancer_name = load_balancer.name
|
|
||||||
|
|
||||||
stack = conn.describe_stacks()[0]
|
|
||||||
stack_resources = stack.describe_resources()
|
|
||||||
stack_resources.should.have.length_of(2)
|
|
||||||
for resource in stack_resources:
|
|
||||||
if resource.resource_type == 'AWS::ElasticLoadBalancing::LoadBalancer':
|
|
||||||
load_balancer = resource
|
|
||||||
else:
|
|
||||||
ec2_instance = resource
|
|
||||||
|
|
||||||
load_balancer.logical_resource_id.should.equal("MyELB")
|
@mock_ec2()
|
||||||
load_balancer.physical_resource_id.should.equal(load_balancer_name)
|
@mock_redshift()
|
||||||
ec2_instance.physical_resource_id.should.equal(instance_id)
|
@mock_cloudformation()
|
||||||
|
def test_redshift_stack():
|
||||||
|
redshift_template_json = json.dumps(redshift.template)
|
||||||
|
|
||||||
|
vpc_conn = boto.vpc.connect_to_region("us-west-2")
|
||||||
|
conn = boto.cloudformation.connect_to_region("us-west-2")
|
||||||
|
conn.create_stack(
|
||||||
|
"redshift_stack",
|
||||||
|
template_body=redshift_template_json,
|
||||||
|
parameters=[
|
||||||
|
("DatabaseName", "mydb"),
|
||||||
|
("ClusterType", "multi-node"),
|
||||||
|
("NumberOfNodes", 2),
|
||||||
|
("NodeType", "dw1.xlarge"),
|
||||||
|
("MasterUsername", "myuser"),
|
||||||
|
("MasterUserPassword", "mypass"),
|
||||||
|
("InboundTraffic", "10.0.0.1/16"),
|
||||||
|
("PortNumber", 5439),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
redshift_conn = boto.redshift.connect_to_region("us-west-2")
|
||||||
|
|
||||||
|
cluster_res = redshift_conn.describe_clusters()
|
||||||
|
clusters = cluster_res['DescribeClustersResponse']['DescribeClustersResult']['Clusters']
|
||||||
|
clusters.should.have.length_of(1)
|
||||||
|
cluster = clusters[0]
|
||||||
|
cluster['DBName'].should.equal("mydb")
|
||||||
|
cluster['NumberOfNodes'].should.equal(2)
|
||||||
|
cluster['NodeType'].should.equal("dw1.xlarge")
|
||||||
|
cluster['MasterUsername'].should.equal("myuser")
|
||||||
|
cluster['Port'].should.equal(5439)
|
||||||
|
cluster['VpcSecurityGroups'].should.have.length_of(1)
|
||||||
|
security_group_id = cluster['VpcSecurityGroups'][0]['VpcSecurityGroupId']
|
||||||
|
|
||||||
|
groups = vpc_conn.get_all_security_groups(group_ids=[security_group_id])
|
||||||
|
groups.should.have.length_of(1)
|
||||||
|
group = groups[0]
|
||||||
|
group.rules.should.have.length_of(1)
|
||||||
|
group.rules[0].grants[0].cidr_ip.should.equal("10.0.0.1/16")
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2()
|
@mock_ec2()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user