right_aws 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,16 +37,19 @@ module RightAws
37
37
  # reserved-instances-id, start, state, tag-key, tag-value, tag:key, usage-price
38
38
  #
39
39
  # ec2.describe_reserved_instances #=>
40
- # [{:aws_id=>"1ba8e2e3-1c40-434c-a741-5ff16a4c542e",
41
- # :aws_duration=>31536000,
42
- # :aws_instance_type=>"m1.small",
43
- # :aws_usage_price=>0.03,
44
- # :aws_availability_zone=>"us-east-1b",
45
- # :aws_state=>"payment-pending",
46
- # :aws_product_description=>"Test",
47
- # :aws_fixed_price=>325.0,
48
- # :aws_start=>"2009-12-18T20:39:39.569Z"
49
- # :aws_instance_count=>1}]
40
+ # [{:currency_code=>"USD",
41
+ # :aws_fixed_price=>350.0,
42
+ # :aws_availability_zone=>"us-east-1c",
43
+ # :aws_instance_count=>1,
44
+ # :tags=>{},
45
+ # :aws_id=>"4357912c-ad94-4f57-8625-15ca71a8e66d",
46
+ # :aws_product_description=>"Linux/UNIX",
47
+ # :aws_state=>"active",
48
+ # :aws_start=>"2010-03-18T20:39:39.569Z",
49
+ # :aws_duration=>94608000,
50
+ # :aws_instance_type=>"m1.small",
51
+ # :instance_tenancy=>"default",
52
+ # :aws_usage_price=>0.03}]
50
53
  #
51
54
  # ec2.describe_reserved_instances(:filters => {'availability-zone' => 'us-east-1a'})
52
55
  #
@@ -63,22 +66,25 @@ module RightAws
63
66
  # Filters: availability-zone, duration, fixed-price, instance-type, product-description, reserved-instances-offering-id, usage-price
64
67
  #
65
68
  # ec2.describe_reserved_instances_offerings #=>
66
- # [{:aws_instance_type=>"c1.medium",
67
- # :aws_availability_zone=>"us-east-1c",
68
- # :aws_duration=>94608000,
69
+ # [{:currency_code=>"USD",
70
+ # :aws_fixed_price=>700.0,
71
+ # :aws_id=>"248e7b75-933c-451b-b126-be25865e02a5",
69
72
  # :aws_product_description=>"Linux/UNIX",
70
- # :aws_id=>"e5a2ff3b-f6eb-4b4e-83f8-b879d7060257",
73
+ # :aws_instance_type=>"c1.medium",
74
+ # :aws_duration=>94608000,
75
+ # :instance_tenancy=>"default",
71
76
  # :aws_usage_price=>0.06,
72
- # :aws_fixed_price=>1000.0},
73
- # ...
74
- # {:aws_instance_type=>"m1.xlarge",
75
- # :aws_availability_zone=>"us-east-1a",
76
- # :aws_duration=>31536000,
77
- # :aws_product_description=>"Linux/UNIX",
78
- # :aws_id=>"c48ab04c-63ab-4cd6-b8f5-978a29eb9bcc",
79
- # :aws_usage_price=>0.24,
80
- # :aws_fixed_price=>2600.0}]
81
- #
77
+ # :aws_availability_zone=>"us-east-1a"},
78
+ # {:currency_code=>"USD",
79
+ # :aws_fixed_price=>700.0,
80
+ # :aws_id=>"c48ab04c-7e03-46b2-891a-2df1116e51a3",
81
+ # :aws_product_description=>"Linux/UNIX (Amazon VPC)",
82
+ # :aws_instance_type=>"c1.medium",
83
+ # :aws_duration=>94608000,
84
+ # :instance_tenancy=>"default",
85
+ # :aws_usage_price=>0.06,
86
+ # :aws_availability_zone=>"us-east-1a"}, ... ]
87
+ #
82
88
  # ec2.describe_reserved_instances_offerings(:filters => {'availability-zone' => 'us-east-1c'})
83
89
  #
84
90
  # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeReservedInstancesOfferings.html
@@ -123,6 +129,8 @@ module RightAws
123
129
  when 'productDescription' then @item[:aws_product_description] = @text
124
130
  when 'state' then @item[:aws_state] = @text
125
131
  when 'start' then @item[:aws_start] = @text
132
+ when 'instanceTenancy' then @item[:instance_tenancy] = @text
133
+ when 'currencyCode' then @item[:currency_code] = @text
126
134
  else
127
135
  case full_tag_name
128
136
  when %r{/tagSet/item/key$} then @aws_tag[:key] = @text
@@ -149,9 +157,11 @@ module RightAws
149
157
  when 'duration' then @item[:aws_duration] = @text.to_i
150
158
  when 'usagePrice' then @item[:aws_usage_price] = @text.to_f
151
159
  when 'fixedPrice' then @item[:aws_fixed_price] = @text.to_f
160
+ when 'instanceTenancy' then @item[:instance_tenancy] = @text
161
+ when 'currencyCode' then @item[:currency_code] = @text
152
162
  when 'productDescription' then @item[:aws_product_description] = @text
153
- when 'item' then @result << @item
154
- end
163
+ when 'item' then @result << @item
164
+ end
155
165
  end
156
166
  def reset
157
167
  @result = []
@@ -30,6 +30,7 @@ module RightAws
30
30
  #-----------------------------------------------------------------
31
31
 
32
32
  # Retrieve Security Groups information.
33
+ # Options: By default this methods expects security group ids but if you wanna pass their names then :describe_by => :group_name option must be set.
33
34
  #
34
35
  # Accepts a list of security groups and/or a set of filters as the last parameter.
35
36
  #
@@ -40,35 +41,45 @@ module RightAws
40
41
  # ec2 = Rightscale::Ec2.new(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
41
42
  # ec2.describe_security_groups #=>
42
43
  # [{:aws_perms=>
43
- # [{:group=>"default", :owner=>"048291609141"},
44
- # {:to_port=>"22",
45
- # :protocol=>"tcp",
46
- # :from_port=>"22",
47
- # :cidr_ips=>"0.0.0.0/0"},
48
- # {:to_port=>"9997",
49
- # :protocol=>"tcp",
50
- # :from_port=>"9997",
51
- # :cidr_ips=>"0.0.0.0/0"}],
52
- # :aws_group_name=>"photo_us",
53
- # :aws_description=>"default group",
54
- # :aws_owner=>"826693181925"}]
44
+ # [{:protocol=>"-1", :cidr_ips=>"0.0.0.0/0", :direction=>:egress},
45
+ # {:protocol=>"tcp",
46
+ # :cidr_ips=>"127.0.0.2/32",
47
+ # :direction=>:egress,
48
+ # :from_port=>"1111",
49
+ # :to_port=>"1111"},
50
+ # {:protocol=>"tcp",
51
+ # :cidr_ips=>"127.0.0.1/32",
52
+ # :direction=>:egress,
53
+ # :from_port=>"1111",
54
+ # :to_port=>"1111"}],
55
+ # :aws_group_name=>"kd-vpc-egress-test-1",
56
+ # :vpc_id=>"vpc-e16cf988",
57
+ # :aws_description=>"vpc test",
58
+ # :aws_owner=>"826693181925",
59
+ # :group_id=>"sg-b72032db"}]
60
+ #
61
+ # # Describe by group ids
62
+ # ec2.describe_security_groups("sg-a0b85dc9", "sg-00b05d39", "sg-a1b86dc8")
63
+ #
64
+ # # Describe by group names
65
+ # ec2.describe_security_groups("default", "default1", "kd", :describe_by => :group_name)
55
66
  #
56
67
  # # Eucalyptus cloud:
57
68
  # ec2 = Rightscale::Ec2.new(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, :eucalyptus => true)
58
69
  # ec2.describe_security_groups #=>
59
70
  # [{:aws_perms=>
60
71
  # [{:to_port=>"65535",
61
- # :group=>"default",
72
+ # :group_name=>"default",
62
73
  # :protocol=>"tcp",
63
74
  # :owner=>"048291609141",
64
75
  # :from_port=>"1"},
65
76
  # {:to_port=>"65535",
66
- # :group=>"default",
77
+ # :group_name=>"default",
67
78
  # :protocol=>"udp",
68
79
  # :owner=>"048291609141",
69
80
  # :from_port=>"1"},
70
81
  # {:to_port=>"-1",
71
- # :group=>"default",
82
+ # :group_name=>"default",
72
83
  # :protocol=>"icmp",
73
84
  # :owner=>"048291609141",
74
85
  # :from_port=>"-1"},
@@ -89,29 +100,38 @@ module RightAws
89
100
  # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSecurityGroups.html
90
101
  #
91
102
  def describe_security_groups(*list_and_options)
92
- describe_resources_with_list_and_options('DescribeSecurityGroups', 'GroupName', QEc2DescribeSecurityGroupsParser, list_and_options) do |parser|
103
+ list, options = AwsUtils::split_items_and_params(list_and_options)
104
+ describe_by = options.delete(:describe_by) == :group_name ? 'GroupName' : 'GroupId'
105
+ describe_resources_with_list_and_options('DescribeSecurityGroups', describe_by, QEc2DescribeSecurityGroupsParser, list_and_options) do |parser|
93
106
  result = []
94
107
  parser.result.each do |item|
95
108
  result_item = { :aws_owner => item[:owner_id],
96
109
  :aws_group_name => item[:group_name],
97
110
  :aws_description => item[:group_description] }
111
+ result_item[:group_id] = item[:group_id] unless item[:group_id].right_blank?
112
+ result_item[:vpc_id] = item[:vpc_id] unless item[:vpc_id].right_blank?
98
113
  aws_perms = []
99
114
  item[:ip_permissions].each do |permission|
100
115
  result_perm = {}
101
- result_perm[:from_port] = permission[:from_port]
102
- result_perm[:to_port] = permission[:to_port]
116
+ result_perm[:from_port] = permission[:from_port] unless permission[:from_port].right_blank?
117
+ result_perm[:to_port] = permission[:to_port] unless permission[:to_port].right_blank?
103
118
  result_perm[:protocol] = permission[:ip_protocol]
119
+ result_perm[:direction] = permission[:direction]
104
120
  # IP permissions
105
121
  Array(permission[:ip_ranges]).each do |ip_range|
106
122
  perm = result_perm.dup
107
- perm[:cidr_ips] = ip_range
123
+ # Mhhh... For Eucalyptus we somehow get used to use ":cidr_ip" instead of ":cidr_ips"...
124
+ if @params[:eucalyptus] then perm[:cidr_ip] = ip_range
125
+ else perm[:cidr_ips] = ip_range
126
+ end
108
127
  aws_perms << perm
109
128
  end
110
129
  # Group permissions
111
130
  Array(permission[:groups]).each do |group|
112
131
  perm = result_perm.dup
113
- perm[:group] = group[:group_name]
114
- perm[:owner] = group[:user_id]
132
+ perm[:group_name] = group[:group_name] unless group[:group_name].right_blank?
133
+ perm[:group_id] = group[:group_id] unless group[:group_id].right_blank?
134
+ perm[:owner] = group[:user_id] unless group[:user_id].right_blank?
115
135
  aws_perms << perm
116
136
  end
117
137
  end
@@ -122,87 +142,68 @@ module RightAws
122
142
  end
123
143
  end
124
144
 
145
+ def describe_security_groups_by_name(*list)
146
+ describe_security_groups(list, :describe_by => :group_name)
147
+ end
148
+
125
149
  # Create new Security Group. Returns +true+ or an exception.
150
+ # Options: :vpc_id
126
151
  #
127
- # ec2.create_security_group('default-1',"Default allowing SSH, HTTP, and HTTPS ingress") #=> true
152
+ # ec2.create_security_group('default-1',"Default allowing SSH, HTTP, and HTTPS ingress") #=>
153
+ # { :group_id=>"sg-f0227599", :return=>true }
128
154
  #
129
- def create_security_group(name, description=nil)
130
- # EC2 doesn't like an empty description...
131
- description = "-" if description.right_blank?
132
- link = generate_request("CreateSecurityGroup",
133
- 'GroupName' => name.to_s,
134
- 'GroupDescription' => description.to_s)
135
- request_info(link, RightBoolResponseParser.new(:logger => @logger))
155
+ # ec2.create_security_group('default-2',"my VPC group", :vpc_id => 'vpc-e16c0000') #=>
156
+ # { :group_id=>"sg-76d1c31a", :return=>true }
157
+ #
158
+ def create_security_group(name, description = nil, options = {})
159
+ options = options.dup
160
+ options[:group_name] = name
161
+ options[:group_description] = description.right_blank? ? '-' : description # EC2 rejects an empty description...
162
+ link = generate_request("CreateSecurityGroup", map_api_keys_and_values(options, :group_name, :group_description, :vpc_id))
163
+ request_info(link, QEc2CreateSecurityGroupsParser.new(:logger => @logger))
136
164
  rescue Exception
137
165
  on_exception
138
166
  end
139
167
 
140
168
  # Remove Security Group. Returns +true+ or an exception.
169
+ # Options: :group_name, :group_id
170
+ #
171
+ # # Delete security group by group_id:
172
+ # ec2.delete_security_group('sg-90054ef9') #=> true
173
+ # ec2.delete_security_group(:group_id => 'sg-90054ef9') #=> true
141
174
  #
142
- # ec2.delete_security_group('default-1') #=> true
175
+ # # Delete security group by name (EC2 only):
176
+ # ec2.delete_security_group(:group_name => 'my-group']) #=> true
143
177
  #
144
- def delete_security_group(name)
145
- link = generate_request("DeleteSecurityGroup",
146
- 'GroupName' => name.to_s)
178
+ def delete_security_group(group_id_or_options={})
179
+ options = group_id_or_options.is_a?(Hash) ? group_id_or_options : { :group_id => group_id_or_options }
180
+ link = generate_request("DeleteSecurityGroup", map_api_keys_and_values(options, :group_name, :group_id))
147
181
  request_info(link, RightBoolResponseParser.new(:logger => @logger))
148
182
  rescue Exception
149
183
  on_exception
150
184
  end
151
185
 
152
- # Edit AWS/Eucaliptus security group permissions.
153
- #
154
- # Options:
155
- # action - :authorize (or :grant) | :revoke (or :remove)
156
- # group_name - security group name
157
- # permissions - a combination of options below:
158
- # :source_group_owner => UserId
159
- # :source_group => GroupName
160
- # :from_port => from port
161
- # :to_port => to port
162
- # :port => set both :from_port and to_port with the same value
163
- # :protocol => :tcp | :udp | :icmp
164
- # :cidr_ip => '0.0.0.0/0'
165
- #
166
- # ec2.edit_security_group( :grant,
167
- # 'kd-sg-test',
168
- # :source_group => "sketchy",
169
- # :source_group_owner => "600000000006",
170
- # :protocol => 'tcp',
171
- # :port => '80',
172
- # :cidr_ip => '127.0.0.1/32') #=> true
173
- #
174
- # P.S. This method is deprecated for AWS and but still good for Eucaliptus clouds.
175
- # Use +modify_security_group_ingress+ method for AWS clouds.
176
- #
177
- def edit_security_group(action, group_name, params)
178
- hash = {}
179
- case action
180
- when :authorize, :grant then action = "AuthorizeSecurityGroupIngress"
181
- when :revoke, :remove then action = "RevokeSecurityGroupIngress"
182
- else raise "Unknown action #{action.inspect}!"
183
- end
184
- hash['GroupName'] = group_name
185
- hash['SourceSecurityGroupName'] = params[:source_group] unless params[:source_group].right_blank?
186
- hash['SourceSecurityGroupOwnerId'] = params[:source_group_owner].to_s.gsub(/-/,'') unless params[:source_group_owner].right_blank?
187
- hash['IpProtocol'] = params[:protocol] unless params[:protocol].right_blank?
188
- unless params[:port].right_blank?
189
- hash['FromPort'] = params[:port]
190
- hash['ToPort'] = params[:port]
191
- end
192
- hash['FromPort'] = params[:from_port] unless params[:from_port].right_blank?
193
- hash['ToPort'] = params[:to_port] unless params[:to_port].right_blank?
194
- hash['CidrIp'] = params[:cidr_ip] unless params[:cidr_ip].right_blank?
195
- #
196
- link = generate_request(action, hash)
197
- request_info(link, RightBoolResponseParser.new(:logger => @logger))
198
- rescue Exception
199
- on_exception
186
+ def grant_security_group_ingress(group_id, permissions)
187
+ modify_security_group(:grant, :ingress, group_id, permissions)
188
+ end
189
+
190
+ def revoke_security_group_ingress(group_id, permissions)
191
+ modify_security_group(:revoke, :ingress, group_id, permissions)
192
+ end
193
+
194
+ def grant_security_group_egress(group_id, permissions)
195
+ modify_security_group(:grant, :egress, group_id, permissions)
196
+ end
197
+
198
+ def revoke_security_group_egress(group_id, permissions)
199
+ modify_security_group(:revoke, :egress, group_id, permissions)
200
200
  end
201
201
 
202
202
  # Modify AWS security group permissions.
203
203
  #
204
204
  # Options:
205
205
  # action - :authorize (or :grant) | :revoke (or :remove)
206
+ # direction - :ingress | :egress
206
207
  # group_name - security group name
207
208
  # permissions - a combination of options below:
208
209
  # # Ports:
@@ -210,70 +211,65 @@ module RightAws
210
211
  # :to_port => to port
211
212
  # :port => set both :from_port and to_port with the same value
212
213
  # # Protocol
213
- # :protocol => :tcp | :udp | :icmp
214
- # # Group(s)
215
- # :source_group_owner => UserId
216
- # :source_group => GroupName
217
- # # or
218
- # :source_groups => { UserId1 => GroupName1, UserName2 => GroupName2 }
219
- # :source_groups => [ [ UserId1, GroupName1 ], [ UserName2 => GroupName2 ] ]
214
+ # :protocol => :tcp | :udp | :icmp | -1
215
+ # # or (ingress)
216
+ # :groups => { UserId1 => GroupId1, UserName2 => GroupId2 }
217
+ # :groups => [ [ UserId1, GroupId1 ], [ UserName2 => GroupId2 ] ]
218
+ # # or (egress)
219
+ # :groups => [ GroupId1, GroupId2 ]
220
220
  # # CidrIp(s)
221
221
  # :cidr_ip => '0.0.0.0/0'
222
222
  # :cidr_ips => ['1.1.1.1/1', '2.2.2.2/2']
223
223
  #
224
224
  # # CidrIP based permissions:
225
225
  #
226
- # ec2.modify_security_group_ingress(:authorize, 'my_cool_group',
227
- # :cidr_ip => "127.0.0.0/31",
228
- # :port => 811,
229
- # :protocol => 'tcp' ) #=> true
226
+ # ec2.modify_security_group(:authorize, :ingress, 'sg-75d1c319',
227
+ # :cidr_ip => "127.0.0.0/31",
228
+ # :port => 811,
229
+ # :protocol => 'tcp' ) #=> true
230
230
  #
231
- # ec2.modify_security_group_ingress(:revoke, 'my_cool_group',
232
- # :cidr_ips => ["127.0.0.1/32", "127.0.0.2/32"],
233
- # :port => 812,
234
- # :protocol => 'tcp' ) #=> true
231
+ # ec2.modify_security_group(:revoke, :ingress, 'sg-75d1c319',
232
+ # :cidr_ips => ["127.0.0.1/32", "127.0.0.2/32"],
233
+ # :port => 812,
234
+ # :protocol => 'tcp' ) #=> true
235
235
  #
236
236
  # # Group based permissions:
237
237
  #
238
- # ec2.modify_security_group_ingress(:authorize, 'my_cool_group',
239
- # :source_group_owner => "586789340000",
240
- # :source_group => "sketchy-us",
241
- # :port => 800,
242
- # :protocol => 'tcp' ) #=> true
243
- #
244
- # ec2.modify_security_group_ingress(:authorize, 'my_cool_group',
245
- # :source_groups => { "586789340000" => "sketchy-us",
246
- # "635201710000" => "sketchy" },
247
- # :port => 801,
248
- # :protocol => 'tcp' ) #=> true
238
+ # ec2.modify_security_group(:authorize, :ingress, 'sg-75d1c319',
239
+ # :groups => { "586789340000" => "sg-75d1c300",
240
+ # "635201710000" => "sg-75d1c301" },
241
+ # :port => 801,
242
+ # :protocol => 'tcp' ) #=> true
249
243
  #
250
- # ec2.modify_security_group_ingress(:revoke, 'my_cool_group',
251
- # :source_groups => [[ "586789340000", "sketchy-us" ],
252
- # [ "586789340000", "default" ]],
253
- # :port => 809,
254
- # :protocol => 'tcp' ) #=> true
244
+ # ec2.modify_security_group(:revoke, :ingress, 'sg-75d1c319',
245
+ # :groups => [[ "586789340000", "sg-75d1c300" ],
246
+ # [ "586789340000", "sg-75d1c302" ]],
247
+ # :port => 809,
248
+ # :protocol => 'tcp' ) #=> true
255
249
  #
256
250
  # # +Permissions+ can be an array of permission hashes:
257
251
  #
258
- # ec2.modify_security_group_ingress(:authorize, 'my_cool_group',
259
- # [{ :source_groups => { "586789340000" => "sketchy-us",
260
- # "635201710000" => "sketchy" },
261
- # :port => 803,
262
- # :protocol => 'tcp'},
263
- # { :cidr_ips => ["127.0.0.1/32", "127.0.0.2/32"],
264
- # :port => 812,
265
- # :protocol => 'tcp' }]) #=> true
252
+ # ec2.modify_security_group(:authorize, :ingress, 'sg-75d1c319',
253
+ # [{ :groups => { "586789340000" => "sg-75d1c300",
254
+ # "635201710000" => "sg-75d1c301" },
255
+ # :port => 803,
256
+ # :protocol => 'tcp'},
257
+ # { :cidr_ips => ["127.0.0.1/32", "127.0.0.2/32"],
258
+ # :port => 812,
259
+ # :protocol => 'tcp' }]) #=> true
266
260
  #
267
- def modify_security_group_ingress(action, group_name, permissions)
261
+ def modify_security_group(action, direction, group_id, permissions)
268
262
  hash = {}
269
- case action
270
- when :authorize, :grant then action = "AuthorizeSecurityGroupIngress"
271
- when :revoke, :remove then action = "RevokeSecurityGroupIngress"
272
- else raise "Unknown action #{action.inspect}!"
273
- end
263
+ raise "Unknown action #{action.inspect}!" unless [:authorize, :grant, :revoke, :remove].include?(action)
264
+ raise "Unknown direction #{direction.inspect}!" unless [:ingress, :egress].include?(direction)
265
+ # Remote action
266
+ remote_action = case action
267
+ when :authorize, :grant then direction == :ingress ? "AuthorizeSecurityGroupIngress" : "AuthorizeSecurityGroupEgress"
268
+ when :revoke, :remove then direction == :ingress ? "RevokeSecurityGroupIngress" : "RevokeSecurityGroupEgress"
269
+ end
274
270
  # Group Name
275
- hash["GroupName"] = group_name
276
- #
271
+ hash["GroupId"] = group_id
272
+ # Permissions
277
273
  permissions = [permissions] unless permissions.is_a?(Array)
278
274
  permissions.each_with_index do |permission, idx|
279
275
  pid = idx+1
@@ -287,30 +283,112 @@ module RightAws
287
283
  hash["IpPermissions.#{pid}.FromPort"] = permission[:from_port]
288
284
  hash["IpPermissions.#{pid}.ToPort"] = permission[:to_port]
289
285
  end
290
- # Source Group(s)
291
- # Old way (if it is used):
292
- # :source_group_owner => UserId, :source_group => GroupName
293
- if !permission[:source_group].right_blank? && !permission[:source_group_owner].right_blank?
294
- permission[:source_groups] = { permission[:source_group_owner] => permission[:source_group]}
286
+ # Groups
287
+ case direction
288
+ when :ingress
289
+ # :groups => {UserId1 => GroupId1, ... UserIdN => GroupIdN}
290
+ # or (this allows using same UserId multiple times )
291
+ # :groups => [[UserId1, GroupId1], ... [UserIdN, GroupIdN]]
292
+ # or even (unset user is == current account user)
293
+ # :groups => [GroupId1, GroupId2, ... GroupIdN]
294
+ # :groups => [[UserId1, GroupId1], GroupId2, ... GroupIdN, ... [UserIdM, GroupIdM]]
295
+ #
296
+ index = 1
297
+ unless permission[:group_names].right_blank?
298
+ owner_and_groups = []
299
+ groups_only = []
300
+ Array(permission[:group_names]).each do |item|
301
+ if item.is_a?(Array) && item.size == 2
302
+ owner_and_groups << item
303
+ else
304
+ groups_only << item
305
+ end
306
+ end
307
+ hash.merge!(amazonize_list( ["IpPermissions.#{pid}.Groups.?.UserId", "IpPermissions.#{pid}.Groups.?.GroupName"], owner_and_groups, :index => index ))
308
+ index += owner_and_groups.size
309
+ groups_only = groups_only.flatten
310
+ hash.merge!(amazonize_list( "IpPermissions.#{pid}.Groups.?.GroupName", groups_only, :index => index ))
311
+ index += groups_only.size
312
+ end
313
+ unless permission[:groups].right_blank?
314
+ owner_and_groups = []
315
+ groups_only = []
316
+ Array(permission[:groups]).each do |item|
317
+ if item.is_a?(Array) && item.size == 2
318
+ owner_and_groups << item
319
+ else
320
+ groups_only << item
321
+ end
322
+ end
323
+ hash.merge!(amazonize_list( ["IpPermissions.#{pid}.Groups.?.UserId", "IpPermissions.#{pid}.Groups.?.GroupId"], owner_and_groups, :index => index ))
324
+ index += owner_and_groups.size
325
+ groups_only = groups_only.flatten
326
+ hash.merge!(amazonize_list( "IpPermissions.#{pid}.Groups.?.GroupId", groups_only, :index => index ))
327
+ end
328
+ when :egress
329
+ # :groups => [GroupId1, ... GroupIdN]
330
+ hash.merge!(amazonize_list( "IpPermissions.#{pid}.Groups.?.GroupId", permission[:groups] ))
295
331
  end
296
- # # Fix UserId(s): '0000-0000-0000' => '000000000000'
297
- # permission[:source_groups] = Array(permission[:source_groups])
298
- # permission[:source_groups].each do |item|
299
- # item[0] = item[0].to_s.gsub(/-/,'')
300
- # end
301
- # New way:
302
- # :source_groups => {UserId1 => GroupName1, ... UserIdN => GroupNameN}
303
- # or (this allows using same UserId multiple times )
304
- # :source_groups => [[UserId1, GroupName1], ... [UserIdN, GroupNameN]]
305
- hash.merge!(amazonize_list( ["IpPermissions.#{pid}.Groups.?.UserId",
306
- "IpPermissions.#{pid}.Groups.?.GroupName"],
307
- permission[:source_groups] ))
308
332
  # CidrIp(s)
309
333
  cidr_ips = permission[:cidr_ips] unless permission[:cidr_ips].right_blank?
310
334
  cidr_ips ||= permission[:cidr_ip] unless permission[:cidr_ip].right_blank?
311
335
  hash.merge!(amazonize_list("IpPermissions.1.IpRanges.?.CidrIp", cidr_ips))
312
336
  end
313
337
  #
338
+ link = generate_request(remote_action, hash)
339
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
340
+ rescue Exception
341
+ on_exception
342
+ end
343
+
344
+ #-----------------------------------------------------------------
345
+ # Eucalyptus
346
+ #-----------------------------------------------------------------
347
+
348
+ # Edit AWS/Eucaliptus security group permissions.
349
+ #
350
+ # Options:
351
+ # action - :authorize (or :grant) | :revoke (or :remove)
352
+ # group_name - security group name
353
+ # permissions - a combination of options below:
354
+ # :source_group_owner => UserId
355
+ # :source_group => GroupName
356
+ # :from_port => from port
357
+ # :to_port => to port
358
+ # :port => set both :from_port and to_port with the same value
359
+ # :protocol => :tcp | :udp | :icmp
360
+ # :cidr_ip => '0.0.0.0/0'
361
+ #
362
+ # ec2.edit_security_group( :grant,
363
+ # 'kd-sg-test',
364
+ # :source_group => "sketchy",
365
+ # :source_group_owner => "600000000006",
366
+ # :protocol => 'tcp',
367
+ # :port => '80',
368
+ # :cidr_ip => '127.0.0.1/32') #=> true
369
+ #
370
+ # P.S. This method is deprecated for AWS and but still good for Eucaliptus clouds.
371
+ # Use +modify_security_group_ingress+ method for AWS clouds.
372
+ #
373
+ def edit_security_group(action, group_name, params)
374
+ hash = {}
375
+ case action
376
+ when :authorize, :grant then action = "AuthorizeSecurityGroupIngress"
377
+ when :revoke, :remove then action = "RevokeSecurityGroupIngress"
378
+ else raise "Unknown action #{action.inspect}!"
379
+ end
380
+ hash['GroupName'] = group_name
381
+ hash['SourceSecurityGroupName'] = params[:source_group] unless params[:source_group].right_blank?
382
+ hash['SourceSecurityGroupOwnerId'] = params[:source_group_owner].to_s.gsub(/-/,'') unless params[:source_group_owner].right_blank?
383
+ hash['IpProtocol'] = params[:protocol] unless params[:protocol].right_blank?
384
+ unless params[:port].right_blank?
385
+ hash['FromPort'] = params[:port]
386
+ hash['ToPort'] = params[:port]
387
+ end
388
+ hash['FromPort'] = params[:from_port] unless params[:from_port].right_blank?
389
+ hash['ToPort'] = params[:to_port] unless params[:to_port].right_blank?
390
+ hash['CidrIp'] = params[:cidr_ip] unless params[:cidr_ip].right_blank?
391
+ #
314
392
  link = generate_request(action, hash)
315
393
  request_info(link, RightBoolResponseParser.new(:logger => @logger))
316
394
  rescue Exception
@@ -355,35 +433,52 @@ module RightAws
355
433
  # PARSERS: Security Groups
356
434
  #-----------------------------------------------------------------
357
435
 
436
+ class QEc2CreateSecurityGroupsParser < RightAWSParser #:nodoc:
437
+ def tagend(name)
438
+ case name
439
+ when 'groupId' then @result[:group_id] = @text
440
+ when 'return' then @result[:return] = @text == 'true'
441
+ end
442
+ end
443
+ def reset
444
+ @result = {}
445
+ end
446
+ end
447
+
358
448
  class QEc2DescribeSecurityGroupsParser < RightAWSParser #:nodoc:
359
449
  def tagstart(name, attributes)
360
450
  if name == 'item'
361
- case
362
- when @xmlpath[/securityGroupInfo$/] then @item = { :ip_permissions => [] }
363
- when @xmlpath[/ipPermissions$/] then @ip_permission = { :groups => [], :ip_ranges => [] }
364
- when @xmlpath[/groups$/] then @group = {}
451
+ case full_tag_name
452
+ when %r{securityGroupInfo/item$} then @item = { :ip_permissions => [] }
453
+ when %r{ipPermissions/item$} then @ip_perm = { :groups => [], :ip_ranges => [], :direction => :ingress }
454
+ when %r{ipPermissionsEgress/item$} then @ip_perm = { :groups => [], :ip_ranges => [], :direction => :egress }
455
+ when %r{ipPermissions(Egress)?/item/groups/item$} then @group = {}
365
456
  end
366
457
  end
367
458
  end
368
459
  def tagend(name)
369
460
  case name
370
- when 'ownerId' then @item[:owner_id] = @text
371
- when 'groupDescription' then @item[:group_description] = @text
372
- when 'ipProtocol' then @ip_permission[:ip_protocol] = @text
373
- when 'fromPort' then @ip_permission[:from_port] = @text
374
- when 'toPort' then @ip_permission[:to_port] = @text
375
- when 'cidrIp' then @ip_permission[:ip_ranges] << @text
376
- when 'userId' then @group[:user_id] = @text
377
- when 'groupName'
378
- case
379
- when @xmlpath[/securityGroupInfo\/item$/] then @item[:group_name] = @text
380
- when @xmlpath[/groups\/item$/] then @group[:group_name] = @text
381
- end
382
- when 'item'
383
- case
384
- when @xmlpath[/groups$/] then @ip_permission[:groups] << @group
385
- when @xmlpath[/ipPermissions$/] then @item[:ip_permissions] << @ip_permission
386
- when @xmlpath[/securityGroupInfo$/]then @result << @item
461
+ when 'ownerId' then @item[:owner_id] = @text
462
+ when 'groupDescription' then @item[:group_description] = @text
463
+ when 'vpcId' then @item[:vpc_id] = @text
464
+ else
465
+ case full_tag_name
466
+ when %r{securityGroupInfo/item/groupName$} then @item[:group_name] = @text
467
+ when %r{securityGroupInfo/item/groupId$} then @item[:group_id] = @text
468
+ # ipPermission[Egress]
469
+ when %r{ipPermissions(Egress)?/item/ipProtocol$} then @ip_perm[:ip_protocol] = @text
470
+ when %r{ipPermissions(Egress)?/item/fromPort$} then @ip_perm[:from_port] = @text
471
+ when %r{ipPermissions(Egress)?/item/toPort$} then @ip_perm[:to_port] = @text
472
+ when %r{ipPermissions(Egress)?/item/ipRanges/item/cidrIp$} then @ip_perm[:ip_ranges] << @text
473
+ # ipPermissions[Egress]/Groups
474
+ when %r{ipPermissions(Egress)?/item/groups/item/groupName$} then @group[:group_name] = @text
475
+ when %r{ipPermissions(Egress)?/item/groups/item/groupId$} then @group[:group_id] = @text
476
+ when %r{ipPermissions(Egress)?/item/groups/item/userId$} then @group[:user_id] = @text
477
+ # Sets
478
+ when %r{ipPermissions(Egress)?/item/groups/item$} then @ip_perm[:groups] << @group
479
+ when %r{ipPermissions/item$} then @item[:ip_permissions] << @ip_perm
480
+ when %r{ipPermissionsEgress/item$} then @item[:ip_permissions] << @ip_perm
481
+ when %r{securityGroupInfo/item$} then @result << @item
387
482
  end
388
483
  end
389
484
  end