Packages
An adapter for the openstex library for making calls to Openstack compliant Rackspace services.
Current section
Files
Jump to
Current section
Files
lib/rackspace/config.ex
defmodule Openstex.Adapters.Rackspace.Config do
defmacro __using__(opts) do
quote bind_quoted: [opts: opts] do
@moduledoc :false
alias Openstex.Keystone.V2.Helpers.Identity
alias Openstex.Adapters.Rackspace.Utils
alias Openstex.Keystone.V2.Helpers
@default_headers [{"Content-Type", "application/json; charset=utf-8"}]
@default_options [timeout: (60 * 1000), recv_timeout: (10 * 60 * 1000)]
@default_adapter HTTPipe.Adapters.Hackney
@default_rackspace_region :nil
use Openstex.Adapter.Config
# public
def start_agent(client, opts) do
otp_app = Keyword.get(opts, :otp_app, :false) || raise("Client has not been configured correctly, missing `:otp_app`")
identity = Utils.create_identity(client, otp_app)
Agent.start_link(fn -> config(client, otp_app, identity) end, name: agent_name(client))
end
@doc "Gets the rackspace related config variables from a supervised Agent"
def rackspace_config(client) do
Agent.get(agent_name(client), fn(config) -> config[:rackspace] end)
end
# private
defp config(client, otp_app, identity) do
[
rackspace: rackspace_config(client, otp_app),
keystone: keystone_config(client, otp_app, identity),
swift: swift_config(client, otp_app, identity),
hackney: hackney_config(client, otp_app)
]
end
defp rackspace_config(client, otp_app) do
get_config_from_env(client, otp_app) |> Keyword.fetch!(:rackspace)
end
defp keystone_config(client, otp_app, identity) do
keystone_config = get_keystone_config_from_env(client, otp_app)
tenant_id = keystone_config[:tenant_id] ||
identity.token.tenant.id ||
raise("cannot retrieve the tenant_id for keystone")
user_id = keystone_config[:user_id] ||
identity.user.id ||
raise("cannot retrieve the user_id for keystone")
endpoint = keystone_config[:endpoint] ||
"https://identity.api.rackspacecloud.com/v2.0"
[
tenant_id: tenant_id,
user_id: user_id,
endpoint: endpoint
]
end
defp swift_config(client, otp_app, identity) do
swift_config = get_swift_config_from_env(client, otp_app)
account_temp_url_key1 = get_account_temp_url(client, otp_app, :key1) ||
swift_config[:account_temp_url_key1] ||
:nil
if account_temp_url_key1 != :nil && swift_config[:account_temp_url_key1] != account_temp_url_key1 do
error_msg =
"Warning, the `account_temp_url_key1` for the elixir `config.exs` for the swift client " <>
"#{inspect client} does not match the `X-Account-Meta-Temp-Url-Key` on the server. " <>
"This issue should probably be addressed. See Openstex.Adapter.Config.set_account_temp_url_key1/2."
IO.puts(:stdio, error_msg)
end
account_temp_url_key2 = get_account_temp_url(client, otp_app, :key2) ||
swift_config[:account_temp_url_key2] ||
:nil
if account_temp_url_key2 != :nil && swift_config[:account_temp_url_key2] != account_temp_url_key2 do
error_msg =
"Warning, the `account_temp_url_key2` for the elixir `config.exs` for the swift client " <>
"#{inspect client} does not match the `X-Account-Meta-Temp-Url-Key-2` on the server. " <>
"This issue should probably be addressed. See Openstex.Adapter.Config.set_account_temp_url_key2/2."
IO.puts(:stdio, error_msg)
end
region = swift_config[:region] ||
identity.user.mapail["RAX-AUTH:defaultRegion"] ||
raise("cannot retrieve the region for keystone")
if swift_config[:region] != :nil && identity.user.mapail["RAX-AUTH:defaultRegion"] != swift_config[:region] do
error_msg =
"Warning, the `swift_config[:region]` for the elixir `config.exs` for the swift client " <>
"#{inspect client} does not match the `RAX-AUTH:defaultRegion` on the server. " <>
"This issue should probably be addressed."
IO.puts(:stdio, error_msg)
end
[
account_temp_url_key1: account_temp_url_key1,
account_temp_url_key2: account_temp_url_key2,
region: region
]
end
defp hackney_config(client, otp_app) do
hackney_config = get_hackney_config_from_env(client, otp_app)
timeout = hackney_config[:timeout] || @default_options[:timeout]
receive_timeout = hackney_config[:recv_timeout] || @default_options[:recv_timeout]
[
timeout: timeout,
recv_timeout: receive_timeout,
]
end
defp get_account_temp_url(client, otp_app, key_atom) do
identity = Utils.create_identity(client, otp_app)
x_auth_token = Map.get(identity, :token) |> Map.get(:id)
endpoint = get_public_url(client, otp_app, identity)
headers =
@default_headers ++
[
{
"X-Auth-Token", x_auth_token
}
]
|> Enum.into(%{})
header =
case key_atom do
:key1 -> "X-Account-Meta-Temp-Url-Key"
:key2 -> "X-Account-Meta-Temp-Url-Key-2"
end
request =
%HTTPipe.Request{
method: :get,
url: endpoint,
body: :nil,
headers: headers
}
{:ok, conn} = %HTTPipe.Conn{request: request, adapter_options: @default_options, adapter: @default_adapter}
|> Openstex.Request.request(:nil)
HTTPipe.Conn.get_resp_header(conn, header)
end
defp get_public_url(client, otp_app, identity) do
swift_config = get_swift_config_from_env(client, otp_app)
region = swift_config[:region] ||
identity.user.mapail["RAX-AUTH:defaultRegion"] ||
@default_rackspace_region ||
raise("cannot retrieve the region for keystone")
identity
|> Map.get(:service_catalog)
|> Enum.find(fn(%Identity.Service{} = service) ->
service.name == swift_service_name() &&
service.type == swift_service_type()
end)
|> Map.get(:endpoints)
|> Enum.find(fn(%Identity.Endpoint{} = endpoint) ->
endpoint.region == region
end)
|> Map.get(:public_url)
end
end
end
end