ey_instance_api_client 0.1.1

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.
@@ -0,0 +1,56 @@
1
+ module EY
2
+ module InstanceAPIClient
3
+ class Backup
4
+ def initialize(connection, attributes)
5
+ @connection = connection
6
+ @attributes = attributes
7
+ end
8
+
9
+ def upload_urls
10
+ @attributes['upload_urls']
11
+ end
12
+
13
+ def download_urls
14
+ @attributes['download_urls']
15
+ end
16
+
17
+ def finish_url
18
+ @attributes['finish_url']
19
+ end
20
+
21
+ def extension
22
+ @attributes["extension"]
23
+ end
24
+
25
+ def started_at
26
+ if started_at = @attributes['started_at']
27
+ Time.at(started_at)
28
+ end
29
+ end
30
+
31
+ def finished_at
32
+ if finished_at = @attributes['finished_at']
33
+ Time.at(finished_at)
34
+ end
35
+ end
36
+
37
+ def pending?
38
+ status == "pending"
39
+ end
40
+
41
+ def status
42
+ if finished_at
43
+ "finished"
44
+ elsif started_at
45
+ "pending"
46
+ else
47
+ "unknown"
48
+ end
49
+ end
50
+
51
+ def finish!
52
+ @connection.finish_backup(finish_url)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,28 @@
1
+ module EY
2
+ module InstanceAPIClient
3
+ class Config
4
+ def self.default_config
5
+ Config.from_file("/etc/engineyard/instance_api.yml")
6
+ end
7
+
8
+ class MissingConfig < StandardError; end
9
+
10
+ def self.from_file(file)
11
+ config = YAML::load_file(file)
12
+ base_url = config['base_url'] || (raise MissingConfig.new("couldn't find base_url in #{file.inspect}"))
13
+ instance_id = config['instance_id'] || (raise MissingConfig.new("couldn't find instance_id in #{file.inspect}"))
14
+ token = config['token'] || (raise MissingConfig.new("couldn't find token in #{file.inspect}"))
15
+ new(base_url, instance_id, token)
16
+ end
17
+
18
+ def initialize(base_url, instance_id, token)
19
+ @base_url = base_url
20
+ @instance_id = instance_id
21
+ @token = token
22
+ end
23
+
24
+ attr_reader :base_url, :instance_id, :token
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,81 @@
1
+ module EY
2
+ module InstanceAPIClient
3
+ class Connection
4
+ def initialize(base_url, instance_id, token)
5
+ unless base_url.match(/\/$/)
6
+ base_url += '/'
7
+ end
8
+ @base_url = base_url
9
+ @instance_id = instance_id
10
+ @token = token
11
+ end
12
+ attr_reader :base_url
13
+
14
+ #PUBLIC API:
15
+
16
+ def list_snapshots
17
+ r = api_call(snapshots_url, 200)
18
+ data = r.get(:params => params, :accept => "application/json")
19
+ data["snapshots"].collect{ |s| Snapshot.new(s) }
20
+ end
21
+
22
+ def request_snapshot
23
+ r = api_call(snapshots_url, 201)
24
+ r.post(params, :accept => "application/json")
25
+ end
26
+
27
+ def list_backups(database_id)
28
+ r = api_call(database_url(database_id), 200)
29
+ data = r.get(:params => params, :accept => "application/json")
30
+ data["backups"].collect{ |b| Backup.new(self, b) }
31
+ end
32
+
33
+ def start_backup(database_id, extension, part_count)
34
+ r = api_call(database_url(database_id), 201)
35
+ data = r.post(params.merge(:extension => extension, :part_count => part_count), :accept => "application/json")
36
+ Backup.new(self, data["backup"])
37
+ end
38
+
39
+ #SORTA-PRIVATE stuff:
40
+
41
+ def snapshots_url
42
+ URI.join(@base_url, "volumes/all/snapshots").to_s
43
+ end
44
+
45
+ def database_url(database_id)
46
+ URI.join(@base_url, "databases/#{database_id}/backups").to_s
47
+ end
48
+
49
+ def finish_backup(finished_url)
50
+ r = api_call(finished_url, 200)
51
+ r.put(params, :accept => "application/json")
52
+ end
53
+
54
+ def params
55
+ {:token => @token, :instance_id => @instance_id}
56
+ end
57
+
58
+ class InvalidCredentials < StandardError; end
59
+ class UnexpectedStatus < StandardError; end
60
+ class AlreadyFinished < StandardError; end
61
+ class NotFound < StandardError; end
62
+
63
+ def api_call(full_url, expects)
64
+ RestClient::Resource.new(full_url.to_s) do |response, request, raw|
65
+ case response.code
66
+ when 403
67
+ raise InvalidCredentials
68
+ when 404
69
+ raise NotFound
70
+ when 409
71
+ raise AlreadyFinished
72
+ when expects
73
+ JSON.parse(response)
74
+ else
75
+ raise UnexpectedStatus, "request to #{full_url} failed with #{response.code}"
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,29 @@
1
+ module EY
2
+ module InstanceAPIClient
3
+ class Snapshot
4
+ def initialize(attributes)
5
+ @attributes = attributes
6
+ end
7
+
8
+ def state
9
+ @attributes['state']
10
+ end
11
+
12
+ def progress
13
+ @attributes['progress']
14
+ end
15
+
16
+ def volume
17
+ @attributes['volume_type']
18
+ end
19
+
20
+ def id
21
+ @attributes['snapshot_id']
22
+ end
23
+
24
+ def created_at
25
+ Time.parse(@attributes['created_at'])
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ module EY
2
+ module InstanceAPIClient
3
+ VERSION = "0.1.1"
4
+ end
5
+ end
@@ -0,0 +1,43 @@
1
+ # $:.shift(File.expand_path(__FILE__))
2
+ require 'json'
3
+ require 'rest-client'
4
+ require 'ey_instance_api_client/snapshot'
5
+ require 'ey_instance_api_client/backup'
6
+ require 'ey_instance_api_client/connection'
7
+ require 'ey_instance_api_client/config'
8
+
9
+ module EY
10
+ module InstanceAPIClient
11
+
12
+ class Client
13
+ def initialize(config = Config.default_config)
14
+ @backend = Connection.new(config.base_url, config.instance_id, config.token)
15
+ end
16
+ attr_reader :backend
17
+ def base_url
18
+ @backend.base_url
19
+ end
20
+ end
21
+
22
+ class Snapshots < Client
23
+ def list
24
+ @backend.list_snapshots
25
+ end
26
+
27
+ def request
28
+ @backend.request_snapshot
29
+ end
30
+ end
31
+
32
+ class Backups < Client
33
+ def list(database_id)
34
+ @backend.list_backups(database_id)
35
+ end
36
+
37
+ def start(database_id, extension, part_count)
38
+ @backend.start_backup(database_id, extension, part_count)
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,88 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe "Backups" do
4
+ before do
5
+ start_server("backup_base_config")
6
+ end
7
+
8
+ after do
9
+ stop_server
10
+ end
11
+
12
+ describe "with an invalid creds" do
13
+ it "returns 403 when the token is invalid" do
14
+ client = EY::InstanceAPIClient::Backups.new(EY::InstanceAPIClient::Config.new(base_url, "my-instance", "invalid-creds"))
15
+ lambda { client.list("doesntmatter") }.
16
+ should raise_error(EY::InstanceAPIClient::Connection::InvalidCredentials)
17
+ end
18
+ end
19
+
20
+ describe "starting a backup for non-existant database" do
21
+ it "return 404" do
22
+ client = EY::InstanceAPIClient::Backups.new(EY::InstanceAPIClient::Config.new(base_url, "my-instance", "token-for-my-instance"))
23
+ lambda { client.list("nonexistant") }.
24
+ should raise_error(EY::InstanceAPIClient::Connection::NotFound)
25
+ end
26
+ end
27
+
28
+ context "with an database that exists" do
29
+ before do
30
+ @database_id = "database-1"
31
+ @client = EY::InstanceAPIClient::Backups.new(EY::InstanceAPIClient::Config.new(base_url, "my-instance", "token-for-my-instance"))
32
+ end
33
+
34
+ describe "listing backups" do
35
+ it "Makes a request and Gets an empty list" do
36
+ list = @client.list(@database_id)
37
+ list.should == []
38
+ end
39
+
40
+ end
41
+
42
+ describe "starting a backup" do
43
+ before do
44
+ @backup = @client.start(@database_id, ".gz", 1)
45
+ end
46
+
47
+ it "returns the upload and finished url" do
48
+ @backup.should have(1).upload_urls
49
+ @backup.upload_urls.first.should =~ %r{^http://s3/PUT}
50
+ @backup.finish_url.should =~ %r{#{base_url}}
51
+ @backup.status.should == "pending"
52
+ end
53
+
54
+ it "should show started_at in the listing" do
55
+ list = @client.list(@database_id)
56
+ list.size.should == 1
57
+ backup = list.first
58
+ backup.status.should == "pending"
59
+ backup.started_at.should_not be_nil
60
+ backup.download_urls.should be_nil
61
+ backup.upload_urls.should be_nil
62
+ backup.finished_at.should be_nil
63
+ end
64
+
65
+ describe "finishing that backup" do
66
+ before do
67
+ @backup.finish!
68
+ end
69
+
70
+ it "should show finished_at in the listing" do
71
+ list = @client.list(@database_id)
72
+ list.size.should == 1
73
+ backup = list.first
74
+ backup.should have(1).download_urls
75
+ backup.download_urls.first.should =~ %r{^http://s3/GET}
76
+ backup.upload_urls.should be_nil
77
+ backup.started_at.should_not be_nil
78
+ backup.finished_at.should_not be_nil
79
+ end
80
+
81
+ it "should return 409 if you attempt to finish it again" do
82
+ lambda { @backup.finish! }.
83
+ should raise_error(EY::InstanceAPIClient::Connection::AlreadyFinished)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,39 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe "Config" do
4
+
5
+ describe "default_config" do
6
+ before(:each) do
7
+ YAML.stub!(:load_file).and_return do |path, *args|
8
+ if path =~ %r"/etc/engineyard/instance_api\.yml"
9
+ {
10
+ "base_url" => "http://localhost/",
11
+ "instance_id" => "my-instance",
12
+ "token" => "token"
13
+ }
14
+ end
15
+ end
16
+ EY::InstanceAPIClient::Connection.stub!(:new) do |*args|
17
+ @connection_called_with = args
18
+ end
19
+ end
20
+
21
+ it "Backups should load config from /etc/engineyard/instance_api.yml" do
22
+ EY::InstanceAPIClient::Backups.new
23
+ @connection_called_with.should == ["http://localhost/", "my-instance", "token"]
24
+ end
25
+
26
+ it "Snapshots should load config from /etc/engineyard/instance_api.yml" do
27
+ EY::InstanceAPIClient::Snapshots.new
28
+ @connection_called_with.should == ["http://localhost/", "my-instance", "token"]
29
+ end
30
+ end
31
+
32
+ it "ensures base_url ends in a slash" do
33
+ client = EY::InstanceAPIClient::Snapshots.new(EY::InstanceAPIClient::Config.new("http://localhost/end-point-without-a-slash", "some-instance", "some-creds"))
34
+ client.base_url.should == "http://localhost/end-point-without-a-slash/"
35
+ client = EY::InstanceAPIClient::Backups.new(EY::InstanceAPIClient::Config.new("http://localhost/end-point-without-a-slash", "some-instance", "some-creds"))
36
+ client.base_url.should == "http://localhost/end-point-without-a-slash/"
37
+ end
38
+
39
+ end
@@ -0,0 +1,82 @@
1
+
2
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../../../server/lib')
3
+ require 'ey_instance_api_server'
4
+ require 'ey_instance_api_server/backups/example_callback'
5
+
6
+ class MyCallback < EY::InstanceAPIServer::Backups::ExampleCallback
7
+ def initialize(base_url, s3_base_url, automatic_databases, real_s3)
8
+ super(base_url)
9
+ @s3_base_url = s3_base_url
10
+ @automatic_databases = automatic_databases
11
+ @real_s3 = real_s3
12
+ end
13
+
14
+ def download_url_for(backup_id, part)
15
+ if @real_s3
16
+ URI.join(@s3_base_url, "files/#{backup_id}.part#{part}").to_s
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ def upload_url_for(backup_id, part)
23
+ if @real_s3
24
+ download_url_for(backup_id, part)
25
+ else
26
+ super
27
+ end
28
+ end
29
+
30
+ def backups_for(instance_id, database_id)
31
+ if @automatic_databases
32
+ add_database(instance_id, database_id)
33
+ end
34
+ super
35
+ end
36
+ end
37
+
38
+ base_url = ENV["BASE_URL"] || abort("Provide a base url")
39
+ automatic_databases = ENV["AUTO_DATABASES"] == "true"
40
+ real_s3 = ENV["REAL_S3"] == "true"
41
+
42
+ callback = MyCallback.new(URI.join(base_url, "api/").to_s, URI.join(base_url, "s3/").to_s, automatic_databases, real_s3)
43
+ callback.add_instance("my-instance")
44
+ callback.add_database("my-instance", "database-1")
45
+ EY::InstanceAPIServer.callback_module = callback
46
+
47
+ class S3Fake < Sinatra::Base
48
+ enable :raise_errors
49
+ disable :dump_errors
50
+ disable :show_exceptions
51
+
52
+ def files
53
+ @@files ||= {}
54
+ end
55
+
56
+ get "/files/:id" do |id|
57
+ puts "downloading file from #{id.inspect}"
58
+ files[id] || not_found
59
+ end
60
+
61
+ put "/files/:id" do |id|
62
+ unless request.content_type == "application/octet-stream"
63
+ raise "Incorrect content type: #{request.content_type}"
64
+ end
65
+ puts "uploading file to #{id.inspect}"
66
+ files[id] = request.body.read
67
+ end
68
+ end
69
+
70
+ map "/s3" do
71
+ run S3Fake
72
+ end
73
+
74
+ map "/api" do
75
+ run EY::InstanceAPIServer.app
76
+ end
77
+
78
+ map "/" do
79
+ run lambda {
80
+ Rack::Response.new("hello").finish
81
+ }
82
+ end
@@ -0,0 +1,45 @@
1
+
2
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../../../server/lib')
3
+ require 'ey_instance_api_server'
4
+ require 'ey_instance_api_server/snapshots/example_callback'
5
+
6
+ class MyCallback < EY::InstanceAPIServer::Snapshots::ExampleCallback
7
+ def initialize(base_url)
8
+ super(base_url)
9
+ end
10
+
11
+ def perform_all
12
+ @instances.each do |instance_id, instance|
13
+ instance[:volumes].each do |volume_id, volume|
14
+ volume[:snapshots].each do |snapshot_id, snapshot|
15
+ perform_snapshots_for(instance_id, volume_id, snapshot_id)
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ base_url = ENV["BASE_URL"] || abort("Provide a base url")
24
+
25
+ callback = MyCallback.new(URI.join(base_url, "api/"))
26
+ callback.add_instance("my-instance")
27
+ callback.add_volume("my-instance", "volume-1", "db")
28
+ EY::InstanceAPIServer.callback_module = callback
29
+
30
+ map "/api/peform_all" do
31
+ run lambda {
32
+ callback.perform_all
33
+ Rack::Response.new("{}").finish
34
+ }
35
+ end
36
+
37
+ map "/api" do
38
+ run EY::InstanceAPIServer.app
39
+ end
40
+
41
+ map "/" do
42
+ run lambda {
43
+ Rack::Response.new("hello").finish
44
+ }
45
+ end
@@ -0,0 +1,69 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe "Snapshots" do
4
+ before do
5
+ start_server("snapshot_base_config")
6
+ end
7
+
8
+ after do
9
+ stop_server
10
+ end
11
+
12
+ describe "with an invalid creds" do
13
+ it "returns 403 when the token is invalid" do
14
+ client = EY::InstanceAPIClient::Snapshots.new(EY::InstanceAPIClient::Config.new(base_url, "my-instance", "invalid-creds"))
15
+ lambda { client.list }.
16
+ should raise_error(EY::InstanceAPIClient::Connection::InvalidCredentials)
17
+ end
18
+ end
19
+
20
+ context "with an instance that exists" do
21
+ before do
22
+ @instance_id = 'my-instance'
23
+ @volume_id = 'volume-1'
24
+ @client = EY::InstanceAPIClient::Snapshots.new(EY::InstanceAPIClient::Config.new(base_url, "my-instance", "token-for-my-instance"))
25
+ end
26
+
27
+ describe "listing snapshots" do
28
+ it "Makes a request and Gets an empty list" do
29
+ list = @client.list
30
+ list.should == []
31
+ end
32
+ end
33
+
34
+ describe "requesting a snapshot" do
35
+ before do
36
+ @client.request
37
+ end
38
+
39
+ it "should show a requested snapshot in the list" do
40
+ list = @client.list
41
+ list.size.should == 1
42
+ snapshot = list.first
43
+ snapshot.state.should == "requested"
44
+ snapshot.progress.should be_nil
45
+ snapshot.volume.should == 'db' #should be one of 'util', 'data', 'db'
46
+ snapshot.id.should_not be_nil
47
+ snapshot.created_at.should be_within(4).of(Time.now)
48
+ end
49
+
50
+ describe "when the snapshot is performed" do
51
+ before do
52
+ @client.backend.api_call(URI.join(base_url, "peform_all").to_s, 200).post({})
53
+ end
54
+
55
+ it "should show in the listing" do
56
+ list = @client.list
57
+ list.size.should == 1
58
+ snapshot = list.first
59
+ snapshot.state.should == "in progress"
60
+ snapshot.progress.should == "0%"
61
+ snapshot.volume.should == 'db' #should be one of 'util', 'data', 'db'
62
+ snapshot.id.should_not be_nil
63
+ snapshot.created_at.should be_within(4).of(Time.now)
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,32 @@
1
+ Bundler.require(:test)
2
+
3
+ require 'ey_instance_api_client'
4
+
5
+ module Helpers
6
+ def start_server(config)
7
+ config_ru = File.dirname(__FILE__) + "/fixtures/#{config}.ru"
8
+ @server = RealWeb.start_server(config_ru, Proc.new do |server|
9
+ ENV["BASE_URL"] = server_url_for(server.port)
10
+ end)
11
+ end
12
+
13
+ def stop_server
14
+ @server.stop
15
+ end
16
+
17
+ def server_url
18
+ server_url_for(@server.port)
19
+ end
20
+
21
+ def server_url_for(port)
22
+ "http://127.0.0.1:#{port}/"
23
+ end
24
+
25
+ def base_url
26
+ URI.join(server_url, "api/").to_s
27
+ end
28
+ end
29
+
30
+ RSpec.configure do |c|
31
+ c.include Helpers
32
+ end
metadata ADDED
@@ -0,0 +1,211 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ey_instance_api_client
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Engine Yard
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-23 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rest-client
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: rake
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: rspec
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :development
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: ruby-debug
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :development
90
+ version_requirements: *id005
91
+ - !ruby/object:Gem::Dependency
92
+ name: rcov
93
+ prerelease: false
94
+ requirement: &id006 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ type: :development
104
+ version_requirements: *id006
105
+ - !ruby/object:Gem::Dependency
106
+ name: realweb
107
+ prerelease: false
108
+ requirement: &id007 !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - "="
112
+ - !ruby/object:Gem::Version
113
+ hash: 23
114
+ segments:
115
+ - 0
116
+ - 1
117
+ - 6
118
+ version: 0.1.6
119
+ type: :development
120
+ version_requirements: *id007
121
+ - !ruby/object:Gem::Dependency
122
+ name: sinatra
123
+ prerelease: false
124
+ requirement: &id008 !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ hash: 3
130
+ segments:
131
+ - 0
132
+ version: "0"
133
+ type: :development
134
+ version_requirements: *id008
135
+ - !ruby/object:Gem::Dependency
136
+ name: fog
137
+ prerelease: false
138
+ requirement: &id009 !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ hash: 3
144
+ segments:
145
+ - 0
146
+ version: "0"
147
+ type: :development
148
+ version_requirements: *id009
149
+ description: Used by backups and snapshots
150
+ email:
151
+ - gems@engineyard.com
152
+ executables: []
153
+
154
+ extensions: []
155
+
156
+ extra_rdoc_files: []
157
+
158
+ files:
159
+ - lib/ey_instance_api_client/backup.rb
160
+ - lib/ey_instance_api_client/config.rb
161
+ - lib/ey_instance_api_client/connection.rb
162
+ - lib/ey_instance_api_client/snapshot.rb
163
+ - lib/ey_instance_api_client/version.rb
164
+ - lib/ey_instance_api_client.rb
165
+ - spec/backup_client_spec.rb
166
+ - spec/config_spec.rb
167
+ - spec/fixtures/backup_base_config.ru
168
+ - spec/fixtures/snapshot_base_config.ru
169
+ - spec/snapshot_client_spec.rb
170
+ - spec/spec_helper.rb
171
+ has_rdoc: true
172
+ homepage: http://github.com/engineyard/ey_instance_api_client
173
+ licenses: []
174
+
175
+ post_install_message:
176
+ rdoc_options: []
177
+
178
+ require_paths:
179
+ - lib
180
+ required_ruby_version: !ruby/object:Gem::Requirement
181
+ none: false
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ hash: 3
186
+ segments:
187
+ - 0
188
+ version: "0"
189
+ required_rubygems_version: !ruby/object:Gem::Requirement
190
+ none: false
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ hash: 3
195
+ segments:
196
+ - 0
197
+ version: "0"
198
+ requirements: []
199
+
200
+ rubyforge_project:
201
+ rubygems_version: 1.5.2
202
+ signing_key:
203
+ specification_version: 3
204
+ summary: Client libraries used to consume instance api exposed by AWSM.
205
+ test_files:
206
+ - spec/backup_client_spec.rb
207
+ - spec/config_spec.rb
208
+ - spec/fixtures/backup_base_config.ru
209
+ - spec/fixtures/snapshot_base_config.ru
210
+ - spec/snapshot_client_spec.rb
211
+ - spec/spec_helper.rb