2014-08-27 15:17:06 +00:00
from __future__ import unicode_literals
2014-08-25 22:09:38 +00:00
# Ensure 'assert_raises' context manager support for Python 2.6
2015-02-14 13:57:14 +00:00
import tests . backport_assert_raises # noqa
2014-08-25 22:09:38 +00:00
from nose . tools import assert_raises
2016-04-20 21:01:09 +00:00
import boto3
2013-02-22 04:13:01 +00:00
import boto
2016-10-15 13:08:44 +00:00
from boto . exception import EC2ResponseError , JSONResponseError
2013-08-03 21:21:25 +00:00
import sure # noqa
2013-02-22 04:13:01 +00:00
from moto import mock_ec2
@mock_ec2
2013-02-23 20:26:54 +00:00
def test_create_and_describe_security_group ( ) :
conn = boto . connect_ec2 ( ' the_key ' , ' the_secret ' )
2016-10-15 13:08:44 +00:00
with assert_raises ( JSONResponseError ) as ex :
security_group = conn . create_security_group ( ' test security group ' , ' this is a test security group ' , dry_run = True )
ex . exception . reason . should . equal ( ' DryRunOperation ' )
ex . exception . status . should . equal ( 400 )
ex . exception . message . should . equal ( ' An error occurred (DryRunOperation) when calling the CreateSecurityGroup operation: Request would have succeeded, but DryRun flag is set ' )
2013-02-23 20:26:54 +00:00
security_group = conn . create_security_group ( ' test security group ' , ' this is a test security group ' )
2013-03-05 13:35:18 +00:00
security_group . name . should . equal ( ' test security group ' )
2013-02-23 20:26:54 +00:00
security_group . description . should . equal ( ' this is a test security group ' )
# Trying to create another group with the same name should throw an error
2014-08-25 17:54:47 +00:00
with assert_raises ( EC2ResponseError ) as cm :
conn . create_security_group ( ' test security group ' , ' this is a test security group ' )
cm . exception . code . should . equal ( ' InvalidGroup.Duplicate ' )
cm . exception . status . should . equal ( 400 )
cm . exception . request_id . should_not . be . none
2013-02-23 20:26:54 +00:00
all_groups = conn . get_all_security_groups ( )
2015-03-14 22:50:41 +00:00
all_groups . should . have . length_of ( 2 ) # The default group gets created automatically
group_names = [ group . name for group in all_groups ]
set ( group_names ) . should . equal ( set ( [ " default " , " test security group " ] ) )
2013-02-23 20:26:54 +00:00
2014-03-20 23:22:37 +00:00
2014-05-11 21:37:00 +00:00
@mock_ec2
def test_create_security_group_without_description_raises_error ( ) :
conn = boto . connect_ec2 ( ' the_key ' , ' the_secret ' )
2014-08-25 17:54:47 +00:00
with assert_raises ( EC2ResponseError ) as cm :
conn . create_security_group ( ' test security group ' , ' ' )
cm . exception . code . should . equal ( ' MissingParameter ' )
cm . exception . status . should . equal ( 400 )
cm . exception . request_id . should_not . be . none
2014-05-11 21:37:00 +00:00
2015-03-14 22:50:41 +00:00
@mock_ec2
def test_default_security_group ( ) :
conn = boto . ec2 . connect_to_region ( ' us-east-1 ' )
groups = conn . get_all_security_groups ( )
groups . should . have . length_of ( 1 )
groups [ 0 ] . name . should . equal ( " default " )
2013-10-31 00:55:13 +00:00
@mock_ec2
def test_create_and_describe_vpc_security_group ( ) :
conn = boto . connect_ec2 ( ' the_key ' , ' the_secret ' )
vpc_id = ' vpc-5300000c '
2013-12-06 01:56:46 +00:00
security_group = conn . create_security_group ( ' test security group ' , ' this is a test security group ' , vpc_id = vpc_id )
2013-10-31 00:55:13 +00:00
security_group . vpc_id . should . equal ( vpc_id )
security_group . name . should . equal ( ' test security group ' )
security_group . description . should . equal ( ' this is a test security group ' )
2013-10-31 03:11:15 +00:00
# Trying to create another group with the same name in the same VPC should throw an error
2014-08-25 17:54:47 +00:00
with assert_raises ( EC2ResponseError ) as cm :
conn . create_security_group ( ' test security group ' , ' this is a test security group ' , vpc_id )
cm . exception . code . should . equal ( ' InvalidGroup.Duplicate ' )
cm . exception . status . should . equal ( 400 )
cm . exception . request_id . should_not . be . none
2013-10-31 00:55:13 +00:00
2015-03-14 22:50:41 +00:00
all_groups = conn . get_all_security_groups ( filters = { ' vpc_id ' : [ vpc_id ] } )
2013-10-31 00:55:13 +00:00
all_groups [ 0 ] . vpc_id . should . equal ( vpc_id )
all_groups . should . have . length_of ( 1 )
all_groups [ 0 ] . name . should . equal ( ' test security group ' )
2014-05-11 21:13:48 +00:00
2013-10-31 03:11:15 +00:00
@mock_ec2
def test_create_two_security_groups_with_same_name_in_different_vpc ( ) :
conn = boto . connect_ec2 ( ' the_key ' , ' the_secret ' )
vpc_id = ' vpc-5300000c '
vpc_id2 = ' vpc-5300000d '
2014-05-11 21:13:48 +00:00
conn . create_security_group ( ' test security group ' , ' this is a test security group ' , vpc_id )
conn . create_security_group ( ' test security group ' , ' this is a test security group ' , vpc_id2 )
2013-10-31 03:11:15 +00:00
all_groups = conn . get_all_security_groups ( )
2015-03-14 22:50:41 +00:00
all_groups . should . have . length_of ( 3 )
group_names = [ group . name for group in all_groups ]
# The default group is created automatically
set ( group_names ) . should . equal ( set ( [ " default " , " test security group " ] ) )
2013-10-31 03:11:15 +00:00
2013-02-23 20:26:54 +00:00
@mock_ec2
def test_deleting_security_groups ( ) :
conn = boto . connect_ec2 ( ' the_key ' , ' the_secret ' )
security_group1 = conn . create_security_group ( ' test1 ' , ' test1 ' )
2013-02-26 05:31:01 +00:00
conn . create_security_group ( ' test2 ' , ' test2 ' )
2013-02-23 20:26:54 +00:00
2015-03-14 22:50:41 +00:00
conn . get_all_security_groups ( ) . should . have . length_of ( 3 ) # We need to include the default security group
2013-02-23 20:26:54 +00:00
# Deleting a group that doesn't exist should throw an error
2014-08-25 17:54:47 +00:00
with assert_raises ( EC2ResponseError ) as cm :
conn . delete_security_group ( ' foobar ' )
cm . exception . code . should . equal ( ' InvalidGroup.NotFound ' )
cm . exception . status . should . equal ( 400 )
cm . exception . request_id . should_not . be . none
2013-02-23 20:26:54 +00:00
# Delete by name
2016-10-15 13:08:44 +00:00
with assert_raises ( JSONResponseError ) as ex :
conn . delete_security_group ( ' test2 ' , dry_run = True )
ex . exception . reason . should . equal ( ' DryRunOperation ' )
ex . exception . status . should . equal ( 400 )
ex . exception . message . should . equal ( ' An error occurred (DryRunOperation) when calling the DeleteSecurityGroup operation: Request would have succeeded, but DryRun flag is set ' )
2013-02-23 20:26:54 +00:00
conn . delete_security_group ( ' test2 ' )
2015-03-14 22:50:41 +00:00
conn . get_all_security_groups ( ) . should . have . length_of ( 2 )
2013-02-23 20:26:54 +00:00
# Delete by group id
2013-12-06 22:34:13 +00:00
conn . delete_security_group ( group_id = security_group1 . id )
2015-03-14 22:50:41 +00:00
conn . get_all_security_groups ( ) . should . have . length_of ( 1 )
2013-02-23 21:27:43 +00:00
2014-05-11 21:13:48 +00:00
2013-12-06 01:00:35 +00:00
@mock_ec2
def test_delete_security_group_in_vpc ( ) :
conn = boto . connect_ec2 ( ' the_key ' , ' the_secret ' )
vpc_id = " vpc-12345 "
security_group1 = conn . create_security_group ( ' test1 ' , ' test1 ' , vpc_id )
2013-12-06 01:56:46 +00:00
# this should not throw an exception
2013-12-06 22:34:13 +00:00
conn . delete_security_group ( group_id = security_group1 . id )
2013-12-06 01:00:35 +00:00
2013-02-23 21:27:43 +00:00
@mock_ec2
def test_authorize_ip_range_and_revoke ( ) :
conn = boto . connect_ec2 ( ' the_key ' , ' the_secret ' )
security_group = conn . create_security_group ( ' test ' , ' test ' )
2016-10-15 13:08:44 +00:00
with assert_raises ( JSONResponseError ) as ex :
success = security_group . authorize ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.123/32 " , dry_run = True )
ex . exception . reason . should . equal ( ' DryRunOperation ' )
ex . exception . status . should . equal ( 400 )
ex . exception . message . should . equal ( ' An error occurred (DryRunOperation) when calling the GrantSecurityGroupIngress operation: Request would have succeeded, but DryRun flag is set ' )
2013-02-23 21:27:43 +00:00
success = security_group . authorize ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.123/32 " )
assert success . should . be . true
2015-03-14 22:50:41 +00:00
security_group = conn . get_all_security_groups ( groupnames = [ ' test ' ] ) [ 0 ]
2013-02-23 21:27:43 +00:00
int ( security_group . rules [ 0 ] . to_port ) . should . equal ( 2222 )
security_group . rules [ 0 ] . grants [ 0 ] . cidr_ip . should . equal ( " 123.123.123.123/32 " )
# Wrong Cidr should throw error
2014-08-25 17:54:47 +00:00
with assert_raises ( EC2ResponseError ) as cm :
security_group . revoke ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.122/32 " )
cm . exception . code . should . equal ( ' InvalidPermission.NotFound ' )
cm . exception . status . should . equal ( 400 )
cm . exception . request_id . should_not . be . none
2013-02-23 21:27:43 +00:00
# Actually revoke
2016-10-15 13:08:44 +00:00
with assert_raises ( JSONResponseError ) as ex :
security_group . revoke ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.123/32 " , dry_run = True )
ex . exception . reason . should . equal ( ' DryRunOperation ' )
ex . exception . status . should . equal ( 400 )
ex . exception . message . should . equal ( ' An error occurred (DryRunOperation) when calling the RevokeSecurityGroupIngress operation: Request would have succeeded, but DryRun flag is set ' )
2013-02-23 21:27:43 +00:00
security_group . revoke ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.123/32 " )
security_group = conn . get_all_security_groups ( ) [ 0 ]
security_group . rules . should . have . length_of ( 0 )
2016-01-15 20:36:11 +00:00
# Test for egress as well
egress_security_group = conn . create_security_group ( ' testegress ' , ' testegress ' , vpc_id = ' vpc-3432589 ' )
2016-10-15 13:08:44 +00:00
with assert_raises ( JSONResponseError ) as ex :
success = conn . authorize_security_group_egress ( egress_security_group . id , " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.123/32 " , dry_run = True )
ex . exception . reason . should . equal ( ' DryRunOperation ' )
ex . exception . status . should . equal ( 400 )
ex . exception . message . should . equal ( ' An error occurred (DryRunOperation) when calling the GrantSecurityGroupEgress operation: Request would have succeeded, but DryRun flag is set ' )
2016-01-15 20:36:11 +00:00
success = conn . authorize_security_group_egress ( egress_security_group . id , " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.123/32 " )
assert success . should . be . true
egress_security_group = conn . get_all_security_groups ( groupnames = ' testegress ' ) [ 0 ]
2016-04-20 21:01:09 +00:00
# There are two egress rules associated with the security group:
# the default outbound rule and the new one
2016-04-19 21:50:46 +00:00
int ( egress_security_group . rules_egress [ 1 ] . to_port ) . should . equal ( 2222 )
egress_security_group . rules_egress [ 1 ] . grants [ 0 ] . cidr_ip . should . equal ( " 123.123.123.123/32 " )
2016-01-15 20:36:11 +00:00
# Wrong Cidr should throw error
egress_security_group . revoke . when . called_with ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.122/32 " ) . should . throw ( EC2ResponseError )
# Actually revoke
2016-10-15 13:08:44 +00:00
with assert_raises ( JSONResponseError ) as ex :
conn . revoke_security_group_egress ( egress_security_group . id , " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.123/32 " , dry_run = True )
ex . exception . reason . should . equal ( ' DryRunOperation ' )
ex . exception . status . should . equal ( 400 )
ex . exception . message . should . equal ( ' An error occurred (DryRunOperation) when calling the RevokeSecurityGroupEgress operation: Request would have succeeded, but DryRun flag is set ' )
2016-01-15 20:36:11 +00:00
conn . revoke_security_group_egress ( egress_security_group . id , " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.123/32 " )
egress_security_group = conn . get_all_security_groups ( ) [ 0 ]
2016-04-20 21:01:09 +00:00
# There is still the default outbound rule
2016-04-19 21:50:46 +00:00
egress_security_group . rules_egress . should . have . length_of ( 1 )
2016-01-15 20:36:11 +00:00
2013-02-26 05:31:01 +00:00
2013-02-23 21:27:43 +00:00
@mock_ec2
def test_authorize_other_group_and_revoke ( ) :
conn = boto . connect_ec2 ( ' the_key ' , ' the_secret ' )
security_group = conn . create_security_group ( ' test ' , ' test ' )
other_security_group = conn . create_security_group ( ' other ' , ' other ' )
wrong_group = conn . create_security_group ( ' wrong ' , ' wrong ' )
success = security_group . authorize ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , src_group = other_security_group )
assert success . should . be . true
security_group = [ group for group in conn . get_all_security_groups ( ) if group . name == ' test ' ] [ 0 ]
int ( security_group . rules [ 0 ] . to_port ) . should . equal ( 2222 )
security_group . rules [ 0 ] . grants [ 0 ] . group_id . should . equal ( other_security_group . id )
# Wrong source group should throw error
2014-08-25 17:54:47 +00:00
with assert_raises ( EC2ResponseError ) as cm :
security_group . revoke ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , src_group = wrong_group )
cm . exception . code . should . equal ( ' InvalidPermission.NotFound ' )
cm . exception . status . should . equal ( 400 )
cm . exception . request_id . should_not . be . none
2013-02-23 21:27:43 +00:00
# Actually revoke
security_group . revoke ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , src_group = other_security_group )
security_group = [ group for group in conn . get_all_security_groups ( ) if group . name == ' test ' ] [ 0 ]
security_group . rules . should . have . length_of ( 0 )
2014-03-20 23:22:37 +00:00
2014-05-11 21:13:48 +00:00
2016-04-20 21:01:09 +00:00
@mock_ec2
def test_authorize_other_group_egress_and_revoke ( ) :
ec2 = boto3 . resource ( ' ec2 ' , region_name = ' us-west-1 ' )
vpc = ec2 . create_vpc ( CidrBlock = ' 10.0.0.0/16 ' )
sg01 = ec2 . create_security_group ( GroupName = ' sg01 ' , Description = ' Test security group sg01 ' , VpcId = vpc . id )
sg02 = ec2 . create_security_group ( GroupName = ' sg02 ' , Description = ' Test security group sg02 ' , VpcId = vpc . id )
ip_permission = {
2016-04-20 21:21:39 +00:00
' IpProtocol ' : ' tcp ' ,
2016-04-20 21:01:09 +00:00
' FromPort ' : 27017 ,
' ToPort ' : 27017 ,
' UserIdGroupPairs ' : [ { ' GroupId ' : sg02 . id , ' GroupName ' : ' sg02 ' , ' UserId ' : sg02 . owner_id } ] ,
' IpRanges ' : [ ]
}
sg01 . authorize_egress ( IpPermissions = [ ip_permission ] )
sg01 . ip_permissions_egress . should . have . length_of ( 2 )
sg01 . ip_permissions_egress . should . contain ( ip_permission )
sg01 . revoke_egress ( IpPermissions = [ ip_permission ] )
sg01 . ip_permissions_egress . should . have . length_of ( 1 )
2014-03-20 23:22:37 +00:00
@mock_ec2
2014-03-21 00:26:08 +00:00
def test_authorize_group_in_vpc ( ) :
2014-03-20 23:22:37 +00:00
conn = boto . connect_ec2 ( ' the_key ' , ' the_secret ' )
vpc_id = " vpc-12345 "
# create 2 groups in a vpc
2014-05-11 21:13:48 +00:00
security_group = conn . create_security_group ( ' test1 ' , ' test1 ' , vpc_id )
other_security_group = conn . create_security_group ( ' test2 ' , ' test2 ' , vpc_id )
2014-03-20 23:22:37 +00:00
2014-05-11 21:13:48 +00:00
success = security_group . authorize ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , src_group = other_security_group )
2014-03-21 20:31:00 +00:00
success . should . be . true
2014-03-20 23:22:37 +00:00
2014-05-11 21:13:48 +00:00
# Check that the rule is accurate
security_group = [ group for group in conn . get_all_security_groups ( ) if group . name == ' test1 ' ] [ 0 ]
int ( security_group . rules [ 0 ] . to_port ) . should . equal ( 2222 )
security_group . rules [ 0 ] . grants [ 0 ] . group_id . should . equal ( other_security_group . id )
2014-03-20 23:22:37 +00:00
2016-04-20 21:01:09 +00:00
# Now remove the rule
2014-05-11 21:13:48 +00:00
success = security_group . revoke ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , src_group = other_security_group )
success . should . be . true
# And check that it gets revoked
security_group = [ group for group in conn . get_all_security_groups ( ) if group . name == ' test1 ' ] [ 0 ]
security_group . rules . should . have . length_of ( 0 )
2014-08-22 00:04:48 +00:00
@mock_ec2
def test_get_all_security_groups ( ) :
conn = boto . connect_ec2 ( )
2014-09-10 16:42:38 +00:00
sg1 = conn . create_security_group ( name = ' test1 ' , description = ' test1 ' , vpc_id = ' vpc-mjm05d27 ' )
2015-02-14 13:57:14 +00:00
conn . create_security_group ( name = ' test2 ' , description = ' test2 ' )
2014-08-22 00:04:48 +00:00
resp = conn . get_all_security_groups ( groupnames = [ ' test1 ' ] )
resp . should . have . length_of ( 1 )
2014-09-10 16:42:38 +00:00
resp [ 0 ] . id . should . equal ( sg1 . id )
resp = conn . get_all_security_groups ( filters = { ' vpc-id ' : [ ' vpc-mjm05d27 ' ] } )
resp . should . have . length_of ( 1 )
resp [ 0 ] . id . should . equal ( sg1 . id )
2014-08-22 00:04:48 +00:00
resp = conn . get_all_security_groups ( filters = { ' vpc_id ' : [ ' vpc-mjm05d27 ' ] } )
resp . should . have . length_of ( 1 )
2014-09-10 16:42:38 +00:00
resp [ 0 ] . id . should . equal ( sg1 . id )
2014-08-22 00:04:48 +00:00
resp = conn . get_all_security_groups ( filters = { ' description ' : [ ' test1 ' ] } )
resp . should . have . length_of ( 1 )
2014-09-10 16:42:38 +00:00
resp [ 0 ] . id . should . equal ( sg1 . id )
2014-08-22 00:04:48 +00:00
resp = conn . get_all_security_groups ( )
2015-03-14 22:50:41 +00:00
resp . should . have . length_of ( 3 ) # We need to include the default group here
2014-10-06 18:42:12 +00:00
@mock_ec2
def test_authorize_bad_cidr_throws_invalid_parameter_value ( ) :
conn = boto . connect_ec2 ( ' the_key ' , ' the_secret ' )
security_group = conn . create_security_group ( ' test ' , ' test ' )
with assert_raises ( EC2ResponseError ) as cm :
security_group . authorize ( ip_protocol = " tcp " , from_port = " 22 " , to_port = " 2222 " , cidr_ip = " 123.123.123.123 " )
cm . exception . code . should . equal ( ' InvalidParameterValue ' )
cm . exception . status . should . equal ( 400 )
cm . exception . request_id . should_not . be . none
2015-02-14 13:57:14 +00:00
@mock_ec2
def test_security_group_tagging ( ) :
conn = boto . connect_vpc ( )
vpc = conn . create_vpc ( " 10.0.0.0/16 " )
2016-10-15 13:08:44 +00:00
2015-02-14 13:57:14 +00:00
sg = conn . create_security_group ( " test-sg " , " Test SG " , vpc . id )
2016-10-15 13:08:44 +00:00
with assert_raises ( JSONResponseError ) as ex :
sg . add_tag ( " Test " , " Tag " , dry_run = True )
ex . exception . reason . should . equal ( ' DryRunOperation ' )
ex . exception . status . should . equal ( 400 )
ex . exception . message . should . equal ( ' An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set ' )
2015-02-14 13:57:14 +00:00
sg . add_tag ( " Test " , " Tag " )
tag = conn . get_all_tags ( ) [ 0 ]
tag . name . should . equal ( " Test " )
tag . value . should . equal ( " Tag " )
group = conn . get_all_security_groups ( " test-sg " ) [ 0 ]
group . tags . should . have . length_of ( 1 )
group . tags [ " Test " ] . should . equal ( " Tag " )
2015-02-24 22:56:26 +00:00
@mock_ec2
def test_security_group_tag_filtering ( ) :
conn = boto . connect_ec2 ( )
sg = conn . create_security_group ( " test-sg " , " Test SG " )
sg . add_tag ( " test-tag " , " test-value " )
groups = conn . get_all_security_groups ( filters = { " tag:test-tag " : " test-value " } )
groups . should . have . length_of ( 1 )
2016-04-26 08:53:18 +00:00
@mock_ec2
def test_authorize_all_protocols_with_no_port_specification ( ) :
conn = boto . connect_ec2 ( )
sg = conn . create_security_group ( ' test ' , ' test ' )
success = sg . authorize ( ip_protocol = ' -1 ' , cidr_ip = ' 0.0.0.0/0 ' )
success . should . be . true
sg = conn . get_all_security_groups ( ' test ' ) [ 0 ]
sg . rules [ 0 ] . from_port . should . equal ( None )
sg . rules [ 0 ] . to_port . should . equal ( None )
2016-06-23 11:03:29 +00:00
'''
Boto3
'''
@mock_ec2
def test_security_group_tagging_boto3 ( ) :
2016-06-23 11:38:17 +00:00
conn = boto3 . client ( ' ec2 ' , region_name = ' us-east-1 ' )
2016-10-15 13:08:44 +00:00
2016-06-23 11:03:29 +00:00
sg = conn . create_security_group ( GroupName = " test-sg " , Description = " Test SG " )
2016-10-15 13:08:44 +00:00
with assert_raises ( JSONResponseError ) as ex :
conn . create_tags ( Resources = [ sg [ ' GroupId ' ] ] , Tags = [ { ' Key ' : ' Test ' , ' Value ' : ' Tag ' } ] , DryRun = True )
ex . exception . reason . should . equal ( ' DryRunOperation ' )
ex . exception . status . should . equal ( 400 )
ex . exception . message . should . equal ( ' An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set ' )
2016-06-23 11:03:29 +00:00
conn . create_tags ( Resources = [ sg [ ' GroupId ' ] ] , Tags = [ { ' Key ' : ' Test ' , ' Value ' : ' Tag ' } ] )
describe = conn . describe_security_groups ( Filters = [ { ' Name ' : ' tag-value ' , ' Values ' : [ ' Tag ' ] } ] )
tag = describe [ " SecurityGroups " ] [ 0 ] [ ' Tags ' ] [ 0 ]
tag [ ' Value ' ] . should . equal ( " Tag " )
tag [ ' Key ' ] . should . equal ( " Test " )