jzimmek-ec2-control 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jan Zimmek
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,30 @@
1
+ = ec2-control
2
+
3
+ EC2-Control is a ruby based toolkit to ease management and configuration of an Amazon EC2 cloud.
4
+
5
+ == Quickstart
6
+
7
+ cloud "my_network" do
8
+ keypair "jzimmek"
9
+ availability_zone "eu-west-1a"
10
+
11
+ group "webserver" do
12
+ ami "ami-48cfe73c"
13
+ instance "web01" do
14
+ elastic_ip "76.63.XX.YY"
15
+ end
16
+ instance "web01" do
17
+ availability_zone "eu-west-1b"
18
+ mount "vol-4ef91c27", "/dev/sdh"
19
+ end
20
+ end
21
+ end
22
+
23
+ == Usage
24
+
25
+ ... coming soon ...
26
+
27
+
28
+ == Copyright
29
+
30
+ Copyright (c) 2009 Jan Zimmek. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "ec2-control"
8
+ gem.summary = "A EC2 management and configuration toolkit"
9
+ gem.description = "EC2-Control is a ruby based toolkit to ease management and configuration of an Amazon EC2 cloud"
10
+ gem.email = "jan.zimmek@web.de"
11
+ gem.homepage = "http://github.com/jzimmek/ec2-control"
12
+ gem.authors = ["Jan Zimmek"]
13
+ gem.add_dependency "jzimmek-ec2-dsl"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/*_test.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/*_test.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ if File.exist?('VERSION.yml')
47
+ config = YAML.load(File.read('VERSION.yml'))
48
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
49
+ else
50
+ version = ""
51
+ end
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "ec2-control #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
58
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.4
@@ -0,0 +1,52 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{ec2-control}
5
+ s.version = "0.0.4"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Jan Zimmek"]
9
+ s.date = %q{2009-06-14}
10
+ s.description = %q{EC2-Control is a ruby based toolkit to ease management and configuration of an Amazon EC2 cloud}
11
+ s.email = %q{jan.zimmek@web.de}
12
+ s.extra_rdoc_files = [
13
+ "LICENSE",
14
+ "README.rdoc"
15
+ ]
16
+ s.files = [
17
+ ".document",
18
+ ".gitignore",
19
+ "LICENSE",
20
+ "README.rdoc",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "ec2-control.gemspec",
24
+ "lib/ec2-control.rb",
25
+ "lib/ec2/control/controller.rb",
26
+ "lib/ec2/control/query.rb",
27
+ "test/ec2-control_test.rb",
28
+ "test/test_helper.rb"
29
+ ]
30
+ s.homepage = %q{http://github.com/jzimmek/ec2-control}
31
+ s.rdoc_options = ["--charset=UTF-8"]
32
+ s.require_paths = ["lib"]
33
+ s.rubygems_version = %q{1.3.4}
34
+ s.summary = %q{A EC2 management and configuration toolkit}
35
+ s.test_files = [
36
+ "test/ec2-control_test.rb",
37
+ "test/test_helper.rb"
38
+ ]
39
+
40
+ if s.respond_to? :specification_version then
41
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
45
+ s.add_runtime_dependency(%q<jzimmek-ec2-dsl>, [">= 0"])
46
+ else
47
+ s.add_dependency(%q<jzimmek-ec2-dsl>, [">= 0"])
48
+ end
49
+ else
50
+ s.add_dependency(%q<jzimmek-ec2-dsl>, [">= 0"])
51
+ end
52
+ end
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'ec2-dsl'
3
+ require 'EC2'
4
+ require 'ec2/control/controller'
5
+
6
+ @orig_cloud = method(:cloud)
7
+
8
+ def cloud(name, validate=true, &block)
9
+ @orig_cloud.call(name, validate, &block)
10
+
11
+ cloud_ref = instance_variable_get("@#{name}")
12
+
13
+ control = Ec2::Control::Controller.new(cloud_ref, "AKIAJQ24F3G2GJ7RO3RA", "detTWpfPfengwji/qshm88FP6F7x4YuM4fBAIKch", "#{cloud_ref.region_value}.ec2.amazonaws.com")
14
+
15
+ running = control.query.instance_running_names
16
+ pending = control.query.instance_pending_names
17
+ end
18
+
19
+ # cloud "my_network" do
20
+ # keypair "jzimmek"
21
+ # availability_zone "eu-west-1a"
22
+ #
23
+ # group "webserver" do
24
+ # ami "ami-48cfe73c"
25
+ # instance "web01" do
26
+ # availability_zone "eu-west-1b"
27
+ # end
28
+ # # instance "web01" do
29
+ # # availability_zone "eu-west-1b"
30
+ # # mount "vol-4ef91c27", "/dev/sdh"
31
+ # # end
32
+ # end
33
+ # end
34
+ #
@@ -0,0 +1,211 @@
1
+ require 'ec2/control/query'
2
+
3
+ module Ec2
4
+ module Control
5
+ class Controller
6
+
7
+ attr_reader :query
8
+
9
+ def initialize(cloud, access_key, secret_key, server)
10
+
11
+ @ec2 = EC2::Base.new( :access_key_id => access_key,
12
+ :secret_access_key => secret_key,
13
+ :server => server)
14
+
15
+ @query = Ec2::Control::Query.new(@ec2)
16
+ @cloud = cloud
17
+
18
+ ensure_assigned_elastic_ip_exist
19
+ ensure_assigned_mount_volume_exist
20
+ ensure_assigned_availability_zone_exist
21
+ ensure_security_groups
22
+
23
+ ensure_stopping
24
+ @query.init
25
+
26
+ ensure_starting
27
+ @query.init
28
+
29
+ ensure_mounts
30
+ ensure_assigned_elastic_ip_attached
31
+
32
+ end
33
+
34
+ def ensure_assigned_availability_zone_exist
35
+ @cloud.instances.each do |instance|
36
+ if availability_zone = instance.availability_zone_value
37
+ raise "availability zone '#{availability_zone}' of instance '#{instance.name}' is not available or does not exist" unless @query.availability_zone_available?(availability_zone)
38
+ end
39
+ end
40
+ end
41
+
42
+ def ensure_assigned_elastic_ip_attached
43
+
44
+ @cloud.instances.each do |instance|
45
+ if ip = instance.elastic_ip_value
46
+
47
+ puts "elastic ip '#{ip}' should be assigned to instance '#{instance.name}'"
48
+
49
+ unless @query.instance_running_by_name?(instance.name)
50
+ puts "elastic ip '#{ip}' could not be assigned because instance '#{instance.name}' is not running"
51
+ next
52
+ end
53
+
54
+ unless @query.elastic_ip_associated?(ip)
55
+
56
+ puts "elastic ip '#{ip}' is not assigned to any instance"
57
+
58
+ update_ec2(:associate_address,{
59
+ :instance_id => @query.instance_id_by_instance_name(instance.name),
60
+ :public_ip => ip
61
+ })
62
+
63
+ puts "associate elastic ip '#{ip}' with instance '#{instance.name}'"
64
+
65
+ else
66
+ associated_instance_id = @query.elastic_ip_associated_instance_id(ip)
67
+ associated_instance_name = @query.instance_name_by_instance_id(associated_instance_id)
68
+
69
+ if instance.name == associated_instance_name
70
+ puts "elastic ip '#{ip}' is already assigned to instance '#{instance.name}'"
71
+ else
72
+ update_ec2(:associate_address, {
73
+ :instance_id => @query.instance_running_by_name?(instance.name)[:id],
74
+ :public_ip => ip
75
+ })
76
+
77
+ puts "reassign elastic ip '#{ip} from instance '#{associated_instance_name ? associated_instance_name : associated_instance_id}' to instance '#{instance.name}'"
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+ end
84
+ end
85
+
86
+ def ensure_assigned_mount_volume_exist
87
+ @cloud.instances.each do |instance|
88
+ instance.mounts.each do |mount|
89
+ volume_id = mount[:volume_id]
90
+ available = @query.volume_available?(volume_id)
91
+ in_use = @query.volume_mounted?(volume_id)
92
+ if !available && !in_use
93
+ raise "instance '#{instance.name}' mounts volume_id '#{volume_id}' which does not exist or is in invalid state"
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ def ensure_mounts
100
+ @cloud.instances.each do |instance|
101
+ instance.mounts.each do |mount|
102
+
103
+ volume_id = mount[:volume_id]
104
+ device = mount[:device]
105
+
106
+ puts "instance '#{instance.name}' should mount volume_id '#{volume_id}'"
107
+
108
+ unless @query.instance_running_by_name?(instance.name)
109
+ puts "volumne_id '#{volume_id}' could not be mounted because instance '#{instance.name}' is not running"
110
+ next
111
+ end
112
+
113
+ if @query.volume_available?(volume_id)
114
+ puts "volume_id '#{volume_id}' is not mounted on any instance"
115
+ update_ec2(:attach_volume,{
116
+ :volume_id => volume_id,
117
+ :device => device,
118
+ :instance_id => @query.instance_id_by_instance_name(instance.name)
119
+ })
120
+ puts "mounted volume_id '#{volume_id}' on instance '#{instance.name}'"
121
+ end
122
+
123
+ if @query.volume_mounted?(volume_id)
124
+ mounting_instance_id = @query.volume_mounted_instance_id(volume_id)
125
+ mounting_instance_name = @query.instance_name_by_instance_id(mounting_instance_id)
126
+
127
+ if mounting_instance_name != instance.name
128
+ raise "volume_id '#{volume_id}' is already mounted on instance '#{mounting_instance_name ? mounting_instance_name : mounting_instance_id}'"
129
+ end
130
+ end
131
+
132
+ end
133
+ end
134
+ end
135
+
136
+
137
+ def ensure_assigned_elastic_ip_exist
138
+ @cloud.instances.each do |instance|
139
+ if ip = instance.elastic_ip_value
140
+ raise "elastic ip '#{ip}' should be assigned to instance '#{instance.name}' but does not exist" unless @query.elastic_ip_available?(ip)
141
+ end
142
+ end
143
+ end
144
+
145
+
146
+ def ensure_stopping
147
+ valid = @cloud.instances.collect{|instance|instance.name}
148
+ invalid = @query.instances_running_except_names(valid)
149
+
150
+ unless invalid.empty?
151
+ puts "found invalid running instances:"
152
+ invalid.each do |instance|
153
+ puts " name: #{instance[:name]}, id: #{instance[:id]}"
154
+ end
155
+
156
+ update_ec2(:terminate_instances, :instance_id => invalid.collect{|instance|instance[:id]})
157
+ end
158
+ end
159
+
160
+ def ensure_starting
161
+
162
+ @cloud.instances.each do |instance|
163
+
164
+ name = instance.name
165
+
166
+ next if @query.instance_pending_by_name?(name)
167
+ next if @query.instance_running_by_name?(name)
168
+
169
+ ami = instance.ami_value
170
+ region = instance.region_value
171
+ keypair = instance.keypair_value
172
+ security_group = instance.security_group_value
173
+
174
+ puts " instance: #{name}, ami: #{ami}, region: #{region}, keypair: #{keypair}, security_group: #{security_group}"
175
+
176
+ update_ec2(:run_instances, {
177
+ :image_id => ami,
178
+ :min_count => 1,
179
+ :max_count => 1,
180
+ :key_name => keypair,
181
+ :availability_zone => instance.availability_zone_value,
182
+ :group_id => [security_group, "ec2_control_#{name}"]
183
+ })
184
+
185
+
186
+ end
187
+
188
+ end
189
+
190
+ def ensure_security_groups
191
+ @cloud.instances.each do |instance|
192
+ name = instance.name
193
+ unless @query.security_group_exist?("ec2_control_#{name}")
194
+ update_ec2(:create_security_group, {
195
+ :group_name => "ec2_control_#{name}",
196
+ :group_description => "ec2 control identifier for instance #{name}"
197
+ })
198
+ end
199
+ end
200
+ end
201
+
202
+ def update_ec2(method, *args)
203
+ puts "// ---"
204
+ puts "ec2 command: #{method}(#{args.inspect})"
205
+ @ec2.send(method.to_sym, *args)
206
+ puts "--- //"
207
+ end
208
+
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,208 @@
1
+ module Ec2
2
+ module Control
3
+
4
+ class Query
5
+
6
+ def initialize(ec2)
7
+ @ec2 = ec2
8
+ self.init
9
+ end
10
+
11
+ def init
12
+ __init_security_groups(true)
13
+ __init_availability_zones(true)
14
+ __init_volumes(true)
15
+ __init_elastic_ips(true)
16
+ __init_running_and_pending(true)
17
+ end
18
+
19
+ def security_group_exist?(name)
20
+ @security_groups.include?(name)
21
+ end
22
+
23
+ def availability_zone_available?(name)
24
+ @available_zones.find{|zone| zone.status == "available" && zone.name == name}
25
+ end
26
+
27
+ def volume_available?(volume_id)
28
+ @volumes.find{|volume| volume[:status] == "available" && volume[:volume_id] == volume_id}
29
+ end
30
+
31
+ def volume_mounted?(volume_id)
32
+ @volumes.find{|volume| volume[:status] == "in-use" && volume[:volume_id] == volume_id}
33
+ end
34
+
35
+ def volume_mounted_instance_id(volume_id)
36
+ volume = @volumes.find{|volume| volume[:status] == "in-use" && volume[:volume_id] == volume_id}
37
+ volume ? volume[:instance_id] : nil
38
+ end
39
+
40
+ def elastic_ip_available?(ip)
41
+ @elastic_ips.find{|elastic|elastic[:ip] == ip}
42
+ end
43
+
44
+ def elastic_ip_associated?(ip)
45
+ @elastic_ips.find{|elastic|elastic[:ip] == ip && elastic[:instance_id]}
46
+ end
47
+
48
+ def elastic_ip_associated_instance_id(ip)
49
+ @elastic_ips.find{|elastic|elastic[:ip] == ip}[:instance_id]
50
+ end
51
+
52
+ def instance_name_by_instance_id(instance_id)
53
+ instance = @instances.find{|instance|instance[:id] == instance_id}
54
+ instance ? instance[:name] : nil
55
+ end
56
+
57
+ def instance_id_by_instance_name(name)
58
+ instance = @instances.find{|instance|instance[:status] == "running" && instance[:name] == name}
59
+ instance ? instance[:id] : nil
60
+ end
61
+
62
+ def instance_running_by_name?(value)
63
+ @instances.find{|instance|instance[:status] == "running" && instance[:name] == value}
64
+ end
65
+
66
+ def instance_pending_by_name?(value)
67
+ @instances.find{|instance|instance[:status] == "pending" && instance[:name] == value}
68
+ end
69
+
70
+ def instances_running_except_names(names)
71
+ @instances.find_all{|instance|instance[:status] == "running" && !names.include?(instance[:name])}
72
+ end
73
+
74
+ def instance_running_count
75
+ @instances.find_all{|instance|instance[:status] == "running"}.length
76
+ end
77
+
78
+ def instance_pending_count
79
+ @instances.find_all{|instance|instance[:status] == "pending"}.length
80
+ end
81
+
82
+ def instance_running_names
83
+ @instances.find_all{|instance|instance[:status] == "running"}.collect{|instance|instance[:name]}
84
+ end
85
+
86
+ def instance_pending_names
87
+ @instances.find_all{|instance|instance[:status] == "pending"}.collect{|instance|instance[:name]}
88
+ end
89
+
90
+ def __init_security_groups(reload=false)
91
+
92
+ if @security_groups.nil? || reload
93
+ @security_groups = @ec2.describe_security_groups.securityGroupInfo.item.collect{ |security_group| security_group.groupName }
94
+ end
95
+
96
+ @security_groups
97
+
98
+ end
99
+
100
+ def __init_availability_zones(reload=false)
101
+
102
+ if @available_zones.nil? || reload
103
+ available_zones = []
104
+ availability_zone_info = @ec2.describe_availability_zones.availabilityZoneInfo
105
+
106
+ if availability_zone_info && !(z_item = availability_zone_info.item).empty?
107
+ z_item.each do |zone|
108
+ available_zones << {:region => zone.regionName, :name => zone.zoneName, :status => zone.zoneState}
109
+ end
110
+ end
111
+
112
+ @available_zones = available_zones
113
+ end
114
+
115
+ @available_zones
116
+ end
117
+
118
+ def __init_elastic_ips(reload=false)
119
+
120
+ if @elastic_ips.nil? || reload
121
+ ips = []
122
+ addressesSet = @ec2.describe_addresses.addressesSet
123
+
124
+ if addressesSet && !(a_item = addressesSet.item).empty?
125
+ a_item.each do |adr|
126
+ ips << {:instance_id => adr.instanceId, :ip => adr.publicIp}
127
+ end
128
+ end
129
+ @elastic_ips = ips
130
+ end
131
+
132
+ @elastic_ips
133
+ end
134
+
135
+
136
+ def __init_volumes(reload=false)
137
+
138
+ if @volumes.nil? || reload
139
+ volumes = []
140
+ volumeSet = @ec2.describe_volumes.volumeSet
141
+
142
+ if volumeSet && !(v_item = volumeSet.item).empty?
143
+ v_item.each do |volume|
144
+
145
+ volume_id = volume.volumeId
146
+ availability_zone = volume.availabilityZone
147
+ status = volume.status
148
+ instance_id = nil
149
+
150
+ attachmentSet = volume.attachmentSet
151
+
152
+ if attachmentSet && !(a_item = attachmentSet.item).empty?
153
+ raise "this version of ec2-control cannot handle more than one attachement set" if a_item.length > 1
154
+ instance_id = a_item.first.instanceId
155
+ end
156
+
157
+ volumes << {:volume_id => volume_id, :availability_zone => availability_zone, :instance_id => instance_id, :status => status}
158
+ end
159
+ end
160
+
161
+ @volumes = volumes
162
+ end
163
+
164
+ @volumes
165
+
166
+ end
167
+
168
+ def __init_running_and_pending(reload=false)
169
+
170
+ if @instances.nil? || reload
171
+ @instances = []
172
+
173
+ reservationSet = @ec2.describe_instances.reservationSet
174
+
175
+ if reservationSet && !(r_item = reservationSet.item).empty?
176
+ r_item.each do |reservation|
177
+
178
+ reservation.groupSet.item.each do |grp|
179
+
180
+ if grp.groupId =~ /^ec2_control_/
181
+ grp_name = grp.groupId.gsub(/ec2_control_/, '')
182
+
183
+ instancesSet = reservation.instancesSet
184
+
185
+ if instancesSet && !(i_item = instancesSet.item).empty?
186
+
187
+ raise "this version of ec2-control cannot handle more than one instance per reservation" if i_item.length > 1
188
+
189
+ instance = i_item.first
190
+ instance_id = instance.instanceId
191
+
192
+ @instances << {:name => grp_name, :id => instance_id, :status => instance.instanceState.name}
193
+
194
+ end
195
+
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
201
+
202
+ @instances
203
+ end
204
+
205
+ end
206
+
207
+ end
208
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class Ec2ControlTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'ec2-control'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jzimmek-ec2-control
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Jan Zimmek
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-14 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: jzimmek-ec2-dsl
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: EC2-Control is a ruby based toolkit to ease management and configuration of an Amazon EC2 cloud
26
+ email: jan.zimmek@web.de
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION
41
+ - ec2-control.gemspec
42
+ - lib/ec2-control.rb
43
+ - lib/ec2/control/controller.rb
44
+ - lib/ec2/control/query.rb
45
+ - test/ec2-control_test.rb
46
+ - test/test_helper.rb
47
+ has_rdoc: false
48
+ homepage: http://github.com/jzimmek/ec2-control
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.2.0
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: A EC2 management and configuration toolkit
73
+ test_files:
74
+ - test/ec2-control_test.rb
75
+ - test/test_helper.rb