Class: Heroku::Client
- Inherits:
-
Object
- Object
- Heroku::Client
- Defined in:
- lib/heroku/client.rb
Overview
A Ruby class to call the Heroku REST API. You might use this if you want to manage your Heroku apps from within a Ruby program, such as Capistrano.
Example:
require 'heroku'
heroku = Heroku::Client.new('[email protected]', 'mypass')
heroku.create('myapp')
Defined Under Namespace
Classes: AppCrashed, ConsoleSession, Service
Instance Attribute Summary collapse
-
#host ⇒ Object
readonly
Returns the value of attribute host.
-
#password ⇒ Object
readonly
Returns the value of attribute password.
-
#user ⇒ Object
readonly
Returns the value of attribute user.
Class Method Summary collapse
Instance Method Summary collapse
-
#add_collaborator(app_name, email) ⇒ Object
Invite a person by email address to collaborate on the app.
- #add_config_vars(app_name, new_vars) ⇒ Object
- #add_domain(app_name, domain) ⇒ Object
-
#add_key(key) ⇒ Object
Add an ssh public key to the current user.
- #add_ssl(app_name, pem, key) ⇒ Object
- #addons ⇒ Object
-
#bounce(app_name, upid) ⇒ Object
Bounce a service.
-
#bundle_capture(app_name, bundle_name = nil) ⇒ Object
Capture a bundle from the given app, as a backup or for download.
- #bundle_destroy(app_name, bundle_name) ⇒ Object
- #bundle_download(app_name, fname, bundle_name = nil) ⇒ Object
-
#bundle_url(app_name, bundle_name = nil) ⇒ Object
Get a temporary URL where the bundle can be downloaded.
-
#bundles(app_name) ⇒ Object
Get a list of bundles of the app.
- #clear_config_vars(app_name) ⇒ Object
- #config_vars(app_name) ⇒ Object
- #confirm_billing ⇒ Object
-
#console(app_name, cmd = nil) ⇒ Object
Execute a one-off console command, or start a new console tty session if cmd is nil.
-
#create(name = nil, options = {}) ⇒ Object
Create a new app, with an optional name.
-
#cron_logs(app_name) ⇒ Object
Fetch recent cron logs from the app server.
- #database_reset(app_name) ⇒ Object
- #database_session(app_name) ⇒ Object
-
#delete(uri, extra_headers = {}) ⇒ Object
:nodoc:.
-
#destroy(name) ⇒ Object
Destroy the app permanently.
-
#down(app_name, upid) ⇒ Object
Bring a service down.
-
#escape(value) ⇒ Object
:nodoc:.
- #extract_warning(response) ⇒ Object
-
#get(uri, extra_headers = {}) ⇒ Object
:nodoc:.
-
#heroku_headers ⇒ Object
:nodoc:.
-
#info(name_or_domain) ⇒ Object
Show info such as mode, custom domain, and collaborators on an app.
-
#initialize(user, password, host = 'heroku.com') ⇒ Client
constructor
A new instance of Client.
- #install_addon(app_name, addon, config = {}) ⇒ Object
- #installed_addons(app_name) ⇒ Object
-
#keys ⇒ Object
Get the list of ssh public keys for the current user.
-
#list ⇒ Object
Show a list of apps which you are a collaborator on.
-
#list_collaborators(app_name) ⇒ Object
Get a list of collaborators on the app, returns an array of hashes each with :email.
- #list_domains(app_name) ⇒ Object
-
#logs(app_name) ⇒ Object
Fetch recent logs from the app server.
- #maintenance(app_name, mode) ⇒ Object
- #on_warning(&blk) ⇒ Object
-
#post(uri, payload = "", extra_headers = {}) ⇒ Object
:nodoc:.
- #process(method, uri, extra_headers = {}, payload = nil) ⇒ Object
-
#ps(app_name) ⇒ Object
Retreive ps list for the given app name.
-
#put(uri, payload, extra_headers = {}) ⇒ Object
:nodoc:.
-
#rake(app_name, cmd) ⇒ Object
Run a rake command on the Heroku app and return all output as a string.
-
#remove_all_keys ⇒ Object
Clear all keys on the current user.
-
#remove_collaborator(app_name, email) ⇒ Object
Remove a collaborator.
- #remove_config_var(app_name, key) ⇒ Object
- #remove_domain(app_name, domain) ⇒ Object
- #remove_domains(app_name) ⇒ Object
-
#remove_key(key) ⇒ Object
Remove an existing ssh public key from the current user.
- #remove_ssl(app_name, domain) ⇒ Object
- #resource(uri) ⇒ Object
-
#restart(app_name) ⇒ Object
Restart the app servers.
-
#run_console_command(url, command, prefix = nil) ⇒ Object
internal method to run console commands formatting the output.
-
#service(app_name, upid) ⇒ Object
Get a Service instance to execute commands against.
-
#set_dynos(app_name, qty) ⇒ Object
Scales the web processes.
-
#set_workers(app_name, qty) ⇒ Object
Scales the background processes.
-
#start(app_name, command, attached = false) ⇒ Object
Run a service.
- #uninstall_addon(app_name, addon) ⇒ Object
-
#up(app_name, upid) ⇒ Object
Bring a service up.
-
#update(name, attributes) ⇒ Object
Update an app.
-
#xml(raw) ⇒ Object
:nodoc:.
Constructor Details
#initialize(user, password, host = 'heroku.com') ⇒ Client
Returns a new instance of Client.
27 28 29 30 31 |
# File 'lib/heroku/client.rb', line 27 def initialize(user, password, host='heroku.com') @user = user @password = password @host = host end |
Instance Attribute Details
#host ⇒ Object (readonly)
Returns the value of attribute host.
25 26 27 |
# File 'lib/heroku/client.rb', line 25 def host @host end |
#password ⇒ Object (readonly)
Returns the value of attribute password.
25 26 27 |
# File 'lib/heroku/client.rb', line 25 def password @password end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
25 26 27 |
# File 'lib/heroku/client.rb', line 25 def user @user end |
Class Method Details
.gem_version_string ⇒ Object
21 22 23 |
# File 'lib/heroku/client.rb', line 21 def self.gem_version_string "heroku-gem/#{version}" end |
.version ⇒ Object
17 18 19 |
# File 'lib/heroku/client.rb', line 17 def self.version '1.6.3' end |
Instance Method Details
#add_collaborator(app_name, email) ⇒ Object
Invite a person by email address to collaborate on the app.
80 81 82 83 84 85 |
# File 'lib/heroku/client.rb', line 80 def add_collaborator(app_name, email) xml(post("/apps/#{app_name}/collaborators", { 'collaborator[email]' => email })) rescue RestClient::RequestFailed => e raise e unless e.http_code == 422 e.response.body end |
#add_config_vars(app_name, new_vars) ⇒ Object
375 376 377 |
# File 'lib/heroku/client.rb', line 375 def add_config_vars(app_name, new_vars) put("/apps/#{app_name}/config_vars", new_vars.to_json) end |
#add_domain(app_name, domain) ⇒ Object
107 108 109 |
# File 'lib/heroku/client.rb', line 107 def add_domain(app_name, domain) post("/apps/#{app_name}/domains", domain) end |
#add_key(key) ⇒ Object
Add an ssh public key to the current user.
136 137 138 |
# File 'lib/heroku/client.rb', line 136 def add_key(key) post("/user/keys", key, { 'Content-Type' => 'text/ssh-authkey' }) end |
#add_ssl(app_name, pem, key) ⇒ Object
119 120 121 |
# File 'lib/heroku/client.rb', line 119 def add_ssl(app_name, pem, key) JSON.parse(post("/apps/#{app_name}/ssl", :pem => pem, :key => key)) end |
#addons ⇒ Object
387 388 389 |
# File 'lib/heroku/client.rb', line 387 def addons JSON.parse get("/addons", :accept => 'application/json') end |
#bounce(app_name, upid) ⇒ Object
Bounce a service.
307 308 309 |
# File 'lib/heroku/client.rb', line 307 def bounce(app_name, upid) service(app_name, upid).bounce end |
#bundle_capture(app_name, bundle_name = nil) ⇒ Object
Capture a bundle from the given app, as a backup or for download.
338 339 340 |
# File 'lib/heroku/client.rb', line 338 def bundle_capture(app_name, bundle_name=nil) xml(post("/apps/#{app_name}/bundles", :bundle => { :name => bundle_name })).elements["//bundle/name"].text end |
#bundle_destroy(app_name, bundle_name) ⇒ Object
342 343 344 |
# File 'lib/heroku/client.rb', line 342 def bundle_destroy(app_name, bundle_name) delete("/apps/#{app_name}/bundles/#{bundle_name}") end |
#bundle_download(app_name, fname, bundle_name = nil) ⇒ Object
353 354 355 356 357 |
# File 'lib/heroku/client.rb', line 353 def bundle_download(app_name, fname, bundle_name=nil) warn "[DEPRECATION] `bundle_download` is deprecated. Please use `bundle_url` instead" data = RestClient.get(bundle_url(app_name, bundle_name)) File.open(fname, "wb") { |f| f.write data } end |
#bundle_url(app_name, bundle_name = nil) ⇒ Object
Get a temporary URL where the bundle can be downloaded. If bundle_name is nil it will use the most recently captured bundle for the app
348 349 350 351 |
# File 'lib/heroku/client.rb', line 348 def bundle_url(app_name, bundle_name=nil) bundle = JSON.parse(get("/apps/#{app_name}/bundles/#{bundle_name || 'latest'}", { :accept => 'application/json' })) bundle['temporary_url'] end |
#bundles(app_name) ⇒ Object
Get a list of bundles of the app.
360 361 362 363 364 365 366 367 368 369 |
# File 'lib/heroku/client.rb', line 360 def bundles(app_name) doc = xml(get("/apps/#{app_name}/bundles")) doc.elements.to_a("//bundles/bundle").map do |a| { :name => a.elements['name'].text, :state => a.elements['state'].text, :created_at => Time.parse(a.elements['created-at'].text), } end end |
#clear_config_vars(app_name) ⇒ Object
383 384 385 |
# File 'lib/heroku/client.rb', line 383 def clear_config_vars(app_name) delete("/apps/#{app_name}/config_vars") end |
#config_vars(app_name) ⇒ Object
371 372 373 |
# File 'lib/heroku/client.rb', line 371 def config_vars(app_name) JSON.parse get("/apps/#{app_name}/config_vars") end |
#confirm_billing ⇒ Object
403 404 405 |
# File 'lib/heroku/client.rb', line 403 def confirm_billing post("/user/#{escape(@user)}/confirm_billing") end |
#console(app_name, cmd = nil) ⇒ Object
Execute a one-off console command, or start a new console tty session if cmd is nil.
170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/heroku/client.rb', line 170 def console(app_name, cmd=nil) if block_given? id = post("/apps/#{app_name}/consoles") yield ConsoleSession.new(id, app_name, self) delete("/apps/#{app_name}/consoles/#{id}") else run_console_command("/apps/#{app_name}/console", cmd) end rescue RestClient::RequestFailed => e raise(AppCrashed, e.response.body) if e.response.code.to_i == 502 raise e end |
#create(name = nil, options = {}) ⇒ Object
Create a new app, with an optional name.
55 56 57 58 |
# File 'lib/heroku/client.rb', line 55 def create(name=nil, ={}) [:name] = name if name xml(post('/apps', :app => )).elements["//app/name"].text end |
#cron_logs(app_name) ⇒ Object
Fetch recent cron logs from the app server.
323 324 325 |
# File 'lib/heroku/client.rb', line 323 def cron_logs(app_name) get("/apps/#{app_name}/cron_logs") end |
#database_reset(app_name) ⇒ Object
479 480 481 |
# File 'lib/heroku/client.rb', line 479 def database_reset(app_name) post("/apps/#{app_name}/database/reset", '') end |
#database_session(app_name) ⇒ Object
475 476 477 |
# File 'lib/heroku/client.rb', line 475 def database_session(app_name) post("/apps/#{app_name}/database/session", '') end |
#delete(uri, extra_headers = {}) ⇒ Object
:nodoc:
434 435 436 |
# File 'lib/heroku/client.rb', line 434 def delete(uri, extra_headers={}) # :nodoc: process(:delete, uri, extra_headers) end |
#destroy(name) ⇒ Object
Destroy the app permanently.
67 68 69 |
# File 'lib/heroku/client.rb', line 67 def destroy(name) delete("/apps/#{name}") end |
#down(app_name, upid) ⇒ Object
Bring a service down.
302 303 304 |
# File 'lib/heroku/client.rb', line 302 def down(app_name, upid) service(app_name, upid).down end |
#escape(value) ⇒ Object
:nodoc:
470 471 472 473 |
# File 'lib/heroku/client.rb', line 470 def escape(value) # :nodoc: escaped = URI.escape(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) escaped.gsub('.', '%2E') # not covered by the previous URI.escape end |
#extract_warning(response) ⇒ Object
447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/heroku/client.rb', line 447 def extract_warning(response) return unless response if response.headers[:x_heroku_warning] && @warning_callback warning = response.headers[:x_heroku_warning] @displayed_warnings ||= {} unless @displayed_warnings[warning] @warning_callback.call(warning) @displayed_warnings[warning] = true end end end |
#get(uri, extra_headers = {}) ⇒ Object
:nodoc:
422 423 424 |
# File 'lib/heroku/client.rb', line 422 def get(uri, extra_headers={}) # :nodoc: process(:get, uri, extra_headers) end |
#heroku_headers ⇒ Object
:nodoc:
459 460 461 462 463 464 |
# File 'lib/heroku/client.rb', line 459 def heroku_headers # :nodoc: { 'X-Heroku-API-Version' => '2', 'User-Agent' => self.class.gem_version_string, } end |
#info(name_or_domain) ⇒ Object
Show info such as mode, custom domain, and collaborators on an app.
44 45 46 47 48 49 50 51 52 |
# File 'lib/heroku/client.rb', line 44 def info(name_or_domain) name_or_domain = name_or_domain.gsub(/^(http:\/\/)?(www\.)?/, '') doc = xml(get("/apps/#{name_or_domain}")) attrs = doc.elements.to_a('//app/*').inject({}) do |hash, element| hash[element.name.gsub(/-/, '_').to_sym] = element.text; hash end attrs.merge!(:collaborators => list_collaborators(attrs[:name])) attrs.merge!(:addons => installed_addons(attrs[:name])) end |
#install_addon(app_name, addon, config = {}) ⇒ Object
395 396 397 |
# File 'lib/heroku/client.rb', line 395 def install_addon(app_name, addon, config={}) post("/apps/#{app_name}/addons/#{escape(addon)}", { :config => config }, :accept => 'application/json') end |
#installed_addons(app_name) ⇒ Object
391 392 393 |
# File 'lib/heroku/client.rb', line 391 def installed_addons(app_name) JSON.parse get("/apps/#{app_name}/addons", :accept => 'application/json') end |
#keys ⇒ Object
Get the list of ssh public keys for the current user.
128 129 130 131 132 133 |
# File 'lib/heroku/client.rb', line 128 def keys doc = xml get('/user/keys') doc.elements.to_a('//keys/key').map do |key| key.elements['contents'].text end end |
#list ⇒ Object
Show a list of apps which you are a collaborator on.
34 35 36 37 38 39 40 41 |
# File 'lib/heroku/client.rb', line 34 def list doc = xml(get('/apps')) doc.elements.to_a("//apps/app").map do |a| name = a.elements.to_a("name").first owner = a.elements.to_a("owner").first [name.text, owner.text] end end |
#list_collaborators(app_name) ⇒ Object
Get a list of collaborators on the app, returns an array of hashes each with :email
72 73 74 75 76 77 |
# File 'lib/heroku/client.rb', line 72 def list_collaborators(app_name) doc = xml(get("/apps/#{app_name}/collaborators")) doc.elements.to_a("//collaborators/collaborator").map do |a| { :email => a.elements['email'].text } end end |
#list_domains(app_name) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/heroku/client.rb', line 92 def list_domains(app_name) doc = xml(get("/apps/#{app_name}/domains")) doc.elements.to_a("//domain-names/*").map do |d| attrs = { :domain => d.elements['domain'].text } if cert = d.elements['cert'] attrs[:cert] = { :expires_at => Time.parse(cert.elements['expires-at'].text), :subject => cert.elements['subject'].text, :issuer => cert.elements['issuer'].text, } end attrs end end |
#logs(app_name) ⇒ Object
Fetch recent logs from the app server.
318 319 320 |
# File 'lib/heroku/client.rb', line 318 def logs(app_name) get("/apps/#{app_name}/logs") end |
#maintenance(app_name, mode) ⇒ Object
483 484 485 486 |
# File 'lib/heroku/client.rb', line 483 def maintenance(app_name, mode) mode = mode == :on ? '1' : '0' post("/apps/#{app_name}/server/maintenance", :maintenance_mode => mode) end |
#on_warning(&blk) ⇒ Object
407 408 409 |
# File 'lib/heroku/client.rb', line 407 def on_warning(&blk) @warning_callback = blk end |
#post(uri, payload = "", extra_headers = {}) ⇒ Object
:nodoc:
426 427 428 |
# File 'lib/heroku/client.rb', line 426 def post(uri, payload="", extra_headers={}) # :nodoc: process(:post, uri, extra_headers, payload) end |
#process(method, uri, extra_headers = {}, payload = nil) ⇒ Object
438 439 440 441 442 443 444 445 |
# File 'lib/heroku/client.rb', line 438 def process(method, uri, extra_headers={}, payload=nil) headers = heroku_headers.merge(extra_headers) args = [method, payload, headers].compact response = resource(uri).send(*args) extract_warning(response) response end |
#ps(app_name) ⇒ Object
Retreive ps list for the given app name.
281 282 283 |
# File 'lib/heroku/client.rb', line 281 def ps(app_name) JSON.parse resource("/apps/#{app_name}/ps").get(:accept => 'application/json') end |
#put(uri, payload, extra_headers = {}) ⇒ Object
:nodoc:
430 431 432 |
# File 'lib/heroku/client.rb', line 430 def put(uri, payload, extra_headers={}) # :nodoc: process(:put, uri, extra_headers, payload) end |
#rake(app_name, cmd) ⇒ Object
Run a rake command on the Heroku app and return all output as a string.
154 155 156 |
# File 'lib/heroku/client.rb', line 154 def rake(app_name, cmd) start(app_name, "rake #{cmd}", attached=true).to_s end |
#remove_all_keys ⇒ Object
Clear all keys on the current user.
146 147 148 |
# File 'lib/heroku/client.rb', line 146 def remove_all_keys delete("/user/keys") end |
#remove_collaborator(app_name, email) ⇒ Object
Remove a collaborator.
88 89 90 |
# File 'lib/heroku/client.rb', line 88 def remove_collaborator(app_name, email) delete("/apps/#{app_name}/collaborators/#{escape(email)}") end |
#remove_config_var(app_name, key) ⇒ Object
379 380 381 |
# File 'lib/heroku/client.rb', line 379 def remove_config_var(app_name, key) delete("/apps/#{app_name}/config_vars/#{key}") end |
#remove_domain(app_name, domain) ⇒ Object
111 112 113 |
# File 'lib/heroku/client.rb', line 111 def remove_domain(app_name, domain) delete("/apps/#{app_name}/domains/#{domain}") end |
#remove_domains(app_name) ⇒ Object
115 116 117 |
# File 'lib/heroku/client.rb', line 115 def remove_domains(app_name) delete("/apps/#{app_name}/domains") end |
#remove_key(key) ⇒ Object
Remove an existing ssh public key from the current user.
141 142 143 |
# File 'lib/heroku/client.rb', line 141 def remove_key(key) delete("/user/keys/#{escape(key)}") end |
#remove_ssl(app_name, domain) ⇒ Object
123 124 125 |
# File 'lib/heroku/client.rb', line 123 def remove_ssl(app_name, domain) delete("/apps/#{app_name}/domains/#{domain}/ssl") end |
#resource(uri) ⇒ Object
413 414 415 416 417 418 419 420 |
# File 'lib/heroku/client.rb', line 413 def resource(uri) RestClient.proxy = ENV['HTTP_PROXY'] if uri =~ /^https?/ RestClient::Resource.new(uri, user, password) else RestClient::Resource.new("https://api.#{host}", user, password)[uri] end end |
#restart(app_name) ⇒ Object
Restart the app servers.
313 314 315 |
# File 'lib/heroku/client.rb', line 313 def restart(app_name) delete("/apps/#{app_name}/server") end |
#run_console_command(url, command, prefix = nil) ⇒ Object
internal method to run console commands formatting the output
184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/heroku/client.rb', line 184 def run_console_command(url, command, prefix=nil) output = post(url, command) return output unless prefix if output.include?("\n") lines = output.split("\n") (lines[0..-2] << "#{prefix}#{lines.last}").join("\n") else prefix + output end rescue RestClient::RequestFailed => e raise e unless e.http_code == 422 e.http_body end |
#service(app_name, upid) ⇒ Object
Get a Service instance to execute commands against.
292 293 294 |
# File 'lib/heroku/client.rb', line 292 def service(app_name, upid) Service.new(self, app_name, upid) end |
#set_dynos(app_name, qty) ⇒ Object
Scales the web processes.
328 329 330 |
# File 'lib/heroku/client.rb', line 328 def set_dynos(app_name, qty) put("/apps/#{app_name}/dynos", :dynos => qty).to_i end |
#set_workers(app_name, qty) ⇒ Object
Scales the background processes.
333 334 335 |
# File 'lib/heroku/client.rb', line 333 def set_workers(app_name, qty) put("/apps/#{app_name}/workers", :workers => qty).to_i end |
#start(app_name, command, attached = false) ⇒ Object
Run a service. If Responds to #each and yields output as it’s received.
286 287 288 289 |
# File 'lib/heroku/client.rb', line 286 def start(app_name, command, attached=false) service = Service.new(self, app_name) service.start(command, attached) end |
#uninstall_addon(app_name, addon) ⇒ Object
399 400 401 |
# File 'lib/heroku/client.rb', line 399 def uninstall_addon(app_name, addon) delete("/apps/#{app_name}/addons/#{escape(addon)}", :accept => 'application/json') end |
#up(app_name, upid) ⇒ Object
Bring a service up.
297 298 299 |
# File 'lib/heroku/client.rb', line 297 def up(app_name, upid) service(app_name, upid).up end |
#update(name, attributes) ⇒ Object
Update an app. Available attributes:
:name => rename the app (changes http and git urls)
62 63 64 |
# File 'lib/heroku/client.rb', line 62 def update(name, attributes) put("/apps/#{name}", :app => attributes) end |
#xml(raw) ⇒ Object
:nodoc:
466 467 468 |
# File 'lib/heroku/client.rb', line 466 def xml(raw) # :nodoc: REXML::Document.new(raw) end |