jzimmek-ec2-control 0.0.4

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.
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