Skip to content

Vpc security group #795

Merged
merged 6 commits into from Mar 15, 2012
+158 −36
View
23 lib/fog/aws.rb
@@ -221,6 +221,10 @@ def self.volume_id
"vol-#{Fog::Mock.random_hex(8)}"
end
+ def self.security_group_id
+ "sg-#{Fog::Mock.random_hex(8)}"
+ end
+
def self.key_id(length=21)
#Probably close enough
Fog::Mock.random_selection('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',length)
@@ -230,5 +234,24 @@ def self.rds_address(db_name,region)
"#{db_name}.#{Fog::Mock.random_letters(rand(12) + 4)}.#{region}.rds.amazonaws.com"
end
end
+
+ def self.parse_security_group_options(group_name, options)
+ if group_name.is_a?(Hash)
+ options = group_name
+ elsif group_name
+ if options.key?('GroupName')
+ raise Fog::Compute::AWS::Error, 'Arguments specified both group_name and GroupName in options'
+ end
+ options = options.clone
+ options['GroupName'] = group_name
+ end
+ if !options.key?('GroupName') && !options.key?('GroupId')
+ raise Fog::Compute::AWS::Error, 'Neither GroupName nor GroupId specified'
+ end
+ if options.key?('GroupName') && options.key?('GroupId')
+ raise Fog::Compute::AWS::Error, 'Both GroupName and GroupId specified'
+ end
+ options
+ end
end
end
View
1 lib/fog/aws/compute.rb
@@ -135,6 +135,7 @@ def self.data
'default' => {
'groupDescription' => 'default group',
'groupName' => 'default',
+ 'groupId' => 'sg-11223344',
'ipPermissionsEgress' => [],
'ipPermissions' => [
{
View
32 lib/fog/aws/requests/compute/authorize_security_group_ingress.rb
@@ -8,8 +8,10 @@ class Real
# Add permissions to a security group
#
# ==== Parameters
- # * group_name<~String> - Name of group
+ # * group_name<~String> - Name of group, optional (can also be specifed as GroupName in options)
# * options<~Hash>:
+ # * 'GroupName'<~String> - Name of security group to modify
+ # * 'GroupId'<~String> - Id of security group to modify
# * 'SourceSecurityGroupName'<~String> - Name of security group to authorize
# * 'SourceSecurityGroupOwnerId'<~String> - Name of owner to authorize
# or
@@ -39,19 +41,14 @@ class Real
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AuthorizeSecurityGroupIngress.html]
def authorize_security_group_ingress(group_name, options = {})
- if group_name.is_a?(Hash)
- Fog::Logger.deprecation("Fog::AWS::Compute#authorize_security_group_ingress now requires the 'group_name' parameter. Only specifying an options hash is now deprecated [light_black](#{caller.first})[/]")
- options = group_name
- group_name = options.delete('GroupName')
- end
+ options = Fog::AWS.parse_security_group_options(group_name, options)
if ip_permissions = options.delete('IpPermissions')
options.merge!(indexed_ip_permissions_params(ip_permissions))
end
request({
'Action' => 'AuthorizeSecurityGroupIngress',
- 'GroupName' => group_name,
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::Basic.new
}.merge!(options))
@@ -85,18 +82,19 @@ def indexed_ip_permissions_params(ip_permissions)
class Mock
def authorize_security_group_ingress(group_name, options = {})
- if group_name.is_a?(Hash)
- Fog::Logger.deprecation("Fog::AWS::Compute#authorize_security_group_ingress now requires the 'group_name' parameter. Only specifying an options hash is now deprecated [light_black](#{caller.first})[/]")
- options = group_name
- group_name = options.delete('GroupName')
+ options = Fog::AWS.parse_security_group_options(group_name, options)
+ if options.key?('GroupName')
+ group_name = options['GroupName']
+ else
+ group_name = self.data[:security_groups].reject { |k,v| v['groupId'] != options['GroupId'] } .keys.first
end
- verify_permission_options(options)
-
response = Excon::Response.new
group = self.data[:security_groups][group_name]
if group
+ verify_permission_options(options, group['vpcId'] != nil)
+
normalized_permissions = normalize_permissions(options)
normalized_permissions.each do |permission|
@@ -133,11 +131,11 @@ def authorize_security_group_ingress(group_name, options = {})
private
- def verify_permission_options(options)
- if options.empty?
+ def verify_permission_options(options, is_vpc)
+ if options.size <= 1
raise Fog::Compute::AWS::Error.new("InvalidRequest => The request received was invalid.")
end
- if options['IpProtocol'] && !['tcp', 'udp', 'icmp'].include?(options['IpProtocol'])
+ if !is_vpc && options['IpProtocol'] && !['tcp', 'udp', 'icmp'].include?(options['IpProtocol'])
raise Fog::Compute::AWS::Error.new("InvalidPermission.Malformed => Unsupported IP protocol \"#{options['IpProtocol']}\" - supported: [tcp, udp, icmp]")
end
if options['IpProtocol'] && (!options['FromPort'] || !options['ToPort'])
@@ -147,7 +145,7 @@ def verify_permission_options(options)
if !options['IpPermissions'].is_a?(Array) || options['IpPermissions'].empty?
raise Fog::Compute::AWS::Error.new("InvalidRequest => The request received was invalid.")
end
- options['IpPermissions'].each {|p| verify_permission_options(p) }
+ options['IpPermissions'].each {|p| verify_permission_options(p, is_vpc) }
end
end
View
2 lib/fog/aws/requests/compute/create_security_group.rb
@@ -10,6 +10,7 @@ class Real
# ==== Parameters
# * group_name<~String> - Name of the security group.
# * group_description<~String> - Description of group.
+ # * vpc_id<~String> - ID of the VPC
#
# ==== Returns
# * response<~Excon::Response>:
@@ -38,6 +39,7 @@ def create_security_group(name, description, vpc_id=nil)
data = {
'groupDescription' => description,
'groupName' => name,
+ 'groupId' => Fog::AWS::Mock.security_group_id,
'ipPermissionsEgress' => [],
'ipPermissions' => [],
'ownerId' => self.data[:owner_id],
View
26 lib/fog/aws/requests/compute/delete_security_group.rb
@@ -8,7 +8,8 @@ class Real
# Delete a security group that you own
#
# ==== Parameters
- # * group_name<~String> - Name of the security group.
+ # * group_name<~String> - Name of the security group, must be nil if id is specified
+ # * group_id<~String> - Id of the security group, must be nil if name is specified
#
# ==== Returns
# * response<~Excon::Response>:
@@ -17,10 +18,20 @@ class Real
# * 'return'<~Boolean> - success?
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteSecurityGroup.html]
- def delete_security_group(name)
+ def delete_security_group(name, id = nil)
+ if name && id
+ raise Fog::Compute::AWS::Error.new("May not specify both group_name and group_id")
+ end
+ if name
+ type_id = 'GroupName'
+ identifier = name
+ else
+ type_id = 'GroupId'
+ identifier = id
+ end
request(
'Action' => 'DeleteSecurityGroup',
- 'GroupName' => name,
+ type_id => identifier,
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::Basic.new
)
@@ -29,11 +40,18 @@ def delete_security_group(name)
end
class Mock
- def delete_security_group(name)
+ def delete_security_group(name, id = nil)
if name == 'default'
raise Fog::Compute::AWS::Error.new("InvalidGroup.Reserved => The security group 'default' is reserved")
end
+ if name && id
+ raise Fog::Compute::AWS::Error.new("May not specify both group_name and group_id")
+ end
+ if id
+ name = self.data[:security_groups].reject { |k,v| v['groupId'] != id } .keys.first
+ end
+
response = Excon::Response.new
if self.data[:security_groups][name]
View
2 lib/fog/aws/requests/compute/describe_security_groups.rb
@@ -73,6 +73,8 @@ def describe_security_groups(filters = {})
if permission_key = filter_key.split('ip-permission.')[1]
if permission_key == 'group-name'
security_group_info = security_group_info.reject{|security_group| !security_group['ipPermissions']['groups'].detect {|group| [*filter_value].include?(group['groupName'])}}
+ elsif permission_key == 'group-id'
+ security_group_info = security_group_info.reject{|security_group| !security_group['ipPermissions']['groups'].detect {|group| [*filter_value].include?(group['groupId'])}}
elsif permission_key == 'user-id'
security_group_info = security_group_info.reject{|security_group| !security_group['ipPermissions']['groups'].detect {|group| [*filter_value].include?(group['userId'])}}
else
View
6 lib/fog/aws/requests/compute/request_spot_instances.rb
@@ -25,7 +25,8 @@ class Real
# * 'LaunchSpecification.KeyName'<~String> - Name of a keypair to add to booting instances
# * 'LaunchSpecification.Monitoring.Enabled'<~Boolean> - Enables monitoring, defaults to disabled
# * 'LaunchSpecification.Placement.AvailabilityZone'<~String> - Placement constraint for instances
- # * 'LaunchSpecification.SecurityGroup'<~Array> or <~String> - Name of security group(s) for instances
+ # * 'LaunchSpecification.SecurityGroup'<~Array> or <~String> - Name of security group(s) for instances, not supported in VPC
+ # * 'LaunchSpecification.SecurityGroupId'<~Array> or <~String> - Id of security group(s) for instances, use this or LaunchSpecification.SecurityGroup
# * 'LaunchSpecification.UserData'<~String> - Additional data to provide to booting instances
# * 'Type'<~String> - spot instance request type in ['one-time', 'persistent']
# * 'ValidFrom'<~Time> - start date for request
@@ -64,6 +65,9 @@ def request_spot_instances(image_id, instance_type, spot_price, options = {})
if security_groups = options.delete('LaunchSpecification.SecurityGroup')
options.merge!(Fog::AWS.indexed_param('LaunchSpecification.SecurityGroup', [*security_groups]))
end
+ if security_group_ids = options.delete('LaunchSpecification.SecurityGroupId')
+ options.merge!(Fog::AWS.indexed_param('LaunchSpecification.SecurityGroupId', [*security_group_ids]))
+ end
if options['LaunchSpecification.UserData']
options['LaunchSpecification.UserData'] = Base64.encode64(options['LaunchSpecification.UserData'])
end
View
24 lib/fog/aws/requests/compute/revoke_security_group_ingress.rb
@@ -8,8 +8,10 @@ class Real
# Remove permissions from a security group
#
# ==== Parameters
- # * group_name<~String> - Name of group
+ # * group_name<~String> - Name of group, optional (can also be specifed as GroupName in options)
# * options<~Hash>:
+ # * 'GroupName'<~String> - Name of security group to modify
+ # * 'GroupId'<~String> - Id of security group to modify
# * 'SourceSecurityGroupName'<~String> - Name of security group to authorize
# * 'SourceSecurityGroupOwnerId'<~String> - Name of owner to authorize
# or
@@ -39,19 +41,14 @@ class Real
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RevokeSecurityGroupIngress.html]
def revoke_security_group_ingress(group_name, options = {})
- if group_name.is_a?(Hash)
- Fog::Logger.deprecation("Fog::AWS::Compute#revoke_security_group_ingress now requires the 'group_name' parameter. Only specifying an options hash is now deprecated [light_black](#{caller.first})[/]")
- options = group_name
- group_name = options.delete('GroupName')
- end
+ options = Fog::AWS.parse_security_group_options(group_name, options)
if ip_permissions = options.delete('IpPermissions')
options.merge!(indexed_ip_permissions_params(ip_permissions))
end
request({
'Action' => 'RevokeSecurityGroupIngress',
- 'GroupName' => group_name,
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::Basic.new
}.merge!(options))
@@ -62,18 +59,19 @@ def revoke_security_group_ingress(group_name, options = {})
class Mock
def revoke_security_group_ingress(group_name, options = {})
- if group_name.is_a?(Hash)
- Fog::Logger.deprecation("Fog::AWS::Compute#revoke_security_group_ingress now requires the 'group_name' parameter. Only specifying an options hash is now deprecated [light_black](#{caller.first})[/]")
- options = group_name
- group_name = options.delete('GroupName')
+ options = Fog::AWS.parse_security_group_options(group_name, options)
+ if options.key?('GroupName')
+ group_name = options['GroupName']
+ else
+ group_name = self.data[:security_groups].reject { |k,v| v['groupId'] != options['GroupId'] } .keys.first
end
- verify_permission_options(options)
-
response = Excon::Response.new
group = self.data[:security_groups][group_name]
if group
+ verify_permission_options(options, group['vpcId'] != nil)
+
normalized_permissions = normalize_permissions(options)
normalized_permissions.each do |permission|
View
6 lib/fog/aws/requests/compute/run_instances.rb
@@ -30,7 +30,8 @@ class Real
# * 'Ebs.DeleteOnTermination'<~String> - specifies whether or not to delete the volume on instance termination
# * 'ClientToken'<~String> - unique case-sensitive token for ensuring idempotency
# * 'DisableApiTermination'<~Boolean> - specifies whether or not to allow termination of the instance from the api
- # * 'SecurityGroup'<~Array> or <~String> - Name of security group(s) for instances (you must omit this parameter if using Virtual Private Clouds)
+ # * 'SecurityGroup'<~Array> or <~String> - Name of security group(s) for instances (not supported for VPC)
+ # * 'SecurityGroupId'<~Array> or <~String> - id's of security group(s) for instances, use this or SecurityGroup
# * 'InstanceInitiatedShutdownBehaviour'<~String> - specifies whether volumes are stopped or terminated when instance is shutdown, in [stop, terminate]
# * 'InstanceType'<~String> - Type of instance to boot. Valid options
# in ['t1.micro', 'm1.small', 'm1.large', 'm1.xlarge', 'c1.medium', 'c1.xlarge', 'm2.xlarge', m2.2xlarge', 'm2.4xlarge', 'cc1.4xlarge', 'cg1.4xlarge']
@@ -97,6 +98,9 @@ def run_instances(image_id, min_count, max_count, options = {})
if security_groups = options.delete('SecurityGroup')
options.merge!(Fog::AWS.indexed_param('SecurityGroup', [*security_groups]))
end
+ if security_group_ids = options.delete('SecurityGroupId')
+ options.merge!(Fog::AWS.indexed_param('SecurityGroupId', [*security_group_ids]))
+ end
if options['UserData']
options['UserData'] = Base64.encode64(options['UserData'])
end
View
72 tests/aws/requests/compute/security_group_tests.rb
@@ -31,6 +31,7 @@
Fog::Compute[:aws].create_security_group('fog_security_group_two', 'tests group').body
end
+ group_id = Fog::Compute[:aws].describe_security_groups('group-name' => 'fog_security_group').body['securityGroupInfo'].first['groupId']
to_be_revoked = []
expected_permissions = []
@@ -63,6 +64,10 @@
array_differences(expected_permissions, Fog::Compute[:aws].describe_security_groups('group-name' => 'fog_security_group').body['securityGroupInfo'].first['ipPermissions'])
end
+ tests("#describe_security_groups('group-id' => '#{group_id}')").returns([]) do
+ array_differences(expected_permissions, Fog::Compute[:aws].describe_security_groups('group-id' => group_id).body['securityGroupInfo'].first['ipPermissions'])
+ end
+
permission = { 'SourceSecurityGroupName' => 'fog_security_group_two', 'SourceSecurityGroupOwnerId' => @owner_id }
tests("#authorize_security_group_ingress('fog_security_group', #{permission.inspect})").formats(AWS::Compute::Formats::BASIC) do
Fog::Compute[:aws].authorize_security_group_ingress('fog_security_group', permission).body
@@ -256,6 +261,56 @@
Fog::Compute[:aws].delete_security_group('fog_security_group_two').body
end
+ vpc_id = Fog::Compute[:aws].create_vpc('10.255.254.64/28').body['vpcSet'].first['vpcId']
+
+ # Create security group in VPC
+ tests("#create_security_group('vpc_security_group', 'tests group')").formats(AWS::Compute::Formats::BASIC) do
+ Fog::Compute[:aws].create_security_group('vpc_security_group', 'tests group', vpc_id).body
+ end
+
+ group_id = Fog::Compute[:aws].describe_security_groups('group-name' => 'vpc_security_group').body['securityGroupInfo'].first['groupId']
+
+ # Access group with name in options array
+ permission = { 'IpProtocol' => '42', 'FromPort' => '22', 'ToPort' => '22', 'CidrIp' => '10.0.0.0/8' }
+ expected_permissions = [
+ {"groups"=>[],
+ "ipRanges"=>[{"cidrIp"=>"10.0.0.0/8"}],
+ "ipProtocol"=>"42",
+ "fromPort"=>22,
+ "toPort"=>22}
+ ]
+
+ options = permission.clone
+ options['GroupName'] = 'vpc_security_group'
+ tests("#authorize_security_group_ingress(#{options.inspect})").formats(AWS::Compute::Formats::BASIC) do
+ Fog::Compute[:aws].authorize_security_group_ingress(options).body
+ end
+
+ tests("#describe_security_groups('group-name' => 'vpc_security_group')").returns([]) do
+ array_differences(expected_permissions, Fog::Compute[:aws].describe_security_groups('group-name' => 'vpc_security_group').body['securityGroupInfo'].first['ipPermissions'])
+ end
+
+ tests("#revoke_security_group_ingress(#{options.inspect})").formats(AWS::Compute::Formats::BASIC) do
+ Fog::Compute[:aws].revoke_security_group_ingress(options).body
+ end
+
+ # Access group with id in options array
+ options = permission.clone
+ options['GroupId'] = group_id
+ tests("#authorize_security_group_ingress(#{options.inspect})").formats(AWS::Compute::Formats::BASIC) do
+ Fog::Compute[:aws].authorize_security_group_ingress(options).body
+ end
+
+ tests("#describe_security_groups('group-name' => 'vpc_security_group')").returns([]) do
+ array_differences(expected_permissions, Fog::Compute[:aws].describe_security_groups('group-name' => 'vpc_security_group').body['securityGroupInfo'].first['ipPermissions'])
+ end
+
+ tests("#revoke_security_group_ingress(#{options.inspect})").formats(AWS::Compute::Formats::BASIC) do
+ Fog::Compute[:aws].revoke_security_group_ingress(options).body
+ end
+
+ Fog::Compute[:aws].delete_vpc(vpc_id)
+
end
tests('failure') do
@@ -358,6 +413,23 @@
tests("#delete_security_group('default')").raises(Fog::Compute::AWS::Error) do
Fog::Compute[:aws].delete_security_group('default')
end
+
+ broken_params = [
+ [ 'fog_security_group', { 'GroupName' => 'fog_security_group'}],
+ [ 'fog_security_group', { 'GroupId' => 'sg-11223344'}],
+ [ { 'GroupName' => 'fog_security_group', 'GroupId' => 'sg-11223344'}, nil]
+ ]
+
+ broken_params.each do |list_elem|
+ tests("#authorize_security_group_ingress(#{list_elem[0].inspect}, #{list_elem[1].inspect})").raises(Fog::Compute::AWS::Error) do
+ Fog::Compute[:aws].authorize_security_group_ingress(list_elem[0], list_elem[1])
+ end
+
+ tests("#revoke_security_group_ingress(#{list_elem[0].inspect}, #{list_elem[1].inspect})").raises(Fog::Compute::AWS::Error) do
+ Fog::Compute[:aws].revoke_security_group_ingress(list_elem[0], list_elem[1])
+ end
+ end
+
end
end
Something went wrong with that request. Please try again.