manageheroku 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8b8aa0c4756084dbb1374e23ec4063f00b0a65ef
4
- data.tar.gz: 7d3ab4230196e8043445cf19f45b450047bc8b1c
3
+ metadata.gz: a2b7e0c6e489cca7b8565cae44c9a3c3149d2a9d
4
+ data.tar.gz: f2cd5ab4739b3854ff62b4a30b7bbb503a4b10fe
5
5
  SHA512:
6
- metadata.gz: 87198db67ae89278903ee28c35bb6401ed340ab8c67b8c47b28568c46967ec384656243375d7fb34496a5b3896872fcc2a2ee3fe6d60b884093f00dc65a32eb9
7
- data.tar.gz: 02557908e8f65e50a73433ad64f654efb6a8b3441c5d7a63ae254cef2e159d6c6b4b1d90396e059a90f706a309390b932f7eccb3809ad2e291fd4273858fe1d8
6
+ metadata.gz: 283d3963c2f5244d3c567d8c5cc24048a8125996dcfcd60f6e34bb97fa8e25d6366b47ceb68058edd9619182a2632026744fef7b47fc7c610ba04d6108a9f363
7
+ data.tar.gz: 4473152d94246b52b250d23185f5af453f720bab81f8f340e5507a8e6f0bb88860722149ff2eb493932750afe3c932b87fdec76bb4c05d0cd4e9ba620c46803d
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Manageheroku
2
2
 
3
- Manage Heroku App Formations
3
+ Manage Heroku App Formations and Apps with YML config files. Allows you to version control important application attributes, and manage configuration for different environments and scenarios.
4
4
 
5
5
  ## Installation
6
6
 
@@ -18,7 +18,56 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- TODO: Write usage instructions here
21
+ Typical usage is to automate scaling any number of services through config files. For example:
22
+
23
+ oauth-token: <%= ENV["HEROKU_OAUTH_TOKEN"] %>
24
+ apps:
25
+ - name: "commerce-app-staging"
26
+ maintenance: false
27
+ - name: "pricing-service-staging"
28
+ maintenance: false
29
+ - name: "messaging-service-staging"
30
+ maintenance: false
31
+ formations:
32
+ - name: "commerce-app-staging"
33
+ procs:
34
+ - process: "web"
35
+ quantity: 4
36
+ size: "standard-2X"
37
+ - process: "resque"
38
+ quantity: 1
39
+ - name: "pricing-service-staging"
40
+ procs:
41
+ - process: "web"
42
+ quantity: 2
43
+ - process: "resque"
44
+ quantity: 1
45
+ - name: "messaging-service-staging"
46
+ procs:
47
+ - process: "web"
48
+ quantity: 2
49
+ - process: "resque"
50
+ quantity: 1
51
+
52
+ This config file is for an imaginary ecommerce application that is composed of a website, a pricing service and a messaging service. Using manageheroku allows you to apply this configuration to the dyno formation of each application listed in the config file. For example:
53
+
54
+ config_file = File.join(Rails.root, 'script', 'config', "black_friday_conf.yml")
55
+ heroku = Manageheroku::Heroku.new(config_file)
56
+ heroku.update!
57
+
58
+ Your application can programmatically run code like that to scale your applications based on a schedule or whatever your needs are. Currently your dyno formation sizes and quantities are the only things updatable. You can find a list of dyno types in heroku docs https://devcenter.heroku.com/articles/dyno-types
59
+
60
+ ### Apps
61
+
62
+ The apps section of the config file allows you to configure attributes of a list of apps. Configurable attributes are maintenance mode and build stack. See https://devcenter.heroku.com/articles/platform-api-reference#app-update
63
+
64
+ ### Formations
65
+
66
+ The formations section of the config file allows you to configure dyno formations for a list of apps. See https://devcenter.heroku.com/articles/platform-api-reference#formation-batch-update for details.
67
+
68
+ ### Real World Usage
69
+
70
+ We have manageheroku config files for shutting down and starting up all of our internal environments: development, staging and performance. Then with cron (or resque scheduler) all these environments shut down at 8pm and start back up at 8am, so we're not paying for loads of resources that aren't being used. We also use manageheroku config files for storing various interesting configurations of the application for our performance testing environments.
22
71
 
23
72
  ## Contributing
24
73
 
@@ -0,0 +1,14 @@
1
+ module Manageheroku
2
+ class App
3
+ attr_reader :name
4
+ def initialize(name, attributes)
5
+ @name = name
6
+ @attributes = attributes
7
+ end
8
+
9
+ def update_params
10
+ [@name, @attributes]
11
+ end
12
+
13
+ end
14
+ end
@@ -15,5 +15,10 @@ module Manageheroku
15
15
  formation_objects = @conf_data["formations"]
16
16
  formation_objects.map{|formation_object| Manageheroku::Formation.new(formation_object["name"], formation_object["procs"]) }
17
17
  end
18
+
19
+ def apps
20
+ app_objects = @conf_data["apps"]
21
+ app_objects.map{|app_object| Manageheroku::App.new(app_object["name"], app_object)}
22
+ end
18
23
  end
19
24
  end
@@ -2,42 +2,74 @@ module Manageheroku
2
2
  class Heroku
3
3
 
4
4
  attr_reader :errors
5
+ attr_accessor :verbose
6
+
5
7
  def initialize(conf_file, api_object=nil)
6
8
  @conf = Manageheroku::Conf.new(conf_file)
7
9
  @formations = @conf.formations
10
+ @apps = @conf.apps
8
11
  @heroku = api_object || PlatformAPI.connect_oauth(@conf.oauth_token)
9
12
  @errors = []
13
+ @verbose = false
10
14
  end
11
15
 
12
16
  def update!
17
+ update_apps!
18
+ update_formations!
19
+ end
20
+
21
+ private
22
+
23
+ def update_apps!
24
+ @apps.each do |app|
25
+ begin
26
+ response = @heroku.app.update(*app.update_params)
27
+ log_info("Updating App #{app.name}:", response) if @verbose
28
+ rescue StandardError => e
29
+ log_errors e
30
+ raise e
31
+ end
32
+ end
33
+ end
34
+
35
+ def update_formations!
13
36
  @formations.each do |formation|
14
37
  begin
15
- @heroku.formation.batch_update(*formation.update_params)
38
+ response = @heroku.formation.batch_update(*formation.update_params)
39
+ log_info("Updating Formation for #{formation.name}:", response) if @verbose
16
40
  rescue StandardError => e
17
- if e.respond_to?(:response)
18
- # errors with a response have good information that you miss in stacktrace form
19
- status = e.response.status
20
- status_line = e.response.status_line
21
- response_body_id = nil
22
- response_body_message = nil
23
- begin
24
- body_hash = JSON.parse(e.response.body)
25
- response_body_id = body_hash["id"]
26
- response_body_message = body_hash["message"]
27
- rescue
28
- response_body_message = e.response.body
29
- end
30
- error_string = <<-OUTPUT
31
- Status: #{[status, status_line].join(";")}
32
- Body: #{[response_body_id, response_body_message].join(";")}
33
- OUTPUT
34
- @errors << error_string
35
- puts error_string #Heroku logs stdout
36
- end
41
+ log_errors e
37
42
  raise e
38
43
  end
39
44
  end
40
45
  end
41
46
 
47
+ def log_info(*log_lines)
48
+ log_lines.each{ |line| puts line }
49
+ end
50
+
51
+ def log_errors(e)
52
+ if e.respond_to?(:response)
53
+ # errors with a response have good information that you miss in stacktrace form
54
+ status = e.response.status
55
+ status_line = e.response.status_line
56
+ response_body_id = nil
57
+ response_body_message = nil
58
+ begin
59
+ body_hash = JSON.parse(e.response.body)
60
+ response_body_id = body_hash["id"]
61
+ response_body_message = body_hash["message"]
62
+ rescue
63
+ response_body_message = e.response.body
64
+ end
65
+ error_string = <<-OUTPUT
66
+ Status: #{[status, status_line].join(";")}
67
+ Body: #{[response_body_id, response_body_message].join(";")}
68
+ OUTPUT
69
+ @errors << error_string
70
+ puts error_string #Heroku logs stdout
71
+ end
72
+ end
73
+
42
74
  end
43
75
  end
@@ -1,3 +1,3 @@
1
1
  module Manageheroku
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/manageheroku.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'platform-api'
2
2
  require "manageheroku/version"
3
+ require "manageheroku/app"
3
4
  require "manageheroku/formation"
4
5
  require "manageheroku/conf"
5
6
  require "manageheroku/heroku"
data/test/conf_test.rb CHANGED
@@ -13,6 +13,12 @@ class ConfTest < MiniTest::Test
13
13
  conf.formations.last.name.must_equal "myapp-performance"
14
14
  end
15
15
 
16
+ it "must update all the apps" do
17
+ conf = Manageheroku::Conf.new(File.join(File.dirname(__FILE__), 'sample_conf.yml'))
18
+ conf.apps.first.name.must_equal "myapp-development"
19
+ conf.apps.last.name.must_equal "myapp-staging"
20
+ end
21
+
16
22
  it "supports ERB magic in the config file" do
17
23
  ENV["TEST_VAL"] = "erb_is_great"
18
24
  conf = Manageheroku::Conf.new(File.join(File.dirname(__FILE__), 'sample_conf.yml'))
data/test/heroku_test.rb CHANGED
@@ -3,8 +3,9 @@ require File.join(File.dirname(__FILE__), 'test_helper')
3
3
  class HerokuTest < MiniTest::Test
4
4
  describe "heroku" do
5
5
  # it "really works" do
6
- # conf_file_path = File.join(File.dirname(__FILE__), 'analysis_conf.yml')
6
+ # conf_file_path = File.join(File.dirname(__FILE__), 'shutdown_development_conf.yml')
7
7
  # heroku = Manageheroku::Heroku.new(conf_file_path)
8
+ # heroku.verbose = true
8
9
  # heroku.update!
9
10
  # end
10
11
  #
@@ -34,6 +35,10 @@ class HerokuTest < MiniTest::Test
34
35
  FormationStub.new
35
36
  end
36
37
 
38
+ def app
39
+ AppStub.new
40
+ end
41
+
37
42
  class FormationStub
38
43
  def batch_update(*params)
39
44
  response_params = {body: {"id"=>"Invalid params", "message"=>"Cannot update the same process twice"}.to_json,
@@ -42,6 +47,11 @@ class HerokuTest < MiniTest::Test
42
47
  raise Excon::Errors::UnprocessableEntity.new("Oh ye gods!", nil, Excon::Response.new(response_params))
43
48
  end
44
49
  end
50
+
51
+ class AppStub
52
+ def update(*params)
53
+ end
54
+ end
45
55
  end
46
56
 
47
57
  class ApiStubDegenerateCase
@@ -49,12 +59,21 @@ class HerokuTest < MiniTest::Test
49
59
  FormationStub.new
50
60
  end
51
61
 
62
+ def app
63
+ AppStub.new
64
+ end
65
+
52
66
  class FormationStub
53
67
  def batch_update(*params)
54
68
  response_params = { status: "503" }
55
69
  raise Excon::Errors::ServiceUnavailable.new("Et tu Heroku?", nil, Excon::Response.new(response_params))
56
70
  end
57
71
  end
72
+
73
+ class AppStub
74
+ def update(*params)
75
+ end
76
+ end
58
77
  end
59
78
 
60
79
  end
data/test/sample_conf.yml CHANGED
@@ -1,4 +1,11 @@
1
1
  oauth-token: <%= ENV["TEST_VAL"] || "the-magic-oauth-token" %>
2
+
3
+ apps:
4
+ - name: "myapp-development"
5
+ maintenance: true
6
+ - name: "myapp-staging"
7
+ maintenance: true
8
+
2
9
  formations:
3
10
  - name: "myapp-development"
4
11
  procs:
@@ -16,5 +23,6 @@ formations:
16
23
  procs:
17
24
  - process: "web"
18
25
  quantity: 0
26
+ size: "2X"
19
27
  - process: "resque-low"
20
28
  quantity: 0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manageheroku
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Cronemeyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-09 00:00:00.000000000 Z
11
+ date: 2016-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: platform-api
@@ -65,6 +65,7 @@ files:
65
65
  - README.md
66
66
  - Rakefile
67
67
  - lib/manageheroku.rb
68
+ - lib/manageheroku/app.rb
68
69
  - lib/manageheroku/conf.rb
69
70
  - lib/manageheroku/formation.rb
70
71
  - lib/manageheroku/heroku.rb
@@ -94,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
95
  version: '0'
95
96
  requirements: []
96
97
  rubyforge_project:
97
- rubygems_version: 2.2.2
98
+ rubygems_version: 2.5.1
98
99
  signing_key:
99
100
  specification_version: 4
100
101
  summary: Manage Heroku Apps from config files