krisr-amazon-ec2 0.5.0
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/.gitignore +6 -0
- data/ChangeLog +284 -0
- data/LICENSE +66 -0
- data/README.rdoc +329 -0
- data/Rakefile +101 -0
- data/VERSION +1 -0
- data/amazon-ec2.gemspec +123 -0
- data/bin/ec2-gem-example.rb +66 -0
- data/bin/ec2-gem-profile.rb +10 -0
- data/bin/ec2sh +62 -0
- data/bin/setup.rb +26 -0
- data/deps.rip +1 -0
- data/lib/AWS.rb +239 -0
- data/lib/AWS/EC2.rb +67 -0
- data/lib/AWS/EC2/availability_zones.rb +43 -0
- data/lib/AWS/EC2/console.rb +46 -0
- data/lib/AWS/EC2/elastic_ips.rb +154 -0
- data/lib/AWS/EC2/image_attributes.rb +168 -0
- data/lib/AWS/EC2/images.rb +136 -0
- data/lib/AWS/EC2/instances.rb +218 -0
- data/lib/AWS/EC2/keypairs.rb +96 -0
- data/lib/AWS/EC2/products.rb +45 -0
- data/lib/AWS/EC2/security_groups.rb +234 -0
- data/lib/AWS/EC2/snapshots.rb +96 -0
- data/lib/AWS/EC2/volumes.rb +172 -0
- data/lib/AWS/ELB.rb +57 -0
- data/lib/AWS/ELB/load_balancers.rb +201 -0
- data/lib/AWS/exceptions.rb +169 -0
- data/lib/AWS/responses.rb +61 -0
- data/lib/EC2.rb +31 -0
- data/perftools/ec2prof +0 -0
- data/perftools/ec2prof-results.dot +193 -0
- data/perftools/ec2prof-results.txt +126 -0
- data/perftools/ec2prof.symbols +129 -0
- data/test/test_EC2.rb +68 -0
- data/test/test_EC2_availability_zones.rb +49 -0
- data/test/test_EC2_console.rb +54 -0
- data/test/test_EC2_elastic_ips.rb +144 -0
- data/test/test_EC2_image_attributes.rb +238 -0
- data/test/test_EC2_images.rb +197 -0
- data/test/test_EC2_instances.rb +348 -0
- data/test/test_EC2_keypairs.rb +123 -0
- data/test/test_EC2_products.rb +48 -0
- data/test/test_EC2_responses.rb +52 -0
- data/test/test_EC2_s3_xmlsimple.rb +80 -0
- data/test/test_EC2_security_groups.rb +205 -0
- data/test/test_EC2_snapshots.rb +83 -0
- data/test/test_EC2_volumes.rb +142 -0
- data/test/test_ELB_load_balancers.rb +238 -0
- data/test/test_helper.rb +19 -0
- data/wsdl/2007-08-29.ec2.wsdl +1269 -0
- data/wsdl/2008-02-01.ec2.wsdl +1614 -0
- data/wsdl/2008-05-05.ec2.wsdl +2052 -0
- data/wsdl/2008-12-01.ec2.wsdl +2354 -0
- metadata +184 -0
data/Rakefile
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "amazon-ec2"
|
8
|
+
gem.summary = %Q{Amazon EC2 Ruby Gem}
|
9
|
+
gem.description = %Q{An interface library that allows Ruby applications to easily connect to the HTTP 'Query API' for the Amazon Web Services Elastic Compute Cloud (EC2) and manipulate cloud servers.}
|
10
|
+
gem.email = "glenn@rempe.us"
|
11
|
+
gem.homepage = "http://github.com/grempe/amazon-ec2"
|
12
|
+
gem.authors = ["Glenn Rempe"]
|
13
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
14
|
+
|
15
|
+
# gem.autorequire = 'EC2'
|
16
|
+
gem.rdoc_options = ["--quiet", "--title", "amazon-ec2 documentation", "--opname", "index.html", "--line-numbers", "--main", "README.rdoc", "--inline-source"]
|
17
|
+
|
18
|
+
gem.rubyforge_project = 'amazon-ec2'
|
19
|
+
|
20
|
+
gem.add_dependency('xml-simple', '>= 1.0.12')
|
21
|
+
gem.add_development_dependency('mocha', '>= 0.9.5')
|
22
|
+
gem.add_development_dependency('test-spec', '>= 0.10.0')
|
23
|
+
gem.add_development_dependency('rcov', '>= 0.8.1.2.0')
|
24
|
+
gem.add_development_dependency('perftools.rb', '= 0.1.6')
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
rescue LoadError
|
29
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'rake/testtask'
|
33
|
+
Rake::TestTask.new(:test) do |test|
|
34
|
+
test.libs << 'lib' << 'test'
|
35
|
+
test.pattern = 'test/**/test_*.rb'
|
36
|
+
test.verbose = true
|
37
|
+
end
|
38
|
+
|
39
|
+
begin
|
40
|
+
require 'rcov/rcovtask'
|
41
|
+
Rcov::RcovTask.new do |test|
|
42
|
+
test.libs << 'test'
|
43
|
+
test.pattern = 'test/**/test_*.rb'
|
44
|
+
test.verbose = true
|
45
|
+
end
|
46
|
+
rescue LoadError
|
47
|
+
task :rcov do
|
48
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
task :default => :test
|
54
|
+
|
55
|
+
require 'rake/rdoctask'
|
56
|
+
Rake::RDocTask.new do |rdoc|
|
57
|
+
if File.exist?('VERSION.yml')
|
58
|
+
config = YAML.load(File.read('VERSION.yml'))
|
59
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
60
|
+
else
|
61
|
+
version = ""
|
62
|
+
end
|
63
|
+
|
64
|
+
rdoc.rdoc_dir = 'rdoc'
|
65
|
+
rdoc.title = "amazon-ec2 #{version}"
|
66
|
+
rdoc.rdoc_files.include('README*')
|
67
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
68
|
+
end
|
69
|
+
|
70
|
+
begin
|
71
|
+
require 'rake/contrib/sshpublisher'
|
72
|
+
namespace :rubyforge do
|
73
|
+
|
74
|
+
desc "Release gem and RDoc documentation to RubyForge"
|
75
|
+
task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
|
76
|
+
|
77
|
+
namespace :release do
|
78
|
+
desc "Publish RDoc to RubyForge."
|
79
|
+
task :docs => [:rdoc] do
|
80
|
+
config = YAML.load(
|
81
|
+
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
82
|
+
)
|
83
|
+
|
84
|
+
host = "#{config['username']}@rubyforge.org"
|
85
|
+
remote_dir = "/var/www/gforge-projects/amazon-ec2/"
|
86
|
+
local_dir = 'rdoc'
|
87
|
+
|
88
|
+
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
rescue LoadError
|
93
|
+
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
94
|
+
end
|
95
|
+
|
96
|
+
desc "Generate a perftools.rb profile"
|
97
|
+
task :profile do
|
98
|
+
system("CPUPROFILE=perftools/ec2prof RUBYOPT='-r/usr/local/lib/ruby/gems/1.8/gems/perftools.rb-0.1.6/lib/perftools.bundle' ruby -r'rubygems' bin/ec2-gem-profile.rb")
|
99
|
+
system("pprof.rb --text --ignore=Gem perftools/ec2prof > perftools/ec2prof-results.txt")
|
100
|
+
system("pprof.rb --dot --ignore=Gem perftools/ec2prof > perftools/ec2prof-results.dot")
|
101
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.5.0
|
data/amazon-ec2.gemspec
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{amazon-ec2}
|
5
|
+
s.version = "0.5.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Glenn Rempe"]
|
9
|
+
s.date = %q{2009-08-04}
|
10
|
+
s.description = %q{An interface library that allows Ruby applications to easily connect to the HTTP 'Query API' for the Amazon Web Services Elastic Compute Cloud (EC2) and manipulate cloud servers.}
|
11
|
+
s.email = %q{glenn@rempe.us}
|
12
|
+
s.executables = ["ec2-gem-example.rb", "ec2-gem-profile.rb", "ec2sh", "setup.rb"]
|
13
|
+
s.extra_rdoc_files = [
|
14
|
+
"ChangeLog",
|
15
|
+
"LICENSE",
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"ChangeLog",
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"amazon-ec2.gemspec",
|
26
|
+
"bin/ec2-gem-example.rb",
|
27
|
+
"bin/ec2-gem-profile.rb",
|
28
|
+
"bin/ec2sh",
|
29
|
+
"bin/setup.rb",
|
30
|
+
"deps.rip",
|
31
|
+
"lib/AWS.rb",
|
32
|
+
"lib/AWS/EC2.rb",
|
33
|
+
"lib/AWS/EC2/availability_zones.rb",
|
34
|
+
"lib/AWS/EC2/console.rb",
|
35
|
+
"lib/AWS/EC2/elastic_ips.rb",
|
36
|
+
"lib/AWS/EC2/image_attributes.rb",
|
37
|
+
"lib/AWS/EC2/images.rb",
|
38
|
+
"lib/AWS/EC2/instances.rb",
|
39
|
+
"lib/AWS/EC2/keypairs.rb",
|
40
|
+
"lib/AWS/EC2/products.rb",
|
41
|
+
"lib/AWS/EC2/security_groups.rb",
|
42
|
+
"lib/AWS/EC2/snapshots.rb",
|
43
|
+
"lib/AWS/EC2/volumes.rb",
|
44
|
+
"lib/AWS/ELB.rb",
|
45
|
+
"lib/AWS/ELB/load_balancers.rb",
|
46
|
+
"lib/AWS/exceptions.rb",
|
47
|
+
"lib/AWS/responses.rb",
|
48
|
+
"lib/EC2.rb",
|
49
|
+
"perftools/ec2prof",
|
50
|
+
"perftools/ec2prof-results.dot",
|
51
|
+
"perftools/ec2prof-results.txt",
|
52
|
+
"perftools/ec2prof.symbols",
|
53
|
+
"test/test_EC2.rb",
|
54
|
+
"test/test_EC2_availability_zones.rb",
|
55
|
+
"test/test_EC2_console.rb",
|
56
|
+
"test/test_EC2_elastic_ips.rb",
|
57
|
+
"test/test_EC2_image_attributes.rb",
|
58
|
+
"test/test_EC2_images.rb",
|
59
|
+
"test/test_EC2_instances.rb",
|
60
|
+
"test/test_EC2_keypairs.rb",
|
61
|
+
"test/test_EC2_products.rb",
|
62
|
+
"test/test_EC2_responses.rb",
|
63
|
+
"test/test_EC2_s3_xmlsimple.rb",
|
64
|
+
"test/test_EC2_security_groups.rb",
|
65
|
+
"test/test_EC2_snapshots.rb",
|
66
|
+
"test/test_EC2_volumes.rb",
|
67
|
+
"test/test_ELB_load_balancers.rb",
|
68
|
+
"test/test_helper.rb",
|
69
|
+
"wsdl/2007-08-29.ec2.wsdl",
|
70
|
+
"wsdl/2008-02-01.ec2.wsdl",
|
71
|
+
"wsdl/2008-05-05.ec2.wsdl",
|
72
|
+
"wsdl/2008-12-01.ec2.wsdl"
|
73
|
+
]
|
74
|
+
s.homepage = %q{http://github.com/grempe/amazon-ec2}
|
75
|
+
s.rdoc_options = ["--quiet", "--title", "amazon-ec2 documentation", "--opname", "index.html", "--line-numbers", "--main", "README.rdoc", "--inline-source"]
|
76
|
+
s.require_paths = ["lib"]
|
77
|
+
s.rubyforge_project = %q{amazon-ec2}
|
78
|
+
s.rubygems_version = %q{1.3.4}
|
79
|
+
s.summary = %q{Amazon EC2 Ruby Gem}
|
80
|
+
s.test_files = [
|
81
|
+
"test/test_EC2.rb",
|
82
|
+
"test/test_EC2_availability_zones.rb",
|
83
|
+
"test/test_EC2_console.rb",
|
84
|
+
"test/test_EC2_elastic_ips.rb",
|
85
|
+
"test/test_EC2_image_attributes.rb",
|
86
|
+
"test/test_EC2_images.rb",
|
87
|
+
"test/test_EC2_instances.rb",
|
88
|
+
"test/test_EC2_keypairs.rb",
|
89
|
+
"test/test_EC2_products.rb",
|
90
|
+
"test/test_EC2_responses.rb",
|
91
|
+
"test/test_EC2_s3_xmlsimple.rb",
|
92
|
+
"test/test_EC2_security_groups.rb",
|
93
|
+
"test/test_EC2_snapshots.rb",
|
94
|
+
"test/test_EC2_volumes.rb",
|
95
|
+
"test/test_ELB_load_balancers.rb",
|
96
|
+
"test/test_helper.rb"
|
97
|
+
]
|
98
|
+
|
99
|
+
if s.respond_to? :specification_version then
|
100
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
101
|
+
s.specification_version = 3
|
102
|
+
|
103
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
104
|
+
s.add_runtime_dependency(%q<xml-simple>, [">= 1.0.12"])
|
105
|
+
s.add_development_dependency(%q<mocha>, [">= 0.9.5"])
|
106
|
+
s.add_development_dependency(%q<test-spec>, [">= 0.10.0"])
|
107
|
+
s.add_development_dependency(%q<rcov>, [">= 0.8.1.2.0"])
|
108
|
+
s.add_development_dependency(%q<perftools.rb>, ["= 0.1.6"])
|
109
|
+
else
|
110
|
+
s.add_dependency(%q<xml-simple>, [">= 1.0.12"])
|
111
|
+
s.add_dependency(%q<mocha>, [">= 0.9.5"])
|
112
|
+
s.add_dependency(%q<test-spec>, [">= 0.10.0"])
|
113
|
+
s.add_dependency(%q<rcov>, [">= 0.8.1.2.0"])
|
114
|
+
s.add_dependency(%q<perftools.rb>, ["= 0.1.6"])
|
115
|
+
end
|
116
|
+
else
|
117
|
+
s.add_dependency(%q<xml-simple>, [">= 1.0.12"])
|
118
|
+
s.add_dependency(%q<mocha>, [">= 0.9.5"])
|
119
|
+
s.add_dependency(%q<test-spec>, [">= 0.10.0"])
|
120
|
+
s.add_dependency(%q<rcov>, [">= 0.8.1.2.0"])
|
121
|
+
s.add_dependency(%q<perftools.rb>, ["= 0.1.6"])
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Amazon Web Services EC2 Query API Ruby library
|
4
|
+
#
|
5
|
+
# Ruby Gem Name:: amazon-ec2
|
6
|
+
# Author:: Glenn Rempe (mailto:glenn@rempe.us)
|
7
|
+
# Copyright:: Copyright (c) 2007-2008 Glenn Rempe
|
8
|
+
# License:: Distributes under the same terms as Ruby
|
9
|
+
# Home:: http://github.com/grempe/amazon-ec2/tree/master
|
10
|
+
#++
|
11
|
+
|
12
|
+
require File.dirname(__FILE__) + '/../lib/AWS'
|
13
|
+
require 'pp'
|
14
|
+
|
15
|
+
# pull these from the local shell environment variables set in ~/.bash_login
|
16
|
+
# or using appropriate methods specific to your login shell.
|
17
|
+
#
|
18
|
+
# e.g. in ~/.bash_login
|
19
|
+
#
|
20
|
+
# # For amazon-ec2 and amazon s3 ruby gems
|
21
|
+
# export AMAZON_ACCESS_KEY_ID="FOO"
|
22
|
+
# export AMAZON_SECRET_ACCESS_KEY="BAR"
|
23
|
+
|
24
|
+
ACCESS_KEY_ID = ENV['AMAZON_ACCESS_KEY_ID']
|
25
|
+
SECRET_ACCESS_KEY = ENV['AMAZON_SECRET_ACCESS_KEY']
|
26
|
+
|
27
|
+
if ACCESS_KEY_ID.nil? || ACCESS_KEY_ID.empty?
|
28
|
+
puts "Error : You must add the shell environment variables AMAZON_ACCESS_KEY_ID and AMAZON_SECRET_ACCESS_KEY before calling #{$0}!"
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
|
32
|
+
# us-east-1.ec2.amazonaws.com == ec2.amazonaws.com
|
33
|
+
# eu-west-1.ec2.amazonaws.com for the european region
|
34
|
+
# test different servers by running something like:
|
35
|
+
# export EC2_URL='https://ec2.amazonaws.com';./bin/ec2-gem-example.rb
|
36
|
+
if ENV['EC2_URL']
|
37
|
+
ec2 = AWS::EC2::Base.new( :access_key_id => ACCESS_KEY_ID, :secret_access_key => SECRET_ACCESS_KEY, :server => URI.parse(ENV['EC2_URL']).host )
|
38
|
+
else
|
39
|
+
# default server is US ec2.amazonaws.com
|
40
|
+
ec2 = AWS::EC2::Base.new( :access_key_id => ACCESS_KEY_ID, :secret_access_key => SECRET_ACCESS_KEY )
|
41
|
+
end
|
42
|
+
|
43
|
+
puts "----- ec2.methods.sort -----"
|
44
|
+
p ec2.methods.sort
|
45
|
+
|
46
|
+
puts "----- listing images owned by 'amazon' -----"
|
47
|
+
ec2.describe_images(:owner_id => "amazon").imagesSet.item.each do |image|
|
48
|
+
image.keys.each do |key|
|
49
|
+
puts "#{key} => #{image[key]}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
puts "----- listing all running instances -----"
|
54
|
+
pp ec2.describe_instances()
|
55
|
+
|
56
|
+
puts "----- creating a security group -----"
|
57
|
+
pp ec2.create_security_group(:group_name => "ec2-example-rb-test-group", :group_description => "ec-example.rb test group description.")
|
58
|
+
|
59
|
+
puts "----- listing security groups -----"
|
60
|
+
pp ec2.describe_security_groups()
|
61
|
+
|
62
|
+
puts "----- deleting a security group -----"
|
63
|
+
pp ec2.delete_security_group(:group_name => "ec2-example-rb-test-group")
|
64
|
+
|
65
|
+
puts "----- listing my keypairs (verbose mode) -----"
|
66
|
+
pp ec2.describe_keypairs()
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Basic single command application that we can call with perftools.rb to get consistent results.
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + '/../lib/AWS'
|
6
|
+
ACCESS_KEY_ID = ENV['AMAZON_ACCESS_KEY_ID']
|
7
|
+
SECRET_ACCESS_KEY = ENV['AMAZON_SECRET_ACCESS_KEY']
|
8
|
+
ec2 = AWS::EC2::Base.new( :access_key_id => ACCESS_KEY_ID, :secret_access_key => SECRET_ACCESS_KEY )
|
9
|
+
@images = ec2.describe_images
|
10
|
+
|
data/bin/ec2sh
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Amazon Web Services EC2 Query API Ruby library
|
4
|
+
#
|
5
|
+
# Ruby Gem Name:: amazon-ec2
|
6
|
+
# Author:: Glenn Rempe (mailto:glenn@rempe.us)
|
7
|
+
# Copyright:: Copyright (c) 2007-2008 Glenn Rempe
|
8
|
+
# License:: Distributes under the same terms as Ruby
|
9
|
+
# Home:: http://github.com/grempe/amazon-ec2/tree/master
|
10
|
+
#++
|
11
|
+
|
12
|
+
# CREDITS : Credit for this bit of shameful ripoff coolness
|
13
|
+
# goes to Marcel Molina and his AWS::S3 gem. Thanks!
|
14
|
+
|
15
|
+
# Usage : running this starts up an irb session and
|
16
|
+
# sets up the connection to EC2 as a class variable called
|
17
|
+
# '@ec2'. So just do something like the following on the
|
18
|
+
# shell command line:
|
19
|
+
|
20
|
+
# macbook-pro:~ glenn$ ec2sh
|
21
|
+
# >> @ec2.describe_images
|
22
|
+
# => [#<AWS::EC2::Item image_location...
|
23
|
+
|
24
|
+
aws_lib = File.dirname(__FILE__) + '/../lib/AWS'
|
25
|
+
setup = File.dirname(__FILE__) + '/setup'
|
26
|
+
irb_name = RUBY_PLATFORM =~ /mswin32/ ? 'irb.bat' : 'irb'
|
27
|
+
|
28
|
+
if ( ENV['AMAZON_ACCESS_KEY_ID'] && ENV['AMAZON_SECRET_ACCESS_KEY'] )
|
29
|
+
|
30
|
+
welcome_message = <<-MESSAGE
|
31
|
+
|
32
|
+
'ec2sh' usage :
|
33
|
+
This is an interactive 'irb' command shell that allows you to use all
|
34
|
+
commands available to the amazon-ec2 gem. You'll find this to be a
|
35
|
+
great tool to help you debug issues and practice running commands
|
36
|
+
against the live EC2 servers prior to putting them in your code.
|
37
|
+
|
38
|
+
The EC2 connection is wired to the class instance '@ec2'. Make method calls
|
39
|
+
on this to execute commands on EC2. Adding a #to_s
|
40
|
+
at the end of any command should give you a full String representation of the
|
41
|
+
response.
|
42
|
+
|
43
|
+
Examples to try:
|
44
|
+
|
45
|
+
returns : all ec2 public methods
|
46
|
+
>> @ec2.methods.sort
|
47
|
+
|
48
|
+
returns : a string representation of ALL images
|
49
|
+
>> @ec2.describe_images.to_s
|
50
|
+
|
51
|
+
returns : an Array of AWS::Response objects, each an EC2 image and its data
|
52
|
+
>> @ec2.describe_images.imagesSet.item
|
53
|
+
>> @ec2.describe_images.imagesSet.item[0] (a hash representing a single item in that array)
|
54
|
+
>> @ec2.describe_images.imagesSet.item[0].to_s (a String representation of that item)
|
55
|
+
|
56
|
+
MESSAGE
|
57
|
+
|
58
|
+
puts welcome_message
|
59
|
+
exec "#{irb_name} -r #{aws_lib} -r #{setup} --simple-prompt"
|
60
|
+
else
|
61
|
+
puts "You must define AMAZON_ACCESS_KEY_ID and AMAZON_SECRET_ACCESS_KEY as shell environment variables before running #{$0}!"
|
62
|
+
end
|
data/bin/setup.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Amazon Web Services EC2 Query API Ruby library
|
4
|
+
#
|
5
|
+
# Ruby Gem Name:: amazon-ec2
|
6
|
+
# Author:: Glenn Rempe (mailto:glenn@rempe.us)
|
7
|
+
# Copyright:: Copyright (c) 2007-2008 Glenn Rempe
|
8
|
+
# License:: Distributes under the same terms as Ruby
|
9
|
+
# Home:: http://github.com/grempe/amazon-ec2/tree/master
|
10
|
+
#++
|
11
|
+
|
12
|
+
if ENV['AMAZON_ACCESS_KEY_ID'] && ENV['AMAZON_SECRET_ACCESS_KEY']
|
13
|
+
opts = {
|
14
|
+
:access_key_id => ENV['AMAZON_ACCESS_KEY_ID'],
|
15
|
+
:secret_access_key => ENV['AMAZON_SECRET_ACCESS_KEY']
|
16
|
+
}
|
17
|
+
if ENV['EC2_URL']
|
18
|
+
opts[:server] = URI.parse(ENV['EC2_URL']).host
|
19
|
+
end
|
20
|
+
@ec2 = AWS::EC2::Base.new(opts)
|
21
|
+
@elb = AWS::ELB::Base.new(opts)
|
22
|
+
end
|
23
|
+
|
24
|
+
puts "EC2 Server: #{opts[:server]}"
|
25
|
+
|
26
|
+
include AWS
|
data/deps.rip
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
xml-simple 1.0.12
|
data/lib/AWS.rb
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
# Require any lib files that we have bundled with this Ruby Gem in the lib/AWS directory.
|
2
|
+
# Parts of the AWS module and Base class are broken out into separate
|
3
|
+
# files for maintainability and are organized by the functional groupings defined
|
4
|
+
# in the AWS API developers guide.
|
5
|
+
|
6
|
+
|
7
|
+
%w[ base64 cgi openssl digest/sha1 net/https rexml/document time ostruct ].each { |f| require f }
|
8
|
+
|
9
|
+
module AWS
|
10
|
+
# Builds the canonical string for signing. This strips out all '&', '?', and '='
|
11
|
+
# from the query string to be signed.
|
12
|
+
# Note: The parameters in the path passed in must already be sorted in
|
13
|
+
# case-insensitive alphabetical order and must not be url encoded.
|
14
|
+
def AWS.canonical_string(params, host, method="POST", base="/")
|
15
|
+
# Sort, and encode parameters into a canonical string.
|
16
|
+
sorted_params = params.sort {|x,y| x[0] <=> y[0]}
|
17
|
+
encoded_params = sorted_params.collect do |p|
|
18
|
+
encoded = (CGI::escape(p[0].to_s) +
|
19
|
+
"=" + CGI::escape(p[1].to_s))
|
20
|
+
# Ensure spaces are encoded as '%20', not '+'
|
21
|
+
encoded.gsub('+', '%20')
|
22
|
+
end
|
23
|
+
sigquery = encoded_params.join("&")
|
24
|
+
|
25
|
+
# Generate the request description string
|
26
|
+
req_desc =
|
27
|
+
method + "\n" +
|
28
|
+
host + "\n" +
|
29
|
+
base + "\n" +
|
30
|
+
sigquery
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
# Encodes the given string with the secret_access_key, by taking the
|
35
|
+
# hmac-sha1 sum, and then base64 encoding it. Optionally, it will also
|
36
|
+
# url encode the result of that to protect the string if it's going to
|
37
|
+
# be used as a query string parameter.
|
38
|
+
def AWS.encode(secret_access_key, str, urlencode=true)
|
39
|
+
digest = OpenSSL::Digest::Digest.new('sha1')
|
40
|
+
b64_hmac =
|
41
|
+
Base64.encode64(
|
42
|
+
OpenSSL::HMAC.digest(digest, secret_access_key, str)).gsub("\n","")
|
43
|
+
|
44
|
+
if urlencode
|
45
|
+
return CGI::escape(b64_hmac)
|
46
|
+
else
|
47
|
+
return b64_hmac
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Base
|
52
|
+
|
53
|
+
attr_reader :use_ssl, :server, :proxy_server, :port
|
54
|
+
|
55
|
+
def initialize( options = {} )
|
56
|
+
|
57
|
+
options = { :access_key_id => "",
|
58
|
+
:secret_access_key => "",
|
59
|
+
:use_ssl => true,
|
60
|
+
:server => default_host,
|
61
|
+
:proxy_server => nil
|
62
|
+
}.merge(options)
|
63
|
+
|
64
|
+
@server = options[:server]
|
65
|
+
@proxy_server = options[:proxy_server]
|
66
|
+
@use_ssl = options[:use_ssl]
|
67
|
+
|
68
|
+
raise ArgumentError, "No :access_key_id provided" if options[:access_key_id].nil? || options[:access_key_id].empty?
|
69
|
+
raise ArgumentError, "No :secret_access_key provided" if options[:secret_access_key].nil? || options[:secret_access_key].empty?
|
70
|
+
raise ArgumentError, "No :use_ssl value provided" if options[:use_ssl].nil?
|
71
|
+
raise ArgumentError, "Invalid :use_ssl value provided, only 'true' or 'false' allowed" unless options[:use_ssl] == true || options[:use_ssl] == false
|
72
|
+
raise ArgumentError, "No :server provided" if options[:server].nil? || options[:server].empty?
|
73
|
+
|
74
|
+
if options[:port]
|
75
|
+
# user-specified port
|
76
|
+
@port = options[:port]
|
77
|
+
elsif @use_ssl
|
78
|
+
# https
|
79
|
+
@port = 443
|
80
|
+
else
|
81
|
+
# http
|
82
|
+
@port = 80
|
83
|
+
end
|
84
|
+
|
85
|
+
@access_key_id = options[:access_key_id]
|
86
|
+
@secret_access_key = options[:secret_access_key]
|
87
|
+
|
88
|
+
# Use proxy server if defined
|
89
|
+
# Based on patch by Mathias Dalheimer. 20070217
|
90
|
+
proxy = @proxy_server ? URI.parse(@proxy_server) : OpenStruct.new
|
91
|
+
@http = Net::HTTP::Proxy( proxy.host,
|
92
|
+
proxy.port,
|
93
|
+
proxy.user,
|
94
|
+
proxy.password).new(options[:server], @port)
|
95
|
+
|
96
|
+
@http.use_ssl = @use_ssl
|
97
|
+
|
98
|
+
# Don't verify the SSL certificates. Avoids SSL Cert warning in log on every GET.
|
99
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
protected
|
105
|
+
|
106
|
+
# pathlist is a utility method which takes a key string and and array as input.
|
107
|
+
# It converts the array into a Hash with the hash key being 'Key.n' where
|
108
|
+
# 'n' increments by 1 for each iteration. So if you pass in args
|
109
|
+
# ("ImageId", ["123", "456"]) you should get
|
110
|
+
# {"ImageId.1"=>"123", "ImageId.2"=>"456"} returned.
|
111
|
+
def pathlist(key, arr)
|
112
|
+
params = {}
|
113
|
+
arr.each_with_index do |value, i|
|
114
|
+
params["#{key}.#{i+1}"] = value
|
115
|
+
end
|
116
|
+
params
|
117
|
+
end
|
118
|
+
|
119
|
+
# Same as _pathlist_ except it deals with arrays of hashes.
|
120
|
+
# So if you pass in args
|
121
|
+
# ("People", [{:name=>'jon', :age=>'22'}, {:name=>'chris'}], {:name => 'Name', :age => 'Age'}) you should get
|
122
|
+
# {"People.1.Name"=>"jon", "People.1.Age"=>'22', 'People.2.Name'=>'chris'}
|
123
|
+
def pathhashlist(key, arr_of_hashes, mappings)
|
124
|
+
params ={}
|
125
|
+
arr_of_hashes.each_with_index do |hash, i|
|
126
|
+
hash.each do |attribute, value|
|
127
|
+
params["#{key}.#{i+1}.#{mappings[attribute]}"] = value
|
128
|
+
end
|
129
|
+
end
|
130
|
+
params
|
131
|
+
end
|
132
|
+
|
133
|
+
# Make the connection to AWS EC2 passing in our request. This is generally called from
|
134
|
+
# within a 'Response' class object or one of its sub-classes so the response is interpreted
|
135
|
+
# in its proper context. See lib/EC2/responses.rb
|
136
|
+
def make_request(action, params, data='')
|
137
|
+
|
138
|
+
@http.start do
|
139
|
+
|
140
|
+
# remove any keys that have nil or empty values
|
141
|
+
params.reject! { |key, value| value.nil? or value.empty?}
|
142
|
+
|
143
|
+
params.merge!( {"Action" => action,
|
144
|
+
"SignatureVersion" => "2",
|
145
|
+
"SignatureMethod" => 'HmacSHA1',
|
146
|
+
"AWSAccessKeyId" => @access_key_id,
|
147
|
+
"Version" => api_version,
|
148
|
+
"Timestamp"=>Time.now.getutc.iso8601} )
|
149
|
+
|
150
|
+
sig = get_aws_auth_param(params, @secret_access_key, @server)
|
151
|
+
|
152
|
+
query = params.sort.collect do |param|
|
153
|
+
CGI::escape(param[0]) + "=" + CGI::escape(param[1])
|
154
|
+
end.join("&") + "&Signature=" + sig
|
155
|
+
|
156
|
+
req = Net::HTTP::Post.new("/")
|
157
|
+
req.content_type = 'application/x-www-form-urlencoded'
|
158
|
+
req['User-Agent'] = "github-amazon-ec2-ruby-gem"
|
159
|
+
response = @http.request(req, query)
|
160
|
+
|
161
|
+
# Make a call to see if we need to throw an error based on the response given by EC2
|
162
|
+
# All error classes are defined in EC2/exceptions.rb
|
163
|
+
aws_error?(response)
|
164
|
+
|
165
|
+
return response
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
# Set the Authorization header using AWS signed header authentication
|
172
|
+
def get_aws_auth_param(params, secret_access_key, server)
|
173
|
+
canonical_string = AWS.canonical_string(params, server)
|
174
|
+
encoded_canonical = AWS.encode(secret_access_key, canonical_string)
|
175
|
+
end
|
176
|
+
|
177
|
+
# allow us to have a one line call in each method which will do all of the work
|
178
|
+
# in making the actual request to AWS.
|
179
|
+
def response_generator( options = {} )
|
180
|
+
|
181
|
+
options = {
|
182
|
+
:action => "",
|
183
|
+
:params => {}
|
184
|
+
}.merge(options)
|
185
|
+
|
186
|
+
raise ArgumentError, ":action must be provided to response_generator" if options[:action].nil? || options[:action].empty?
|
187
|
+
|
188
|
+
http_response = make_request(options[:action], options[:params])
|
189
|
+
http_xml = http_response.body
|
190
|
+
return Response.parse(:xml => http_xml)
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
# Raises the appropriate error if the specified Net::HTTPResponse object
|
195
|
+
# contains an Amazon EC2 error; returns +false+ otherwise.
|
196
|
+
def aws_error?(response)
|
197
|
+
|
198
|
+
# return false if we got a HTTP 200 code,
|
199
|
+
# otherwise there is some type of error (40x,50x) and
|
200
|
+
# we should try to raise an appropriate exception
|
201
|
+
# from one of our exception classes defined in
|
202
|
+
# exceptions.rb
|
203
|
+
return false if response.is_a?(Net::HTTPSuccess)
|
204
|
+
|
205
|
+
# parse the XML document so we can walk through it
|
206
|
+
doc = REXML::Document.new(response.body)
|
207
|
+
|
208
|
+
# Check that the Error element is in the place we would expect.
|
209
|
+
# and if not raise a generic error exception
|
210
|
+
if doc.root.elements['Error']
|
211
|
+
error_element = doc.root.elements['Error']
|
212
|
+
elsif doc.root.elements['Errors'] && doc.root.elements['Errors'].elements['Error'] && doc.root.elements['Errors'].elements['Error'].name == 'Error'
|
213
|
+
error_element = doc.root.elements['Errors'].elements['Error']
|
214
|
+
else
|
215
|
+
raise Error, "Unexpected error format. response.body is: #{response.body}"
|
216
|
+
end
|
217
|
+
|
218
|
+
# An valid error response looks like this:
|
219
|
+
# <?xml version="1.0"?><Response><Errors><Error><Code>InvalidParameterCombination</Code><Message>Unknown parameter: foo</Message></Error></Errors><RequestID>291cef62-3e86-414b-900e-17246eccfae8</RequestID></Response>
|
220
|
+
# AWS EC2 throws some exception codes that look like Error.SubError. Since we can't name classes this way
|
221
|
+
# we need to strip out the '.' in the error 'Code' and we name the error exceptions with this
|
222
|
+
# non '.' name as well.
|
223
|
+
error_code = error_element.elements['Code'].text.gsub('.', '')
|
224
|
+
error_message = error_element.elements['Message'].text
|
225
|
+
|
226
|
+
# Raise one of our specific error classes if it exists.
|
227
|
+
# otherwise, throw a generic EC2 Error with a few details.
|
228
|
+
if AWS.const_defined?(error_code)
|
229
|
+
raise AWS.const_get(error_code), error_message
|
230
|
+
else
|
231
|
+
raise AWS::Error, error_message
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
235
|
+
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
Dir[File.join(File.dirname(__FILE__), 'AWS/*.rb')].sort.each { |lib| require lib }
|