module Deltacloud::Helpers::Application

Constants

HTML_ESCAPE
NEW_BLOB_FORM_ID

Public Class Methods

included(klass) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 343
def Application.included(klass)
  klass.extend SinatraHelper
end

Public Instance Methods

action_method(action, collection) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 63
def action_method(action, collection)
  http_method = collection.operation(action).http_method
  http_method || Deltacloud::Rabbit::BaseCollection.http_method_for(action)
end
additional_features_for?(collection_name, apart_from = []) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 318
def additional_features_for?(collection_name, apart_from = [])
  features_arr = (driver.class.features[collection_name.to_sym] || [] )  - apart_from
  not features_arr.empty?
end
auth_feature_name() click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 54
def auth_feature_name
  return 'key' if driver.class.has_feature?(:instances, :authentication_key)
  return 'password' if driver.class.has_feature?(:instances, :authentication_password)
end
bt(trace) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 353
def bt(trace)
  return [] unless trace
  return trace.join("\n") if params['fulltrace']
  app_path = File::expand_path("../../..", __FILE__)
  dots = false
  trace = trace.map { |t| t.match(%r{^#{app_path}(.*)$}) ? "$app#{$1}" : "..." }.select do |t|
    if t == "..."
      keep = ! dots
      dots = true
    else
      keep = true
      dots = false
    end
    keep
  end
  "[\nAbbreviated trace\n   pass fulltrace=1 as query param to see everything\n  $app = #{app_path}\n]\n" + trace.join("\n")
end
cdata(text = nil, &block) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 181
def cdata(text = nil, &block)
  text ||= capture_haml(&block)
  "<![CDATA[#{text.strip}]]>"
end
collections_to_json(collections) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 25
def collections_to_json(collections)
  r = {
    :version => settings.version,
    :driver => driver_symbol,
    :provider => Thread.current[:provider] || ENV['API_PROVIDER'],
    :links => collections.map { |c|
      {
        :rel => c.collection_name,
        :href => self.send(:"#{c.collection_name}_url"),
        :features => c.features.select { |f| driver.class.has_feature?(c.collection_name, f.name) }.map { |f|
          f.operations.map { |o|
            { :name => f.name, :rel => o.name, :params => o.params_array, :constraints => constraints_hash_for(c.collection_name, f.name) }
          }
        }
      }
    }
  }
  r[:provider] ||= 'default'
  JSON::dump(:api => r)
end
constraints_hash_for(collection_name, feature_name) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 46
def constraints_hash_for(collection_name, feature_name)
  driver.class.constraints(:collection => collection_name, :feature => feature_name).inject({}) { |r, v| r[v[0]]=v[1];r }
end
current_provider() click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 21
def current_provider
  Thread.current[:provider] || ENV['API_PROVIDER'] || 'default'
end
driver_provider(d) click to toggle source

Reverse the entrypoints hash for a driver from drivers.yaml; note that d is a hash, not an actual driver object

# File lib/deltacloud/helpers/deltacloud_helper.rb, line 221
def driver_provider(d)
  result = {}
  if d[:entrypoints]
    d[:entrypoints].each do |kind, details|
      details.each do |prov, url|
        result[prov] ||= {}
        result[prov][kind] = url
      end
    end
  end
  result
end
filter_all(model) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 68
def filter_all(model)
  begin
    @benchmark = Benchmark.measure { @elements = driver.send(model.to_sym, credentials, params) }
  rescue => e
    @exception = e
  end
  if @elements
    headers['X-Backend-Runtime'] = @benchmark.real.to_s
    instance_variable_set(:"@#{model}", @elements)
    respond_to do |format|
      format.html { haml :"#{model}/index", :locals => { :elements => @elements } }
      format.xml { haml :"#{model}/index", :locals => { :elements => @elements } }
      format.json { JSON::dump({ model => @elements.map { |el| el.to_hash(self) }}) }
    end
  else
    report_error(@exception.respond_to?(:code) ? @exception.code : nil)
  end
end
format_hardware_property(prop) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 283
def format_hardware_property(prop)
  return "&empty;" unless prop
  u = hardware_property_unit(prop)
  case prop.kind
  when :range
    "#{prop.first} #{u} - #{prop.last} #{u} (default: #{prop.default} #{u})"
  when :enum
    prop.values.collect{ |v| "#{v} #{u}"}.join(', ') + " (default: #{prop.default} #{u})"
  else
    "#{prop.value} #{u}"
  end
end
format_instance_profile(ip) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 296
def format_instance_profile(ip)
  o = ip.overrides.collect do |p, v|
    u = hardware_property_unit(p)
    "#{p} = #{v} #{u}"
  end
  if o.empty?
    nil
  else
    "with #{o.join(", ")}"
  end
end
h(s) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 349
def h(s)
  s.to_s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }
end
header(title, opts={}, &block) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 234
def header(title, opts={}, &block)
  opts[:theme] ||= 'b'
  opts[:back] ||= 'true'
  capture_haml do
    haml_tag :div, :'data-role' => :header, :'data-theme' => opts[:theme], :'data-add-back-btn' => opts[:back] do
      haml_tag :a, :'data-rel' => :back do
        haml_concat "Back"
      end if opts[:back] == 'true'
      haml_tag :h1 do
        haml_concat title
      end
      block.call if block_given?
    end
  end
end
image_for_state(state) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 213
def image_for_state(state)
  capture_haml do
    haml_tag :img, :src => "/images/#{state}" % state.downcase, :title => state
  end
end
instance_action(name) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 145
def instance_action(name)
  unless original_instance = driver.instance(credentials, :id => params[:id])
    return report_error(403)
  end

  # If original instance doesn't include called action
  # return with 405 error (Method is not Allowed)
  unless driver.instance_actions_for(original_instance.state).include?(name.to_sym)
    return report_error(405)
  end

  @benchmark = Benchmark.measure do
    @instance = driver.send(:"#{name}_instance", credentials, params[:id])
  end

  headers['X-Backend-Runtime'] = @benchmark.real.to_s

  if name == :destroy
    response = respond_to do |format|
      format.html { redirect(instances_url) }
    end
    halt 204, response
  end

  unless @instance.class == Deltacloud::Instance
    redirect instance_url(params[:id])
  else
    response = respond_to do |format|
      format.xml { haml :"instances/show", :locals => { :instance => @instance } }
      format.html { haml :"instances/show", :locals => { :instance => @instance } }
      format.json { JSON::dump(@instance.to_hash(self)) }
    end
    halt 202, response
  end
end
instance_action_method(action) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 59
def instance_action_method(action)
  action_method(action, Deltacloud::Rabbit::InstancesCollection)
end
log() click to toggle source

Log errors to the same logger as we use for logging requests

# File lib/deltacloud/helpers/deltacloud_helper.rb, line 105
def log
  Deltacloud::Exceptions.logger(Deltacloud.default_frontend.logger)
end
new_blob_form_url(bucket) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 279
def new_blob_form_url(bucket)
  bucket_url(@bucket.name) + "/" + NEW_BLOB_FORM_ID
end
order_hardware_profiles(profiles) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 308
def order_hardware_profiles(profiles)
  #have to deal with opaque hardware profiles
  uncomparables = profiles.select{|x| x.cpu.nil? or x.memory.nil? }
  if uncomparables.empty?
    profiles.sort_by{|a| [a.cpu.default, a.memory.default] }
  else
    (profiles - uncomparables).sort_by{|a| [a.cpu.default, a.memory.default] } + uncomparables
  end
end
render_cdata(text) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 186
def render_cdata(text)
  "<![CDATA[#{text.strip}]]>" unless text.nil?
end
report_error(code=nil, message=nil) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 109
def report_error(code=nil, message=nil)

  if !code.nil?
    error = Deltacloud::Exceptions.exception_from_status(code, message || translate_error_code(code)[:message])
    message = error.message
  else
    error = request.env['sinatra.error'] || @exception
    code = error.respond_to?(:code) ? error.code : 500
    message = error.respond_to?(:message) ? error.message : translate_error_code(code)[:message]
  end

  response.status = code

  backtrace = (error.respond_to?(:backtrace) and !error.backtrace.nil?) ?
    "\n\n#{error.backtrace[0..20].join("\n")}\n\n" : ''

  if code.to_s =~ /5(\d+)/
    log.error(code.to_s) { "[#{error.class.to_s}] #{message}#{backtrace}" }
  end

  respond_to do |format|
    format.xml {  haml :"errors/common", :layout => false, :locals => { :err => error } }
    format.json { JSON::dump({ :code => code || error.code, :message => message, :error => error.class.name }) }
    format.html {
      begin
        haml :"errors/common", :layout => :error, :locals => { :err => error }
      rescue RuntimeError
        # If the HTML representation of error is missing, then try to report
        # it through XML
        @media_type=:xml
        haml :"errors/common", :layout => false
      end
    }
  end
end
request_headers() click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 50
def request_headers
  env.inject({}){|acc, (k,v)| acc[$1.downcase] = v if k =~ /^http_(.*)/; acc}
end
show(model) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 87
def show(model)
  @benchmark = Benchmark.measure do
    @element = driver.send(model, credentials, { :id => params[:id]} )
  end
  headers['X-Backend-Runtime'] = @benchmark.real.to_s
  instance_variable_set("@#{model}", @element)
  if @element
    respond_to do |format|
      format.html { haml :"#{model.to_s.pluralize}/show", :locals=>{model=>@element}}
      format.xml { haml :"#{model.to_s.pluralize}/show" , :locals=>{model=>@element}}
      format.json { JSON::dump(model => @element.to_hash(self)) }
    end
  else
    report_error(404)
  end
end
subheader(title, opts={}) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 250
def subheader(title, opts={})
  opts[:theme] ||= 'a'
  capture_haml do
    haml_tag :div, :'data-role' => :header, :'data-theme' => opts[:theme] do
      haml_tag :p, :class => 'inner-right' do
        haml_concat title
      end
    end
  end
end
translate_error_code(code) click to toggle source
# File lib/deltacloud/helpers/deltacloud_helper.rb, line 261
def translate_error_code(code)
  case code
  when 400; { :message => "Bad Request" }
  when 401; { :message => "Unauthorized" }
  when 403; { :message => "Forbidden" }
  when 404; { :message => "Not Found" }
  when 405; { :message => "Method Not Allowed" }
  when 406; { :message => "Not Acceptable" }
  when 409; { :message => "Resource Conflict" }
  when 500; { :message => "Internal Server Error" }
  when 502; { :message => "Backend Server Error" }
  when 504; { :message => "Gateway Timeout" }
  when 501; { :message => "Not Supported" }
  end
end