Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Rack API and Rails Engine for Heroku and Opperator add-ons

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 lib
Octocat-spinner-32 spec
Octocat-spinner-32 .gitignore
Octocat-spinner-32 .travis.yml
Octocat-spinner-32 Gemfile
Octocat-spinner-32 HISTORY
Octocat-spinner-32 LICENCE
Octocat-spinner-32 README.textile
Octocat-spinner-32 Rakefile
Octocat-spinner-32 addon-manifest.json
Octocat-spinner-32 config.ru
Octocat-spinner-32 maitre_d.gemspec
README.textile

Maître d’

Rack APIs powered by Grape for managing Heroku, CloudControl and Opperator add-ons.

Maître d’ manages all the authorisation checking for API requests and provides simple hooks for you to write just the code you need to handle provisioning, plan changes, deprovisioning and single-sign-on (SSO) requests.

Installing

Add the following to your Gemfile – and take note that we need the git repository reference for Grape, as it includes some needed commits that aren’t in the latest gem release.

gem 'grape',
  :git => 'git://github.com/intridea/grape.git',
  :ref => '212c96cdfb253a59bc93790808c568e559d04468'
gem 'maitre_d', '~> 0.4.0'

With Rails

Add the appropriate Rack apps to your routes file:

mount MaitreD::Broadstack::API   => '/broadstack'
mount MaitreD::Heroku::API       => '/heroku'
mount MaitreD::CloudControl::API => '/cloudcontrol'
mount MaitreD::Opperator::API    => '/opperator'

Without Rails

This library provides two APIs as mountable Rack applications for you – so you’ll want to mount them at the appropriate paths: MaitreD::Heroku::API at /heroku, MaitreD::CloudControl::API at /cloudcontrol, and/or MaitreD::Opperator::API at /opperator.

Configuration

You’ll need to provide Maître d’ with the appropriate provider credentials – in a Rails app, this would go in an initializer, but for Rack/Sinatra apps just get the values set before the routing is defined.

require 'maitre_d/heroku'

MaitreD::Heroku.configure do |config|
  config.id       = 'addon-id'
  config.password = 'random'
  config.sso_salt = 'gibberish'
  config.listener = HerokuListener
end

require 'maitre_d/cloud_control'

MaitreD::CloudControl.configure do |config|
  config.id       = 'addon-id'
  config.password = 'random'
  config.sso_salt = 'gibberish'
  config.listener = CloudControlListener
end

require 'maitre_d/opperator'

MaitreD::Opperator.configure do |config|
  config.shared_secret = 'something-special'
  config.listener      = OpperatorListener
end

The listeners that are mentioned in the code above are classes, which will handle valid API requests. Read on for more details on how to set them up.

Heroku Listener

Your Heroku listener class should handle the following four methods:

provision(heroku_id, plan, region, callback_url, logplex_token, options)

This gets called when Heroku’s requesting an app be provisioned within your service, and expects a hash to be returned with the following keys:

id
Your local resource id, which Heroku will use in related requests (to change plans, deprovision or initialise single-sign-on).
config
A hash of the newly provisioned resource’s configuration values (that are provided as environment variables to the app in question).
message
An optional message that will be displayed when your add-on is added via the command-line.

plan_change(resource_id, heroku_id, plan)

This gets called when an app is upgrading or downgrading from their current plan. You need to return a hash with the following keys:

config
A hash of the modified resource’s configuration values (that are provided as environment variables to the app in question).
message
An optional message that will be displayed when an app using your add-on is upgraded or downgraded via the command-line.

deprovision(resource_id)

This gets called when an app is removing your add-on from itself. You don’t have to return anything in particular for this, though Heroku may pass through the message argument like it does for the provision and plan_change calls.

single_sign_on(resource_id)

Maître d’ will check the token and timestamp provided, and sets up the nav-data cookie, but you’ll need to decide where the user gets redirected to and what other details you wish to track via their session. To do this, just return a hash with the following keys:

uri
The URI to redirect the user to, now that you’ve signed them in.
session
A hash of any session values you wish to be set.

Here’s a very basic example:

class HerokuListener
  def provision(heroku_id, plan, region, callback_url, logplex_token, options)
    plan   = Plan.find_by_name plan
    widget = Widget.create(
      :heroku_id    => heroku_id,
      :callback_url => callback_url,
      :plan         => plan,
      :region       => region
    )

    {
      :id      => widget.id,
      :config  => {'WIDGET_KEY' => widget.key},
      :message => 'Add-on provisioned!'
    }
  end

  def plan_change(resource_id, heroku_id, plan)
    plan   = Plan.find_by_name plan
    widget = Widget.find resource_id
    widget.plan = plan
    widget.save

    {:config => {'WIDGET_KEY' => widget.key}}
  end

  def deprovision(resource_id)
    widget = Widget.find resource_id
    widget.destroy
  end

  def single_sign_on(resource_id)
    widget = Widget.find resource_id

    {
      :uri     => '/my/dashboard',
      :session => {:widget_id => widget.id}
    }
  end
end

You can have the listener class wherever you like – as long as it’s available within the context of your Rails/Rack site, it’ll work as expected.

CloudControl Listener

CloudControl is pretty much the same as Heroku – it has the same expectations for a listener, so perhaps you can use the same class if you like. Anything that Heroku sends through as the heroku_id becomes cloudcontrol_id – but that’s just a matter of treating the given parameter appropriately.

Opperator Listener

This listener is currently in progress as the Opperator API is established.

Contributing

Contributions are very much welcome – but keep in mind the following:

  • Keep patches in a separate branch.
  • Write tests for your patches.
  • Don’t mess with the version or history file. I’ll take care of that when the patch is merged in.

Credits

Copyright © 2011-2014, Maître d’ is developed and maintained by Pat Allan, and is released under the open MIT Licence.

Something went wrong with that request. Please try again.