heroku-api 0.1.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 +4 -0
- data/.travis.yml +14 -0
- data/Gemfile +4 -0
- data/README.md +120 -0
- data/Rakefile +23 -0
- data/changelog.txt +4 -0
- data/heroku-api.gemspec +23 -0
- data/lib/heroku-api.rb +1 -0
- data/lib/heroku/api.rb +85 -0
- data/lib/heroku/api/addons.rb +47 -0
- data/lib/heroku/api/apps.rb +62 -0
- data/lib/heroku/api/collaborators.rb +33 -0
- data/lib/heroku/api/config_vars.rb +33 -0
- data/lib/heroku/api/domains.rb +33 -0
- data/lib/heroku/api/errors.rb +9 -0
- data/lib/heroku/api/keys.rb +42 -0
- data/lib/heroku/api/logs.rb +18 -0
- data/lib/heroku/api/mock.rb +176 -0
- data/lib/heroku/api/mock/addons.rb +153 -0
- data/lib/heroku/api/mock/apps.rb +184 -0
- data/lib/heroku/api/mock/cache/get_addons.json +1 -0
- data/lib/heroku/api/mock/collaborators.rb +55 -0
- data/lib/heroku/api/mock/config_vars.rb +46 -0
- data/lib/heroku/api/mock/domains.rb +71 -0
- data/lib/heroku/api/mock/keys.rb +46 -0
- data/lib/heroku/api/mock/logs.rb +20 -0
- data/lib/heroku/api/mock/processes.rb +191 -0
- data/lib/heroku/api/mock/releases.rb +124 -0
- data/lib/heroku/api/mock/stacks.rb +84 -0
- data/lib/heroku/api/processes.rb +77 -0
- data/lib/heroku/api/releases.rb +33 -0
- data/lib/heroku/api/stacks.rb +22 -0
- data/lib/heroku/api/vendor/okjson.rb +559 -0
- data/lib/heroku/api/version.rb +5 -0
- data/test/test_addons.rb +169 -0
- data/test/test_apps.rb +119 -0
- data/test/test_collaborators.rb +73 -0
- data/test/test_config_vars.rb +54 -0
- data/test/test_domains.rb +63 -0
- data/test/test_helper.rb +35 -0
- data/test/test_keys.rb +39 -0
- data/test/test_logs.rb +20 -0
- data/test/test_processes.rb +245 -0
- data/test/test_releases.rb +91 -0
- data/test/test_stacks.rb +49 -0
- metadata +134 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
Heroku Ruby Client
|
2
|
+
==================
|
3
|
+
|
4
|
+
The Heroku Ruby Client is used to interact with the Heroku API from Ruby.
|
5
|
+
|
6
|
+
For more about the Heroku API see <http://api-docs.heroku.com>.
|
7
|
+
|
8
|
+
[](https://secure.travis-ci.org/heroku/heroku.rb)
|
9
|
+
|
10
|
+
Usage
|
11
|
+
-----
|
12
|
+
|
13
|
+
Start by creating a connection to Heroku with your credentials:
|
14
|
+
|
15
|
+
require 'heroku-rb'
|
16
|
+
|
17
|
+
heroku = Heroku.new(:api_key => API_KEY)
|
18
|
+
|
19
|
+
NOTE: You can leave out the `:api_key` if `ENV['HEROKU_API_KEY']` is set instead.
|
20
|
+
|
21
|
+
Now you can make requests to the api.
|
22
|
+
|
23
|
+
Requests
|
24
|
+
--------
|
25
|
+
|
26
|
+
What follows is an overview of commands you can run for the client.
|
27
|
+
|
28
|
+
For additional details about any of the commands, see the [API docs](http://api-docs.heroku.com).
|
29
|
+
|
30
|
+
### Add-ons
|
31
|
+
|
32
|
+
heroku.delete('app', 'addon') # remove 'addon' add-on from an 'app' app
|
33
|
+
heroku.get_addons # see a listing of all available add-ons
|
34
|
+
heroku.get_addons('app') # see listing of installed add-ons for 'app' app
|
35
|
+
heroku.post_addon('app', 'addon') # add 'addon' add-on to 'app' app
|
36
|
+
heroku.put_addon('app', 'addon') # update 'addon' add-on on 'app' app
|
37
|
+
|
38
|
+
### Apps
|
39
|
+
|
40
|
+
heroku.delete_app('app') # delete an app named 'app'
|
41
|
+
heroku.get_app('app') # get info about an app named 'app'
|
42
|
+
heroku.get_apps # get a list of your apps
|
43
|
+
heroku.post_apps # create an app with a generated name and the default stack
|
44
|
+
|
45
|
+
heroku.post_apps('name' => 'app') # create an app with a specified name
|
46
|
+
|
47
|
+
### Collaborators
|
48
|
+
|
49
|
+
delete_collaborator('app', 'email@example.com') # remove 'email@example.com' collaborator from 'app' app
|
50
|
+
delete_collaborator('app') # list collaborators for 'app' app
|
51
|
+
post_collaborator('app', 'email@example.com') # add 'email@example.com' collaborator to 'app' app
|
52
|
+
|
53
|
+
### Config Variables
|
54
|
+
|
55
|
+
delete_config_var('app', 'KEY') # remove 'KEY' key from 'app' app
|
56
|
+
get_config_vars('app') # get list of config vars for 'app' app
|
57
|
+
put_config_vars('app', 'KEY' => 'value') # set 'KEY' key to 'value' for 'app' app
|
58
|
+
|
59
|
+
### Domains
|
60
|
+
|
61
|
+
delete_domain('app', 'example.com') # remove the 'example.com' domain from the 'app' app
|
62
|
+
get_domains('app') # list configured domains for the 'app' app
|
63
|
+
post_domains('app', 'example.com') # add 'example.com' domain to the 'app' app
|
64
|
+
|
65
|
+
### Keys
|
66
|
+
|
67
|
+
delete_key('user@hostname.local') # remove the 'user@hostname.local' key
|
68
|
+
delete_keys # remove all keys
|
69
|
+
get_keys # list configured keys
|
70
|
+
post_key('key data') # add key defined by 'key data'
|
71
|
+
|
72
|
+
### Logs
|
73
|
+
|
74
|
+
get_logs('app') # return logs information for 'app' app
|
75
|
+
|
76
|
+
### Processes
|
77
|
+
|
78
|
+
get_ps('app') # list current processes for 'app' app
|
79
|
+
post_ps('app', 'command') # run 'command' command in context of 'app' app
|
80
|
+
post_ps_restart('app') # restart all processes for 'app' app
|
81
|
+
post_ps_scale('app', 'type', 'quantity') # scale 'type' type processes to 'quantity' for 'app' app
|
82
|
+
post_ps_stop('app', 'ps' => 'web.1') # stop 'web.1' process for 'app' app
|
83
|
+
post_ps_stop('app', 'type' => 'web') # stop all 'web' processes for 'app' app
|
84
|
+
put_dynos('app', 'dynos') # set number of dynos for bamboo app 'app' to 'dynos'
|
85
|
+
put_workers('app', 'workers') # set number of workers for bamboo app 'app' to 'workers'
|
86
|
+
|
87
|
+
post_ps_restart('app', 'ps' => 'web.1') # restart 'web.1' process for 'app' app
|
88
|
+
|
89
|
+
### Releases
|
90
|
+
|
91
|
+
get_releases('app') # list of releases for 'app' app
|
92
|
+
get_release('app', 'v#') # get details of 'v#' release for 'app' app
|
93
|
+
post_release('app', 'v#') # rollback 'app' app to 'v#' release
|
94
|
+
|
95
|
+
### Stacks
|
96
|
+
|
97
|
+
get_stack('app') # list available stacks
|
98
|
+
put_stack('app', 'stack') # migrate 'app' app to 'stack' stack
|
99
|
+
|
100
|
+
|
101
|
+
Mock
|
102
|
+
----
|
103
|
+
|
104
|
+
For practice or testing you can also use a simulated Heroku:
|
105
|
+
|
106
|
+
require 'heroku-rb'
|
107
|
+
|
108
|
+
heroku = Heroku.new(:api_key => API_KEY, :mock => true)
|
109
|
+
|
110
|
+
After that commands should still behave the same, but they will only modify some local data instead of updating the state of things on Heroku.
|
111
|
+
|
112
|
+
Tests
|
113
|
+
-----
|
114
|
+
|
115
|
+
To run tests, first set `ENV['HEROKU_API_KEY']` to your api key. Then use `bundle exec rake` to run mock tests or `MOCK=false bundle exec rake` to run integration tests.
|
116
|
+
|
117
|
+
Meta
|
118
|
+
----
|
119
|
+
|
120
|
+
Released under the [MIT license](http://www.opensource.org/licenses/mit-license.php).
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
task :default => :test
|
6
|
+
|
7
|
+
Rake::TestTask.new do |task|
|
8
|
+
task.name = :test
|
9
|
+
task.test_files = FileList['test/test*.rb']
|
10
|
+
end
|
11
|
+
|
12
|
+
task :cache, [:api_key] do |task, args|
|
13
|
+
unless args.api_key
|
14
|
+
puts('cache requires an api key, please call as `cache[api_key]`')
|
15
|
+
else
|
16
|
+
require "#{File.dirname(__FILE__)}/lib/heroku/api"
|
17
|
+
heroku = Heroku.new(:api_key => args.api_key)
|
18
|
+
data = Heroku::API::OkJson.encode(heroku.get_addons.body)
|
19
|
+
File.open("#{File.dirname(__FILE__)}/lib/heroku/stubs/cache/get_addons.json", 'w') do |file|
|
20
|
+
file.write(data)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/changelog.txt
ADDED
data/heroku-api.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "heroku/api/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "heroku-api"
|
7
|
+
s.version = Heroku::API::VERSION
|
8
|
+
s.authors = ["geemus (Wesley Beary)"]
|
9
|
+
s.email = ["wesley@heroku.com"]
|
10
|
+
s.homepage = "http://github.com/heroku/heroku.rb"
|
11
|
+
s.summary = %q{Ruby Client for the Heroku API}
|
12
|
+
s.description = %q{Ruby Client for the Heroku API}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_runtime_dependency 'excon', '~>0.9.4'
|
20
|
+
|
21
|
+
s.add_development_dependency 'minitest'
|
22
|
+
s.add_development_dependency 'rake'
|
23
|
+
end
|
data/lib/heroku-api.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "heroku/api"
|
data/lib/heroku/api.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require "base64"
|
2
|
+
require "cgi"
|
3
|
+
require "excon"
|
4
|
+
require "securerandom"
|
5
|
+
|
6
|
+
require "heroku/api/vendor/okjson"
|
7
|
+
|
8
|
+
require "heroku/api/errors"
|
9
|
+
require "heroku/api/mock"
|
10
|
+
require "heroku/api/version"
|
11
|
+
|
12
|
+
require "heroku/api/addons"
|
13
|
+
require "heroku/api/apps"
|
14
|
+
require "heroku/api/collaborators"
|
15
|
+
require "heroku/api/config_vars"
|
16
|
+
require "heroku/api/domains"
|
17
|
+
require "heroku/api/keys"
|
18
|
+
require "heroku/api/logs"
|
19
|
+
require "heroku/api/processes"
|
20
|
+
require "heroku/api/releases"
|
21
|
+
require "heroku/api/stacks"
|
22
|
+
|
23
|
+
srand
|
24
|
+
|
25
|
+
module Heroku
|
26
|
+
class API
|
27
|
+
|
28
|
+
def initialize(options={})
|
29
|
+
@api_key = options.delete(:api_key) || ENV['HEROKU_API_KEY']
|
30
|
+
user_pass = ":#{@api_key}"
|
31
|
+
options = {
|
32
|
+
:headers => {},
|
33
|
+
:host => 'api.heroku.com',
|
34
|
+
:scheme => 'https'
|
35
|
+
}.merge(options)
|
36
|
+
options[:headers] = {
|
37
|
+
'Accept' => 'application/json',
|
38
|
+
'Authorization' => "Basic #{Base64.encode64(user_pass).gsub("\n", '')}",
|
39
|
+
'User-Agent' => "heroku-rb/#{Heroku::API::VERSION}",
|
40
|
+
'X-Heroku-API-Version' => '3',
|
41
|
+
'X-Ruby-Version' => RUBY_VERSION,
|
42
|
+
'X-Ruby-Platform' => RUBY_PLATFORM
|
43
|
+
}.merge(options[:headers])
|
44
|
+
@connection = Excon.new("#{options[:scheme]}://#{options[:host]}", options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def request(params, &block)
|
48
|
+
begin
|
49
|
+
response = @connection.request(params, &block)
|
50
|
+
rescue Excon::Errors::NotFound => error
|
51
|
+
reerror = Heroku::API::Errors::NotFound.new(error.message)
|
52
|
+
reerror.set_backtrace(error.backtrace)
|
53
|
+
raise reerror
|
54
|
+
rescue Excon::Errors::Error => error
|
55
|
+
reerror = Heroku::API::Errors::Error.new(error.message)
|
56
|
+
reerror.set_backtrace(error.backtrace)
|
57
|
+
raise reerror
|
58
|
+
end
|
59
|
+
|
60
|
+
if response.body && !response.body.empty?
|
61
|
+
begin
|
62
|
+
response.body = Heroku::API::OkJson.decode(response.body)
|
63
|
+
rescue
|
64
|
+
# leave non-JSON body as is
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# reset (non-persistent) connection
|
69
|
+
@connection.reset
|
70
|
+
|
71
|
+
response
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def app_params(params)
|
77
|
+
app_params = {}
|
78
|
+
params.each do |key, value|
|
79
|
+
app_params["app[#{key}]"] = value
|
80
|
+
end
|
81
|
+
app_params
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Heroku
|
2
|
+
class API
|
3
|
+
|
4
|
+
# DELETE /apps/:app/addons/:addon
|
5
|
+
def delete_addon(app, addon)
|
6
|
+
request(
|
7
|
+
:expects => 200,
|
8
|
+
:method => :delete,
|
9
|
+
:path => "/apps/#{app}/addons/#{addon}"
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /addons
|
14
|
+
# GET /apps/:app/addons
|
15
|
+
def get_addons(app=nil)
|
16
|
+
path = if app
|
17
|
+
"/apps/#{app}/addons"
|
18
|
+
else
|
19
|
+
"/addons"
|
20
|
+
end
|
21
|
+
request(
|
22
|
+
:expects => 200,
|
23
|
+
:method => :get,
|
24
|
+
:path => path
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
# POST /apps/:app/addons/:addon
|
29
|
+
def post_addon(app, addon)
|
30
|
+
request(
|
31
|
+
:expects => 200,
|
32
|
+
:method => :post,
|
33
|
+
:path => "/apps/#{app}/addons/#{addon}"
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
# PUT /apps/:app/addons/:addon
|
38
|
+
def put_addon(app, addon)
|
39
|
+
request(
|
40
|
+
:expects => 200,
|
41
|
+
:method => :put,
|
42
|
+
:path => "/apps/#{app}/addons/#{addon}"
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Heroku
|
2
|
+
class API
|
3
|
+
|
4
|
+
# DELETE /apps/:app
|
5
|
+
def delete_app(app)
|
6
|
+
request(
|
7
|
+
:expects => 200,
|
8
|
+
:method => :delete,
|
9
|
+
:path => "/apps/#{app}"
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /apps
|
14
|
+
def get_apps
|
15
|
+
request(
|
16
|
+
:expects => 200,
|
17
|
+
:method => :get,
|
18
|
+
:path => "/apps"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
# GET /apps/:app
|
23
|
+
def get_app(app)
|
24
|
+
request(
|
25
|
+
:expects => 200,
|
26
|
+
:method => :get,
|
27
|
+
:path => "/apps/#{app}"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
# POST /apps
|
32
|
+
def post_app(params={})
|
33
|
+
request(
|
34
|
+
:expects => 202,
|
35
|
+
:method => :post,
|
36
|
+
:path => '/apps',
|
37
|
+
:query => app_params(params)
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
# POST /apps/:app/server/maintenance
|
42
|
+
def post_app_server_maintenance(app, new_server_maintenance)
|
43
|
+
request(
|
44
|
+
:expects => 200,
|
45
|
+
:method => :post,
|
46
|
+
:path => "/apps/#{app}/server/maintenance",
|
47
|
+
:query => {'maintenance_mode' => maintenance_mode}
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
# PUT /apps/:app
|
52
|
+
def put_app(app, params)
|
53
|
+
request(
|
54
|
+
:expects => 200,
|
55
|
+
:method => :put,
|
56
|
+
:path => "/apps/#{app}",
|
57
|
+
:query => app_params(params)
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Heroku
|
2
|
+
class API
|
3
|
+
|
4
|
+
# DELETE /apps/:app/collaborators/:email
|
5
|
+
def delete_collaborator(app, email)
|
6
|
+
request(
|
7
|
+
:expects => 200,
|
8
|
+
:method => :delete,
|
9
|
+
:path => "/apps/#{app}/collaborators/#{email}"
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /apps/:app/collaborators
|
14
|
+
def get_collaborators(app)
|
15
|
+
request(
|
16
|
+
:expects => 200,
|
17
|
+
:method => :get,
|
18
|
+
:path => "/apps/#{app}/collaborators"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
# POST /apps/:app/collaborators
|
23
|
+
def post_collaborator(app, email)
|
24
|
+
request(
|
25
|
+
:expects => 200,
|
26
|
+
:method => :post,
|
27
|
+
:path => "/apps/#{app}/collaborators",
|
28
|
+
:query => {'collaborator[email]' => email}
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Heroku
|
2
|
+
class API
|
3
|
+
|
4
|
+
# DELETE /apps/:app/config_vars/:key
|
5
|
+
def delete_config_var(app, key)
|
6
|
+
request(
|
7
|
+
:expects => 200,
|
8
|
+
:method => :delete,
|
9
|
+
:path => "/apps/#{app}/config_vars/#{key}"
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /apps/:app/config_vars
|
14
|
+
def get_config_vars(app)
|
15
|
+
request(
|
16
|
+
:expects => 200,
|
17
|
+
:method => :get,
|
18
|
+
:path => "/apps/#{app}/config_vars"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
# PUT /apps/:app/config_vars
|
23
|
+
def put_config_vars(app, vars)
|
24
|
+
request(
|
25
|
+
:body => Heroku::API::OkJson.encode(vars),
|
26
|
+
:expects => 200,
|
27
|
+
:method => :put,
|
28
|
+
:path => "/apps/#{app}/config_vars"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|