ec2-instance-manager 0.2.0

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 Oliver Kiessler
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,25 @@
1
+ = ec2-instance-manager
2
+
3
+ Simple EC2 Instance Manager that is able to work with multiple AWS accounts (in config.yml). See config.yml.sample.
4
+
5
+ Create a "config.yml" in the current directory and run "ec2_instance_manager". You can launch & terminate instances, assign public IP's and
6
+ attach volumes.
7
+
8
+ Run ec2-instance-manager --help for options and commands.
9
+
10
+ This gem should be considered ALPHA! More features to come...
11
+
12
+ == Note on Patches/Pull Requests
13
+
14
+ * Fork the project.
15
+ * Make your feature addition or bug fix.
16
+ * Add tests for it. This is important so I don't break it in a
17
+ future version unintentionally.
18
+ * Commit, do not mess with rakefile, version, or history.
19
+ (if you want to have your own version, that is fine but
20
+ bump version in a commit by itself I can ignore when I pull)
21
+ * Send me a pull request. Bonus points for topic branches.
22
+
23
+ == Copyright
24
+
25
+ Copyright (c) 2009 Oliver Kiessler. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "ec2-instance-manager"
8
+ gem.summary = %Q{Simple EC2 Instance Manager}
9
+ gem.description = %Q{Launches EC2 instances for multiple AWS accounts}
10
+ gem.email = "kiessler@inceedo.com"
11
+ gem.homepage = "http://github.com/okiess/ec2-instance-manager"
12
+ gem.authors = ["Oliver Kiessler"]
13
+ gem.add_development_dependency "thoughtbot-shoulda"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/*_test.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+ task :test => :check_dependencies
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ if File.exist?('VERSION')
47
+ version = File.read('VERSION')
48
+ else
49
+ version = ""
50
+ end
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "ec2-instance-manager #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../lib/ec2-instance-manager'
4
+
5
+ # Create and run the application
6
+ app = Ec2InstanceManager.new(ARGV, STDIN)
7
+ app.run
data/config.yml.sample ADDED
@@ -0,0 +1,24 @@
1
+ default:
2
+ amazon_access_key_id:
3
+ amazon_secret_access_key:
4
+ amazon_account_number:
5
+ key:
6
+ availability_zone: eu-west-1a
7
+ instance_type: m1.small
8
+
9
+ customer1:
10
+ amazon_access_key_id:
11
+ amazon_secret_access_key:
12
+ amazon_account_number:
13
+ key:
14
+ availability_zone: eu-west-1a
15
+ instance_type: m1.small
16
+
17
+ customer2:
18
+ amazon_access_key_id:
19
+ amazon_secret_access_key:
20
+ amazon_account_number:
21
+ key:
22
+ availability_zone: eu-west-1a
23
+ instance_type: m1.small
24
+
@@ -0,0 +1,60 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ec2-instance-manager}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Oliver Kiessler"]
12
+ s.date = %q{2009-10-09}
13
+ s.default_executable = %q{ec2-instance-manager}
14
+ s.description = %q{Launches EC2 instances for multiple AWS accounts}
15
+ s.email = %q{kiessler@inceedo.com}
16
+ s.executables = ["ec2-instance-manager"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitignore",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bin/ec2-instance-manager",
29
+ "config.yml.sample",
30
+ "ec2-instance-manager.gemspec",
31
+ "lib/ec2-instance-manager.rb",
32
+ "lib/ec2-instance-manager/ec2_instance_manager.rb",
33
+ "lib/ec2-instance-manager/launch.rb",
34
+ "lib/ec2-instance-manager/status.rb",
35
+ "test/ec2-instance-manager_test.rb",
36
+ "test/test_helper.rb"
37
+ ]
38
+ s.homepage = %q{http://github.com/okiess/ec2-instance-manager}
39
+ s.rdoc_options = ["--charset=UTF-8"]
40
+ s.require_paths = ["lib"]
41
+ s.rubygems_version = %q{1.3.5}
42
+ s.summary = %q{Simple EC2 Instance Manager}
43
+ s.test_files = [
44
+ "test/ec2-instance-manager_test.rb",
45
+ "test/test_helper.rb"
46
+ ]
47
+
48
+ if s.respond_to? :specification_version then
49
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
50
+ s.specification_version = 3
51
+
52
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
53
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
54
+ else
55
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
59
+ end
60
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require 'optparse'
5
+
6
+ gem 'amazon-ec2'
7
+ require 'AWS'
8
+
9
+ require File.dirname(__FILE__) + '/ec2-instance-manager/ec2_instance_manager'
@@ -0,0 +1,88 @@
1
+ require File.dirname(__FILE__) + '/status'
2
+ require File.dirname(__FILE__) + '/launch'
3
+
4
+ class Ec2InstanceManager
5
+ include Status
6
+ include Launch
7
+ VERSION = '0.2'
8
+
9
+ attr_reader :config, :customer_key, :options
10
+
11
+ def initialize(arguments, stdin)
12
+ @arguments = arguments
13
+ @stdin = stdin
14
+ options = {}
15
+
16
+ optparse = OptionParser.new do |opts|
17
+ opts.banner = "Usage: ec2-instance-manager [options]"
18
+
19
+ options[:status] = false
20
+ opts.on( '-s', '--status', 'Status only' ) do
21
+ options[:status] = true
22
+ end
23
+
24
+ options[:terminate] = false
25
+ opts.on( '-t', '--terminate-all', 'Terminates all instances running under a config key' ) do
26
+ options[:terminate] = true
27
+ end
28
+
29
+ options[:config] = nil
30
+ opts.on( '-c', '--config CONFIG_KEY', 'Sets the config key' ) do |key|
31
+ options[:config] = key
32
+ end
33
+
34
+ opts.on( '-h', '--help', 'Display this screen' ) do
35
+ puts opts
36
+ exit
37
+ end
38
+ end
39
+
40
+ optparse.parse!
41
+ @options = options
42
+ end
43
+
44
+ def config; @config ||= read_config; end
45
+ def read_config
46
+ if File.exists?("config.yml")
47
+ @config = YAML.load(File.read("config.yml"))
48
+ else
49
+ begin
50
+ @config = YAML.load(File.read("#{ENV['HOME']}/.ec2_instance_manager_config.yml"))
51
+ rescue Errno::ENOENT
52
+ raise "config.yml expected in current directory or ~/.ec2_instance_manager_config.yml"
53
+ end
54
+ end
55
+ end
56
+
57
+ def ec2
58
+ @ec2 ||= AWS::EC2::Base.new(:access_key_id => config[@customer_key]['amazon_access_key_id'],
59
+ :secret_access_key => config[@customer_key]['amazon_secret_access_key'])
60
+ end
61
+
62
+ def run
63
+ puts "EC2 Instance Manager"
64
+ puts
65
+ unless options[:config]
66
+ puts "Which customer config do you want to use? (#{config.keys.join(", ")})"
67
+ @customer_key = gets
68
+ @customer_key = @customer_key.rstrip.lstrip
69
+ @customer_key = 'default' if @customer_key.empty?
70
+ else
71
+ @customer_key = options[:config]
72
+ end
73
+
74
+ puts "Configuration: #{@customer_key}"
75
+ puts "AMAZON_ACCESS_KEY_ID: #{config[@customer_key]['amazon_access_key_id']}"
76
+ puts "KEY: #{config[@customer_key]['key']}"
77
+ puts "ZONE: #{config[@customer_key]['availability_zone']}"
78
+ puts
79
+
80
+ status_info
81
+
82
+ if options[:terminate]
83
+ terminate
84
+ else
85
+ launch unless options[:status]
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,74 @@
1
+ module Launch
2
+ def launch
3
+ puts
4
+ puts "Which AMI Id do you want to launch?"
5
+ ami_id = gets
6
+ ami_id = ami_id.lstrip.rstrip
7
+
8
+ result = ec2.run_instances(
9
+ :image_id => ami_id,
10
+ :instance_type => config[@customer_key]['instance_type'],
11
+ :key_name => config[@customer_key]['key'],
12
+ :availability_zone => config[@customer_key]['availability_zone']
13
+ )
14
+
15
+ instance_id = result.instancesSet.item[0].instanceId
16
+ puts "=> Starting Instance Id: #{instance_id}"
17
+ puts
18
+
19
+ instance_state = nil
20
+ while(instance_state != 'running')
21
+ instance_state, dns_name = get_instance_state(instance_id)
22
+ puts "=> Checking for running state... #{instance_state}"
23
+ puts "=> Public DNS: #{dns_name}" if instance_state == 'running'
24
+ sleep 10 unless instance_state == 'running'
25
+ end
26
+
27
+ puts
28
+
29
+ puts "Do you want to associate a public IP? (leave empty if not)"
30
+ public_ip = gets
31
+
32
+ if not public_ip.empty? and public_ip.size > 1
33
+ puts "Associating public IP address... #{public_ip}"
34
+ result = ec2.associate_address(:instance_id => instance_id, :public_ip => public_ip.lstrip.rstrip)
35
+ if result["return"] == "true"
36
+ puts "=> Success."
37
+ end
38
+ end
39
+
40
+ puts
41
+ puts "Please enter your volume id (leave empty if you don't want to attach a volume):"
42
+ volume_id = gets
43
+
44
+ if not volume_id.empty? and volume_id.size > 1
45
+ puts "Attaching volume... #{volume_id}"
46
+ result = ec2.attach_volume(:volume_id => volume_id.lstrip.rstrip, :instance_id => instance_id, :device => '/dev/sdf')
47
+ if result["return"] == "true"
48
+ puts "=> Success."
49
+ end
50
+ end
51
+ end
52
+
53
+ def terminate(wait = true)
54
+ instances = get_running_instances_list
55
+ if instances and instances.any?
56
+ puts
57
+ puts "Warning: Terminating all instances: #{instances.join(", ")}"
58
+ puts "Please cancel within the next 5 seconds..."
59
+ sleep 5
60
+ ec2.terminate_instances(:instance_id => instances)
61
+ puts
62
+ puts "All instances are going to terminate now."
63
+ end
64
+ end
65
+
66
+ def get_running_instances_list
67
+ result = ec2.describe_instances
68
+ if result and result["reservationSet"]
69
+ result["reservationSet"]["item"].collect do |item|
70
+ item["instancesSet"]["item"].first["instanceId"] if item["instancesSet"]["item"].first["instanceState"]["name"] == 'running'
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,72 @@
1
+ module Status
2
+ def get_instance_state(instance_id)
3
+ result = ec2.describe_instances(:instance_id => instance_id)
4
+ instance_state = result["reservationSet"]["item"].first["instancesSet"]["item"].first["instanceState"]["name"]
5
+ dns_name = result["reservationSet"]["item"].first["instancesSet"]["item"].first["dnsName"]
6
+ return instance_state, dns_name
7
+ end
8
+
9
+ def display_ami_ids(owner_id = nil)
10
+ result = ec2.describe_images(:owner_id => owner_id || config[@customer_key]['amazon_account_number'])
11
+ if result and result["imagesSet"]
12
+ result["imagesSet"]["item"].each {|image| puts "#{image["imageId"]} - #{image["imageLocation"]}"}
13
+ else
14
+ puts "No images."
15
+ end
16
+ end
17
+
18
+ def display_instances
19
+ result = ec2.describe_instances
20
+ if result and result["reservationSet"]
21
+ result["reservationSet"]["item"].each do |item|
22
+ instance_id = item["instancesSet"]["item"].first["instanceId"]
23
+ ami_id = item["instancesSet"]["item"].first["imageId"]
24
+ running_state = item["instancesSet"]["item"].first["instanceState"]["name"]
25
+ dns_name = item["instancesSet"]["item"].first["dnsName"]
26
+ puts "Instance Id: #{instance_id} - #{running_state} (AMI Id: #{ami_id}) #{dns_name}"
27
+ end
28
+ else
29
+ puts "No instances."
30
+ end
31
+ end
32
+
33
+ def display_addresses
34
+ result = ec2.describe_addresses
35
+ if result and result["addressesSet"]
36
+ result["addressesSet"]["item"].each do |ip|
37
+ puts "#{ip["publicIp"]} => #{ip["instanceId"].nil? ? 'unassigned' : ip["instanceId"]}"
38
+ end
39
+ else
40
+ puts "No addresses."
41
+ end
42
+ end
43
+
44
+ def display_volumes
45
+ result = ec2.describe_volumes
46
+ if result and result["volumeSet"]
47
+ result["volumeSet"]["item"].each do |vol|
48
+ instance_id = nil
49
+ if vol["attachmentSet"]
50
+ instance_id = vol["attachmentSet"]["item"].first["instanceId"]
51
+ end
52
+ puts "#{vol["volumeId"]} (Size: #{vol["size"]} / Zone: #{vol["availabilityZone"]}) - #{vol["status"]} => #{instance_id.nil? ? 'unassigned' : instance_id}"
53
+ end
54
+ else
55
+ puts "No volumes."
56
+ end
57
+ end
58
+
59
+ def status_info
60
+ puts "Fetching information about your instances..."
61
+ display_instances
62
+ puts
63
+ puts "Fetching your registered private AMI Id's..."
64
+ display_ami_ids
65
+ puts
66
+ puts "Fetching information about your public IP's..."
67
+ display_addresses
68
+ puts
69
+ puts "Fetching information about your volumes..."
70
+ display_volumes
71
+ end
72
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class Ec2InstanceManagerTest < Test::Unit::TestCase
4
+ should "test" do
5
+ assert true
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-instance-manager'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ec2-instance-manager
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Oliver Kiessler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-09 00:00:00 +02:00
13
+ default_executable: ec2-instance-manager
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: thoughtbot-shoulda
17
+ type: :development
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: Launches EC2 instances for multiple AWS accounts
26
+ email: kiessler@inceedo.com
27
+ executables:
28
+ - ec2-instance-manager
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
+ - bin/ec2-instance-manager
42
+ - config.yml.sample
43
+ - ec2-instance-manager.gemspec
44
+ - lib/ec2-instance-manager.rb
45
+ - lib/ec2-instance-manager/ec2_instance_manager.rb
46
+ - lib/ec2-instance-manager/launch.rb
47
+ - lib/ec2-instance-manager/status.rb
48
+ - test/ec2-instance-manager_test.rb
49
+ - test/test_helper.rb
50
+ has_rdoc: true
51
+ homepage: http://github.com/okiess/ec2-instance-manager
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options:
56
+ - --charset=UTF-8
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.3.5
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Simple EC2 Instance Manager
78
+ test_files:
79
+ - test/ec2-instance-manager_test.rb
80
+ - test/test_helper.rb