heroku-api 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +4 -0
  2. data/.travis.yml +14 -0
  3. data/Gemfile +4 -0
  4. data/README.md +120 -0
  5. data/Rakefile +23 -0
  6. data/changelog.txt +4 -0
  7. data/heroku-api.gemspec +23 -0
  8. data/lib/heroku-api.rb +1 -0
  9. data/lib/heroku/api.rb +85 -0
  10. data/lib/heroku/api/addons.rb +47 -0
  11. data/lib/heroku/api/apps.rb +62 -0
  12. data/lib/heroku/api/collaborators.rb +33 -0
  13. data/lib/heroku/api/config_vars.rb +33 -0
  14. data/lib/heroku/api/domains.rb +33 -0
  15. data/lib/heroku/api/errors.rb +9 -0
  16. data/lib/heroku/api/keys.rb +42 -0
  17. data/lib/heroku/api/logs.rb +18 -0
  18. data/lib/heroku/api/mock.rb +176 -0
  19. data/lib/heroku/api/mock/addons.rb +153 -0
  20. data/lib/heroku/api/mock/apps.rb +184 -0
  21. data/lib/heroku/api/mock/cache/get_addons.json +1 -0
  22. data/lib/heroku/api/mock/collaborators.rb +55 -0
  23. data/lib/heroku/api/mock/config_vars.rb +46 -0
  24. data/lib/heroku/api/mock/domains.rb +71 -0
  25. data/lib/heroku/api/mock/keys.rb +46 -0
  26. data/lib/heroku/api/mock/logs.rb +20 -0
  27. data/lib/heroku/api/mock/processes.rb +191 -0
  28. data/lib/heroku/api/mock/releases.rb +124 -0
  29. data/lib/heroku/api/mock/stacks.rb +84 -0
  30. data/lib/heroku/api/processes.rb +77 -0
  31. data/lib/heroku/api/releases.rb +33 -0
  32. data/lib/heroku/api/stacks.rb +22 -0
  33. data/lib/heroku/api/vendor/okjson.rb +559 -0
  34. data/lib/heroku/api/version.rb +5 -0
  35. data/test/test_addons.rb +169 -0
  36. data/test/test_apps.rb +119 -0
  37. data/test/test_collaborators.rb +73 -0
  38. data/test/test_config_vars.rb +54 -0
  39. data/test/test_domains.rb +63 -0
  40. data/test/test_helper.rb +35 -0
  41. data/test/test_keys.rb +39 -0
  42. data/test/test_logs.rb +20 -0
  43. data/test/test_processes.rb +245 -0
  44. data/test/test_releases.rb +91 -0
  45. data/test/test_stacks.rb +49 -0
  46. metadata +134 -0
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ script: bundle exec rake
2
+
3
+ rvm:
4
+ - 1.8.7
5
+ - 1.9.2
6
+ - 1.9.3
7
+
8
+ notifications:
9
+ email: false
10
+ webhooks:
11
+ on_success: always
12
+ on_failure: always
13
+ urls:
14
+ - http://dx-helper.herokuapp.com/travis
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in heroku-rb.gemspec
4
+ gemspec
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
+ [![Build Status](https://secure.travis-ci.org/heroku/heroku.rb.png)](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
@@ -0,0 +1,4 @@
1
+ 0.1.0 02/02/2012
2
+ ================
3
+
4
+ Initial release
@@ -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