def initialize(connection)
tries = connection.retries
time = 3
begin
server = Net::HTTP::Proxy(connection.proxy_host, connection.proxy_port).new(connection.auth_host, connection.auth_port)
if connection.auth_scheme == "https"
server.use_ssl = true
server.verify_mode = OpenSSL::SSL::VERIFY_NONE
unless connection.ca_cert.nil?
server.ca_file = connection.ca_cert
server.verify_mode = OpenSSL::SSL::VERIFY_PEER
end
server.ssl_version = connection.ssl_version unless connection.ssl_version.nil?
end
server.start
rescue
puts "Can't connect to the server: #{tries} tries to reconnect" if connection.is_debug
sleep time += 1
retry unless (tries -= 1) <= 0
raise OpenStack::Exception::Connection, "Unable to connect to #{server}"
end
auth = { "auth" => { "identity" => {} } }
case connection.auth_method.to_sym
when :password
auth["auth"]["identity"]["methods"] = ["password"]
auth["auth"]["identity"]["password"] = { "user" => { "name" => connection.authuser, "password" => connection.authkey } }
auth["auth"]["identity"]["password"]["user"]["domain"] = connection.user_domain ? { "name" => connection.user_domain } : { "id" => connection.user_domain_id }
when :password_user_id
auth["auth"]["identity"]["methods"] = ["password"]
auth["auth"]["identity"]["password"] = { "user" => { "id" => connection.authuser, "password" => connection.authkey } }
when :token
auth["auth"]["identity"]["methods"] = ["token"]
auth["auth"]["identity"]["token"] = { "id" => connection.authkey }
else
raise Exception::InvalidArgument, "Unrecognized auth method #{connection.auth_method}."
end
if (connection.project_id || connection.project_name) && (connection.project_domain_name || connection.project_domain_id)
auth["auth"]["scope"] = { "project" => { "domain" => {} } }
auth["auth"]["scope"]["project"]["name"] = connection.project_name if connection.project_name
auth["auth"]["scope"]["project"]["id"] = connection.project_id if connection.project_id
auth["auth"]["scope"]["project"]["domain"]["name"] = connection.project_domain_name if connection.project_domain_name
auth["auth"]["scope"]["project"]["domain"]["id"] = connection.project_domain_id if connection.project_domain_id
end
if connection.domain_name || connection.domain_id
auth["auth"]["scope"] = { "domain" => {} }
auth["auth"]["scope"]["domain"]["name"] = connection.domain_name if connection.domain_name
auth["auth"]["scope"]["domain"]["id"] = connection.domain_id if connection.domain_id
end
response = server.post(connection.auth_path.chomp('/') + '/auth/tokens',
JSON.generate(auth),
{'Content-Type' => 'application/json'})
if connection.is_debug
puts "REQUEST: POST => #{connection.auth_path.chomp('/') + '/auth/tokens'}"
puts "RESPONSE: #{response.body}"
puts '----------------------------------------'
end
if response.code =~ /^20./
connection.authtoken = response['X-Subject-Token']
resp_data=JSON.parse(response.body)
catalog = resp_data["token"]["catalog"]
unless catalog
raise OpenStack::Exception::Authentication, "No service catalog returned. Maybe your auth request is unscoped. Please check if your selected user has a default project."
end
implemented_services = resp_data["token"]["catalog"].map {|service| service['type']}
raise OpenStack::Exception::NotImplemented.new("The requested service: \"#{connection.service_type}\" is not present " +
"in the returned service catalogue.", 501, "#{resp_data["access"]["serviceCatalog"]}") unless implemented_services.include?(connection.service_type)
catalog.each do |service|
service["endpoints"].each do |endpoint|
connection.regions_list[endpoint["region"]] ||= []
connection.regions_list[endpoint["region"]] << {:service=>service["type"], :versionId => endpoint["versionId"]}
end
if connection.service_name
check_service_name = connection.service_name
else
check_service_name = service['name']
end
if service['type'] == connection.service_type and service['name'] == check_service_name
endpoints = service["endpoints"]
interface_type = connection.endpoint_type.gsub('URL','')
endpoints = endpoints.select {|ep| ep['interface'] == interface_type}
if connection.region
endpoints.each do |ep|
if ep["region"] and ep["region"].upcase == connection.region.upcase
@uri = URI.parse(ep['url'])
end
end
else
@uri = URI.parse(endpoints[0]['url'])
end
if @uri == ""
raise OpenStack::Exception::Authentication, "No API endpoint for region #{connection.region}"
else
connection.service_host = @uri.host
connection.service_path = @uri.path
connection.service_port = @uri.port
connection.service_scheme = @uri.scheme
connection.authok = true
end
end
end
else
connection.authtoken = false
raise OpenStack::Exception::Authentication, "Authentication failed with response code #{response.code}"
end
server.finish if server.started?
end