Fork me on GitHub

An elegantly designed OpenStack SDK for Ruby

require 'aviator'

openstack =
              :config_file => 'path/to/aviator.yml',
              :environment => :production,
              :log_file    => 'path/to/aviator.log'


keystone = openstack.identity_service
response = keystone.request(:list_tenants)
puts response.body

Configure for multiple environments

The config file is a simple YAML file that can have one or more environment definitions.

  provider: openstack
    name: identity
    host_uri: ''
    request: create_token
    validator: list_tenants
    api_version: v2
    token_id: 2c963f5512d067b24fdc312707c80c7a6d3d261b
    tenant_name: admin

  provider: openstack
    name: identity
    host_uri: 'http://devstack:5000/v2.0'
    request: create_token
    validator: list_tenants
    username: myusername
    password: mypassword
    tenant_name: myproject

The auth_credentials in the config file are optional.

Supply credentials at runtime

You can provide the auth_credentials during authentication:

openstack.authenticate do |params|
  params.username    = 'myusername'
  params.password    = 'mypassword'
  params.tenant_name = 'mytenant'

Configure with an in-memory hash

Configuration files not your thing? Give it a hash object instead.

require 'aviator'

configuration = {
  :provider => 'openstack',
  :auth_service => {
    :name      => 'identity',
    :host_uri  => 'http://devstack:5000/v2.0',
    :request   => 'create_token',
    :validator => 'list_tenants'
  :auth_credentials => {
    :username    => 'myusername',
    :password    => 'mypassword',
    :tenant_name => 'myproject'

openstack =
              :config   =>  configuration,
              :log_file => 'path/to/aviator.log'


keystone = openstack.identity_service
response = keystone.request(:list_tenants)
puts response.body

Use the Service Token Directly

Do you want to use Aviator for seeding OpenStack? No problem! Use the service token directly in your requests. No authentication needed.

require 'aviator'

configuration = {
  :provider => 'openstack'

openstack =
              :config   =>  configuration,
              :log_file => 'path/to/aviator.log'

keystone = openstack.identity_service

session_data = {
  :base_url      => '',
  :service_token => 'service-token-created-at-openstack-install-time'

response = keystone.request(:create_tenant, :api_version => :v2, :session_data => session_data) do |params|        = 'Tenant A'
  params.description = 'First Tenant!'
  params.enabled     = true

puts response.status

Note how we're also providing a :base_url in our session_data variable above. This is necessary since we normally get the service endpoints from Keystone when we authenticate. Since we are not authenticating against Keystone, then we don't have that catalogue to begin with. Thus the need to hardcode it in the request.

Browse the available requests

Aviator comes with a handy dandy command line interface called describe that allows you to inspect the available requests in the library:

$ aviator describe openstack
Available services for openstack:

$ aviator describe openstack compute
Available requests for openstack compute_service:
  v2 admin confirm_server_resize
  v2 admin get_host_details
  v2 admin list_hosts
  v2 admin resize_server
  v2 admin revert_server_resize
  v2 public change_admin_password
  v2 public create_image
  v2 public create_server

$ aviator describe openstack compute v2 public create_server
Request: create_server

 | NAME        | REQUIRED | ALIAS       |
 | accessIPv4  |    N     | access_ipv4 |
 | accessIPv6  |    N     | access_ipv6 |
 | adminPass   |    N     | admin_pass  |
 | flavorRef   |    Y     | flavor_ref  |
 | imageRef    |    Y     | image_ref   |
 | metadata    |    N     |             |
 | name        |    Y     |             |
 | networks    |    N     |             |
 | personality |    N     |             |

Sample Code:
  session.compute_service.request(:create_server) do |params|
    params.access_ipv4 = value
    params.access_ipv6 = value
    params.admin_pass = value
    params.metadata = value
    params.networks = value
    params.personality = value
    params.image_ref = value
    params.flavor_ref = value = value


TIP: On OS X, command click on the link to open it in a browser.

...Or Read the Code Directly

We designed a DSL for the request definition files so that they are easy to read, easy to add to, and pretty much be self documenting (in fact, the same code is used by the describe CLI tool). For instance, here is the actual code for the create_server request:

module Aviator

  define_request :create_server, :inherit => [:openstack, :common, :v2, :public, :base] do

    meta :service, :compute

    link 'documentation',

    param :accessIPv4,  :required => false, :alias => :access_ipv4
    param :accessIPv6,  :required => false, :alias => :access_ipv6
    param :adminPass,   :required => false, :alias => :admin_pass
    param :imageRef,    :required => true,  :alias => :image_ref
    param :flavorRef,   :required => true,  :alias => :flavor_ref
    param :metadata,    :required => false
    param :name,        :required => true
    param :networks,    :required => false
    param :personality, :required => false

    def body
      p = {
        :server => {
          :flavorRef => params[:flavorRef],
          :imageRef  => params[:imageRef],
          :name      => params[:name]

      [:adminPass, :metadata, :personality, :networks, :accessIPv4, :accessIPv6].each do |key|
        p[:server][key] = params[key] if params[key]


    def headers

    def http_method

    def url
      "#{ base_url }/servers"



Browse the rest of the request files here.

Session Management API

Serialize the session information for caching. The output is in plaintext JSON which contains sensitive information. You are responsible for securing that.

session = ... )
str = session.dump

Creating a new Session object from a session dump is just as easy.

session = Aviator::Session.load(str)

This DOES NOT create a new token in the backend. If you employed any form of encryption on the string, make sure to decrypt it first!

Depending on how old the loaded session dump is, its session data may already be expired. Check if it's still current by calling Session#validate and reauthenticate as needed.

session.authenticate unless session.validate

IMPORTANT: The validator must be defined in the config file and it must refer to the name of a request that is known to Aviator (list_tenants usually will do). See the configuration example above.

If you want the newly deserialized session to log its output, make sure to indicate it on load

session = Aviator::Session.load(
            :log_file => 'path/to/aviator.log'

Need a way to persist session dumps? Give Aviator::SessionPool a try!

Install It Now!

Add this line to your application's Gemfile:

gem 'aviator'

Or if you want to live on the edge:

gem 'aviator', :git => '', :branch => 'master'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install aviator

Need Some Samples?

Check out the demo project for a quick sampling of how you can use Aviator.

Good to Know

In some instances, Session::load is inefficient because it creates a new session object each time. If object re-use is important to you, use Session#load (instance method, as opposed to class method). This will 'infect' an already existing session object with the supplied session dump and return itself instead of creating a brand new session object.


You can choose to be explicit about the endpoint type. Useful in those rare instances when the same request name means differently depending on the endpoint type. For example, in OpenStack, :list_tenants will return only the tenants the user is a member of in the public endpoint whereas the admin endpoint will return all tenants in the system.

response = keystone.request(:list_tenants, :endpoint_type => 'admin')

In the configuration file, the validator can be any request name as long as:

  • It is defined in Aviator
  • Does not require any parameters
  • It returns an HTTP status 200 or 203 to indicate auth info validity.
  • It returns any other HTTP status to indicate that the auth info is invalid.

Useful Links

Project Stats

Build Status Coverage Status Code Climate Gem Version