require(File.expand_path(File.join(File.dirname(__FILE__), 'core'))) module Fog module OpenStack extend Fog::Provider module Errors class ServiceError < Fog::Errors::Error attr_reader :response_data def self.slurp(error) if error.response.body.empty? data = nil message = nil else data = MultiJson.decode(error.response.body) message = data['message'] end new_error = super(error, message) new_error.instance_variable_set(:@response_data, data) new_error end end class InternalServerError < ServiceError; end class Conflict < ServiceError; end class NotFound < ServiceError; end class ServiceUnavailable < ServiceError; end class BadRequest < ServiceError attr_reader :validation_errors def self.slurp(error) new_error = super(error) unless new_error.response_data.nil? new_error.instance_variable_set(:@validation_errors, new_error.response_data['validationErrors']) end new_error end end end service(:compute, 'openstack/compute', 'Compute') # legacy v1.0 style auth def self.authenticate_v1(options, connection_options = {}) openstack_auth_url = options[:openstack_auth_url] uri = URI.parse(openstack_auth_url) connection = Fog::Connection.new(openstack_auth_url, false, connection_options) @openstack_api_key = options[:openstack_api_key] @openstack_username = options[:openstack_username] response = connection.request({ :expects => [200, 204], :headers => { 'X-Auth-Key' => @openstack_api_key, 'X-Auth-User' => @openstack_username }, :host => uri.host, :method => 'GET', :path => (uri.path and not uri.path.empty?) ? uri.path : 'v1.0' }) return { :token => response.headers['X-Auth-Token'], :server_management_url => response.headers['X-Server-Management-Url'] } end # keystone style auth def self.authenticate_v2(options, connection_options = {}) openstack_auth_url = options[:openstack_auth_url] uri = URI.parse(openstack_auth_url) connection = Fog::Connection.new(openstack_auth_url, false, connection_options) @openstack_api_key = options[:openstack_api_key] @openstack_username = options[:openstack_username] @openstack_tenant = options[:openstack_tenant] @compute_service_name = options[:openstack_compute_service_name] req_body= { 'auth' => { 'passwordCredentials' => { 'username' => @openstack_username, 'password' => @openstack_api_key } } } req_body['auth']['tenantName'] = @openstack_tenant if @openstack_tenant response = connection.request({ :expects => [200, 204], :headers => {'Content-Type' => 'application/json'}, :body => MultiJson.encode(req_body), :host => uri.host, :method => 'POST', :path => (uri.path and not uri.path.empty?) ? uri.path : 'v2.0' }) body=MultiJson.decode(response.body) if svc = body['access']['serviceCatalog'].detect{|x| x['name'] == @compute_service_name} mgmt_url = svc['endpoints'].detect{|x| x['publicURL']}['publicURL'] token = body['access']['token']['id'] return { :token => token, :server_management_url => mgmt_url } else raise "Unable to parse service catalog." end end end end