dustMason-right_aws 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/History.txt +305 -0
  2. data/Manifest.txt +60 -0
  3. data/README.txt +165 -0
  4. data/Rakefile +112 -0
  5. data/lib/acf/right_acf_interface.rb +549 -0
  6. data/lib/acf/right_acf_invalidations.rb +144 -0
  7. data/lib/acf/right_acf_origin_access_identities.rb +230 -0
  8. data/lib/acf/right_acf_streaming_interface.rb +229 -0
  9. data/lib/acw/right_acw_interface.rb +248 -0
  10. data/lib/as/right_as_interface.rb +698 -0
  11. data/lib/awsbase/benchmark_fix.rb +39 -0
  12. data/lib/awsbase/right_awsbase.rb +1174 -0
  13. data/lib/awsbase/support.rb +35 -0
  14. data/lib/awsbase/version.rb +9 -0
  15. data/lib/ec2/right_ec2.rb +458 -0
  16. data/lib/ec2/right_ec2_ebs.rb +465 -0
  17. data/lib/ec2/right_ec2_images.rb +413 -0
  18. data/lib/ec2/right_ec2_instances.rb +785 -0
  19. data/lib/ec2/right_ec2_monitoring.rb +70 -0
  20. data/lib/ec2/right_ec2_placement_groups.rb +108 -0
  21. data/lib/ec2/right_ec2_reserved_instances.rb +174 -0
  22. data/lib/ec2/right_ec2_security_groups.rb +396 -0
  23. data/lib/ec2/right_ec2_spot_instances.rb +425 -0
  24. data/lib/ec2/right_ec2_tags.rb +139 -0
  25. data/lib/ec2/right_ec2_vpc.rb +583 -0
  26. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  27. data/lib/elb/right_elb_interface.rb +571 -0
  28. data/lib/iam/right_iam_access_keys.rb +71 -0
  29. data/lib/iam/right_iam_groups.rb +195 -0
  30. data/lib/iam/right_iam_interface.rb +341 -0
  31. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  32. data/lib/iam/right_iam_users.rb +251 -0
  33. data/lib/rds/right_rds_interface.rb +1309 -0
  34. data/lib/right_aws.rb +88 -0
  35. data/lib/route_53/right_route_53_interface.rb +630 -0
  36. data/lib/s3/right_s3.rb +1123 -0
  37. data/lib/s3/right_s3_interface.rb +1198 -0
  38. data/lib/sdb/active_sdb.rb +1107 -0
  39. data/lib/sdb/right_sdb_interface.rb +753 -0
  40. data/lib/sns/right_sns.rb +205 -0
  41. data/lib/sns/right_sns_interface.rb +343 -0
  42. data/lib/sqs/right_sqs.rb +387 -0
  43. data/lib/sqs/right_sqs_gen2.rb +342 -0
  44. data/lib/sqs/right_sqs_gen2_interface.rb +523 -0
  45. data/lib/sqs/right_sqs_interface.rb +593 -0
  46. data/right_aws.gemspec +91 -0
  47. data/test/acf/test_helper.rb +2 -0
  48. data/test/acf/test_right_acf.rb +138 -0
  49. data/test/awsbase/test_helper.rb +2 -0
  50. data/test/awsbase/test_right_awsbase.rb +12 -0
  51. data/test/ec2/test_helper.rb +2 -0
  52. data/test/ec2/test_right_ec2.rb +108 -0
  53. data/test/http_connection.rb +87 -0
  54. data/test/rds/test_helper.rb +2 -0
  55. data/test/rds/test_right_rds.rb +120 -0
  56. data/test/s3/test_helper.rb +2 -0
  57. data/test/s3/test_right_s3.rb +421 -0
  58. data/test/s3/test_right_s3_stubbed.rb +97 -0
  59. data/test/sdb/test_active_sdb.rb +357 -0
  60. data/test/sdb/test_batch_put_attributes.rb +54 -0
  61. data/test/sdb/test_helper.rb +3 -0
  62. data/test/sdb/test_right_sdb.rb +253 -0
  63. data/test/sns/test_helper.rb +2 -0
  64. data/test/sns/test_right_sns.rb +73 -0
  65. data/test/sqs/test_helper.rb +2 -0
  66. data/test/sqs/test_right_sqs.rb +285 -0
  67. data/test/sqs/test_right_sqs_gen2.rb +264 -0
  68. data/test/test_credentials.rb +37 -0
  69. data/test/ts_right_aws.rb +14 -0
  70. metadata +244 -0
@@ -0,0 +1,70 @@
1
+ #
2
+ # Copyright (c) 2009 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ module RightAws
25
+
26
+ class Ec2
27
+
28
+ # Enables monitoring for a running instances. For more information, refer to the Amazon CloudWatch Developer Guide.
29
+ #
30
+ # ec2.monitor_instances('i-8437ddec') #=>
31
+ # {:instance_id=>"i-8437ddec", :monitoring_state=>"pending"}
32
+ #
33
+ def monitor_instances(*list)
34
+ link = generate_request("MonitorInstances", amazonize_list('InstanceId', list.flatten) )
35
+ request_info(link, QEc2MonitorInstancesParser.new(:logger => @logger)).first
36
+ rescue Exception
37
+ on_exception
38
+ end
39
+
40
+ # Disables monitoring for a running instances. For more information, refer to the Amazon CloudWatch Developer Guide.
41
+ #
42
+ # ec2.unmonitor_instances('i-8437ddec') #=>
43
+ # {:instance_id=>"i-8437ddec", :monitoring_state=>"disabling"}
44
+ #
45
+ def unmonitor_instances(*list)
46
+ link = generate_request("UnmonitorInstances", amazonize_list('InstanceId', list.flatten) )
47
+ request_info(link, QEc2MonitorInstancesParser.new(:logger => @logger)).first
48
+ rescue Exception
49
+ on_exception
50
+ end
51
+
52
+ class QEc2MonitorInstancesParser < RightAWSParser #:nodoc:
53
+ def tagstart(name, attributes)
54
+ @item = {} if name == 'item'
55
+ end
56
+ def tagend(name)
57
+ case name
58
+ when 'instanceId' then @item[:instance_id] = @text
59
+ when 'state' then @item[:monitoring_state] = @text
60
+ when 'item' then @result << @item
61
+ end
62
+ end
63
+ def reset
64
+ @result = []
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,108 @@
1
+ #
2
+ # Copyright (c) 2010 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ module RightAws
25
+
26
+ class Ec2
27
+
28
+ #-----------------------------------------------------------------
29
+ # Placement Groups
30
+ #-----------------------------------------------------------------
31
+
32
+ # Describe placement groups.
33
+ #
34
+ # Accepts a list of placement groups and/or a set of filters as the last parameter.
35
+ #
36
+ # Filters: group-name, state, strategy
37
+ #
38
+ # If you don’t specify a particular placement group, the response includes
39
+ # information about all of them. The information includes the group name, the strategy,
40
+ # and the group state (e.g., pending, available, etc.).
41
+ #
42
+ # ec2.describe_placement_groups #=>
43
+ # [{:state=>"available", :strategy=>"cluster", :group_name=>"kd_first"},
44
+ # {:state=>"available", :strategy=>"cluster", :group_name=>"kd_second"}]
45
+ #
46
+ # ec2.describe_placement_groups('kd_second') #=>
47
+ # [{:strategy=>"cluster", :group_name=>"kd_second", :state=>"available"}]
48
+ #
49
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference_query_DescribePlacementGroups.html
50
+ #
51
+ def describe_placement_groups(*list_and_options)
52
+ describe_resources_with_list_and_options('DescribePlacementGroups', 'GroupName', QEc2DescribePlacementGroupsParser, list_and_options)
53
+ end
54
+
55
+ # Create placement group creates a placement group (i.e. logical cluster group)
56
+ # into which you can then launch instances. You must provide a name for the group
57
+ # that is unique within the scope of your account. You must also provide a strategy
58
+ # value. Currently the only value accepted is cluster.
59
+ #
60
+ # ec2.create_placement_group('kd_second') #=> true
61
+ #
62
+ def create_placement_group(placement_group_name, strategy = 'cluster')
63
+ link = generate_request('CreatePlacementGroup',
64
+ 'GroupName' => placement_group_name.to_s,
65
+ 'Strategy' => strategy.to_s)
66
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
67
+ rescue Exception
68
+ on_exception
69
+ end
70
+
71
+ # Delete placement group deletes a placement group that you own. The group must not
72
+ # contain any instances.
73
+ #
74
+ # ec2.delete_placement_group('kd_second') #=> true
75
+ #
76
+ def delete_placement_group(placement_group_name)
77
+ link = generate_request('DeletePlacementGroup',
78
+ 'GroupName' => placement_group_name.to_s)
79
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
80
+ rescue Exception
81
+ on_exception
82
+ end
83
+
84
+ #-----------------------------------------------------------------
85
+ # PARSERS: Placement Groups
86
+ #-----------------------------------------------------------------
87
+
88
+ class QEc2DescribePlacementGroupsParser < RightAWSParser #:nodoc:
89
+ def tagstart(name, attributes)
90
+ case name
91
+ when 'item' then @item = {}
92
+ end
93
+ end
94
+ def tagend(name)
95
+ case name
96
+ when 'groupName' then @item[:group_name] = @text
97
+ when 'strategy' then @item[:strategy] = @text
98
+ when 'state' then @item[:state] = @text
99
+ when 'item' then @result << @item
100
+ end
101
+ end
102
+ def reset
103
+ @result = []
104
+ end
105
+ end
106
+
107
+ end
108
+ end
@@ -0,0 +1,174 @@
1
+ #
2
+ # Copyright (c) 2009 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ module RightAws
25
+
26
+ class Ec2
27
+
28
+ #-----------------------------------------------------------------
29
+ # Reserved instances
30
+ #-----------------------------------------------------------------
31
+
32
+ # Retrieve reserved instances list.
33
+ #
34
+ # Accepts a list of reserved instances and/or a set of filters as the last parameter.
35
+ #
36
+ # Filters: availability-zone, duration, fixed-price, instance-type, product-description,
37
+ # reserved-instances-id, start, state, tag-key, tag-value, tag:key, usage-price
38
+ #
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}]
50
+ #
51
+ # ec2.describe_reserved_instances(:filters => {'availability-zone' => 'us-east-1a'})
52
+ #
53
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeReservedInstances.html
54
+ #
55
+ def describe_reserved_instances(*list_and_options)
56
+ describe_resources_with_list_and_options('DescribeReservedInstances', 'ReservedInstancesId', QEc2DescribeReservedInstancesParser, list_and_options)
57
+ end
58
+
59
+ # Retrieve reserved instances offerings.
60
+ #
61
+ # Accepts a list of reserved instances offerings and/or a set of filters as the last parameter.
62
+ #
63
+ # Filters: availability-zone, duration, fixed-price, instance-type, product-description, reserved-instances-offering-id, usage-price
64
+ #
65
+ # ec2.describe_reserved_instances_offerings #=>
66
+ # [{:aws_instance_type=>"c1.medium",
67
+ # :aws_availability_zone=>"us-east-1c",
68
+ # :aws_duration=>94608000,
69
+ # :aws_product_description=>"Linux/UNIX",
70
+ # :aws_id=>"e5a2ff3b-f6eb-4b4e-83f8-b879d7060257",
71
+ # :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
+ #
82
+ # ec2.describe_reserved_instances_offerings(:filters => {'availability-zone' => 'us-east-1c'})
83
+ #
84
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeReservedInstancesOfferings.html
85
+ #
86
+ def describe_reserved_instances_offerings(*list_and_options)
87
+ describe_resources_with_list_and_options('DescribeReservedInstancesOfferings', 'ReservedInstancesOfferingId', QEc2DescribeReservedInstancesOfferingsParser, list_and_options)
88
+ end
89
+
90
+ # Purchase a Reserved Instance.
91
+ # Returns ReservedInstancesId value.
92
+ #
93
+ # ec2.purchase_reserved_instances_offering('e5a2ff3b-f6eb-4b4e-83f8-b879d7060257', 3) # => '4b2293b4-5813-4cc8-9ce3-1957fc1dcfc8'
94
+ #
95
+ def purchase_reserved_instances_offering(reserved_instances_offering_id, instance_count=1)
96
+ link = generate_request("PurchaseReservedInstancesOffering", { 'ReservedInstancesOfferingId' => reserved_instances_offering_id,
97
+ 'InstanceCount' => instance_count })
98
+ request_info(link, QEc2PurchaseReservedInstancesOfferingParser.new)
99
+ rescue Exception
100
+ on_exception
101
+ end
102
+
103
+ #-----------------------------------------------------------------
104
+ # PARSERS: ReservedInstances
105
+ #-----------------------------------------------------------------
106
+
107
+ class QEc2DescribeReservedInstancesParser < RightAWSParser #:nodoc:
108
+ def tagstart(name, attributes)
109
+ case full_tag_name
110
+ when %r{/reservedInstancesSet/item$} then @item = { :tags => {} }
111
+ when %r{/tagSet/item$} then @aws_tag = {}
112
+ end
113
+ end
114
+ def tagend(name)
115
+ case name
116
+ when 'reservedInstancesId' then @item[:aws_id] = @text
117
+ when 'instanceType' then @item[:aws_instance_type] = @text
118
+ when 'availabilityZone' then @item[:aws_availability_zone] = @text
119
+ when 'duration' then @item[:aws_duration] = @text.to_i
120
+ when 'usagePrice' then @item[:aws_usage_price] = @text.to_f
121
+ when 'fixedPrice' then @item[:aws_fixed_price] = @text.to_f
122
+ when 'instanceCount' then @item[:aws_instance_count] = @text.to_i
123
+ when 'productDescription' then @item[:aws_product_description] = @text
124
+ when 'state' then @item[:aws_state] = @text
125
+ when 'start' then @item[:aws_start] = @text
126
+ else
127
+ case full_tag_name
128
+ when %r{/tagSet/item/key$} then @aws_tag[:key] = @text
129
+ when %r{/tagSet/item/value$} then @aws_tag[:value] = @text
130
+ when %r{/tagSet/item$} then @item[:tags][@aws_tag[:key]] = @aws_tag[:value]
131
+ when %r{/reservedInstancesSet/item$} then @result << @item
132
+ end
133
+ end
134
+ end
135
+ def reset
136
+ @result = []
137
+ end
138
+ end
139
+
140
+ class QEc2DescribeReservedInstancesOfferingsParser < RightAWSParser #:nodoc:
141
+ def tagstart(name, attributes)
142
+ @item = {} if name == 'item'
143
+ end
144
+ def tagend(name)
145
+ case name
146
+ when 'reservedInstancesOfferingId' then @item[:aws_id] = @text
147
+ when 'instanceType' then @item[:aws_instance_type] = @text
148
+ when 'availabilityZone' then @item[:aws_availability_zone] = @text
149
+ when 'duration' then @item[:aws_duration] = @text.to_i
150
+ when 'usagePrice' then @item[:aws_usage_price] = @text.to_f
151
+ when 'fixedPrice' then @item[:aws_fixed_price] = @text.to_f
152
+ when 'productDescription' then @item[:aws_product_description] = @text
153
+ when 'item' then @result << @item
154
+ end
155
+ end
156
+ def reset
157
+ @result = []
158
+ end
159
+ end
160
+
161
+ class QEc2PurchaseReservedInstancesOfferingParser < RightAWSParser #:nodoc:
162
+ def tagend(name)
163
+ if name == 'reservedInstancesId'
164
+ @result = @text
165
+ end
166
+ end
167
+ def reset
168
+ @result = ''
169
+ end
170
+ end
171
+
172
+ end
173
+
174
+ end
@@ -0,0 +1,396 @@
1
+ #
2
+ # Copyright (c) 2010 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ module RightAws
25
+
26
+ class Ec2
27
+
28
+ #-----------------------------------------------------------------
29
+ # Security groups
30
+ #-----------------------------------------------------------------
31
+
32
+ # Retrieve Security Groups information.
33
+ #
34
+ # Accepts a list of security groups and/or a set of filters as the last parameter.
35
+ #
36
+ # Filters: description, group-name, ip-permission.cidr, ip-permission.from-port, ip-permission.group-name,
37
+ # ip-permission.protocol, ip-permission.to-port, ip-permission.user-id, owner-id
38
+ #
39
+ # # Amazon cloud:
40
+ # ec2 = Rightscale::Ec2.new(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
41
+ # ec2.describe_security_groups #=>
42
+ # [{: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"}]
55
+ #
56
+ # # Eucalyptus cloud:
57
+ # ec2 = Rightscale::Ec2.new(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, :eucalyptus => true)
58
+ # ec2.describe_security_groups #=>
59
+ # [{:aws_perms=>
60
+ # [{:to_port=>"65535",
61
+ # :group=>"default",
62
+ # :protocol=>"tcp",
63
+ # :owner=>"048291609141",
64
+ # :from_port=>"1"},
65
+ # {:to_port=>"65535",
66
+ # :group=>"default",
67
+ # :protocol=>"udp",
68
+ # :owner=>"048291609141",
69
+ # :from_port=>"1"},
70
+ # {:to_port=>"-1",
71
+ # :group=>"default",
72
+ # :protocol=>"icmp",
73
+ # :owner=>"048291609141",
74
+ # :from_port=>"-1"},
75
+ # {:to_port=>"22",
76
+ # :protocol=>"tcp",
77
+ # :from_port=>"22",
78
+ # :cidr_ip=>"0.0.0.0/0"},
79
+ # {:to_port=>"9997",
80
+ # :protocol=>"tcp",
81
+ # :from_port=>"9997",
82
+ # :cidr_ip=>"0.0.0.0/0"}],
83
+ # :aws_group_name=>"photo_us",
84
+ # :aws_description=>"default group",
85
+ # :aws_owner=>"826693181925"}]
86
+ #
87
+ # ec2.describe_security_groups(:filters => {'ip-permission.from-port' => '22'})
88
+ #
89
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSecurityGroups.html
90
+ #
91
+ def describe_security_groups(*list_and_options)
92
+ describe_resources_with_list_and_options('DescribeSecurityGroups', 'GroupName', QEc2DescribeSecurityGroupsParser, list_and_options) do |parser|
93
+ result = []
94
+ parser.result.each do |item|
95
+ result_item = { :aws_owner => item[:owner_id],
96
+ :aws_group_name => item[:group_name],
97
+ :aws_description => item[:group_description] }
98
+ aws_perms = []
99
+ item[:ip_permissions].each do |permission|
100
+ result_perm = {}
101
+ result_perm[:from_port] = permission[:from_port]
102
+ result_perm[:to_port] = permission[:to_port]
103
+ result_perm[:protocol] = permission[:ip_protocol]
104
+ # IP permissions
105
+ Array(permission[:ip_ranges]).each do |ip_range|
106
+ perm = result_perm.dup
107
+ perm[:cidr_ips] = ip_range
108
+ aws_perms << perm
109
+ end
110
+ # Group permissions
111
+ Array(permission[:groups]).each do |group|
112
+ perm = result_perm.dup
113
+ perm[:group] = group[:group_name]
114
+ perm[:owner] = group[:user_id]
115
+ aws_perms << perm
116
+ end
117
+ end
118
+ result_item[:aws_perms] = aws_perms.uniq
119
+ result << result_item
120
+ end
121
+ result
122
+ end
123
+ end
124
+
125
+ # Create new Security Group. Returns +true+ or an exception.
126
+ #
127
+ # ec2.create_security_group('default-1',"Default allowing SSH, HTTP, and HTTPS ingress") #=> true
128
+ #
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))
136
+ rescue Exception
137
+ on_exception
138
+ end
139
+
140
+ # Remove Security Group. Returns +true+ or an exception.
141
+ #
142
+ # ec2.delete_security_group('default-1') #=> true
143
+ #
144
+ def delete_security_group(name)
145
+ link = generate_request("DeleteSecurityGroup",
146
+ 'GroupName' => name.to_s)
147
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
148
+ rescue Exception
149
+ on_exception
150
+ end
151
+
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
200
+ end
201
+
202
+ # Modify AWS security group permissions.
203
+ #
204
+ # Options:
205
+ # action - :authorize (or :grant) | :revoke (or :remove)
206
+ # group_name - security group name
207
+ # permissions - a combination of options below:
208
+ # # Ports:
209
+ # :from_port => from port
210
+ # :to_port => to port
211
+ # :port => set both :from_port and to_port with the same value
212
+ # # 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 ] ]
220
+ # # CidrIp(s)
221
+ # :cidr_ip => '0.0.0.0/0'
222
+ # :cidr_ips => ['1.1.1.1/1', '2.2.2.2/2']
223
+ #
224
+ # # CidrIP based permissions:
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
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
235
+ #
236
+ # # Group based permissions:
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
249
+ #
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
255
+ #
256
+ # # +Permissions+ can be an array of permission hashes:
257
+ #
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
266
+ #
267
+ def modify_security_group_ingress(action, group_name, permissions)
268
+ 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
274
+ # Group Name
275
+ hash["GroupName"] = group_name
276
+ #
277
+ permissions = [permissions] unless permissions.is_a?(Array)
278
+ permissions.each_with_index do |permission, idx|
279
+ pid = idx+1
280
+ # Protocol
281
+ hash["IpPermissions.#{pid}.IpProtocol"] = permission[:protocol]
282
+ # Port
283
+ unless permission[:port].right_blank?
284
+ hash["IpPermissions.#{pid}.FromPort"] = permission[:port]
285
+ hash["IpPermissions.#{pid}.ToPort"] = permission[:port]
286
+ else
287
+ hash["IpPermissions.#{pid}.FromPort"] = permission[:from_port]
288
+ hash["IpPermissions.#{pid}.ToPort"] = permission[:to_port]
289
+ 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]}
295
+ 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
+ # CidrIp(s)
309
+ cidr_ips = permission[:cidr_ips] unless permission[:cidr_ips].right_blank?
310
+ cidr_ips ||= permission[:cidr_ip] unless permission[:cidr_ip].right_blank?
311
+ hash.merge!(amazonize_list("IpPermissions.1.IpRanges.?.CidrIp", cidr_ips))
312
+ end
313
+ #
314
+ link = generate_request(action, hash)
315
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
316
+ rescue Exception
317
+ on_exception
318
+ end
319
+
320
+ # Authorize named ingress for security group. Allows instances that are member of someone
321
+ # else's security group to open connections to instances in my group.
322
+ #
323
+ # ec2.authorize_security_group_named_ingress('my_awesome_group', '7011-0219-8268', 'their_group_name') #=> true
324
+ #
325
+ def authorize_security_group_named_ingress(name, owner, group)
326
+ edit_security_group( :authorize, name, :source_group_owner => owner, :source_group => group)
327
+ end
328
+
329
+ # Revoke named ingress for security group.
330
+ #
331
+ # ec2.revoke_security_group_named_ingress('my_awesome_group', aws_user_id, 'another_group_name') #=> true
332
+ #
333
+ def revoke_security_group_named_ingress(name, owner, group)
334
+ edit_security_group( :revoke, name, :source_group_owner => owner, :source_group => group)
335
+ end
336
+
337
+ # Add permission to a security group. Returns +true+ or an exception. +protocol+ is one of :'tcp'|'udp'|'icmp'.
338
+ #
339
+ # ec2.authorize_security_group_IP_ingress('my_awesome_group', 80, 82, 'udp', '192.168.1.0/8') #=> true
340
+ # ec2.authorize_security_group_IP_ingress('my_awesome_group', -1, -1, 'icmp') #=> true
341
+ #
342
+ def authorize_security_group_IP_ingress(name, from_port, to_port, protocol='tcp', cidr_ip='0.0.0.0/0')
343
+ edit_security_group( :authorize, name, :from_port => from_port, :to_port => to_port, :protocol => protocol, :cidr_ip => cidr_ip )
344
+ end
345
+
346
+ # Remove permission from a security group. Returns +true+ or an exception. +protocol+ is one of :'tcp'|'udp'|'icmp' ('tcp' is default).
347
+ #
348
+ # ec2.revoke_security_group_IP_ingress('my_awesome_group', 80, 82, 'udp', '192.168.1.0/8') #=> true
349
+ #
350
+ def revoke_security_group_IP_ingress(name, from_port, to_port, protocol='tcp', cidr_ip='0.0.0.0/0')
351
+ edit_security_group( :revoke, name, :from_port => from_port, :to_port => to_port, :protocol => protocol, :cidr_ip => cidr_ip )
352
+ end
353
+
354
+ #-----------------------------------------------------------------
355
+ # PARSERS: Security Groups
356
+ #-----------------------------------------------------------------
357
+
358
+ class QEc2DescribeSecurityGroupsParser < RightAWSParser #:nodoc:
359
+ def tagstart(name, attributes)
360
+ 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 = {}
365
+ end
366
+ end
367
+ end
368
+ def tagend(name)
369
+ 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
387
+ end
388
+ end
389
+ end
390
+ def reset
391
+ @result = []
392
+ end
393
+ end
394
+
395
+ end
396
+ end