tengine_resource_ec2 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MGQ1NWRmMzBkYjljMTRlZTkyZjdiM2FmMmJhNjc2ZjBmOTFkZDkzZQ==
5
+ data.tar.gz: !binary |-
6
+ NjMzNjhlMmFlNjhhMzgwODdkMzBjZjFjN2YxY2QyYmJlYjM0ZDI4MQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MjE0N2U4YTI3YzMwMzJjZjgzN2VlYzY1MDA1YzQ2NjYyODI1ZDJlZDQ2M2E4
10
+ NzA4YjgzYmI5MWJhODE0Nzk5MDY0NjVjMzExYzI5NzM3NTAwNjlmZDQ4Y2Zi
11
+ ZTIzYmFlZDhiN2EzNWE0N2M1ZTdkMzEyNjFiZGRhNGQ3OTdiMWY=
12
+ data.tar.gz: !binary |-
13
+ NGU1NTNmN2ZmYjk2OTdjYzNiNTA5ZTA1YzY1OGU3NWFhNWJiM2ZiYmFhNGNm
14
+ ZTE4YzY1YjhmMTFlYmQyOWJhMmZlNTZkNDcxYWEwMTdmMDM5YjUwYzI2OGIx
15
+ ZjQ3NTg2NjQ3NDNmN2NhNmNkMGNmZWMzMTU4NjI3Y2I1M2NjNGQ=
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+ source "http://rubygems.org"
3
+
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,125 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tengine_resource_ec2 (1.2.0)
5
+ right_aws (~> 2.1.0)
6
+ tengine_resource (~> 1.2.0)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ ZenTest (4.9.1)
12
+ activemodel (3.2.12)
13
+ activesupport (= 3.2.12)
14
+ builder (~> 3.0.0)
15
+ activesupport (3.2.12)
16
+ i18n (~> 0.6)
17
+ multi_json (~> 1.0)
18
+ amq-client (0.9.12)
19
+ amq-protocol (>= 1.2.0)
20
+ eventmachine
21
+ amq-protocol (1.2.0)
22
+ amqp (0.9.10)
23
+ amq-client (~> 0.9.12)
24
+ amq-protocol (~> 1.2.0)
25
+ eventmachine
26
+ autotest (4.4.6)
27
+ ZenTest (>= 4.4.1)
28
+ builder (3.0.4)
29
+ coderay (1.0.9)
30
+ columnize (0.3.6)
31
+ daemons (1.1.9)
32
+ debugger (1.5.0)
33
+ columnize (>= 0.3.1)
34
+ debugger-linecache (~> 1.2.0)
35
+ debugger-ruby_core_source (~> 1.2.0)
36
+ debugger-linecache (1.2.0)
37
+ debugger-ruby_core_source (1.2.0)
38
+ diff-lcs (1.1.3)
39
+ eventmachine (1.0.3)
40
+ i18n (0.6.4)
41
+ macaddr (1.6.1)
42
+ systemu (~> 2.5.0)
43
+ method_source (0.8.1)
44
+ mongoid (3.1.3)
45
+ activemodel (~> 3.2)
46
+ moped (~> 1.4.2)
47
+ origin (~> 1.0)
48
+ tzinfo (~> 0.3.22)
49
+ moped (1.4.5)
50
+ multi_json (1.7.2)
51
+ net-ssh (2.5.2)
52
+ origin (1.1.0)
53
+ pry (0.9.12.1)
54
+ coderay (~> 1.0.5)
55
+ method_source (~> 0.8)
56
+ slop (~> 3.4)
57
+ pry-debugger (0.2.2)
58
+ debugger (~> 1.3)
59
+ pry (~> 0.9.10)
60
+ pry-doc (0.4.5)
61
+ pry (>= 0.9)
62
+ yard (>= 0.8)
63
+ rake (10.0.4)
64
+ right_aws (2.1.0)
65
+ right_http_connection (>= 1.2.5)
66
+ right_http_connection (1.3.0)
67
+ rspec (2.10.0)
68
+ rspec-core (~> 2.10.0)
69
+ rspec-expectations (~> 2.10.0)
70
+ rspec-mocks (~> 2.10.0)
71
+ rspec-core (2.10.1)
72
+ rspec-expectations (2.10.0)
73
+ diff-lcs (~> 1.1.3)
74
+ rspec-mocks (2.10.1)
75
+ selectable_attr (0.3.17)
76
+ i18n
77
+ simplecov (0.7.1)
78
+ multi_json (~> 1.0)
79
+ simplecov-html (~> 0.7.1)
80
+ simplecov-html (0.7.1)
81
+ slop (3.4.4)
82
+ systemu (2.5.2)
83
+ tengine_core (1.2.0)
84
+ activemodel (>= 3.1.0)
85
+ activesupport (>= 3.1.0)
86
+ daemons (~> 1.1.4)
87
+ mongoid (>= 3.0.22)
88
+ selectable_attr (~> 0.3.15)
89
+ tengine_event (~> 1.2.0)
90
+ tengine_support (~> 1.2.0)
91
+ tengine_event (1.2.0)
92
+ activesupport (>= 3.0.0)
93
+ amqp (~> 0.9.10)
94
+ tengine_support (~> 1.2.0)
95
+ uuid (~> 2.3.4)
96
+ tengine_resource (1.2.0)
97
+ net-ssh (~> 2.5.2)
98
+ tengine_core (~> 1.2.0)
99
+ tengine_support (~> 1.2.0)
100
+ text-table (~> 1.2.2)
101
+ thor (>= 0.14.6)
102
+ tengine_support (1.2.0)
103
+ activesupport (>= 3.0.0)
104
+ text-table (1.2.3)
105
+ thor (0.18.1)
106
+ tzinfo (0.3.37)
107
+ uuid (2.3.7)
108
+ macaddr (~> 1.0)
109
+ yard (0.8.6.1)
110
+
111
+ PLATFORMS
112
+ ruby
113
+
114
+ DEPENDENCIES
115
+ ZenTest (~> 4.9.0)
116
+ autotest
117
+ bundler
118
+ pry
119
+ pry-debugger
120
+ pry-doc
121
+ rake
122
+ rspec (~> 2.10.0)
123
+ simplecov
124
+ tengine_resource_ec2!
125
+ yard
data/README.rdoc ADDED
@@ -0,0 +1,20 @@
1
+ = tengine_resource
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to tengine_resource
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == License
16
+ tengine_resource is distributed under the MPL2.0 or LGPLv3 or the dual license of MPL2.0/LGPLv3
17
+
18
+ == Copyright
19
+
20
+ Copyright (c) 2012 Groovenauts, Inc.
@@ -0,0 +1,167 @@
1
+ # -*- coding: utf-8 -*-
2
+ # EC2に実際には接続しないであたかも接続しているかのように見せるためのダミーです。
3
+ #
4
+ # 環境変数EC2_DUMMYがtrueの場合に、RightAws::Ec2の代わりにこのクラスからインスタンスが生成されます。
5
+ # 起動してから環境変数EC2_DUMMY_INTERVALで指定された秒数が経過したインスタンス(のダミー)はちゃんとrunningになるようになっています。
6
+ #
7
+ # [10/08/19 13:06:41] akimatter: モックはtestでしか使えません。
8
+ # [10/08/19 13:08:47] akimatter: developmentでは、RightAws::Ec2のインスタンスの代わりのダミー(一般的にはモックって言うけど、specのモックと区別して敢えてダミーします)を使うようにするべきかも。
9
+ # [10/08/19 13:09:19] akimatter: ただし、developmentでもダミーではなくEC2にちゃんと繋ぎたい場合もあるので、
10
+ # [10/08/19 13:09:41] akimatter: 環境変数か何かの設定でこれらの動作が変わる方が良いかと思います。
11
+ class Tengine::ResourceEc2::DummyConnection
12
+ cattr_accessor :last_instance_index
13
+ @@last_instance_index = 0
14
+
15
+ # クラス変数で生成しているインスタンスを保持したいところですが、
16
+ # それだとdevelopmentモードでクラスがロードされる度に保持している内容がクリア
17
+ # されてしまうのでNGでした。
18
+ # 他に影響を与えないように実装する手段が他に思いつかなかったので、グローバル変数を使います。
19
+ # cattr_accessor :instances
20
+ # @@instances = {}
21
+ def self.instances
22
+ $ec2_dummy_instances ||= {}
23
+ end
24
+ def self.instances=(value)
25
+ $ec2_dummy_instances = value
26
+ end
27
+
28
+ def instances
29
+ self.class.instances
30
+ end
31
+
32
+ def initialize(access_key, secret_access_key, options = {})
33
+ @access_key, @secret_access_key = access_key, secret_access_key
34
+ @options = options || {}
35
+ end
36
+
37
+ STATIC_ATTRS = {
38
+ :aws_reservation_id=>"r-71a46435",
39
+ :aws_owner=>"000000000888",
40
+ :aws_ramdisk_id=>"ari-c12e7f84",
41
+ :aws_product_codes=>[],
42
+ :monitoring_state=>"disabled",
43
+ :aws_instance_type=>"m1.small",
44
+ :root_device_type=>"instance-store",
45
+ :aws_reason=>"",
46
+ :aws_kernel_id=>"aki-773c6d32",
47
+ :aws_availability_zone=>"us-west-1a"
48
+ }
49
+
50
+ def launch_instances(image_id, options)
51
+ launch_time = Time.zone.now
52
+ count = options.delete(:min_count) || 1
53
+ options.delete(:max_count) # :max_countは無視
54
+ idx = 0
55
+ result = []
56
+ count.times do
57
+ instance_index = (self.class.last_instance_index += 1)
58
+ instanceid = "i-DMY%05d" % instance_index
59
+ instance_hash = {
60
+ :aws_instance_id => instanceid,
61
+ :aws_image_id => image_id,
62
+ :state_reason_code=>"pending",
63
+ :ssh_key_name => options[:key_name],
64
+ :aws_groups => options[:group_ids],
65
+ :state_reason_message=>"pending",
66
+ :aws_state_code=>0,
67
+ :dns_name=>"",
68
+ :private_dns_name => "",
69
+ :aws_launch_time => launch_time.iso8601,
70
+ :aws_state => "pending",
71
+ :ami_launch_index => idx.to_s,
72
+ }.update(STATIC_ATTRS.dup)
73
+ idx += 1
74
+ result << instance_hash
75
+ instances[instanceid] = instance_hash
76
+ end
77
+ result
78
+ end
79
+
80
+ def describe_instances(instance_ids = [])
81
+ update_instances
82
+ if instance_ids.empty?
83
+ instances.values.sort_by{|hash| hash[:aws_instance_id]}
84
+ else
85
+ instance_ids.map{|id| instances[id]}
86
+ end
87
+ end
88
+
89
+ def terminate_instances(instance_ids)
90
+ update_instances
91
+ instance_ids.each do |instance_id|
92
+ update_status_running(instance_id) # 停止する前に一度はrunningにしておく
93
+ hash = instances[instance_id]
94
+ hash.update(
95
+ :state_reason_code=>"Client.UserInitiatedShutdown",
96
+ :state_reason_message=>"Client.UserInitiatedShutdown: User initiated shutdown",
97
+ :aws_state_code=>48,
98
+ :dns_name=>"",
99
+ :private_dns_name=>"",
100
+ :aws_state=>"terminated"
101
+ )
102
+ hash.delete(:ip_address)
103
+ hash.delete(:private_ip_address)
104
+ end
105
+ instance_ids.map do |instance_id|
106
+ {
107
+ :aws_prev_state_name => "running",
108
+ :aws_instance_id => instance_id,
109
+ :aws_current_state_code => 32,
110
+ :aws_current_state_name => "shutting-down",
111
+ :aws_prev_state_code => 16
112
+ }
113
+ end
114
+ end
115
+
116
+
117
+ def describe_availability_zones(*args)
118
+ [
119
+ {:region_name=>"us-east-1", :zone_name=>"us-east-1a", :zone_state=>"available"},
120
+ {:region_name=>"us-east-1", :zone_name=>"us-east-1b", :zone_state=>"available"},
121
+ {:region_name=>"us-east-1", :zone_name=>"us-east-1c", :zone_state=>"available"},
122
+ {:region_name=>"us-east-1", :zone_name=>"us-east-1d", :zone_state=>"available"}
123
+ ]
124
+ end
125
+
126
+ def describe_images_by_owner(*args)
127
+ []
128
+ end
129
+
130
+ def describe_images(*args)
131
+ []
132
+ end
133
+
134
+
135
+ private
136
+ UPDATE_INTERVAL = (ENV['EC2_DUMMY_INTERVAL'] || 30).to_i.seconds
137
+
138
+ def update_instances
139
+ t = (Time.zone || Time).now
140
+ instances.each do |instanceid, hash|
141
+ next unless hash[:aws_state] == "pending"
142
+ launch_time = Time.zone.parse(hash[:aws_launch_time])
143
+ next if (t - launch_time) < UPDATE_INTERVAL
144
+ update_status_running(instanceid)
145
+ end
146
+ end
147
+
148
+ def update_status_running(instance_id)
149
+ hash = instances[instance_id]
150
+ unless hash
151
+ raise ArgumentError, "No instance found for #{instance_id.inspect}. " << instances.keys.map(&:to_s).join("\n") << " exist."
152
+ end
153
+ instance_index = hash[:aws_instance_id].sub(/^i\-DMY/, '').to_i
154
+ hash.update(
155
+ :aws_state_code=>16,
156
+ :dns_name=>"ec2-184-72-20-#{instance_index}.us-west-1.compute.amazonaws.com",
157
+ :ip_address=>"184.72.20.#{instance_index}",
158
+ :private_dns_name=>"ip-10-162-153-#{instance_index}.us-west-1.compute.internal",
159
+ :private_ip_address=>"10.162.153.#{instance_index}",
160
+ :aws_state=>"running",
161
+ :architecture=>"i386"
162
+ )
163
+ hash.delete(:state_reason_message)
164
+ hash.delete(:state_reason_code)
165
+ end
166
+
167
+ end
@@ -0,0 +1,148 @@
1
+ # -*- coding: utf-8 -*-
2
+ # EC2に実際には接続しないであたかも接続しているかのように見せるためのダミーです。
3
+ #
4
+ # 環境変数EC2_DUMMYがtrueの場合に、RightAws::Ec2の代わりにこのクラスからインスタンスが生成されます。
5
+ # 起動してから環境変数EC2_DUMMY_INTERVALで指定された秒数が経過したインスタンス(のダミー)はちゃんとrunningになるようになっています。
6
+ #
7
+ # [10/08/19 13:06:41] akimatter: モックはtestでしか使えません。
8
+ # [10/08/19 13:08:47] akimatter: developmentでは、RightAws::Ec2のインスタンスの代わりのダミー(一般的にはモックって言うけど、specのモックと区別して敢えてダミーします)を使うようにするべきかも。
9
+ # [10/08/19 13:09:19] akimatter: ただし、developmentでもダミーではなくEC2にちゃんと繋ぎたい場合もあるので、
10
+ # [10/08/19 13:09:41] akimatter: 環境変数か何かの設定でこれらの動作が変わる方が良いかと思います。
11
+ class Tengine::Resource::Credential::Ec2::Dummy
12
+ cattr_accessor :last_instance_index
13
+ @@last_instance_index = 0
14
+
15
+ # クラス変数で生成しているインスタンスを保持したいところですが、
16
+ # それだとdevelopmentモードでクラスがロードされる度に保持している内容がクリア
17
+ # されてしまうのでNGでした。
18
+ # 他に影響を与えないように実装する手段が他に思いつかなかったので、グローバル変数を使います。
19
+ # cattr_accessor :instances
20
+ # @@instances = {}
21
+ def self.instances
22
+ $ec2_dummy_instances ||= {}
23
+ end
24
+ def self.instances=(value)
25
+ $ec2_dummy_instances = value
26
+ end
27
+
28
+ def instances
29
+ self.class.instances
30
+ end
31
+
32
+ def initialize(access_key, secret_access_key, options = {})
33
+ @access_key, @secret_access_key = access_key, secret_access_key
34
+ @options = options || {}
35
+ end
36
+
37
+ STATIC_ATTRS = {
38
+ :aws_reservation_id=>"r-71a46435",
39
+ :aws_owner=>"000000000888",
40
+ :aws_ramdisk_id=>"ari-c12e7f84",
41
+ :aws_product_codes=>[],
42
+ :monitoring_state=>"disabled",
43
+ :aws_instance_type=>"m1.small",
44
+ :root_device_type=>"instance-store",
45
+ :aws_reason=>"",
46
+ :aws_kernel_id=>"aki-773c6d32",
47
+ :aws_availability_zone=>"us-west-1a"
48
+ }
49
+
50
+ def launch_instances(image_id, options)
51
+ launch_time = Time.zone.now
52
+ count = options.delete(:min_count) || 1
53
+ options.delete(:max_count) # :max_countは無視
54
+ idx = 0
55
+ result = []
56
+ count.times do
57
+ instance_index = (self.class.last_instance_index += 1)
58
+ instanceid = "i-DMY%05d" % instance_index
59
+ instance_hash = {
60
+ :aws_instance_id => instanceid,
61
+ :aws_image_id => image_id,
62
+ :state_reason_code=>"pending",
63
+ :ssh_key_name => options[:key_name],
64
+ :aws_groups => options[:group_ids],
65
+ :state_reason_message=>"pending",
66
+ :aws_state_code=>0,
67
+ :dns_name=>"",
68
+ :private_dns_name => "",
69
+ :aws_launch_time => launch_time.iso8601,
70
+ :aws_state => "pending",
71
+ :ami_launch_index => idx.to_s,
72
+ }.update(STATIC_ATTRS.dup)
73
+ idx += 1
74
+ result << instance_hash
75
+ instances[instanceid] = instance_hash
76
+ end
77
+ result
78
+ end
79
+
80
+ def describe_instances(instance_ids = [])
81
+ update_instances
82
+ if instance_ids.empty?
83
+ instances.values.sort_by{|hash| hash[:aws_instance_id]}
84
+ else
85
+ instance_ids.map{|id| instances[id]}
86
+ end
87
+ end
88
+
89
+ def terminate_instances(instance_ids)
90
+ update_instances
91
+ instance_ids.each do |instance_id|
92
+ update_status_running(instance_id) # 停止する前に一度はrunningにしておく
93
+ hash = instances[instance_id]
94
+ hash.update(
95
+ :state_reason_code=>"Client.UserInitiatedShutdown",
96
+ :state_reason_message=>"Client.UserInitiatedShutdown: User initiated shutdown",
97
+ :aws_state_code=>48,
98
+ :dns_name=>"",
99
+ :private_dns_name=>"",
100
+ :aws_state=>"terminated"
101
+ )
102
+ hash.delete(:ip_address)
103
+ hash.delete(:private_ip_address)
104
+ end
105
+ instance_ids.map do |instance_id|
106
+ {
107
+ :aws_prev_state_name => "running",
108
+ :aws_instance_id => instance_id,
109
+ :aws_current_state_code => 32,
110
+ :aws_current_state_name => "shutting-down",
111
+ :aws_prev_state_code => 16
112
+ }
113
+ end
114
+ end
115
+
116
+ private
117
+ UPDATE_INTERVAL = (ENV['EC2_DUMMY_INTERVAL'] || 30).to_i.seconds
118
+
119
+ def update_instances
120
+ t = Time.zone.now
121
+ instances.each do |instanceid, hash|
122
+ next unless hash[:aws_state] == "pending"
123
+ launch_time = Time.zone.parse(hash[:aws_launch_time])
124
+ next if (t - launch_time) < UPDATE_INTERVAL
125
+ update_status_running(instanceid)
126
+ end
127
+ end
128
+
129
+ def update_status_running(instance_id)
130
+ hash = instances[instance_id]
131
+ unless hash
132
+ raise ArgumentError, "No instance found for #{instance_id.inspect}. " << instances.keys.map(&:to_s).join("\n") << " exist."
133
+ end
134
+ instance_index = hash[:aws_instance_id].sub(/^i\-DMY/, '').to_i
135
+ hash.update(
136
+ :aws_state_code=>16,
137
+ :dns_name=>"ec2-184-72-20-#{instance_index}.us-west-1.compute.amazonaws.com",
138
+ :ip_address=>"184.72.20.#{instance_index}",
139
+ :private_dns_name=>"ip-10-162-153-#{instance_index}.us-west-1.compute.internal",
140
+ :private_ip_address=>"10.162.153.#{instance_index}",
141
+ :aws_state=>"running",
142
+ :architecture=>"i386"
143
+ )
144
+ hash.delete(:state_reason_message)
145
+ hash.delete(:state_reason_code)
146
+ end
147
+
148
+ end
@@ -0,0 +1,182 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'tengine/support/core_ext/enumerable/map_to_hash'
3
+
4
+ class Tengine::ResourceEc2::LaunchOptions
5
+
6
+ def initialize(credential)
7
+ @credential = credential
8
+ end
9
+
10
+ LAUNCH_OPTIONS_KEYS = %w(current_region regions availability_zones key_pairs
11
+ security_groups images instance_types kernel_ids ramdisk_ids)
12
+
13
+ def launch_options(connection, current_region)
14
+ @connection, @current_region = connection, current_region
15
+ LAUNCH_OPTIONS_KEYS.map_to_hash{|m| send(m)}
16
+ ensure
17
+ @connection, @current_region = nil, nil
18
+ end
19
+
20
+ attr_reader :current_region
21
+
22
+ DEFAULT_REGION_CAPTIONS = {
23
+ "us-east-1" => "US East(Northern Virginia)" ,
24
+ "us-west-1" => "US West(Northern California)" ,
25
+ "eu-west-1" => "EU West(Ireland)" ,
26
+ "ap-southeast-1" => "Asia Pacific(Singapore)",
27
+ "ap-northeast-1" => "Asia Pacific(Tokyo)",
28
+ }.freeze
29
+
30
+ def regions
31
+ # ["eu-west-1", "us-east-1", "us-west-1", "ap-southeast-1"]
32
+ raw = @connection.describe_regions
33
+ raw.inject([]) do |dest, region|
34
+ dest << {"name" => region, "caption" => DEFAULT_REGION_CAPTIONS[region]}
35
+ end
36
+ end
37
+
38
+ def availability_zones
39
+ # [
40
+ # {:region_name=>"us-east-1", :zone_name=>"us-east-1a", :zone_state=>"available"},
41
+ # {:region_name=>"us-east-1", :zone_name=>"us-east-1b", :zone_state=>"available"},
42
+ # {:region_name=>"us-east-1", :zone_name=>"us-east-1c", :zone_state=>"available"},
43
+ # {:region_name=>"us-east-1", :zone_name=>"us-east-1d", :zone_state=>"available"}
44
+ # ]
45
+ raw = @connection.describe_availability_zones
46
+ raw.map{|h| h[:zone_name]}.sort
47
+ end
48
+
49
+ def key_pairs
50
+ # [{:aws_key_name=>"west-dev01", :aws_fingerprint=>"7c:89:2f:c9:4a:1c:02:65:1b:14:dc:a5:c9:a0:da:fb:46:08:4a:99"}]
51
+ raw = @connection.describe_key_pairs
52
+ raw.map{|h| h[:aws_key_name]}
53
+ end
54
+
55
+ def security_groups
56
+ # [
57
+ # { :aws_owner=>"892601002221", :aws_group_name=>"default", :aws_description=>"default group",
58
+ # :aws_perms=>[{:owner=>"892601002221", :group=>"default"}, {:from_port=>"22", :to_port=>"22", :cidr_ips=>"0.0.0.0/0", :protocol=>"tcp"}]},
59
+ # { :aws_owner=>"892601002221", :aws_group_name=>"ruby-dev", :aws_description=>"for developmewnt with ruby",
60
+ # :aws_perms=>[{:from_port=>"80", :to_port=>"80", :cidr_ips=>"0.0.0.0/0", :protocol=>"tcp"}]}
61
+ # ]
62
+ raw = @connection.describe_security_groups
63
+ raw.map{|h| h[:aws_group_name]}
64
+ end
65
+
66
+ def images
67
+ # [
68
+ # {
69
+ # :aws_id=>"ami-5189d814",
70
+ # :aws_architecture=>"i386", :root_device_type=>"instance-store",
71
+ # :root_device_name=>"/dev/sda1",
72
+ # :aws_location=>"akm2000-us-west-2/dev-20100521-01.manifest.xml",
73
+ # :aws_image_type=>"machine", :aws_state=>"available",
74
+ # :aws_owner=>"892601002221", :aws_is_public=>false,
75
+ # :aws_kernel_id=>"aki-773c6d32", :aws_ramdisk_id=>"ari-c12e7f84",
76
+ # },
77
+ # ]
78
+ saved_images = Tengine::Resource::VirtualServerImage.all
79
+ # raw_images = @connection.describe_images_by_owner('self')
80
+ raw_images = @connection.describe_images(saved_images.map(&:provided_id).uniq.compact) #クラスタに登録されているAMI
81
+ # raw_images += @connection.describe_images_by_executable_by("self") # 実行可能なAMI
82
+ amiid_to_hash = raw_images.inject({}){|d, hash| d[hash[:aws_id]] = hash; d}
83
+ result = saved_images.map do |saved_image|
84
+ if ami = amiid_to_hash[saved_image.provided_id]
85
+ {
86
+ 'id' => saved_image.id,
87
+ 'name' => ami[:aws_id],
88
+ 'caption' => saved_image.description,
89
+ 'aws_architecture' => ami[:aws_architecture],
90
+ 'aws_arch_root_dev' => to_aws_arch_root_dev(ami),
91
+ }
92
+ else
93
+ nil
94
+ end
95
+ end
96
+ result.compact.uniq
97
+ end
98
+
99
+ def instance_types
100
+ # rawなし
101
+ INSTANCE_TYPES
102
+ end
103
+
104
+ def kernel_ids
105
+ # [
106
+ # {
107
+ # :aws_id=>"aki-233c6d66",
108
+ # :aws_architecture=>"i386", :root_device_type=>"instance-store",
109
+ # :aws_location=>"ec2-paid-ibm-images-us-west-1/vmlinuz-2.6.16.60-0.29-xenpae.i386.manifest.xml",
110
+ # :aws_image_type=>"kernel", :aws_state=>"available", :aws_owner=>"470254534024",
111
+ # :aws_is_public=>true, :image_owner_alias=>"amazon",
112
+ # },
113
+ # ]
114
+ raw = amazon_images.select{|img| img[:aws_image_type] == 'kernel'}
115
+ raw.inject({}) do |dest, hash|
116
+ key = hash[:aws_architecture]
117
+ dest[key] ||= []
118
+ dest[key] << hash[:aws_id]
119
+ dest
120
+ end
121
+ end
122
+
123
+ def ramdisk_ids
124
+ # [
125
+ # {
126
+ # :aws_id=>"ari-2d3c6d68",
127
+ # :aws_architecture=>"i386", :root_device_type=>"instance-store",
128
+ # :aws_location=>"ec2-paid-ibm-images-us-west-1/initrd-2.6.16.60-0.29-xenpae.i386.manifest.xml",
129
+ # :aws_image_type=>"ramdisk", :aws_state=>"available", :aws_owner=>"470254534024",
130
+ # :aws_is_public=>true, :image_owner_alias=>"amazon"
131
+ # },
132
+ # ]
133
+ raw = amazon_images.select{|img| img[:aws_image_type] == 'ramdisk'}
134
+ raw.inject({}) do |dest, hash|
135
+ key = hash[:aws_architecture]
136
+ dest[key] ||= []
137
+ dest[key] << hash[:aws_id]
138
+ dest
139
+ end
140
+ end
141
+
142
+ private
143
+
144
+ def amazon_images
145
+ @amazon_images ||= @connection.describe_images_by_owner('amazon')
146
+ end
147
+
148
+
149
+ def to_aws_arch_root_dev(hash)
150
+ "#{hash[:aws_architecture]}_#{hash[:root_device_type]}"
151
+ end
152
+
153
+ INSTANCE_TYPES = {
154
+ 'i386_instance-store' => [
155
+ { "value" => "m1.small" , "caption" => "Small" },
156
+ { "value" => "c1.medium" , "caption" => "High-CPU Medium" },
157
+ ].freeze,
158
+ 'i386_ebs' => [
159
+ { "value" => "t1.micro" , "caption" => "Micro" },
160
+ { "value" => "m1.small" , "caption" => "Small" },
161
+ { "value" => "c1.medium" , "caption" => "High-CPU Medium" },
162
+ ].freeze,
163
+ 'x86_64_instance-store' => [
164
+ { "value" => "m1.large" , "caption" => "Large" },
165
+ { "value" => "m1.xlarge" , "caption" => "Extra Large" },
166
+ { "value" => "m2.xlarge" , "caption" => "High-Memory Extra Large" },
167
+ { "value" => "m2.2xlarge", "caption" => "High-Memory Double Extra Large" },
168
+ { "value" => "m2.4xlarge", "caption" => "High-Memory Quadruple Extra Large" },
169
+ { "value" => "c1.xlarge" , "caption" => "High-CPU Extra Large" },
170
+ ].freeze,
171
+ 'x86_64_ebs' => [
172
+ { "value" => "t1.micro" , "caption" => "Micro" },
173
+ { "value" => "m1.large" , "caption" => "Large" },
174
+ { "value" => "m1.xlarge" , "caption" => "Extra Large" },
175
+ { "value" => "m2.xlarge" , "caption" => "High-Memory Extra Large" },
176
+ { "value" => "m2.2xlarge", "caption" => "High-Memory Double Extra Large" },
177
+ { "value" => "m2.4xlarge", "caption" => "High-Memory Quadruple Extra Large" },
178
+ { "value" => "c1.xlarge" , "caption" => "High-CPU Extra Large" },
179
+ ].freeze,
180
+ }.freeze
181
+
182
+ end