deltacloud-core 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/deltacloud.rb +2 -0
- data/lib/deltacloud/base_driver/base_driver.rb +30 -0
- data/lib/deltacloud/base_driver/features.rb +7 -0
- data/lib/deltacloud/base_driver/mock_driver.rb +18 -0
- data/lib/deltacloud/drivers/azure/azure_driver.rb +127 -0
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +128 -4
- data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +5 -2
- data/lib/deltacloud/drivers/mock/mock_driver.rb +10 -16
- data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +1 -1
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +110 -11
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +7 -4
- data/lib/deltacloud/helpers/application_helper.rb +8 -1
- data/lib/deltacloud/helpers/blob_stream.rb +51 -0
- data/lib/deltacloud/models/blob.rb +26 -0
- data/lib/deltacloud/models/bucket.rb +24 -0
- data/lib/drivers.rb +1 -0
- data/lib/sinatra/respond_to.rb +147 -181
- data/lib/sinatra/respond_to_old.rb +253 -0
- data/server.rb +104 -22
- data/tests/instance_states_test.rb +1 -2
- data/tests/instances_test.rb +12 -9
- data/tests/url_for_test.rb +1 -1
- data/views/blobs/show.html.haml +20 -0
- data/views/blobs/show.xml.haml +7 -0
- data/views/buckets/index.html.haml +33 -0
- data/views/buckets/index.xml.haml +10 -0
- data/views/buckets/new.html.haml +13 -0
- data/views/buckets/show.html.haml +19 -0
- data/views/buckets/show.xml.haml +8 -0
- data/views/instance_states/show.html.haml +1 -1
- data/views/instance_states/{show.gv.erb → show.png.erb} +0 -0
- metadata +61 -33
| @@ -0,0 +1,253 @@ | |
| 1 | 
            +
            require 'sinatra/base'
         | 
| 2 | 
            +
            require 'sinatra/accept_media_types'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            # Accept header parsing was looked at but deemed
         | 
| 5 | 
            +
            # too much of an irregularity to deal with.  Problems with the header
         | 
| 6 | 
            +
            # differences from IE, Firefox, Safari, and every other UA causes
         | 
| 7 | 
            +
            # problems with the expected output.  The general expected behavior
         | 
| 8 | 
            +
            # would be serve html when no extension provided, but most UAs say
         | 
| 9 | 
            +
            # they will accept application/xml with out a quality indicator, meaning
         | 
| 10 | 
            +
            # you'd get the xml block served insead.  Just plain retarded, use the
         | 
| 11 | 
            +
            # extension and you'll never be suprised.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            module Sinatra
         | 
| 14 | 
            +
              module RespondTo
         | 
| 15 | 
            +
                class UnhandledFormat < Sinatra::NotFound; end
         | 
| 16 | 
            +
                class MissingTemplate < Sinatra::NotFound
         | 
| 17 | 
            +
                  def code; 500 end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                TEXT_MIME_TYPES = [:txt, :html, :js, :json, :xml, :rss, :atom, :css, :asm, :c, :cc, :conf,
         | 
| 21 | 
            +
                                   :csv, :cxx, :diff, :dtd, :f, :f77, :f90, :for, :gemspec, :h, :hh, :htm,
         | 
| 22 | 
            +
                                   :log, :mathml, :mml, :p, :pas, :pl, :pm, :py, :rake, :rb, :rdf, :rtf, :ru,
         | 
| 23 | 
            +
                                   :s, :sgm, :sgml, :sh, :svg, :svgz, :text, :wsdl, :xhtml, :xsl, :xslt, :yaml,
         | 
| 24 | 
            +
                                   :yml, :ics, :png]
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def self.registered(app)
         | 
| 27 | 
            +
                  app.helpers RespondTo::Helpers
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  app.set :default_charset, 'utf-8'
         | 
| 30 | 
            +
                  app.set :default_content, :html
         | 
| 31 | 
            +
                  app.set :assume_xhr_is_js, true
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                #deltacloud: removed the code that tried to 'guess' content based on extension
         | 
| 34 | 
            +
                #as this broke blobstore api (stripping blob names). Use ?format if present, otherwise 
         | 
| 35 | 
            +
                #use http accept, otherwise set to default
         | 
| 36 | 
            +
                  app.before do
         | 
| 37 | 
            +
                    if (params[:format])
         | 
| 38 | 
            +
                      @mime_types = [Helpers::mime_type(params[:format])]
         | 
| 39 | 
            +
                      format params[:format]
         | 
| 40 | 
            +
                    elsif env['HTTP_ACCEPT'].nil? || env['HTTP_ACCEPT'].empty?
         | 
| 41 | 
            +
                      ext = options.default_content
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                 app.configure :development do |dev|
         | 
| 46 | 
            +
                    dev.error UnhandledFormat do
         | 
| 47 | 
            +
                      content_type :html, :charset => 'utf-8'
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                      (<<-HTML).gsub(/^ {10}/, '')
         | 
| 50 | 
            +
                      <!DOCTYPE html>
         | 
| 51 | 
            +
                      <html>
         | 
| 52 | 
            +
                      <head>
         | 
| 53 | 
            +
                        <style type="text/css">
         | 
| 54 | 
            +
                        body { text-align:center;font-family:helvetica,arial;font-size:22px;
         | 
| 55 | 
            +
                          color:#888;margin:20px}
         | 
| 56 | 
            +
                        #c {margin:0 auto;width:500px;text-align:left}
         | 
| 57 | 
            +
                        </style>
         | 
| 58 | 
            +
                      </head>
         | 
| 59 | 
            +
                      <body>
         | 
| 60 | 
            +
                        <h2>Sinatra doesn't know this ditty.</h2>
         | 
| 61 | 
            +
                        <img src='/__sinatra__/404.png'>
         | 
| 62 | 
            +
                        <div id="c">
         | 
| 63 | 
            +
                          Try this:
         | 
| 64 | 
            +
                          <pre>#{request.request_method.downcase} '#{request.path_info}' do\n  respond_to do |wants|\n    wants.#{format} { "Hello World" }\n  end\nend</pre>
         | 
| 65 | 
            +
                        </div>
         | 
| 66 | 
            +
                      </body>
         | 
| 67 | 
            +
                      </html>
         | 
| 68 | 
            +
                      HTML
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                    dev.error MissingTemplate do
         | 
| 72 | 
            +
                      content_type :html, :charset => 'utf-8'
         | 
| 73 | 
            +
                      response.status = request.env['sinatra.error'].code
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                      engine = request.env['sinatra.error'].message.split('.').last
         | 
| 76 | 
            +
                      engine = 'haml' unless ['haml', 'builder', 'erb'].include? engine
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                      path = File.basename(request.path_info)
         | 
| 79 | 
            +
                      path = "root" if path.nil? || path.empty?
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                      format = engine == 'builder' ? 'xml' : 'html'
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                      layout = case engine
         | 
| 84 | 
            +
                               when 'haml' then "!!!\n%html\n  %body= yield"
         | 
| 85 | 
            +
                               when 'erb' then "<html>\n  <body>\n    <%= yield %>\n  </body>\n</html>"
         | 
| 86 | 
            +
                               when 'builder' then ::Sinatra::VERSION =~ /^1.0/ ? "xml << yield" : "builder do |xml|\n  xml << yield\nend"
         | 
| 87 | 
            +
                               end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                      layout = "<small>app.#{format}.#{engine}</small>\n<pre>#{escape_html(layout)}</pre>"
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                      (<<-HTML).gsub(/^ {10}/, '')
         | 
| 92 | 
            +
                      <!DOCTYPE html>
         | 
| 93 | 
            +
                      <html>
         | 
| 94 | 
            +
                      <head>
         | 
| 95 | 
            +
                        <style type="text/css">
         | 
| 96 | 
            +
                        body { text-align:center;font-family:helvetica,arial;font-size:22px;
         | 
| 97 | 
            +
                          color:#888;margin:20px}
         | 
| 98 | 
            +
                        #c {margin:0 auto;width:500px;text-align:left;}
         | 
| 99 | 
            +
                        small {float:right;clear:both;}
         | 
| 100 | 
            +
                        pre {clear:both;}
         | 
| 101 | 
            +
                        </style>
         | 
| 102 | 
            +
                      </head>
         | 
| 103 | 
            +
                      <body>
         | 
| 104 | 
            +
                        <h2>Sinatra can't find #{request.env['sinatra.error'].message}</h2>
         | 
| 105 | 
            +
                        <img src='/__sinatra__/500.png'>
         | 
| 106 | 
            +
                        <div id="c">
         | 
| 107 | 
            +
                          Try this:<br />
         | 
| 108 | 
            +
                          #{layout}
         | 
| 109 | 
            +
                          <small>#{path}.#{format}.#{engine}</small>
         | 
| 110 | 
            +
                          <pre>Hello World!</pre>
         | 
| 111 | 
            +
                          <small>application.rb</small>
         | 
| 112 | 
            +
                          <pre>#{request.request_method.downcase} '#{request.path_info}' do\n  respond_to do |wants|\n    wants.#{engine == 'builder' ? 'xml' : 'html'} { #{engine} :#{path}#{",\n#{' '*32}layout => :app" if layout} }\n  end\nend</pre>
         | 
| 113 | 
            +
                        </div>
         | 
| 114 | 
            +
                      </body>
         | 
| 115 | 
            +
                      </html>
         | 
| 116 | 
            +
                      HTML
         | 
| 117 | 
            +
                    end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                  app.class_eval do
         | 
| 122 | 
            +
                    private
         | 
| 123 | 
            +
                      def accept_list
         | 
| 124 | 
            +
                        @mime_types || Rack::AcceptMediaTypes.new(env['HTTP_ACCEPT'] || '')
         | 
| 125 | 
            +
                      end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                      # Changes in 1.0 Sinatra reuse render for layout so we store
         | 
| 128 | 
            +
                      # the original value to tell us if this is an automatic attempt
         | 
| 129 | 
            +
                      # to do a layout call.  If it is, it might fail with Errno::ENOENT
         | 
| 130 | 
            +
                      # and we want to pass that back to sinatra since it isn't a MissingTemplate
         | 
| 131 | 
            +
                      # error
         | 
| 132 | 
            +
                      def render_with_format(*args, &block)
         | 
| 133 | 
            +
                        assumed_layout = args[1] == :layout
         | 
| 134 | 
            +
                        args[1] = "#{args[1]}.#{format}".to_sym if args[1].is_a?(::Symbol)
         | 
| 135 | 
            +
                        render_without_format *args, &block
         | 
| 136 | 
            +
                      rescue Errno::ENOENT => e
         | 
| 137 | 
            +
                        raise MissingTemplate, "#{args[1]}.#{args[0]}" unless assumed_layout
         | 
| 138 | 
            +
                        raise e
         | 
| 139 | 
            +
                      end
         | 
| 140 | 
            +
                      alias_method :render_without_format, :render
         | 
| 141 | 
            +
                      alias_method :render, :render_with_format
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                      if ::Sinatra::VERSION =~ /^0\.9/
         | 
| 144 | 
            +
                        def lookup_layout_with_format(*args)
         | 
| 145 | 
            +
                          args[1] = "#{args[1]}.#{format}".to_sym if args[1].is_a?(::Symbol)
         | 
| 146 | 
            +
                          lookup_layout_without_format *args
         | 
| 147 | 
            +
                        end
         | 
| 148 | 
            +
                        alias_method :lookup_layout_without_format, :lookup_layout
         | 
| 149 | 
            +
                        alias_method :lookup_layout, :lookup_layout_with_format
         | 
| 150 | 
            +
                      end
         | 
| 151 | 
            +
                  end
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                module Helpers
         | 
| 155 | 
            +
                  # Patch the content_type function to remember the set type
         | 
| 156 | 
            +
                  # This helps cut down on time in the format helper so it
         | 
| 157 | 
            +
                  # doesn't have to do a reverse lookup on the header
         | 
| 158 | 
            +
                  def self.included(klass)
         | 
| 159 | 
            +
                    klass.class_eval do
         | 
| 160 | 
            +
                      def content_type_with_save(*args)
         | 
| 161 | 
            +
                        content_type_without_save *args
         | 
| 162 | 
            +
                        @_format = args.first.to_sym
         | 
| 163 | 
            +
                        response['Content-Type']
         | 
| 164 | 
            +
                      end
         | 
| 165 | 
            +
                      alias_method :content_type_without_save, :content_type
         | 
| 166 | 
            +
                      alias_method :content_type, :content_type_with_save
         | 
| 167 | 
            +
                    end if ::Sinatra::VERSION =~ /^1.0/
         | 
| 168 | 
            +
                  end
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                  def self.mime_type(sym)
         | 
| 171 | 
            +
                    ::Sinatra::Base.respond_to?(:mime_type) && ::Sinatra::Base.mime_type(sym) || ::Sinatra::Base.media_type(sym)
         | 
| 172 | 
            +
                  end
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                  def format(val=nil)
         | 
| 175 | 
            +
                    unless val.nil?
         | 
| 176 | 
            +
                      mime_type = ::Sinatra::RespondTo::Helpers.mime_type(val)
         | 
| 177 | 
            +
                      fail "Unknown media type #{val}\nTry registering the extension with a mime type" if mime_type.nil?
         | 
| 178 | 
            +
             | 
| 179 | 
            +
                      @_format = val.to_sym
         | 
| 180 | 
            +
                      response['Content-Type'].sub!(/^[^;]+/, mime_type)
         | 
| 181 | 
            +
                      charset options.default_charset if Sinatra::RespondTo::TEXT_MIME_TYPES.include?(format) and format!=:png
         | 
| 182 | 
            +
                    end
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                    @_format
         | 
| 185 | 
            +
                  end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                  # This is mostly just a helper so request.path_info isn't changed when
         | 
| 188 | 
            +
                  # serving files from the public directory
         | 
| 189 | 
            +
                  def static_file?(path)
         | 
| 190 | 
            +
                    public_dir = File.expand_path(options.public)
         | 
| 191 | 
            +
                    path = File.expand_path(File.join(public_dir, unescape(path)))
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                    path[0, public_dir.length] == public_dir && File.file?(path)
         | 
| 194 | 
            +
                  end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                  def charset(val=nil)
         | 
| 197 | 
            +
                    fail "Content-Type must be set in order to specify a charset" if response['Content-Type'].nil?
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                    if response['Content-Type'] =~ /charset=[^;]+/
         | 
| 200 | 
            +
                      response['Content-Type'].sub!(/charset=[^;]+/, (val == '' && '') || "charset=#{val}")
         | 
| 201 | 
            +
                    else
         | 
| 202 | 
            +
                      response['Content-Type'] += ";charset=#{val}"
         | 
| 203 | 
            +
                    end unless val.nil?
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                    response['Content-Type'][/charset=([^;]+)/, 1]
         | 
| 206 | 
            +
                  end
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                  def respond_to(&block)
         | 
| 209 | 
            +
                    wants = Format.new
         | 
| 210 | 
            +
                    yield wants
         | 
| 211 | 
            +
                    fmt, type, handler = match_accept_type(accept_list, wants)
         | 
| 212 | 
            +
                    raise UnhandledFormat if fmt.nil?
         | 
| 213 | 
            +
                    format fmt
         | 
| 214 | 
            +
                    handler.nil? ? nil : handler.call
         | 
| 215 | 
            +
                  end
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                  def match_accept_type(mime_types, format)
         | 
| 218 | 
            +
                    selected = []
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                    accepted_types = mime_types.map {|type| Regexp.escape(type).gsub(/\\\*/,'.*') }
         | 
| 221 | 
            +
                    # Fix for Chrome based browsers which returns XML when 'xhtml' is requested.
         | 
| 222 | 
            +
                    if env['HTTP_USER_AGENT'] =~ /Chrome/ and accepted_types.size>1
         | 
| 223 | 
            +
                      accepted_types[0], accepted_types[1] = accepted_types[1], accepted_types[0]
         | 
| 224 | 
            +
                      if accepted_types[0].eql?('application/xhtml\\+xml')
         | 
| 225 | 
            +
                        accepted_types[0] = 'text/html'
         | 
| 226 | 
            +
                      end
         | 
| 227 | 
            +
                    end
         | 
| 228 | 
            +
                    accepted_types.each do |at|
         | 
| 229 | 
            +
                      format.each do |fmt, ht, handler|
         | 
| 230 | 
            +
                        (selected = [fmt, ht, handler]) and break if ht.match(at)
         | 
| 231 | 
            +
                      end
         | 
| 232 | 
            +
                      break unless selected.empty?
         | 
| 233 | 
            +
                    end
         | 
| 234 | 
            +
                    selected
         | 
| 235 | 
            +
                  end
         | 
| 236 | 
            +
             | 
| 237 | 
            +
                  # NOTE Array instead of hash because order matters (wildcard type
         | 
| 238 | 
            +
                  # matches first handler)
         | 
| 239 | 
            +
                  class Format < Array #:nodoc:
         | 
| 240 | 
            +
                    def method_missing(format, *args, &handler)
         | 
| 241 | 
            +
                      mt = Sinatra::RespondTo::Helpers.mime_type(format)
         | 
| 242 | 
            +
                      if mt.nil?
         | 
| 243 | 
            +
                        Sinatra::Base.send(:fail, "Unknown media type for respond_to: #{format}\nTry registering the extension with a mime type")
         | 
| 244 | 
            +
                      end
         | 
| 245 | 
            +
                      self << [format.to_s, mt, handler]
         | 
| 246 | 
            +
                    end
         | 
| 247 | 
            +
                  end
         | 
| 248 | 
            +
                end
         | 
| 249 | 
            +
              end
         | 
| 250 | 
            +
            end
         | 
| 251 | 
            +
             | 
| 252 | 
            +
            Rack::Mime::MIME_TYPES.merge!({ ".gv" => "text/plain" })
         | 
| 253 | 
            +
            Sinatra::Application.register Sinatra::RespondTo
         | 
    
        data/server.rb
    CHANGED
    
    | @@ -9,6 +9,7 @@ require 'sinatra/lazy_auth' | |
| 9 9 | 
             
            require 'erb'
         | 
| 10 10 | 
             
            require 'haml'
         | 
| 11 11 | 
             
            require 'open3'
         | 
| 12 | 
            +
            require 'lib/deltacloud/helpers/blob_stream'
         | 
| 12 13 |  | 
| 13 14 | 
             
            configure do
         | 
| 14 15 | 
             
              set :raise_errors => false
         | 
| @@ -37,6 +38,8 @@ error Deltacloud::BackendError do | |
| 37 38 | 
             
              report_error(500, "backend_error")
         | 
| 38 39 | 
             
            end
         | 
| 39 40 |  | 
| 41 | 
            +
            Sinatra::Application.register Sinatra::RespondTo
         | 
| 42 | 
            +
             | 
| 40 43 | 
             
            # Redirect to /api
         | 
| 41 44 | 
             
            get '/' do redirect url_for('/api'); end
         | 
| 42 45 |  | 
| @@ -74,7 +77,8 @@ END | |
| 74 77 |  | 
| 75 78 | 
             
              operation :index do
         | 
| 76 79 | 
             
                description <<END
         | 
| 77 | 
            -
                Operation will list all available realms.  | 
| 80 | 
            +
                Operation will list all available realms. Realms can be filtered using
         | 
| 81 | 
            +
                the "architecture" parameter.
         | 
| 78 82 | 
             
            END
         | 
| 79 83 | 
             
                param :id,            :string
         | 
| 80 84 | 
             
                param :architecture,  :string,  :optional,  [ 'i386', 'x86_64' ]
         | 
| @@ -98,9 +102,9 @@ END | |
| 98 102 |  | 
| 99 103 | 
             
              operation :index do
         | 
| 100 104 | 
             
                description <<END
         | 
| 101 | 
            -
                The  | 
| 102 | 
            -
                available to the current use.  | 
| 103 | 
            -
                "owner_id" and "architecture"  | 
| 105 | 
            +
                The images collection will return a set of all images
         | 
| 106 | 
            +
                available to the current use. Images can be filtered using the
         | 
| 107 | 
            +
                "owner_id" and "architecture" parameters.
         | 
| 104 108 | 
             
            END
         | 
| 105 109 | 
             
                param :id,            :string
         | 
| 106 110 | 
             
                param :architecture,  :string,  :optional
         | 
| @@ -138,7 +142,10 @@ collection :instance_states do | |
| 138 142 | 
             
                    format.png do
         | 
| 139 143 | 
             
                      # Trick respond_to into looking up the right template for the
         | 
| 140 144 | 
             
                      # graphviz file
         | 
| 141 | 
            -
                       | 
| 145 | 
            +
                      format_backup = format
         | 
| 146 | 
            +
                      format(:gv)
         | 
| 147 | 
            +
                      gv = erb(:"instance_states/show")
         | 
| 148 | 
            +
                      format(format_backup)
         | 
| 142 149 | 
             
                      png =  ''
         | 
| 143 150 | 
             
                      cmd = 'dot -Kdot -Gpad="0.2,0.2" -Gsize="5.0,8.0" -Gdpi="180" -Tpng'
         | 
| 144 151 | 
             
                      Open3.popen3( cmd ) do |stdin, stdout, stderr|
         | 
| @@ -146,6 +153,7 @@ collection :instance_states do | |
| 146 153 | 
             
                        stdin.close()
         | 
| 147 154 | 
             
                        png = stdout.read
         | 
| 148 155 | 
             
                      end
         | 
| 156 | 
            +
                      content_type 'image/png'
         | 
| 149 157 | 
             
                      png
         | 
| 150 158 | 
             
                    end
         | 
| 151 159 | 
             
                  end
         | 
| @@ -170,7 +178,7 @@ collection :instances do | |
| 170 178 | 
             
            END
         | 
| 171 179 |  | 
| 172 180 | 
             
              operation :index do
         | 
| 173 | 
            -
                description "List all instances"
         | 
| 181 | 
            +
                description "List all instances."
         | 
| 174 182 | 
             
                param :id,            :string,  :optional
         | 
| 175 183 | 
             
                param :state,         :string,  :optional
         | 
| 176 184 | 
             
                control { filter_all(:instances) }
         | 
| @@ -183,7 +191,7 @@ END | |
| 183 191 | 
             
              end
         | 
| 184 192 |  | 
| 185 193 | 
             
              operation :create do
         | 
| 186 | 
            -
                description "Create a new instance"
         | 
| 194 | 
            +
                description "Create a new instance."
         | 
| 187 195 | 
             
                param :image_id,     :string, :required
         | 
| 188 196 | 
             
                param :realm_id,     :string, :optional
         | 
| 189 197 | 
             
                param :hwp_id,       :string, :optional
         | 
| @@ -206,25 +214,25 @@ END | |
| 206 214 | 
             
              end
         | 
| 207 215 |  | 
| 208 216 | 
             
              operation :reboot, :method => :post, :member => true do
         | 
| 209 | 
            -
                description "Reboot running instance"
         | 
| 217 | 
            +
                description "Reboot a running instance."
         | 
| 210 218 | 
             
                param :id,           :string, :required
         | 
| 211 219 | 
             
                control { instance_action(:reboot) }
         | 
| 212 220 | 
             
              end
         | 
| 213 221 |  | 
| 214 222 | 
             
              operation :start, :method => :post, :member => true do
         | 
| 215 | 
            -
                description "Start an instance"
         | 
| 223 | 
            +
                description "Start an instance."
         | 
| 216 224 | 
             
                param :id,           :string, :required
         | 
| 217 225 | 
             
                control { instance_action(:start) }
         | 
| 218 226 | 
             
              end
         | 
| 219 227 |  | 
| 220 228 | 
             
              operation :stop, :method => :post, :member => true do
         | 
| 221 | 
            -
                description "Stop running instance"
         | 
| 229 | 
            +
                description "Stop a running instance."
         | 
| 222 230 | 
             
                param :id,           :string, :required
         | 
| 223 231 | 
             
                control { instance_action(:stop) }
         | 
| 224 232 | 
             
              end
         | 
| 225 233 |  | 
| 226 234 | 
             
              operation :destroy do
         | 
| 227 | 
            -
                description "Destroy instance"
         | 
| 235 | 
            +
                description "Destroy an instance."
         | 
| 228 236 | 
             
                param :id,           :string, :required
         | 
| 229 237 | 
             
                control { instance_action(:destroy) }
         | 
| 230 238 | 
             
              end
         | 
| @@ -239,7 +247,7 @@ collection :hardware_profiles do | |
| 239 247 | 
             
            END
         | 
| 240 248 |  | 
| 241 249 | 
             
              operation :index do
         | 
| 242 | 
            -
                description "List of available hardware profiles"
         | 
| 250 | 
            +
                description "List of available hardware profiles."
         | 
| 243 251 | 
             
                param :id,          :string
         | 
| 244 252 | 
             
                param :architecture,  :string,  :optional,  [ 'i386', 'x86_64' ]
         | 
| 245 253 | 
             
                control do
         | 
| @@ -253,7 +261,7 @@ END | |
| 253 261 | 
             
              end
         | 
| 254 262 |  | 
| 255 263 | 
             
              operation :show do
         | 
| 256 | 
            -
                description "Show specific hardware profile"
         | 
| 264 | 
            +
                description "Show specific hardware profile."
         | 
| 257 265 | 
             
                param :id,          :string,    :required
         | 
| 258 266 | 
             
                control do
         | 
| 259 267 | 
             
                  @profile =  driver.hardware_profile(credentials, params[:id])
         | 
| @@ -275,13 +283,13 @@ collection :storage_snapshots do | |
| 275 283 | 
             
              description "Storage snapshots description here"
         | 
| 276 284 |  | 
| 277 285 | 
             
              operation :index do
         | 
| 278 | 
            -
                description " | 
| 286 | 
            +
                description "List of storage snapshots."
         | 
| 279 287 | 
             
                param :id,            :string
         | 
| 280 288 | 
             
                control { filter_all(:storage_snapshots) }
         | 
| 281 289 | 
             
              end
         | 
| 282 290 |  | 
| 283 291 | 
             
              operation :show do
         | 
| 284 | 
            -
                description "Show storage snapshot"
         | 
| 292 | 
            +
                description "Show storage snapshot."
         | 
| 285 293 | 
             
                param :id,          :string,    :required
         | 
| 286 294 | 
             
                control { show(:storage_snapshot) }
         | 
| 287 295 | 
             
              end
         | 
| @@ -291,13 +299,13 @@ collection :storage_volumes do | |
| 291 299 | 
             
              description "Storage volumes description here"
         | 
| 292 300 |  | 
| 293 301 | 
             
              operation :index do
         | 
| 294 | 
            -
                description " | 
| 302 | 
            +
                description "List of storage volumes."
         | 
| 295 303 | 
             
                param :id,            :string
         | 
| 296 304 | 
             
                control { filter_all(:storage_volumes) }
         | 
| 297 305 | 
             
              end
         | 
| 298 306 |  | 
| 299 307 | 
             
              operation :show do
         | 
| 300 | 
            -
                description "Show storage volume"
         | 
| 308 | 
            +
                description "Show storage volume."
         | 
| 301 309 | 
             
                param :id,          :string,    :required
         | 
| 302 310 | 
             
                control { show(:storage_volume) }
         | 
| 303 311 | 
             
              end
         | 
| @@ -310,23 +318,23 @@ get '/api/keys/new' do | |
| 310 318 | 
             
            end
         | 
| 311 319 |  | 
| 312 320 | 
             
            collection :keys do
         | 
| 313 | 
            -
              description "Instance authentication credentials"
         | 
| 321 | 
            +
              description "Instance authentication credentials."
         | 
| 314 322 |  | 
| 315 323 | 
             
              operation :index do
         | 
| 316 | 
            -
                description "List all available credentials which could be used for instance authentication"
         | 
| 324 | 
            +
                description "List all available credentials which could be used for instance authentication."
         | 
| 317 325 | 
             
                control do
         | 
| 318 326 | 
             
                  filter_all :keys
         | 
| 319 327 | 
             
                end
         | 
| 320 328 | 
             
              end
         | 
| 321 329 |  | 
| 322 330 | 
             
              operation :show do
         | 
| 323 | 
            -
                description "Show details about given instance credential"
         | 
| 331 | 
            +
                description "Show details about given instance credential."
         | 
| 324 332 | 
             
                param :id,  :string,  :required
         | 
| 325 333 | 
             
                control { show :key }
         | 
| 326 334 | 
             
              end
         | 
| 327 335 |  | 
| 328 336 | 
             
              operation :create do
         | 
| 329 | 
            -
                description "Create a new instance credential if backend supports this"
         | 
| 337 | 
            +
                description "Create a new instance credential if backend supports this."
         | 
| 330 338 | 
             
                param :name,  :string,  :required
         | 
| 331 339 | 
             
                control do
         | 
| 332 340 | 
             
                  unless driver.respond_to?(:create_key)
         | 
| @@ -342,7 +350,7 @@ collection :keys do | |
| 342 350 | 
             
              end
         | 
| 343 351 |  | 
| 344 352 | 
             
              operation :destroy do
         | 
| 345 | 
            -
                description "Destroy given instance credential if backend supports this"
         | 
| 353 | 
            +
                description "Destroy given instance credential if backend supports this."
         | 
| 346 354 | 
             
                param :id,  :string,  :required
         | 
| 347 355 | 
             
                control do
         | 
| 348 356 | 
             
                  unless driver.respond_to?(:destroy_key)
         | 
| @@ -355,3 +363,77 @@ collection :keys do | |
| 355 363 | 
             
              end
         | 
| 356 364 |  | 
| 357 365 | 
             
            end
         | 
| 366 | 
            +
             | 
| 367 | 
            +
            get '/api/buckets/:bucket/:blob' do
         | 
| 368 | 
            +
              @blob = driver.blob(credentials, { :id => params[:blob], 'bucket' => params[:bucket]})
         | 
| 369 | 
            +
              if @blob
         | 
| 370 | 
            +
                respond_to do |format|
         | 
| 371 | 
            +
                  format.html { haml :"blobs/show" }
         | 
| 372 | 
            +
                  format.xml { haml :"blobs/show" }
         | 
| 373 | 
            +
                  format.json { convert_to_json(blobs, @blob) }
         | 
| 374 | 
            +
                  end
         | 
| 375 | 
            +
              else
         | 
| 376 | 
            +
                  report_error(404, 'not_found')
         | 
| 377 | 
            +
              end
         | 
| 378 | 
            +
            end
         | 
| 379 | 
            +
             | 
| 380 | 
            +
            get '/api/buckets/new' do
         | 
| 381 | 
            +
              respond_to do |format|
         | 
| 382 | 
            +
                format.html { haml :"buckets/new" }
         | 
| 383 | 
            +
              end
         | 
| 384 | 
            +
            end
         | 
| 385 | 
            +
             | 
| 386 | 
            +
             | 
| 387 | 
            +
            get '/api/buckets/:bucket/:blob/content' do
         | 
| 388 | 
            +
              @blob = driver.blob(credentials, { :id => params[:blob], 'bucket' => params[:bucket]})
         | 
| 389 | 
            +
              params['content_length'] = @blob.content_length
         | 
| 390 | 
            +
              params['content_type'] = @blob.content_type
         | 
| 391 | 
            +
              BlobStream.call(env, credentials, params)
         | 
| 392 | 
            +
            end
         | 
| 393 | 
            +
             | 
| 394 | 
            +
            collection :buckets do
         | 
| 395 | 
            +
              description "Cloud Storage buckets - aka buckets|directories|folders"
         | 
| 396 | 
            +
             | 
| 397 | 
            +
              operation :index do
         | 
| 398 | 
            +
                description "List buckets associated with this account"
         | 
| 399 | 
            +
                param :id,        :string
         | 
| 400 | 
            +
                param :name,      :string
         | 
| 401 | 
            +
                param :size,      :string
         | 
| 402 | 
            +
                control { filter_all(:buckets) }
         | 
| 403 | 
            +
              end
         | 
| 404 | 
            +
             | 
| 405 | 
            +
              operation :show do
         | 
| 406 | 
            +
                description "Show bucket"
         | 
| 407 | 
            +
                param :id,        :string
         | 
| 408 | 
            +
                control { show(:bucket) }
         | 
| 409 | 
            +
              end
         | 
| 410 | 
            +
             | 
| 411 | 
            +
              operation :create do
         | 
| 412 | 
            +
                description "Create a new bucket (POST /api/buckets)"
         | 
| 413 | 
            +
                param :name,      :string,    :required
         | 
| 414 | 
            +
                control do
         | 
| 415 | 
            +
                  @bucket = driver.create_bucket(credentials, params[:name], params)
         | 
| 416 | 
            +
                  respond_to do |format|
         | 
| 417 | 
            +
                    format.xml do
         | 
| 418 | 
            +
                      response.status = 201  # Created
         | 
| 419 | 
            +
                      response['Location'] = bucket_url(@bucket.id)
         | 
| 420 | 
            +
                      haml :"buckets/show"
         | 
| 421 | 
            +
                    end
         | 
| 422 | 
            +
                    format.html do
         | 
| 423 | 
            +
                      redirect bucket_url(@bucket.id) if @bucket and @bucket.id
         | 
| 424 | 
            +
                      redirect buckets_url
         | 
| 425 | 
            +
                    end
         | 
| 426 | 
            +
                  end
         | 
| 427 | 
            +
                end
         | 
| 428 | 
            +
              end
         | 
| 429 | 
            +
             | 
| 430 | 
            +
              operation :destroy do
         | 
| 431 | 
            +
                description "Delete a bucket by name - bucket must be empty"
         | 
| 432 | 
            +
                param :id,    :string,    :required
         | 
| 433 | 
            +
                control do
         | 
| 434 | 
            +
                  driver.delete_bucket(credentials, params[:id], params)
         | 
| 435 | 
            +
                  redirect(buckets_url)
         | 
| 436 | 
            +
                end
         | 
| 437 | 
            +
              end
         | 
| 438 | 
            +
             | 
| 439 | 
            +
            end
         |