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.
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